简体   繁体   English

如何以vmware的清晰度动态切换主题

[英]How to dynamically switch theme with vmware clarity

Vmware Clarity 0.10.16 just released the new dark theme. Vmware Clarity 0.10.16 刚刚发布了新的深色主题。 This is great!这太棒了!

They described how to add that new theme, but nothing about the possibility to dynamically change it inside the page.他们描述了如何添加新主题,但没有提到在页面内动态更改它的可能性。 Is it because it is not doable?是因为它不可行吗?

If it is, how can I do it with Angular 4+?如果是,我该如何使用 Angular 4+ 做到这一点? Any site that could help me explaining how to realize that?任何可以帮助我解释如何实现这一点的网站?

Thanks in advance!提前致谢!

Clarity now ships with stylesheets for both light and dark themes. Clarity 现在附带用于浅色和深色主题的样式表。 We document how to consume them here with both angular-cli or webpack build configurations.我们 在这里记录了如何使用angular-cliwebpack构建配置来使用它们。 That means that once the app is built, that is only style it has.这意味着一旦构建了应用程序,那就是它唯一的风格。

I have some ideas about how to implement a theme switcher for toggling between the two.我有一些关于如何实现主题切换器以在两者之间切换的想法。 Here is a rough idea I might start my prototype with:这是一个粗略的想法,我可以用它来开始我的原型:

  1. Build the app without either of the theme css files (no clarity style at all)在没有任何主题 css 文件的情况下构建应用程序(根本没有清晰的样式)
  2. Copy both css files to the assets folder (during the build)将两个 css 文件复制到 assets 文件夹(在构建期间)
  3. Write a directive or component that can take an @Input of the the src for a stylesheet in the <head>编写一个指令或组件,可以在<head>为样式表采用 src 的@Input
  4. Store the both paths /path/to/light.css and /path/to/dark.css in a service so the app could pass the active theme value around and modify it when needed.将路径/path/to/light.css/path/to/dark.css在服务中,以便应用程序可以传递活动主题值并在需要时对其进行修改。
  5. Add the service to the app components where we want to let users update the theme.将服务添加到我们希望让用户更新主题的应用程序组件中。

Does this give you some ideas for your app?这是否为您的应用程序提供了一些想法?

I'll update here after I have a prototype working so you can see it in action and find the source code.我会在原型工作后更新这里,以便您可以看到它的运行情况并找到源代码。

I've built a proof of concept how you could do this, but it does have some limitations.我已经建立了一个概念证明你可以如何做到这一点,但它确实有一些限制。 Since you can only include one theme file at a time, there can be some lag for the correct theme to render since it happens later in the Angular rendering cycle.由于您一次只能包含一个主题文件,因此正确的主题渲染可能会有一些延迟,因为它发生在 Angular 渲染周期的后期。 It would only big a big deal when the cache is empty for a browser, as subsequent visits would render quickly, but that is a major consideration here.当浏览器的缓存为空时,这只会是一个大问题,因为后续访问会快速呈现,但这是这里的一个主要考虑因素。 Its a start that you might be able to build something more robust upon.它是您可能能够构建更强大的东西的开始。

https://stackblitz.com/edit/clarity-theme-switcher?file=app%2Fapp.component.ts https://stackblitz.com/edit/clarity-theme-switcher?file=app%2Fapp.component.ts

Here is what I did:这是我所做的:

  1. I created two SCSS stylesheets.我创建了两个 SCSS 样式表。 Load them both in the angular.json configuration.angular.json配置中加载它们。 In stylesheet 1, import Clarity default theme.在样式表 1 中,导入 Clarity默认主题。 In stylesheet 2, import Clarity dark theme inside an class-selector .在样式表 2 中,在 class-selector 中导入 Clarity深色主题。 Like so:像这样:
.dark-mode {
    @import "~@clr/ui/src/utils/theme.dark.clarity"; // Dark theme variables
    @import '~@clr/ui/src/utils/components.clarity';

    // @import third party styling...

    // Fix styling HTML-tag.
    // node_modules\@clr\ui\src\typography\_typography.clarity.scss
    & html {
        color: $clr-global-font-color;
        font-family: $clr-font;
        font-size: $clr-baseline-px;
    }
}
  1. In the AppComponent constructor import @Inject(DOCUMENT) private document: Document .AppComponent构造函数中导入@Inject(DOCUMENT) private document: Document
  2. To enable dark-mode, I used the following code:为了启用暗模式,我使用了以下代码:
this.document.documentElement.classList.add('dark-mode');

I used localStorage to store the users preference.我使用localStorage来存储用户首选项。

The advantage of this is:这样做的好处是:

  • There is no FOUC.没有 FOUC。
  • I don't need to tweak with existing stylesheets or replace existing stylesheets.我不需要调整现有的样式表或替换现有的样式表。

The disadvantage is:缺点是:

  • Every CSS selector will be duplicated with in the .dark-mode class-selector.每个 CSS 选择器都将在.dark-mode类选择器中复制。 This doubles the file size.这使文件大小加倍。 I didn't consider this any problem.我不认为这有什么问题。
  • A small fix is needed for the html -element styling. html元素样式需要一个小的修复。 Solution included in the example above.解决方案包含在上面的示例中。

I have implemented it adding a link in the index.html我已经实现了它在 index.html 中添加了一个链接

<link id="theme" rel="stylesheet" href="https://unpkg.com/@clr/ui/clr-ui.min.css" />

Then in your app.component.ts然后在你的 app.component.ts

linkRef: HTMLLinkElement;
themes = [
    'https://unpkg.com/@clr/ui/clr-ui.min.css',
    'https://unpkg.com/@clr/ui/clr-ui-dark.min.css'
];
constructor(){
  this.linkRef = document.getElementById('theme') as HTMLLinkElement;
  // you could change here the theme if you have it stored in local storage
  // for example
  // const theme = localStorage.getItem('theme')
  // if(theme) this.linkRef.href = this.themes[parseInt(theme)]
}
setTheme(dark:bool){
  this.linkRef.href = this.themes[dark ? 1 : 0]
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM