定制主题

Ant Design 设计规范上支持一定程度的样式定制,以满足业务和品牌上多样化的视觉需求,包括但不限于主色、圆角、边框和部分组件的视觉定制。

定制主题 - 图1

定制方式

Ant Design 的样式使用了 Less 作为开发语言,并定义了一系列全局/组件的样式变量,你可以根据需求进行相应调整,默认样式变量:NG-ZORRONG-ALAIN 两部分。

初始化项目时定制主题

在初始化项目时 ng add ng-alain 时选择自定义主题即可自动配置好自定义主题的相关文件,修改 src/styles/theme.less 文件内容就可以自定义主题。

官方主题

我们提供了一些官方主题,欢迎在项目中试用,并且给我们提供反馈。

  • 🌑 暗黑主题(9+ 支持)

  • 📦 紧凑主题(9+ 支持)

方式一

在样式文件 src/styles.less 全量引入 theme-dark.lesstheme-compact.less 覆盖主题变量。

  1. @import '~@delon/theme/system/index';
  2. @import '~@delon/abc/index';
  3. @import '~@delon/chart/index';
  4. @import '~@delon/theme/layout/default/index';
  5. @import '~@delon/theme/layout/fullscreen/index';
  6. @import './styles/index';
  7. @import './styles/theme';
  8. // 可以替换 dark, compact
  9. // - `dark` 🌑 暗黑主题(9+ 支持)
  10. // - `compact` 📦 紧凑主题(9+ 支持)
  11. // @import '~@delon/theme/theme-compact.less';

方式二

如果项目不使用 Less,可在 CSS 文件或者 angular.jsonstyles 字段中,全量引入 dark.css 或者 compact.css

样式文件中:

  1. @import "~@delon/theme/dark.css";

angular.json 中

  1. {
  2. "build": {
  3. "options": {
  4. "styles": [
  5. "node_modules/@delon/theme/dark.css"
  6. ]
  7. }
  8. }
  9. }

主题切换

当使用 @angular/cli 的方式配置主题时必须为每个主题单独打包应用,当你想切换主题而不重新加载应用时(就像这个网站),你可以使用下面的方法将主题编译到单独的样式文件,并在运行时切换:

注意:确保与主题变量相关的样式存在全局样式中,而不是组件样式中,因为组件样式优先级更高将会导致样式无法被覆盖。

  1. 安装依赖
  1. # yarn
  2. yarn add less -D less-plugin-clean-css -D less-plugin-npm-import -D
  3. # npm
  4. # npm i less -D less-plugin-clean-css -D less-plugin-npm-import -D
  1. 编写脚本

以黑暗主题为例,使用 less 编译应用的样式入口文件,并且在 modifyVars 参数中替换样式变量,并输出到目标位置。

完整代码请参考 theme.js

  1. const less = require('less');
  2. const LessPluginCleanCSS = require('less-plugin-clean-css');
  3. const LessPluginNpmImport = require('less-plugin-npm-import');
  4. const fs = require('fs');
  5. const darkThemeVars = require('@delon/theme/theme-dark');
  6. const appStyles = 'src/styles.less'; // 应用的样式入口文件
  7. const themeContent = `@import '${appStyles}';`;
  8. less.render(themeContent, {
  9. javascriptEnabled: true,
  10. plugins: [new LessPluginNpmImport({ prefix: '~' }), new LessPluginCleanCSS({ advanced: true })],
  11. modifyVars: {
  12. ...darkThemeVars
  13. }
  14. }).then(data => {
  15. fs.writeFileSync(
  16. // 主题样式的输出文件
  17. 'src/assets/style.dark.css',
  18. data.css
  19. )
  20. }).catch(e => {
  21. // 记录渲染错误
  22. console.error(e);
  23. });
  1. 运行时切换样式

动态创建 link 标签,将样式文件动态加载在应用中,反之移除。

完整代码请参考 theme-btn

  1. changeTheme(theme: 'default' | 'dark'): void {
  2. if (theme === 'dark') {
  3. const style = document.createElement('link');
  4. style.type = 'text/css';
  5. style.rel = 'stylesheet';
  6. style.id = 'dark-theme';
  7. style.href = 'assets/style.dark.css';
  8. } else {
  9. const dom = document.getElementById('dark-theme');
  10. if (dom) {
  11. dom.remove();
  12. }
  13. }
  14. }

注意:如果你使用 @delon/chart 或第三方组件,可能需要手动修改组件来支持相应的主题。

组件开发问题

以上主题切换方式是在一个将所有 Less 样式内容独立于 src/styles.less 下面,当正常情况下,还会在组件内定义,就像:

  1. @Component({
  2. selector: 'app-dashboard-analysis',
  3. templateUrl: './analysis.component.html',
  4. styleUrls: ['./analysis.component.less'],
  5. changeDetection: ChangeDetectionStrategy.OnPush,
  6. })
  7. export class DashboardAnalysisComponent {}
  1. // analysis.component.less
  2. @import '~@delon/theme/index';
  3. :host ::ng-deep {
  4. color: @text-color;
  5. }

由于组件内定义的样式独立运行在 Angular 下面,是无法根据 @import '~@delon/theme/theme-compact.less'; 的引入来整体切换成暗黑系,如果你希望在组件内也同样使用暗黑系,则必须将:

  1. // analysis.component.less
  2. - @import '~@delon/theme/index';
  3. + @import '~@delon/theme/theme-dark';

或者,重新针对某一个主题重新定义:

  1. // analysis.component.less
  2. [data-theme='dark'] {
  3. :host ::ng-deep {
  4. // 针对暗黑系重新定义
  5. }
  6. }

或紧凑主题:

  1. [data-theme='compact'] {
  2. :host ::ng-deep {
  3. // 针对紧凑重新定义
  4. }
  5. }

相关文章