dojo dragon main logo

使用主题

小部件主题键

Dojo 的主题框架使用“小部件主题键”的概念将样式覆盖连接到相应的目标小部件。样式覆盖通常在主题中指定,但如果需要,也可以通过theme 中间件的 classes 覆盖属性直接传递

给定小部件的主题键确定为

{package-name}/{widget-css-module-name}

其中 package-name 是项目 package.jsonname 属性的值,widget-css-module-name 是用于小部件的主要 CSS 模块的文件名(不含 .m.css 扩展名)。

主题键示例

对于给定项目

package.json

{
	"name": "my-app"
}

遵循小部件 CSS 模块命名约定时,给定的小部件(例如 src/widgets/MyWidget.ts)将使用类似于 src/styles/MyWidget.m.css 的相应 CSS 模块名称。因此,MyWidget 的主题键为

my-app/MyWidget

这里,小部件的名称与它的 CSS 模块文件名称相同,但开发人员应注意不要将小部件的主题键误认为代表小部件的 TypeScript 类名称。

对于第二个不遵循 CSS 模块命名约定的 widget,例如 src/widgets/BespokeWidget.ts,它使用相应的 CSS 模块,例如 src/styles/BespokeStyleSheet.m.css,它的 widget 主题键将改为

my-app/BespokeStyleSheet

编写主题

主题是 TypeScript 模块,它们导出一个默认对象,该对象将小部件主题键映射到类型化的 CSS 模块导入。主题中的 CSS 模块与直接在小部件中使用的常规模块相同。在应用程序中应用主题后,通过主题定义对象中的主题键标识的每个小部件都将覆盖其样式,这些样式在与该小部件主题键关联的 CSS 模块中指定。

以下是针对单个 MyWidget 小部件(使用 MyWidget.m.css 的默认 CSS 模块)的完整主题的简单示例,它包含在名为 my-app 的项目中

src/themes/myTheme/styles/MyWidget.m.css

.root {
	color: blue;
}

src/themes/myTheme/theme.ts

import * as myThemedWidgetCss from './styles/MyWidget.m.css';

export default {
	'my-app/MyWidget': myThemedWidgetCss
};

这里,MyWidget 遵循命名约定,其主要样式类名为 root,允许 myTheme 通过其 src/themes/myTheme/styles/MyWidget.m.css CSS 模块中的 root 类轻松覆盖它。

该主题通过其my-app/MyWidget 的主题键将新的 root 样式类与 MyWidget 关联。当应用 myTheme 时,MyWidget 的颜色将设置为蓝色,并且不再接收其原始 CSS 模块中 root 类中定义的任何其他样式。

为第三方小部件搭建主题

应用程序主题可能需要包含对可能使用的任何第三方小部件的样式,例如由Dojo 的原生小部件库提供的那些。

@dojo/cli-create-theme 包通过其 dojo create theme CLI 命令提供工具支持,以快速生成第三方小部件的主题脚手架。它可以通过以下方式在应用程序中本地安装

npm install --save-dev @dojo/cli-create-theme

并且可以从项目的根目录中按如下方式使用

dojo create theme -n {myThemeName}

运行此命令将通过询问两个问题开始创建指定的 myThemeName 主题

  • 您要对哪个包进行主题化?
    • 此问题的答案应该是包含要进行主题化的第三方小部件的所有包,例如 @dojo/widgets。该命令将继续询问更多包,直到用户完成。
  • 您要为哪些{third-party-package} 主题文件搭建脚手架?
    • 将显示在回答第一个问题时指定的第三方包中所有可主题化的小部件的列表。然后,用户可以选择应该包含在生成的主题中的所有兼容小部件的子集 - 通常只选择当前应用程序中实际使用的小部件,以帮助将主题的大小保持在最小限度。

命令成功执行后,将在当前项目中创建几个文件

  • src/themes/{myThemeName}/theme.ts
  • src/themes/{myThemeName}/{third-party-package}/path/to/{selectedWidget}.m.css

为所有 {selectedWidget} 创建的主题的 CSS 模块附带可主题化的 CSS 选择器,然后可以使用 {myThemeName} 的适当样式填充这些选择器。

兼容包

任何包含 theme 目录的第三方包,该目录包含小部件 CSS 模块文件(*.m.css)及其相应的编译定义文件(*.m.css.js - 有关这些内容的详细信息,请参阅分发主题)都是兼容的。

例如

node_modules
└── {third-party-package}
    └── theme
        │   {widget}.m.css
        │   {widget}.m.css.js

分发主题

Dojo 的cli-build-theme 包提供了一个 CLI 命令,用于帮助构建旨在跨多个应用程序分发的主题。它将创建所有必要的文件以以多种不同的方式使用主题

请注意,当使用dojo create theme 搭建新的主题时,无需使用 dojo build theme,因为所有相关文件都已就位。这适用于通过@dojo/cli-build-app@dojo/cli-build-widget构建的项目的主题。

要使用该工具,请在主题项目中本地安装 @dojo/cli-build-theme

npm install --save-dev @dojo/cli-build-theme

然后要构建主题,请运行该命令并指定主题名称以及可选的发布版本

dojo build theme --name={myThemeName} --release={releaseVersion}

如果未指定 release,则将使用 package.json 中的当前版本。

运行该命令将在项目中创建一个新的 dist/src/{myThemeName} 目录,其中包含

使用 Dojo 提供的主题

@dojo/themes 包提供了一组现成的主题,涵盖了 Dojo 的原生小部件库中的所有小部件。这些主题可以按原样使用,也可以作为完整应用程序主题的基础进行组合

  1. 要使用这些主题,请将 @dojo/themes 安装到您的项目中,例如通过 npm i @dojo/themes。然后,对于常规的 Dojo 应用程序

  2. 将主题 CSS 导入到项目的 main.css

    @import '~@dojo/themes/dojo/index.css';
    
  3. 导入主题 TypeScript 模块并像使用任何其他主题一样使用它

    import theme from '@dojo/themes/dojo';
    
    render() {
    	return w(Button, { theme }, [ 'Hello World' ]);
    }
    

如果尝试在自定义元素中使用这些主题,则在安装 @dojo/themes

  1. 将自定义元素特定的主题 CSS 添加到 index.html

    <link rel="stylesheet" href="node_modules/@dojo/themes/dojo/dojo-{version}.css" />
    
  2. 将自定义元素特定的主题 JS 添加到 index.html

    <script src="node_modules/@dojo/themes/dojo/dojo-{version}.js"></script>