@ 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) 是另一个程序所做的更改.