为 TDesignBlazor 添加暗黑模式

简介: 本文将讲述我为 TDesignBlazor 开源项目提交 PR 的经历,主要介绍暗黑模式功能的实现以及之后如何在项目中使用。我将会分享我在实现这一功能时遇到的问题,以及我是如何解决这些问题的。我希望通过我的经历能够鼓励更多的人参与开源项目,为 TDesignBlazor 贡献代码,帮助项目快速迭代。

1. 背景

TDesign 是腾讯各业务团队在服务业务过程中沉淀的一套企业级设计体系。其支持业界主流的 React/Vue/Angular/微信小程序/Flutter 开发技术栈,并提供桌面端和移动端两套风格统一的组件资源,是一款界面和使用体验都无可挑剔的前端框架。

TDesign 官方是没有提供 Blazor 版本的支持,很幸运的是在我自己搭好了架子捣鼓了一个组件后,发现社区已经有了一个非常完善的 TDesignBlazor。毕竟工作量非常大,一个人的力量是有限的,需要社区的力量来支撑。也是刚好看到张队转载的文章,发起者在寻求 Blazor 爱好者参与,所以我决定加入进来,帮助维护和改进这个项目。这样就能够将 TDesign 的优秀设计和交互体验带到 Blazor 项目中,提高开发效率和用户体验。我相信社区的力量,我们一起能够完成这个目标。

2. 开发过程

TDesign 组件库提供了暗色模式,并且官方的演示站点是有暗黑模式的体验。这里我们要为 TDesignBlazor 项目的演示站点添加暗黑模式,并为使用该 Blazor 组件的项目提供简单的调用暗黑模式的方式。

2.1 实现原理

根据 TDesign 文档的介绍,我们只需要给网页的 html 标签增加 theme-mode 属性即可。其组件库会自动变换颜色模式,通过此种方式也可以设置不同的颜色主题。

暗色模式

其实现的原理也非常简单,组件库使用 css variables(自定义属性)实现颜色的定义,同时定义了 :root[theme-color="custom-theme"][theme-mode="dark"] 选择器来设置浅色/暗色模式两组不同的颜色值,然后通过 js 控制 html 标签的 theme-mode 属性:setAttributeremoveAttribute 来实现主题的切换。

我们可以在官方演示站点通过 F12 打开开发人员工具,审查 html 标签来看到这些信息:

审查元素

2.2 TDesignBlazor 实现思路

通过文档我们已经了解到,暗色模式只需要通过 js 控制 html 标签的 theme-mode 属性:

// 设置暗色模式
document.documentElement.setAttribute('theme-mode', 'dark');
// 重置为浅色模式
document.documentElement.removeAttribute('theme-mode');

这里对于 TDesignBlazor 暗黑功能的实现,我们只需要通过 .NET 调用 JavaScript 函数即可。关于这一块的相关知识可以参考微软官方文档:《JavaScript 互操作》

参与开源项目,首先我们要遵守项目的贡献指南,更要了解这个项目。在 TDesignBlazor 项目中,src 目录下是 TDesign 的 Blazor 类库和测试项目。doc 目录下是 Blazor 类库使用的演示站点,分为 ServerSide 和 WebAssembly 两种形式,Shared 是两者共用的部分。

搞清楚了项目的基本情况,我们就可以动手添加这一部分功能了。前面我们也讲到,最好是在 Blazor 类库中提供可以直接切换的方法。

首先,在 tdesign-blazor.js 添加相关的 js 方法。

/**
 * 暗黑模式
 * */
let theme = {
    /**
     * 浅色模式
     * */
    light: function () {
        document.documentElement.removeAttribute('theme-mode');
    },
    /**
     * 暗色模式
     * */
    dark: function () {
        document.documentElement.setAttribute('theme-mode', 'dark');
    }
}

TDesignExtensions.cs 是 TDesign 的扩展,我在里面添加 ChangeThemeMode 方法。

/// <summary>
/// 执行切换暗黑和浅色模式切换
/// </summary>
/// <param name="js"></param>
/// <param name="isDark">是否为暗黑模式</param>
public static async Task ChangeThemeMode(this IJSRuntime js, bool isDark = true)
{
    var jsObject = await js.ImportScriptAsync();
    await jsObject.InvokeVoidAsync(isDark ? "theme.dark" : "theme.light");
}

对于演示站点的修改,大部分工作主要是界面上的,集中在 doc/TDesign.Docs.Shared/Layouts/MainLayout.razor。这里需要添加一个 TInputRadioGroup 主题切换的按钮,样式按照官方站点设计即可。在需要执行主题切换调用的地方执行 JS.ChangeThemeMode 方法,如下:

@using Microsoft.JSInterop
@inject IJSRuntime JS

<TInputRadioGroup @bind-Value="ThemeMode" OnValueSelected="@(e=>JS.ChangeThemeMode(e=="2"))" Size="Size.Medium" ButtonStyle="RadioButtonStyle.Outline">
    <TInputRadio Value="1">浅色</TInputRadio>
    <TInputRadio Value="2">暗黑</TInputRadio>
