ProComponents, templates & AI tooling
HeroUI
27.7k

v3.2.0

基于 React Aria 1.18 的 Calendar 周/日视图与年份选择器,以及 Radio、Checkbox、Switch 的破坏性组合方式变更。

2026 年 6 月 15 日

Calendar 新增周视图与日视图、重做的年份选择器,以及基于 React Aria 1.18 的范围日历演示。Autocomplete 新增用于大型选项列表的 Virtualizer 示例。Tooltip 新增用于全局显示与隐藏延迟的主题变量。Radio、Checkbox、Switch 迁移到 React Aria 的 *Field + *Button 组合方式。本次发布同时纳入了虚拟化列表、分组字段自动填充、Toast 与 Fieldset 行为,以及滚动与 RTL 样式方面的补丁修复。

⚠️ 破坏性变更RadioCheckboxSwitch 改为显式的 *.Content 组合 —— *.Control 嵌套进 *.Content,标签变为 *.Content 内的纯文本(不嵌套 <Label>),Description/FieldError 变为 *.Content 的兄弟节点。详见破坏性变更

安装

升级到最新版本:

npm i @heroui/styles@latest @heroui/react@latest
pnpm add @heroui/styles@latest @heroui/react@latest
yarn add @heroui/styles@latest @heroui/react@latest
bun add @heroui/styles@latest @heroui/react@latest

正在使用 AI 助手? 对它说「Hey Cursor,把 HeroUI 升级到最新版本」。它会对比版本并应用必要变更。了解更多请参阅 HeroUI MCP 服务器

新增内容

Calendar

CalendarRangeCalendar 新增周视图与日视图,以及来自 React Aria 1.18 的新日历属性。

  • 周视图 / 日视图:通过 visibleDuration 渲染多周或单日布局
  • 多选:在单个 Calendar 中选择多个日期
  • React Aria 1.18 属性weeksInMonth 与用于范围选择的 isDateUnavailable(date, anchorDate)
  • 内部实现:月份标题使用 React Aria 的 CalendarHeading,年份选择器基于 React Aria calendar hooks 重建

周视图:

日视图:

多选:

Autocomplete

