安装 • 妇女 样式 • 妇女 主题 • 妇女 进口 • 妇女 现场医生
代码主题,RSC友好, 仅限无害环境管理 42号内线的UI包.
安装
该工具包在公共npm注册为 @42-central/ui-react。无
需要证书:
npm install @42-central/ui-react @ark-ui/react react react-dom tailwindcss
pnpm add @42-central/ui-react @ark-ui/react react react-dom tailwindcss
yarn add @42-central/ui-react @ark-ui/react react react-dom tailwindcss
bun add @42-central/ui-react @ark-ui/react react react-dom tailwindcss
@ark-ui/react, (中文(简体) ), react, (中文(简体) ), react-dom (所有反应19)和 tailwindcss v4为
相对依赖.
消费者
tsconfig.json必须使用"moduleResolution": "Bundler"(或"NodeNext") (中文(简体) ).
用维特? 添加 @42-central/vite-plugin-theme 用于无闪光的主题
装入( 见 维特) (中文(简体) ).
连接样式
工具箱将它的 Tailwind 主题和调色板作为普通的 CSS 传送—— 没有插件 登记。 在您的全局样式表中选择两个模式之一 .
备选案文A——有意见(一行). 在Tailwind,主题,和a
@source 覆盖扫描已建套件:
@import "@42-central/ui-react/styles.css";
选项B——全控(推荐应用代码). 导入尾风和
主题你自己,和点 @source 在安装的软件包中生产
将所使用的类保留在组件内:
@import "tailwindcss";
@import "@42-central/ui-react/theme.css";
@source "../node_modules/@42-central/ui-react/dist/**/*.js";
选项 A 跳过 @source 因此,生产架构可能错过动态
组件内部使用的类——与选项B相接,除非您有完整的
超时班级报道. 本地单列坡开发点 @source 时间
源树代替——见 apps/docs/app/global.css 以实例为例.
主题(浅/暗/系统)
useTheme() 坚持一个明确的 "light" | "dark" | "system" 选择并保留
data-theme 打开 <html> ——该属性是整个合同(即
@custom-variant dark 内 theme.css (见上文)。 避免错误的闪光
主题需要运行的脚本 在此之前 您的应用程序的JS做的; 您如何交付
框架不同.
Next.js (App路由器/RSC) (英语)
渲染器 ThemeScript 从服务器组件,尽可能早(例如:
第一个孩子 <body>标记根 <html> suppressHydrationWarning
(脚本集) data-theme 在反应水合之前:
// app/layout.tsx
import { ThemeScript } from "@42-central/ui-react/theme-script";
export default function Layout({ children }: LayoutProps<"/">) {
return (
<html lang="en" suppressHydrationWarning>
<body>
<ThemeScript />
{children}
</body>
</html>
);
}
"use client";
import { useTheme } from "@42-central/ui-react";
export function ThemeToggle() {
const { resolvedTheme, setMode } = useTheme();
const next = resolvedTheme === "dark" ? "light" : "dark";
return (
<button onClick={() => setMode(next)}>
{/* Which emoji is *visible* is CSS-driven (dark:), not resolvedTheme —
a server can't know the visitor's real preference, so anything
rendered from resolvedTheme is wrong in the raw server-rendered
HTML until React hydrates. resolvedTheme is only used above, for
the click handler's "what's next" logic. */}
<span className="dark:hidden">☀️</span>
<span className="hidden dark:inline">🌙</span>
</button>
);
}
Vite( 仅限客户 SPA)
没有服务器渲染步骤,所以反应 ThemeScript 组件不能帮助 -
当反应可以插入时 <script>第一次油漆已经发生.
脚本需要降落在 index.html 本身,真正阻挡(不是
type="module",维特视其为被推迟). 有三条路可以到达那里,
优先排序:
1. 联合国. @42-central/vite-plugin-theme (建议.
将脚本注入到 index.html 两者 vite dev 财务报告和审定财务报表 vite build 时间,
因此,你从不手工编辑 HTML :
// vite.config.ts
import { defineConfig } from "vite";
import { themeInitPlugin } from "@42-central/vite-plugin-theme";
export default defineConfig({
plugins: [themeInitPlugin()],
});
安装和选项在 插件读取。 。 。 .
2. 静态资产,抄入 public/。 。 。 . @42-central/ui-react/theme-init.js 实值
预建的、无依赖的脚本。 硬码 <script src="/node_modules/...">
仅工作于 vite dev ——维特的dev服务器服务 node_modules 直接,
但生产建筑不会复制或解决原始的 node_modules 路径,所以
那块牌子是404 在真正建成之后 将文件复制到自己 public/
取而代之的是目录( Vite service) public/ 既用德文,又用正文),例如:.
通过一个小 predev编号 :prebuild 脚本 :
// scripts/copy-theme-init.mjs
import { copyFileSync } from "node:fs";
copyFileSync(
import.meta.resolve("@42-central/ui-react/theme-init.js").replace("file://", ""),
"public/theme-init.js",
);
<!-- index.html -->
<script src="/theme-init.js" data-default-color-scheme="dark"></script>
这是通过 data-* 属性在自己的标签上(不需要构建步骤)
复制一次:
| 属性 | 匹配 useTheme() 选项 |
|---|---|
data-storage-key | storageKey |
data-default-color-scheme | defaultColorScheme |
data-force-color-scheme | forceColorScheme |
data-attribute | attribute 以逗号分隔,例如:. "class,data-theme" |
3. 人工粘贴,作为最后手段 (非 Vite 捆绑器, 完全定制设置)
——字面输出 buildThemeInitScript()数字 :
<script>
(function () {
try {
var k = "ui-theme",
m = ["light", "dark", "system"];
var s = localStorage.getItem(k),
v = null;
if (s) {
try {
v = JSON.parse(s);
} catch (e) {
v = null;
}
}
if (m.indexOf(v) === -1) v = "system";
var d =
v === "system"
? window.matchMedia &&
window.matchMedia("(prefers-color-scheme: dark)").matches
? "dark"
: "light"
: v;
document.documentElement.setAttribute("data-theme", d);
} catch (e) {}
})();
</script>
重新生成此块( R)import { buildThemeInitScript } from "@42-central/ui-react"(中文(简体) )
随时更新软件包,以防其内部变化.
useTheme() 作品在其中任何一个之后都相同——相同的钩子,没有Vite特定的API.
强制或默认颜色方案
defaultColorScheme 覆盖未存储时使用的倒置
(单位:千美元)"system" 除非设定). forceColorScheme 针头 mode编号 :resolvedTheme 改为
已固定 "light"编号 :"dark" 值和转 setMode 改为无操作——用于
页面,无论访客的偏好如何,必须设置一个方案(例如:.
a 专题营销页或嵌入页).
没有一个提供者持有这个配置在一个地方,所以两个选项
必须完全通过 每个 useTheme() 呼叫网站 财务报告和审定财务报表
<ThemeScript> (或被粘贴的维特脚本)——否则水分前置
脚本和钩子在第一个负载上可以有分歧. 这不是一个空白与缺乏
提供商:Mantine,它确实有一个(a)MantineProvider),文档
同样的要求 forceColorScheme - "必须同时设置"
打开 MantineProvider 财务报告和审定财务报表 ColorSchemeScript因为剧本总是运行
在任何提供者存在之前.
// app/layout.tsx
<ThemeScript forceColorScheme="dark" />
"use client";
const { resolvedTheme, setMode } = useTheme({ forceColorScheme: "dark" });
// resolvedTheme is always "dark"; setMode is a no-op while forced.
驾驶a .dark 类也
data-theme 包件本身的合同(theme.css是因为 @custom-variant dark),但其他CSS你(英语:
不要控制 可能会按字面 .dark 类取而代之—— Tailwind 默认值 dark 战略,
其它组件库,或者(如本 repo 自己的docs site) Fumadocs 捆绑样式。 过
attribute (叹气) next-themes' 同名选项) @42-central/ui-react 也开吧,
而不是手卷自己的镜像脚本/观测器 :
// app/layout.tsx
<ThemeScript attribute={["class", "data-theme"]} />
"use client";
const { resolvedTheme, setMode } = useTheme({
attribute: ["class", "data-theme"],
});
喜欢 storageKey编号 :defaultColorScheme编号 :forceColorScheme, (中文(简体) ), attribute 必须完全通过
两者 <ThemeScript> (或被贴上Vite脚本)和每个 useTheme() 呼叫站点, 相同
原因——没有提供者持有这个配置在一个地方. 通过 attribute: "class"
单独(无) "data-theme")也得到支持,如果你真的不需要工具箱自己的合同来获得
给定的页面 resolvedTheme 读取 .dark 直接上课.
停止颜色转换
如果您的 CSS 中的任何一种颜色/ 背景/ 边框属性转换, 请切换
主题使得它通过互换而明显活跃起来——所以过渡是
默认被关闭 每个应用更改周围有一个框架(单击
切换,操作系统偏好在打开时翻转 "system" 模式,并恢复
聚焦到主题在别处改变的标签上。 过 keepTransitions
(模仿曼汀语中同名选项) 选择回归正常
过渡行为 :
const { resolvedTheme, setMode } = useTheme({ keepTransitions: true });
带有更新器的循环模式
setMode 还接受 useState- 风格更新器, 一次解决当前 mode —— 说
用于循环所有三个值而不是双向切换的单个按钮:
const NEXT = { light: "dark", dark: "system", system: "light" } as const;
const { mode, setMode } = useTheme();
<button onClick={() => setMode((mode) => NEXT[mode])}>{mode}</button>;
子路径导入
组件边界上的树摇:
import { Button } from "@42-central/ui-react/button";
import { Modal } from "@42-central/ui-react/modal";
import { ThemeScript } from "@42-central/ui-react/theme-script";
import { cn } from "@42-central/ui-react/cn";
软件包根( R)@42-central/ui-react只有再出口共享的公用事业和类型——
cn, (中文(简体) ), COLORS 编号 : Color, (中文(简体) ), SIZES 编号 : Size, (中文(简体) ), FormControlProps, (中文(简体) ), useLogger,以及
useTheme 编号 : ThemeMode 编号 : ResolvedTheme. 组成部分靠自己生活
副道所以捆绑者从来不拉 整套.