@codefusion-cc/theme

中文文档
0.1.5发布于 2026/11/09MITTypeScriptES Module零依赖近 30 天下载 2211

浅色、暗色或系统主题和取出外观,每个浏览器保留(每个账户也保留外观),并在第一次涂料前显示:页面从不闪出错误的外观,在打开时遵循系统,每个打开的标签都遵循变化,开关可以长出 t

中文使用文档
文档目录8 节
  1. 配置
  2. 外观
  3. 账户上的表情
  4. 第一次画之前
  5. 在页面中
  6. 在反应中
  7. 动画开关
  8. 在应用测试中

@ codumation-cc/ 主题

光,暗或系统主题,每个浏览器保持并显示在第一次油漆之前. 页面从不显示错误 主题,在打开时遵循系统,每一个打开的标签都遵循在另一个标签中所做的更改。 一个人的样子 选取( e)data-look,用于 @codefusion-cc/ui)和其他选择(调色板、口音)保留并显示在 模式,而外观可以跟随每个浏览器的签名人.

npm install @codefusion-cc/theme

配置

一个平面对象,由页面和Vite配置共享,所以预绘脚本和页面永远不能有异议:

// src/themeConfig.ts
import { defineTheme } from '@codefusion-cc/theme'

export const themeConfig = defineTheme({
  storageKey: 'myapp-theme',
  // Tailwind's dark class…
  html: { class: 'dark' },
  // …or daisyUI's data-theme, a value for each:
  // html: { attribute: 'data-theme', light: 'myapp-light', dark: 'myapp-dark' },
  themeColor: '--color-base-100',
})
  • storageKey: 将模式保存在本地Storage中。 存储 light 或者说 dark 计数; 其他一切(无 系统模式(system mode),取自更古老版本的值"垃圾")是系统模式. 系统模式和每一次默认保存为 没有,所以以后的默认 到达所有谁从来没有选择.

  • html问:如何 <html> 显示主题. color-scheme 总是设置, 所以浏览器自己的控制和滚动条 相匹配的。 匹配的.

  • themeColor: CSS 自定义属性, 持有页面背景 。 每个 <meta name="theme-color"> 取其价值 一旦页面已加载,并在每次更改后,那么一个已安装的app的标题栏和一个电话的浏览器栏匹配所选择的主题. 内容 media 属性被丢弃:系统其他模式的元将战胜取出. 计算到另一个颜色 空格( 注册颜色属性给定) oklch(…))被写作sRGB hex,每个浏览器的铬取出.

  • choices: 其它的外观,各自在自己的密钥下,带有它能够构成的值和一个默认值. 选择可以显示为 自己的数据属性( e)attribute: 'data-accent',无效时缺席)和 html其值可以命名为 {name}数字 :

    html: { attribute: 'data-theme', light: '{palette}', dark: '{palette}-dark' },
    choices: {
      palette: { storageKey: 'myapp-palette', values: ['graphite', 'ember'], default: 'graphite' },
      accent: { storageKey: 'myapp-accent', values: ['lime', 'sky'], default: null, attribute: 'data-accent' },
    },
    

defineTheme 丢出一个 TypeError 对于配置错误( 无密钥, 在一个密钥下有两件事, 默认为 不是一个值, a {name} 没有选择,一个看起来的名字 @codefusion-cc/ui (拒绝).

无法选择的存储值( 一个应用程序已删除, 一个在另一个应用程序中打开的更新版本) 选项卡,垃圾)读作选择的默认值,在第一次油漆之前,在页面和每个标签中。 它保存,所以如果 应用程序又有其价值(回滚版), 个人的取回.

外观

外观是一组值 @codefusion-cc/ui 从app的外观模块中编译出:颜色,字体,radi. 内容 样式表选择一个 data-look 打开 <html>,除光和暗(color-scheme) (中文(简体) ). lookChoice 让它成为一个 选择此属性 :

import { defineTheme, lookChoice } from '@codefusion-cc/theme'