</TInputRadioGroup>

@code{
    int ThemeMode { get; set; } = 1;
}

3. 最后

《礼记·学记》中有这样一句:“学然后知不足,教然后知困。知不足,然后能自反也;知困,然后能自强也。故曰教学相长也。”

参与开源项目和写文章也是学习的过程,这可以让你结交不同的朋友,学到更多的知识。项目的贡献不在于大小,每个人都可以做自己力所能及的事情。要相信众人拾柴的力量,这些细小的贡献最终将有助于推动开源社区变得更好。

相关文章
|
8月前
|
SQL 安全 数据库
GoWind Admin|风行 — 开箱即用的企业级全栈中后台框架:数据权限体系设计与实现
GoWind Admin(风行)是开箱即用的企业级全栈中后台框架,内置五层数据权限体系:租户隔离、业务单元、行级、列级、操作/状态级,支持多租户、ABAC动态策略与非侵入式DataScope引擎,实现安全合规、灵活可扩展的权限管理。(239字)
1518 2
|
Java Maven Android开发
【Maven学习】Nexus私服代理其他第三方的Maven仓库
一、背景 【Maven学习】Nexus OSS私服仓库的安装和配置http://blog.csdn.net/ouyang_peng/article/details/78793038 【Maven学习】Nexus OSS私服仓库的备份与迁移http://blog.csdn.net/ouyang_peng/article/details/78796215 通过前面的两篇博客,我们已经将Nexus搭建好并且迁移到了新的机房,现在我发现我们之前的Nexus私服服务器居然没有对第三方经常使用的JCenter等没有做代理。
9240 0
|
并行计算 PyTorch TensorFlow
Ubuntu安装笔记(一):安装显卡驱动、cuda/cudnn、Anaconda、Pytorch、Tensorflow、Opencv、Visdom、FFMPEG、卸载一些不必要的预装软件
这篇文章是关于如何在Ubuntu操作系统上安装显卡驱动、CUDA、CUDNN、Anaconda、PyTorch、TensorFlow、OpenCV、FFMPEG以及卸载不必要的预装软件的详细指南。
12927 4
|
12月前
|
机器学习/深度学习 移动开发 算法
改进的激光方法与更快的矩阵乘法——论文阅读
Josh Alman与Virginia Vassilevska Williams在2021年提出改进的激光方法,将矩阵乘法指数ω的上界从2.37287降至2.37286。虽改进微小,但标志着自1986年以来核心技术的重要突破,展示了激光方法的潜力与优化空间。
423 3
|
SQL 关系型数据库 MySQL
实时计算 Flink版产品使用合集之如何做mysqltomysql同步任务
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStreamAPI、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
|
监控 UED
跨部门协作中的任务协调:上级管理者的高效方法
在现代企业中,跨部门协作至关重要,但常因职能差异、信息不对称和沟通不畅导致任务分配不明确、资源浪费。上级管理者需充当战略目标传达者、任务协调者、信息共享推动者及冲突调解者,通过明确职责、建立协作机制、优化信息流程、引入高效工具等策略,避免重复劳动,提升组织效率。
1500 15
|
JavaScript 前端开发
js 定时器用法详解——setTimeout()、setInterval()、clearTimeout()、clearInterval()
写在前面: 在js应用中,定时器的作用就是可以设定当到达一个时间来执行一个函数,或者每隔几秒重复执行某段函数。这里面涉及到了三个函数方法:setInterval()、setTimeout()、clearInterval(),本文将围绕这三种函数的用法,来实现定时器的功能,需要的朋友可以过来参考下,喜欢的可以点波赞,或者关注一下本人,希望对大家有所帮助。 定时器的应用需求: 1.设定一个时间,当时间到达的时候执行函数————比如:倒计时跳转页面等等。 2.每隔一段时间重复执行某段函数————比如抢票软件,比如设定500毫秒就重复刷新一次页面等等。 倒计时跳转实现demo:
1256 0
js 定时器用法详解——setTimeout()、setInterval()、clearTimeout()、clearInterval()
|
jenkins Java 程序员
实战:向GitHub提交代码时触发Jenkins自动构建
当我们提交代码到GitHub后,可以在Jenkins上执行构建,但是每次都要动手去执行略显麻烦,今天我们就来实战Jenkins的自动构建功能,每次提交代码到GitHub后,Jenkins会进行自动构建
1550 0
实战:向GitHub提交代码时触发Jenkins自动构建
|
存储 算法 固态存储
CRUSH映射图及自定义规则实战篇
Ceph存储系统中CRUSH映射图及自定义规则的实战教程,涵盖了PG与OSD映射调整、CRUSH运行图修改案例以及CRUSH数据分类管理等内容。
674 1
|
API
Vite 中环境变量的配置方法
【10月更文挑战第10天】 Vite 中环境变量的配置方法
1831 2

热门文章

最新文章