支持通过 Virtualizer 渲染大型选项列表,并补充文档、Storybook 示例,以及针对 popover 尺寸和 listbox 滚动高度的样式修复。

  • 虚拟化:在 Autocomplete.Popover 内用 React Aria 的 <Virtualizer> 包裹 ListBox (#6642)
  • Popover 尺寸:listbox 高度上限为 320px 并支持内部滚动;搜索框固定在列表上方

虚拟化:

Table.SortableColumnHeader

Table.SortableColumnHeader 用于渲染 sortable 列标题和可选的升降序指示器。放在 Table.Column render prop 中,并传入 sortDirection (#6588)。

<Table.Column allowsSorting>
  {({sortDirection}) => (
    <Table.SortableColumnHeader sortDirection={sortDirection}>
      Name
    </Table.SortableColumnHeader>
  )}
</Table.Column>
  • 默认指示器:存在排序方向时显示 chevron
  • 自定义指示器:传入 indicator,或用 showIndicator={false} 隐藏
  • 样式插槽.table__sortable-column-header + .table__sortable-column-indicator

Tooltip 延迟主题变量

Tooltip 现在会从主题 CSS 变量读取默认的显示与隐藏延迟 (#6617):

  • --tooltip-delay — 显示 Tooltip 前的延迟(默认:1500ms
  • --tooltip-close-delay — 隐藏 Tooltip 前的延迟(默认:500ms

全局覆盖示例:

:root {
  --tooltip-delay: 700ms;
  --tooltip-close-delay: 0ms;
}

单个 Tooltip 上的 delaycloseDelay 属性仍会覆盖这些值。

行为变更: 使用默认 HeroUI 主题时,Tooltip 延迟现在默认为 1500ms / 500ms,而不是之前的 React Aria 默认值 700ms / 0ms。如需保留旧行为,请显式设置 CSS 变量或 props。

组件修复

  • Toast:Toast 队列会串行化 ViewTransition 更新,避免在 toast.promise() 关闭 loading toast 并打开成功/失败反馈时出现被跳过的过渡和 AbortError (#6511)。
  • Fieldsetdisabled 会传递到 React Aria 的 Button、CheckboxGroup、Link、RadioGroup、Slider、ToggleButton 和 ToggleButtonGroup 上下文 (#6596)。
  • Autocomplete:Popover 内容包裹在 React Aria 的 Dialog 中,打开 popover 时 listbox 不再出现多余的焦点环 (#6627)。
  • Tooltip:Trigger 改用 useFocusable hook 而非 <Focusable> 包装组件,避免 Tooltip 挂载在 inert 子树中(例如位于已打开的 Drawer/Modal 之后)时出现误报的 “child must be focusable” 警告 (#6628)。

样式修复

  • Modal / AlertDialogscroll-inside 对话框通过 max-h-full min-h-0 限制高度,使内容区域滚动而非溢出 (#6597)。
  • ScrollShadow:渐隐遮罩通过 --scroll-shadow-scrollbar-size 为可见的原生滚动条预留空间 (#6598)。
  • Table RTL:列分隔线与拖拽手柄在 RTL 下使用逻辑属性 end-0 定位 (#6606)。
  • Link:移除硬编码的 text-sm,让链接从父元素继承字号;.link__icon 改为相对单位 size-[0.75em],随文本大小缩放,而不再使用固定的 size-2 (#6621)。
  • DatePicker / DateRangePicker:日历 popover 由 max-w-(--trigger-width) 改为 min-w-(--trigger-width),确保 popover 至少与触发器一样宽,避免被水平裁剪 (#6622)。
  • Table:当 Table 被 React Aria 的 <Virtualizer> 包裹时,secondary 表头的边框与圆角能够正确渲染 —— 列选择器不再把每个虚拟化列都同时视为 first 和 last child (#6624)。
  • Autocomplete:Popover 限制为触发器宽度,listbox 高度上限为 320px 并支持内部滚动,避免虚拟化列表溢出 popover (#6642)。
  • ListBox:将 flex flex-col gap 改为普通块级流 + 兄弟节点间距,避免 React Aria Virtualizer 的内容高度被 flex-shrink 压缩 —— 修复虚拟化滚动时滚动条滑块尺寸变化的问题 (#6636)。
  • InputGroup / NumberField / SearchField:浏览器自动填充高亮提升到分组容器上,使 prefix、suffix 和增减按钮槽位共享圆角高亮 (#6625)。
  • Spinner:改用 inline-flex 搭配 shrink-0(替代 relative),使旋转动画在非 flex 布局中也能正确渲染,并支持 motion-reduce (#6644)。
  • Toast:关闭按钮在所有断点下统一使用 -top-1 -right-1,与容器内边距对齐 (#6574)。

依赖

  • React Aria Components1.17.01.18.0 (#6586)。1.18 引入了 toggles 所采用的 *Field + *Button 组合方式、CalendarHeading,以及 isDateUnavailable(date, anchorDate)
  • @internationalized/date3.12.13.12.2
  • React Aria / Stately 辅助包@react-aria/*@react-stately/*@react-types/shared 补丁更新

⚠️ Breaking Changes

Radio、Checkbox 与 Switch:显式 *.Content 组合

这些组件现在在底层使用 React Aria 的 *Field + *Button 组合方式。X.Content 现在是可点击的 label(React Aria 的 *Button)。共有三点变化:

  • X.Control 移进 X.Content —— 它们以前是兄弟节点。
  • 标签是 X.Content 内部的纯文本 —— X.Content 渲染的是 <label> 元素,所以不要嵌套 <Label> 组件(嵌套的 <label> 是无效 HTML)。若要使用独立的 Label,请把它放在外部,并用 htmlFor + 组件 id 关联。
  • Description/FieldError 移到外部,作为 X.Content 的兄弟节点,这样它们会通过 aria-describedby 朗读,而不会被并入无障碍名称。

Checkbox

// v3.1
<Checkbox>
  <Checkbox.Control>
    <Checkbox.Indicator />
  </Checkbox.Control>
  <Checkbox.Content>
    <Label>Accept terms</Label>
    <Description>You agree to our terms</Description>
  </Checkbox.Content>
</Checkbox>

// v3.2
<Checkbox>
  <Checkbox.Content>
    <Checkbox.Control>
      <Checkbox.Indicator />
    </Checkbox.Control>
    Accept terms
  </Checkbox.Content>
  <Description>You agree to our terms</Description>
</Checkbox>

Radio

// v3.1
<Radio value="a">
  <Radio.Control>
    <Radio.Indicator />
  </Radio.Control>
  <Radio.Content>
    <Label>Option A</Label>
  </Radio.Content>
</Radio>

// v3.2
<Radio value="a">
  <Radio.Content>
    <Radio.Control>
      <Radio.Indicator />
    </Radio.Control>
    Option A
  </Radio.Content>
</Radio>

Switch

// v3.1
<Switch>
  <Switch.Control>
    <Switch.Thumb />
  </Switch.Control>
  <Switch.Content>
    <Label>Enable notifications</Label>
  </Switch.Content>
</Switch>

// v3.2
<Switch>
  <Switch.Content>
    <Switch.Control>
      <Switch.Thumb />
    </Switch.Control>
    Enable notifications
  </Switch.Content>
</Switch>

迁移对照

v3.1v3.2
X.ControlX.Content 为兄弟节点X.Control 嵌套进 X.Content
X.Content 是包裹 Label + 帮助文本的布局 <div>X.Content 是包裹 X.Control + 标签文本的可点击 <label>
通过 X.Content 内的 <Label> 提供标签标签是 X.Content 内的纯文本(不嵌套 <Label>
Description / FieldError 位于 X.ContentDescription / FieldError 作为 X.Content 的兄弟节点

外部标签 —— 若要使用独立的 Label,请把它放在组件外部,并用 htmlFor + 组件 id 关联:

<div className="flex items-center gap-3">
  <Checkbox id="terms">
    <Checkbox.Content>
      <Checkbox.Control>
        <Checkbox.Indicator />
      </Checkbox.Control>
    </Checkbox.Content>
  </Checkbox>
  <Label htmlFor="terms">Accept terms</Label>
</div>

仅含控件的 Checkbox 和 Switch(没有标签,例如表格行选择或图标开关)仍需用 X.Content 作为可点击包装。请把 Checkbox.Control / Switch.Control 放进 X.Content,省略标签,并在根组件上传入 aria-label

各组件完整迁移指南:CheckboxCheckbox GroupRadioRadio GroupSwitch

链接

贡献者

感谢所有为本次发布做出贡献的人!

本页目录