「✍ 如何定制我的组件库主题色?」

1,582 阅读1分钟

前言

自己在写组件库的时候,样式通常写的比较随意,更多的精力会放在逻辑编写上,但事实上,主题色/国际化等配置是一个组件库必不可少的元素。

从简

在翻看一些开源ui库的时候,常常会发现以下样式写法

:root{
--theme-primary: #00bc70;
--theme-success: #00bc70;
--theme-warning: #ec9231;
--theme-danger: #ff5050;

 /* button */
 --button-primary: var(--theme-primary)
 --button-success: var(--theme-success)
 --button-warning: var(--theme-warning)
 --button-danger: var(--theme-danger)
}

button.css

.btn-primary{
  background-color: (--button-primary)
}
.btn-success{
  background-color: (--button-success)
}
.btn-warning{
  background-color: (--button-warning)
}
.btn-danger{
  background-color: (--button-danger)
}

这其实就是一种简单粗暴的主题色方案,想要切换某个主题色也很方便

 document.documentElement.style.setProperty('--theme-primary', '#191919')

知道了如何设置主题色,接下来就是包装成组件,下面以一个开源组件库zarm为例

先看看使用zarm时该如何定制主题

<ConfigProvider primaryColor="#1890ff">
    <App />
</ConfigProvider>

zarm 对外提供了一个ConfigProvider组件

export default class ConfigProvider extends PureComponent<ConfigProviderProps, {}> {
  static defaultProps = defaultConfig;

  render() {
    const { children, locale, theme, primaryColor } = this.props;
    changeRunTimeLocale(locale);
    setTheme(theme);
    setPrimaryColor(primaryColor);

    return (
      <ConfigContext.Provider value={{ locale, theme, primaryColor }}>
        {React.Children.only(children)}
      </ConfigContext.Provider>
    );
  }
}

该组件提供了主题/品牌色/国际化等配置,主要看看setThemesetPrimaryColor方法

// 暗黑模式
const themes = {
  '--theme-primary-lighter': '#303030',
  '--color-text': 'rgba(255, 255, 255, 0.85)',
  '--color-text-inverse': 'rgba(255, 255, 255, 0.8)',
  // ...
 }
const setTheme = (value: Theme) => {
  document.body.setAttribute('data-theme', value);
  Object.keys(themes).forEach((key) => {
    value === 'dark' // 如果是暗黑模式,切换色号
      ? document.documentElement.style.setProperty(key, themes[key])
      : document.documentElement.style.removeProperty(key);
  });
};
const setPrimaryColor = (color) => {
  document.documentElement.style.setProperty('--theme-primary', color);
  document.documentElement.style.setProperty('--theme-primary-dark', Color(color).darken(0.05));
  document.documentElement.style.setProperty('--button-primary-shadow-color', Color(color).alpha(0.3));
};

核心还是 document.documentElement.style.setProperty