export const themeConfig = defineTheme({
  storageKey: 'myapp-theme',
  html: { class: 'dark' },
  choices: { look: lookChoice({ storageKey: 'myapp-look', values: ['kuznia', 'noc'], default: 'kuznia' }) },
})
  • 与其他选择一样,它是一个选择:在第一次油漆之前显示,在重新装入时保持,然后是每一个打开的标签,用于 页面. theme.setChoice('look', 'noc') 选择一个, 默认无效; theme.get().choices.look 是显示的,和 revealThemeChange 也可以改变外观.
  • default 是应用程序的外观:人们所看到的从未选择过 (见上文)。 它从未被存储,所以一个新的默认 到达所有从未选择.
  • 名称是外观模块的名称(defineLook({ name }) 内 @codefusion-cc/ui: 小写字母,数字 和连字符,从字母开始. defineTheme 拒绝别人, 和一看没有默认.
  • html 也可以命名, 对于一个仍然有逐个外观 DisyUI 主题的应用程序: light: '{look}', dark: '{look}-dark'。 。 。 .

账户上的表情

useLookSync (单位:千美元)./react将签名人的外观保存在他们的账户上,从而跟踪到每个浏览器; 在登录之前,每个浏览器都保持上述状态。 一次,在应用程序的根:

import { useLookSync } from '@codefusion-cc/theme/react'

function App() {
  const { user } = useSession()
  const look = useLookSync(theme, {
    // The look on the account: a name, null when it has none, undefined while signed out or loading.
    account: user ? user.look : undefined,
    save: (look) => api.put('/me/look', { look }),
  })
  // look.status: 'idle' | 'saving' | 'failed'; look.error; look.retry()
}

规则,顺序:

  • 签名于 到一个有外观的账户时,请在此显示(并保存在本浏览器中供下次访问)。 一个账户 如果一个浏览器是, 则没有使用此浏览器之前所选择的外观; 应用程序的默认值没有保存 .
  • 一个挑 签名时制作的已保存。 在另一个标签中绘制的取号仅由该标签保存,并替换取号 在这里,仍然等待着被拯救,或者他们的储蓄失败.
  • 一次救一个,取出顺序:取出在保存等时所制作的取出,只取出最后的取出.
  • 失败的保存 (单位:千美元)save 扔出或拒绝)保持此浏览器中的外观; status 实值 failed, (中文(简体) ), error 说为什么, 财务报告和审定财务报表 retry() 保存现在显示的外观。 较新的选取取代了失败的选取.
  • 户口变了 (在另一个浏览器中选中) 这里显示, 除了从此页面保存时: 最后的选手赢了.
  • 看这个应用没有 帐号上既不显示也不覆盖: 此浏览器的外观显示, 其中 回到应用程序的默认值.
  • 签名退出 保留浏览器中的视图, 并且不保存更多内容; 保存仍在进行中 它的开始。 切换账户通行证 undefined 介于(签署或加载下一份)之间.

createLookSync (单位:千美元)./browser)是相同的,没有反应: setAccount(look) 每次账户的外观得知, get 财务报告和审定财务报表 subscribe 身份证明, stop()。两者都接受 choice 保留另一个选择 look服务器上 钩子使 idle 却一无所获.

第一次画之前

prePaintTheme 从 ./vite 在每一页中先放一个小的经典脚本 <head>它读取存储的主题和 显示在 <html> 在任何油漆之前,它从来没有扔, 不管存储做什么:

// vite.config.ts
import { prePaintTheme } from '@codefusion-cc/theme/vite'
import { themeConfig } from './src/themeConfig.ts'

export default defineConfig({ plugins: [react(), prePaintTheme(themeConfig)] })

这是作为 /theme.js (单位:千美元)fileName 修改它),一个CSP与 script-src 'self' 允许. inline: true 写入 输入页面(CSP需要散列)。 没有维特, themeScript(config) 从 . 是它的源头.

在页面中

一旦启动,在一个模块中,其余的应用导入:

// src/theme.ts
import { createTheme } from '@codefusion-cc/theme/browser'
import { themeConfig } from './themeConfig.ts'

export const theme = createTheme(themeConfig)

它显示了与剧本相同的存储主题,从此开始:

  • 在模式时遵循系统 system随着变化(在14年前的Safari上也是如此);
  • 遵循在应用程序的另一个分页中绘制的插图;
  • 在本地Storage中保留一个取号,或只当存储被屏蔽、缺失或满载时用于此页面;
  • 一次切换每个颜色: 框架的切换已关闭( 通过 CSSOM, a CSP的软件 style-src 所以按钮不会因为旧主题的颜色而消失;
  • 设置主题-颜色元.

theme.get() 页面显示的是: { mode, resolved, systemDark, choices }。 。 。 . theme.subscribe(listener) 呼唤 每次修改后,听者将说: pick (本页), system 或者说 elsewhere (另一个标签或程序). 选择 : theme.setMode('dark'), (中文(简体) ), theme.toggle() (单光/暗按钮:它选择另一个主题,或 system 当这就是系统 显示,所以点击一次不会将页面控制在一个模式上, theme.setChoice('accent', 'sky') (无) 默认). 未知模式或选择值丢出一个 TypeError:一个编程错误.

在反应中

import { useTheme } from '@codefusion-cc/theme/react'
import { theme } from './theme.ts'

function ThemeButton() {
  const { resolved } = useTheme(theme)
  return <button onClick={theme.toggle}>{resolved === 'dark' ? 'Light' : 'Dark'}</button>
}

每个组件都从任何来源对每个变化再次产生. 不需要供应商.

动画开关

revealThemeChange (单位:千美元)./browser)在视图过渡内运行一个变化:新主题从 按钮在旧的。 没有视图过渡的浏览器、 请求减少运动量的访客和浏览器 拒绝开始过渡 立刻得到改变.

