v3.1.0
中文 React 文档、可访问的 soft foreground 令牌、统一滚动条、useTheme SSR 修复、Toast 清理、Link 下划线与 RTL 布局优化。
v3.1.0 是小版本发布:新增中文 React 文档与本地化示例,soft foreground 默认达到无障碍对比度,滚动条统一由 data-scrollbar 和主题变量控制;同时修复 useTheme、Toast、Link、Fieldset、浮层和 RTL 布局问题。
安装
升级到最新版本:
npm i @lenso/tokens@latest @lenso/ui@latest正在使用 AI 助手? 对它说「Hey Cursor,把 HeroUI 升级到最新版本」。它会对比版本并应用必要变更。了解更多请参阅 HeroUI MCP 服务器。
新增内容
中文 React 文档
React 文档、迁移指南、发布说明和示例现在都有中文版本 (#6533)。组件页、入门指南和迁移参考都可以按 locale 发布。
可访问的 Soft Foreground 令牌
Soft 状态不再直接套语义色,而是使用专门的 foreground token,让 Badge、Chip、Alert、Toast、Avatar 和 Calendar 范围状态的文字对比度更稳定 (#6548)。
可直接覆盖这些 token:
--default-soft--default-soft-foreground--default-soft-hover--accent-soft-foreground--danger-soft-foreground--warning-soft-foreground--success-soft-foreground
默认 palette 现在使用符合无障碍对比度的 soft foreground。需要旧版更饱和、但对比度更低的颜色时,在根元素启用 vibrant palette:
<html data-vibrant-palette="true"> ...</html>此预览复用英文版适配,不代表中文源示例已完成本地实现。
"use client";// Adapted from HeroUI v3.2.6 (e385ac202b2cdb94b1bf6fa76d32c31c8259cc5e), Apache-2.0.import { Chip, Separator } from "@lenso/ui";import * as stylex from "@stylexjs/stylex";import { s } from "../card/display.stylex";
const variants = ["primary", "secondary", "tertiary", "soft"] as const;const colors = ["accent", "default", "success", "warning", "danger"] as const;function ChipMatrix({ isVibrant, title }: { isVibrant?: boolean; title: string }) { return ( <div {...stylex.props(s.column4)} data-vibrant-palette={isVibrant ? "true" : undefined}> <h3 {...stylex.props(s.textSm, s.semibold, s.muted)}>{title}</h3> <div {...stylex.props(s.row3)}> <div {...stylex.props(s.labelCell)} /> {colors.map((color) => ( <div key={color} {...stylex.props(s.matrixCell)}> <span {...stylex.props(s.textXs, s.muted, s.capitalize)}>{color}</span> </div> ))} </div> <div {...stylex.props(s.column3)}> {variants.map((variant) => ( <div key={variant} {...stylex.props(s.row3)}> <div {...stylex.props(s.labelCell, s.textSm, s.muted, s.capitalize)}>{variant}</div> {colors.map((color) => ( <div key={color} {...stylex.props(s.matrixCell)}> <Chip color={color} size="md" variant={variant}> <Chip.Label xstyle={s.capitalize}>{color}</Chip.Label> </Chip> </div> ))} </div> ))} </div> </div> );}export function ChipVibrantPalette() { return ( <div {...stylex.props(s.column8, s.full, s.scroll)}> <ChipMatrix title="Default palette" /> <Separator /> <ChipMatrix isVibrant title="Vibrant palette" /> </div> );}Local adaptation source above. Derived from HeroUI v3.2.6 source.
统一滚动条系统
滚动容器现在共享同一套标准 CSS 滚动条工具:主题 token 负责颜色和宽度,data-scrollbar 负责模式切换 (#6545)。组件滚动区域和自定义 overflow 区域都读取同一组 --scrollbar-* 变量。
三种模式:
- HeroUI 纤细:不设置
data-scrollbar,或设置data-scrollbar="thin"。 - 浏览器默认:设置
data-scrollbar="default",使用操作系统 / 浏览器滚动条。 - 隐藏:设置
data-scrollbar="none",隐藏滚动条但保留滚动。
<div data-scrollbar="thin">使用 HeroUI 主题滚动条</div><div data-scrollbar="default">使用浏览器默认滚动条</div><div data-scrollbar="none">隐藏后代 HeroUI 滚动条</div>此预览复用英文版适配,不代表中文源示例已完成本地实现。
"use client";// HeroUI v3.2.6 release-scrollbar-modes adaptation (Apache-2.0).import * as stylex from "@stylexjs/stylex";import { ListBox, ListBoxItem } from "@lenso/ui";const animals = [ "Aardvark", "Alpaca", "Antelope", "Bear", "Cat", "Dog", "Fox", "Giraffe", "Kangaroo", "Koala", "Lemur", "Otter", "Panda", "Penguin", "Rabbit", "Snake", "Turtle", "Wombat", "Zebra",];const styles = stylex.create({ root: { display: "flex", width: "100%", flexWrap: "wrap", justifyContent: "center", gap: 16 }, group: { display: "flex", width: 260, flexDirection: "column", gap: 8 }, title: { paddingInline: 4, fontSize: 14, fontWeight: 600, color: "var(--muted)" }, surface: { overflow: "hidden", borderRadius: 24, backgroundColor: "var(--surface)", boxShadow: "var(--surface-shadow)", }, viewport: { height: 208, overflowY: "auto", padding: 4 }, thin: { scrollbarWidth: "thin" }, hidden: { scrollbarWidth: "none" },});export function ScrollbarModes() { return ( <div {...stylex.props(styles.root)}> {(["thin", "default", "none"] as const).map((mode, index) => ( <div key={mode} {...stylex.props(styles.group)}> <h3 {...stylex.props(styles.title)}> {["HeroUI thin", "Browser default", "Hidden"][index]} </h3> <div data-scrollbar={mode} {...stylex.props(styles.surface)}> <div {...stylex.props( styles.viewport, mode === "thin" && styles.thin, mode === "none" && styles.hidden, )} > <ListBox aria-label={`${["HeroUI thin", "Browser default", "Hidden"][index]} animals`} selectionMode="single" > {animals.map((name) => ( <ListBoxItem key={name} itemKey={`${mode}-${name.toLowerCase()}`} textValue={name} > {name} </ListBoxItem> ))} </ListBox> </div> </div> </div> ))} </div> );}Local adaptation source above. Derived from HeroUI v3.2.6 source.
Select、ComboBox、Autocomplete、Dropdown、DatePicker、DateRangePicker、ColorPicker、Table、Tabs、Modal、Drawer 和 ScrollShadow 已接入同一套工具。
自定义滚动插槽使用 scrollbar。它读取最近的 data-scrollbar 祖先,并自动应用对应的 --scrollbar-width、--scrollbar-color 和 --scrollbar-gutter。
.alert-dialog__body { @apply min-h-0 flex-1 scrollbar;}主题变量也从单个固定的 --scrollbar 颜色,改为一组更细的滚动条 token:
/* before */--scrollbar: oklch(70.5% 0.015 286.067);
/* after */--scrollbar: var(--scrollbar-thumb);--scrollbar-thumb: color-mix(in oklch, var(--foreground) 15%, transparent);--scrollbar-track: transparent;--scrollbar-gutter: auto;--scrollbar-width: thin;--scrollbar-color: var(--scrollbar-thumb) var(--scrollbar-track);--scrollbar 保留为兼容别名;新的 thumb、track、gutter、width 和 color token 控制最终滚动条。
恢复浏览器默认滚动条:在 <html>、<main> 或任意嵌套容器上设置 data-scrollbar="default"。如果全局已设为默认,但某个局部仍要 HeroUI 样式,在该容器上加 data-scrollbar="thin"。
<html data-scrollbar="default"> <main> <section data-scrollbar="thin"> <!-- 这里使用 HeroUI 主题滚动条 --> </section> </main></html>组件与运行时修复
- Fieldset:
disabled会传给字段标签,并禁用后代 React AriaRadioGroup与Slider(#6547)。 - Toast:非前台 Toast 不再进入 Tab 顺序;卸载时清理已测量高度 (#6510, #6512)。
useTheme:SSR 不再读取浏览器 API;resolvedTheme改为派生值;系统主题订阅改用useSyncExternalStore(#6561)。- Link:默认无下划线;hover 使用 50% 装饰色;active / pressed 使用 100%;移除下划线装饰色过渡 (#6570, #6571)。
布局、浮层与 RTL 修复
- 浮层定位:进入动画只过渡
opacity和transform,不再动画化 React Aria 写入的定位值 (#6549)。 - Dialog 与 Modal 聚焦:Modal 和 AlertDialog 内容改用裁剪处理,避免 focus 触发程序化滚动;body focus ring 不再被 overflow 裁掉 (#6448, #6557)。
- RTL Table 圆角:Table 改用逻辑方向的
border-radius,RTL 外侧圆角保持正确 (#6568)。 - RTL Picker 与 Menu 指示器:Select、ListBox.Item、Autocomplete、ComboBox 和 MenuItem 改用 logical inline start/end,覆盖 chevron、value、checkmark、trigger 和 submenu indicator (#6573)。
文档与依赖
- 主题文档同步当前
theme.css/variables.css:soft foreground 令牌和滚动条变量都已更新。 - 发布说明和迁移文档同步 Link 行为。
- 文档站新增
@fumadocs/language;fumadocs-core/fumadocs-ui升级到16.9.0。 - 文档和样式包的 Tailwind 工具升级到
4.3.0。
链接
贡献者
感谢所有为本次发布做出贡献的朋友!
HeroUI contributors