二、主题系统:从设计令牌到深色模式
2.1 设计令牌(Design Tokens)
HeroUI 的主题基于 CSS 变量 实现,而不是硬编码的颜色值。这使得主题切换极其高效——只需更改变量的值,所有组件自动响应。
核心的 CSS 变量分类:
2.2 亮色/暗色模式原理
HeroUI 不依赖 dark: 前缀来逐个组件定义暗色样式,而是通过 CSS 变量的重新赋值:
/* 亮色模式 - 根作用域 */
:root {
--background: #ffffff;
--foreground: #11181C;
--primary: #3B82F6;
--primary-foreground: #ffffff;
}
/* 暗色模式 - .dark 类作用域 */
.dark {
--background: #000000;
--foreground: #ECEDEE;
--primary: #60A5FA;
--primary-foreground: #000000;
}
当你调用 < Button color="primary"> 时,Button 组件内部使用的是 var(--primary) 和 var(--primary-foreground),所以颜色会自动随主题变化。
https://zlpow.cn
手动切换主题:
import { useTheme } from "@heroui/use-theme";
function ThemeSwitcher() {
const { theme, setTheme } = useTheme();
return (
<Button onClick={() => setTheme(theme === "light" ? "dark" : "light")}>
切换主题
</Button>
);
}
2.3 自定义主题(在 tailwind.config.js 中)
// tailwind.config.js
import { heroui } from "@heroui/react";
export default {
plugins: [
heroui({
themes: {
// 自定义一个名为 "my-brand" 的主题,基于亮色主题扩展
"my-brand": {
extend: "light",
colors: {
primary: {
DEFAULT: "#BEF264", // 品牌主色
foreground: "#000000", // 主色上的文字颜色
},
secondary: {
DEFAULT: "#A855F7",
foreground: "#ffffff",
},
},
layout: {
radius: {
small: "0.25rem",
medium: "0.5rem",
large: "0.75rem",
},
borderWidth: {
small: "1px",
medium: "2px",
},
},
},
},
}),
],
};
然后在应用中使用:
<HeroUIProvider theme="my-brand">
{children}
</HeroUIProvider>
2.4 Theme Builder 可视化工具
HeroUI v3.0.0-beta.4 推出了 Theme Builder(访问 v3.heroui.com/themes)。
功能亮点:
OKLCH 颜色选择器:通过亮度、彩度、色相滑块直观调整
实时预览:所有组件样式同步更新
预设模板:Airbnb、Coinbase、Discord 等品牌风格一键应用
双主题编辑:可同时编辑亮色/暗色模式,颜色值可以关联或独立
导出 CSS 变量:一键复制生成的 CSS 代码
为什么用 OKLCH?
OKLCH 是一种更符合人类视觉感知的色彩模型。简单来说:在 OKLCH 中,当你调整亮度(Lightness)时,颜色的鲜艳度(Chroma)保持不变,不会出现"变暗的同时变灰"的问题。这让暗色模式下的颜色看起来更自然。
2.5 表单字段令牌(--field-* 变量)
从 v3.0.0-alpha.34 开始,HeroUI 引入了 --field-* 系列的 CSS 变量来统一所有表单组件(Input、Select、Textarea 等)的样式 。
可用的表单令牌:
:root {
--field-height: 2.5rem;
--field-padding-x: 0.875rem;
--field-padding-y: 0.5rem;
--field-font-size: 0.875rem;
--field-border-radius: 0.5rem;
--field-border-width: 1px;
--field-background: #ffffff;
--field-border-color: #e4e4e7;
--field-focus-border-color: #3B82F6;
--field-disabled-opacity: 0.7;
}
修改这些变量会同时影响 Input、Select、Textarea 等所有组件,无需逐个调整。