一次,在应用程序的CSS(或 import '@codefusion-cc/theme/reveal.css' 模块中:

@import '@codefusion-cc/theme/reveal.css';

在反应中, revealThemeChangeFrom (单位:千美元)./react从控制中得知:

import { revealThemeChangeFrom } from '@codefusion-cc/theme/react'
import { theme } from './theme.ts'

<button onClick={(event) => revealThemeChangeFrom(event, theme.toggle)} />
// A radio group's own handler, which knows the option's button but has no click (arrow keys):
<Choice onChange={(mode, button) => revealThemeChangeFrom(button, () => theme.setMode(mode))} />
  • 圆从点击开始,或在键盘按下时从控件中心开始(键盘点击没有) 指针位置)或当给定控件本身时 null,取景所中间.
  • 夹子跑进去了 flushSync,那么这些组件将读取 useTheme (按钮的图标和标签)在 新的快照.
  • 水龙头需要400ms,鼠标点击650ms,以设备的指针为准(触摸屏笔记本电脑、iPad) 有轨电车. duration 财务报告和审定财务报表 easing 这些选项如下.

没有反应,或者有你自己的起源, revealThemeChange (单位:千美元)./browser:

import { revealThemeChange } from '@codefusion-cc/theme/browser'

revealThemeChange(() => theme.toggle(), { origin: button })
  • 当回调返回时, 更改必须在页面上: 浏览器将新页面抓取到之后 . theme.toggle() 财务报告和审定财务报表 theme.setMode() 油漆 <html> ; 在 React 中, 填入使组件在 flushSync (单位:千美元)revealThemeChangeFrom 页:1.
  • origin 是一分或一分(圆从它的中心开始);没有一分,就是取景口的中间. duration 财务报告和审定财务报表 easing 是选项。 圆花需要650毫秒(REVEAL_MS),和触摸屏上400毫秒 (单位:千美元)pointer: coarse, (中文(简体) ), TOUCH_REVEAL_MS),该页面在生长时不需要水龙头.
  • 当新主题永远出现在页面上时,承诺就解决了,只以回调错误的方式拒绝.
  • 连续多次点击是好的:浏览器结束运行的过渡并开始下一个过渡.

当圆圈增大时,页面是一个快照:为自己的视图过渡元素应用程序名称 (单位:千美元)view-transition-name 在样式表或内线中,React's <ViewTransition>被固定在地上 标题或共享相片不会自发地淡出或跳出. 揭发者根据他们的计算风格找到他们 并带走 然后把每个都放回原样。 规则匹配 每个元素的成本都要高得多:WebKit在这样的规则开始时和停止时会重新塑造整个页面 应用,每次只要主题本身改变。 班级 cf-theme-reveal (单位:千美元)REVEAL_CLASS开始 <html> 有效期; reveal.css 键入其规则(仅针对过渡的伪元素). 名字删掉 两次,在旧的快照之前,在召回之后的右边; 稍后出现的名称( 在一个效果中, 后一个框架) 没有被扁平.

在应用测试中

@codefusion-cc/theme/testing 是用于在节点测试的浏览器,没有 DOM: 一个站点共享存储的标签, a 光和暗之间交换的系统,以及可以 blocked, (中文(简体) ), missing 或者说 full。每个标签 <html> 保留上面显示的内容 :

import { createTheme } from '@codefusion-cc/theme/browser'
import { testBrowser } from '@codefusion-cc/theme/testing'

const browser = testBrowser({ systemDark: true, stored: { 'myapp-theme': 'light' } })
const [first, second] = [browser.openTab(), browser.openTab()]
const mine = createTheme(themeConfig, first.env)
const theirs = createTheme(themeConfig, second.env)
mine.setMode('system')
expect(second.html.classes).toEqual(['dark'])

tab.runScript(themeScript(config)) 在标签中运行预绘脚本, tab.frame() 运行其动画帧,以及 browser.writeElsewhere(key, value) 是另一个程序所做的更改.

版本与发布记录

@codefusion-cc/theme 共发布 9 个版本,首次发布于 2026/10/02;过去 12 个月发布了 9 个版本。

版本发布日期距今
0.1.5latest2026/11/091 天前
0.1.42026/10/2219 天前
0.1.32026/10/1426 天前
0.1.22026/10/1427 天前
0.1.12026/10/041 个月前
0.1.02026/10/021 个月前

关于 @codefusion-cc/theme 的常见问题

@codefusion-cc/theme 是什么?

浅色、暗色或系统主题和取出外观,每个浏览器保留(每个账户也保留外观),并在第一次涂料前显示:页面从不闪出错误的外观,在打开时遵循系统,每个打开的标签都遵循变化,开关可以长出 t

如何安装 @codefusion-cc/theme?

在项目目录运行 npm install @codefusion-cc/theme,或使用 pnpm add / yarn add / bun add。

@codefusion-cc/theme 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@codefusion-cc/theme 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@codefusion-cc/theme 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=20。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@codefusion-cc/theme 可以商用吗?

@codefusion-cc/theme 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@codefusion-cc/theme 的下载量有多少?

根据 npm 官方下载统计,@codefusion-cc/theme 在 2026/10/10 – 2026/11/08 这 30 天内被下载 2,211 次,日均约 74 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@codefusion-cc/theme 还在维护吗?

最新版本 0.1.5 发布于 2026/11/09(1 天前);至今共发布 9 个版本,其中过去 12 个月发布了 9 个;首次发布于 2026/10/02。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。