@saco/theme
v2.0.3
Published
Theme runtime: core (Proxy) + Vue / React adapters
Maintainers
Readme
@saco/theme
主题运行时:浅色 / 深色、跟随系统、Cookie、跨标签同步、色表 JSON。
| 入口 | 用途 |
| ------------------- | ---------------------------------- |
| @saco/theme | 无框架核心(Proxy) |
| @saco/theme/vue | Vue:app.use + 可解构的 ref |
| @saco/theme/react | React:Provider + 可解构的 state/setter |
安装
pnpm add @saco/theme配置项
传入位置:
| 入口 | 写法 |
| ------------------- | --------------------------- |
| @saco/theme | createTheme(options) |
| @saco/theme/vue | createVueTheme(options) |
| @saco/theme/react | createReactTheme(options) |
| 字段 | 类型 | 默认值 | 说明 |
| ------------------ | ------------------ | ---------------------------------------- | ---------------------------- |
| colors | ColorsConfig | null | 色表来源,可选。不传则只切换主题类型 / html 属性 |
| cookieAttr | string | path=/; max-age=31536000; SameSite=Lax | 写入 Cookie 时附加的属性串 |
| themeCookieName | string | theme-type | 主题类型 Cookie 名 |
| systemCookieName | string | system-theme | 是否跟随系统 Cookie 名 |
| themeTypeDefault | 'light' | 'dark' | 'light' | 无 Cookie 时的主题类型默认值 |
| systemDefault | boolean | false | 无 Cookie 时是否跟随系统 |
| themeAttrName | string | data-theme-type | 写到 html 上的主题类型属性名 |
| systemAttrName | string | data-system-theme | 写到 html 上的跟随系统属性名 |
Vue
export const { themePlugin, useTheme } = createVueTheme<ThemeColors>({ colors })
app.use(themePlugin)
const { themeType, followSystemTheme, isDark, colors: palette } = useTheme()
themeType.value = 'dark'React
export const { ThemeProvider, useTheme } = createReactTheme<ThemeColors>({ colors })
<ThemeProvider>
<App />
</ThemeProvider>
const { themeType, setThemeType, isDark } = useTheme()
setThemeType('dark')无框架
核心是 Proxy:不要解构后赋值(const { themeType } = theme 再赋无效),应写 theme.themeType = 'dark'。
用 subscribe 在变更时刷新 UI:
const theme = createTheme()
// 或 createTheme<ThemeColors>({ colors })
const unsub = theme.subscribe(() => {
// 按需更新 UI,例如:
document.body.dataset.theme = theme.themeType
// 或触发自研框架 / 原生重绘
render()
})
theme.themeType = 'dark'
theme.followSystemTheme = true
// 页面卸载时
unsub()
theme.destroy()Vue / React 适配层内部已接好 subscribe,useTheme() 可直接解构使用。
色表 colors 详解
不传时只切换 themeType / html 属性,由 CSS 变量自行响应;需要在 JS 里读色表时再传。
支持三种写法:
// 1. 直接对象
colors: {
light: { primaryColor: '#409EFF' },
dark: { primaryColor: '#6D62BE' },
}
// 2. 具名懒加载(Vite dynamic import / Webpack)
colors: {
light: () => import('./light.json'),
dark: () => import('./dark.json'),
}
// 3. Vite / Webpack glob 映射
colors: import.meta.glob('./module/*.json')
// webpack 示例:把 require.context 转成 path → () => Promise 再传入License
MIT
