npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@hzab/theme-tools

v0.0.3

Published

主题切换配置

Readme

theme-tools 主题切换插件

一个 React 主题切换解决方案,支持动态主题配置、自动暗色模式、CSS 变量管理和类型安全的主题开发。

✨ 特性

| 功能 | 描述 | |---------------------|--------------------------------------------------------------------| | 🌈 多模式支持 | 亮色/暗色/自动/自定义主题模式以及动态型自定义主题模式 | | 🤖 自动暗色适配 | 智能跟随系统主题变化 | | 🎨 CSS 变量管理 | 自动转换驼峰命名到 CSS 变量格式 (e.g. primaryColor--primary-color) | | 🧩 插件化架构 | 轻松扩展自定义主题配置 | | 🚀 高性能 | 基于 Emotion CSS-in-JS 和智能缓存优化 | | 🔒 类型安全 | 完整的 TypeScript 类型支持 |

⬇️ 安装

npm install @hzab/theme-tools
# 或
yarn add @hzab/theme-tools

📚 核心功能

主题模式

  • light: 强制亮色模式
  • dark: 强制暗色模式
  • auto: 自动匹配系统主题
  • custom: 动态型自定义主题
  • 扩展模式:支持通过配置添加任意主题模式

CSS 变量管理

自动将主题配置转换为 CSS 变量,将小驼峰的变量转为符合CSS变量规范的中划线格式,例如primaryColor会被转换为--primary-color ```css

:root {
  --primary-color: #1677ff;
  --text-color: rgba(0, 0, 0, 0.88);
}

```

主题配置

主题优先级从高到低:overrides > customModes > defaultModes, overrides属性属于修复型配置

📚 API 参考

ThemeProvider

| 属性 | 类型 | 默认值 | 描述 | 版本 | |--------------|-----------------------------------------------------|----------------|---------------------------------|-------| | appearance | "light" | "dark" | "custom" | "auto" | "string" | "light" | 外观 | 0.0.1 | | themeConfig | ThemeConfig | - | 主题配置对象 | 0.0.1 | | prefix | string | - | CSS变量前缀 | 0.0.1 | | hashPriority | "low" | "high" | "high" | 插入样式时是否降低选择器优先级 | 0.0.1 | | cssVarMountName | string | ":root" & body | 自定义CSS变量挂载位置,指为css选择器,选择器名称尽量唯一 | 0.0.3 |

useTheme


const { token, css, cx } = useTheme()

useThemeMode


// 控制主题模式
const {
  themeMode,
  appearance,
  setThemeMode,
  availableModes,
  isDarkMode,
  // ...更多其它属性
}: ThemeContextState = useThemeMode()

Type

ThemeProviderProps

interface ThemeProviderProps {
  /**
   * @title 变量前缀
   */
  prefix?: string;
  /**
   * @title 默认主题模式
   * @default "light"
   */
  appearance?: ThemeMode;
  /**
   * @title 主题配置
   */
  themeConfig?: ThemeConfig;
  /**
   * @title 使用emtion时是否开启优先级降低模式(在开发组件时比较有用,可以更简单的覆盖组件样式)
   */
  hashPriority?: HashPriority;
  /**
   * @title 自定义挂载css变量节点的位置,值为id选择器或者class选择器,名称尽可能的唯一
   */
  cssVarMountName?: string;

  children?: React.ReactNode;
}

ThemeConfig

type ThemeConfig<T = Record<string, any>> = {
/**
 * @title 默认主题配置
 */
  defaultModes?: ThemeConfigDefaultType<T>;
/**
 * @title 自定义主题模式
 */
  customModes?: Record<string, Partial<T>>;
/**
 * @title 全局覆盖(紧急修复用)
 * @description 会覆盖所有模式的配置,慎用
 */
  overrides?: Partial<T>;
};

ThemeContextState


interface ThemeContextState<T = Record<string, any>> {
  /**
   * @title 当前主题配置
   */
  token: T;
  /**
   * @title 外观
   */
  appearance: ThemeAppearance;
  /**
   * @title 主题模式
   * @enum ["light", "dark", "custom", "auto", [key: string]: Record<string, string> ]
   * @enumNames ["亮色模式", "暗色模式", "跟随系统", "动态型自定义","配置型自定义"]
   * @default "light"
   */
  themeMode: ThemeMode;
  /**
   * @title 是否是暗色主题
   */
  isDarkMode: boolean;
  /**
   * @title 主题模式集合
   */
  availableModes?: Array<keyof ThemeConfigDefaultType & T>;

  /**
   * @title EmotionCache
   */
  cache: EmotionCache;

  /**
   * @title 设置主题模式
   */
  setThemeMode: (themeMode: ThemeMode) => void;
  /**
   * @title 设置自定义主题模式
   */
  setCustomToken: (token: T) => void;
  /**
   * @title 重置自定义主题
   */
  resetCustomToken: () => void;

  /**
   * @title 缓存实例
   */
  cacheManager: CacheManager;
}

🎯 最佳实践

支持三种使用方式,建议使用第一种

  • themeConfig中的配置会转换为body节点上的全局css变量,因此在使用时直接使用相关css变量即可;
  • 支持自定义挂载节点配置,将变量挂载到某个id选择器或者class选择器下面,默认挂载位置是“:root”和body;
  • 通过自定义hooks可以拿到相关的token配置;
  • Emotion CSS-in-JS 的写法:通过createStyles函数创建样式对象,返回一个自定义hook,该hook包函样式对象属性,通过className的方式引用样式对象即可;

基础使用

import { ThemeProvider, useTheme } from '@hzab/theme-switch'

function App() {
  return (
    <ThemeProvider
      appearance="auto"
      themeConfig={{
        defaultModes: {
          light: { primary: '#1677ff', text: '#000' },
          dark: { primary: '#1890ff', text: '#fff' }
        }
      }}
    >
      <MyComponent />
    </ThemeProvider>
  )
}

使用方式1:

// 在组件中
function MyComponent() {
  const { token } = useTheme()

  return (
    <div style={{ color: token.text }}>
      <button style={{ background: token.primary }}>
        主题化按钮
      </button>
    </div>
  )
}

使用方式2:

.container {
  width: 100vw;
  height: 100vh;
  background-color: var(--background-color);
}

进阶用法

通过useThemeMode实现模式切换

// 创建带自动 CSS 变量转换的样式
const useStyles = createStyles(({ token, css }) => ({
  container: css`
    background: token.background;
    padding: 16px;
    border: 1px solid ${token.border};
    
    &:hover {
      background: ${token.primary}20;
    }
  `
}))

// 切换主题模式
function ThemeSwitcher() {
  const { themeMode, setThemeMode } = useThemeMode()
  
  return (
    <div>
      <button onClick={() => setThemeMode('light')}>亮色</button>
      <button onClick={() => setThemeMode('dark')}>暗色</button>
      <button onClick={() => setThemeMode('custom')}>自定义</button>
    </div>
  )
}

📌 注意事项

  • React ≥ 16.8 (需要 Hooks)

  • TypeScript ≥ 4.1 (推荐)

  • 推荐使用防抖/节流处理主题更新操作

  • 避免在渲染循环中频繁调用 setCustomToken(),由于是Emotion CSS-in-JS的动态方案,在每次调整主题样式相关的状态时都会插入一个style标签,在大量更新(例如使用调色板)主题状态时,会插入非常多的style标签会