RC 3
TagGroup、Menu、InputGroup 组件,Bottom Sheet Android 返回键修复,Expo 55 兼容
RC 3 带来三个新组件:用于可选标签管理的 TagGroup、基于 Popover/Bottom Sheet 的下拉菜单 Menu,以及带自动测量前后缀槽位的装饰性输入 InputGroup。本版本还为所有基于 Bottom Sheet 的遮罩增加 Android 实体返回键支持;通过关键的 combineStyles 修复保留 Reanimated 动画样式绑定,实现 Expo 55 兼容;并包含若干依赖升级。
安装
升级到最新版本:
npm i heroui-nativepnpm add heroui-nativeyarn add heroui-nativebun add heroui-native使用 AI 助手? 直接提示「Hey Cursor,把 HeroUI Native 升级到最新版本」,助手会自动比对版本并完成必要修改。了解更多请参见 HeroUI Native MCP 服务器。
抢先体验
通过预览应用在真机上体验 RC 3 的全部改进!你可以探索 TagGroup、Menu、InputGroup,以及 Bottom Sheet 的 Android 返回键支持与各项修复。
环境要求
请确保手机已安装最新版本的 Expo Go。
如何访问
方式一:扫描二维码
使用手机相机或 Expo Go 应用扫描:

Android 用户请注意: 若使用系统相机或其他扫码应用会跳转到浏览器并出现 404,请先打开 Expo Go,使用其内置扫码功能扫描。
方式二:点击链接
若设备已安装 Expo Go,将自动在其中打开应用。
更新亮点
新组件
本版本新增 3 个组件:
- TagGroup:用于展示与管理可选标签的复合组件,支持可选移除、单选/多选及表单字段集成。
- Menu:下拉菜单系统,支持 Popover 与 Bottom Sheet 呈现、单选/多选、菜单项变体与按压动画反馈。
- InputGroup:装饰性文本输入,前后缀槽位绝对定位并自动测量宽度,为输入区应用匹配内边距。
TagGroup
TagGroup 以复合组件模式渲染可选标签组,并支持可选移除。支持单选与多选、受控/非受控 API、两种视觉变体(default 与 surface)、三种尺寸、禁用态,以及与 Label、Description、FieldError 的完整表单集成。
特性:
- 复合子组件:
TagGroup.List、TagGroup.Item、TagGroup.ItemLabel、TagGroup.ItemRemoveButton - 单选/多选模式,受控/非受控 API
- 两种视觉变体:
default与surface - 三种尺寸:
sm、md、lg - 单项禁用与
disabledKeys - 通过
onRemove与TagGroup.ItemRemoveButton实现移除 TagGroup.List上renderEmptyState渲染空状态- 与 Label、Description、FieldError、
isInvalid、isRequired的表单集成 useTagGroup与useTagGroupItem供高级用法
用法:
import { TagGroup } from "heroui-native";
export function BasicTagGroup() {
return (
<TagGroup>
<TagGroup.List>
<TagGroup.Item id="react">
<TagGroup.ItemLabel>React</TagGroup.ItemLabel>
</TagGroup.Item>
<TagGroup.Item id="vue">
<TagGroup.ItemLabel>Vue</TagGroup.ItemLabel>
</TagGroup.Item>
<TagGroup.Item id="svelte">
<TagGroup.ItemLabel>Svelte</TagGroup.ItemLabel>
</TagGroup.Item>
</TagGroup.List>
</TagGroup>
);
}
export function RemovableTagGroup() {
const [items, setItems] = useState(["React", "Vue", "Svelte"]);
return (
<TagGroup onRemove={(keys) => setItems((prev) => prev.filter((i) => !keys.has(i)))}>
<TagGroup.List>
{items.map((item) => (
<TagGroup.Item key={item} id={item}>
<TagGroup.ItemLabel>{item}</TagGroup.ItemLabel>
<TagGroup.ItemRemoveButton />
</TagGroup.Item>
))}
</TagGroup.List>
</TagGroup>
);
}完整文档与示例见 TagGroup 组件页。
相关 PR: #309
Menu
Menu 提供基于复合组件的下拉菜单,支持 Popover 与 Bottom Sheet 两种呈现。包含基于 Reanimated 的按压动画、单选/多选、菜单项变体(default 与 danger)、指示器样式及可配置 placement。
特性:
- 复合子组件:
Menu.Trigger、Menu.Portal、Menu.Overlay、Menu.Content、Menu.Label、Menu.Group、Menu.Item、Menu.ItemTitle、Menu.ItemDescription、Menu.ItemIndicator - 两种呈现:
popover与bottom-sheet,placement 可配置(top、bottom、left、right) Menu.Group上通过selectedKeys/onSelectionChange实现单选/多选- 菜单项按压动画(缩放 + 背景色),Reanimated 实现,可通过
animation自定义 - 菜单项变体:
default与danger - 指示器变体:
checkmark、dot或自定义内容 Menu.Label用于分区标题- 分组级
shouldCloseOnSelect控制
用法:
import { Menu } from "heroui-native";
export function BasicMenu() {
return (
<Menu>
<Menu.Trigger>
<Button>Open Menu</Button>
</Menu.Trigger>
<Menu.Portal>
<Menu.Overlay />
<Menu.Content>
<Menu.Item>
<Menu.ItemTitle>Edit</Menu.ItemTitle>
</Menu.Item>
<Menu.Item>
<Menu.ItemTitle>Duplicate</Menu.ItemTitle>
</Menu.Item>
<Menu.Item variant="danger">
<Menu.ItemTitle>Delete</Menu.ItemTitle>
</Menu.Item>
</Menu.Content>
</Menu.Portal>
</Menu>
);
}
export function MenuWithSections() {
return (
<Menu>
<Menu.Trigger>
<Button>Actions</Button>
</Menu.Trigger>
<Menu.Portal>
<Menu.Overlay />
<Menu.Content>
<Menu.Group selectionMode="single" selectedKeys={selected} onSelectionChange={setSelected}>
<Menu.Label>View</Menu.Label>
<Menu.Item id="list">
<Menu.ItemTitle>List View</Menu.ItemTitle>
<Menu.ItemIndicator />
</Menu.Item>
<Menu.Item id="grid">
<Menu.ItemTitle>Grid View</Menu.ItemTitle>
<Menu.ItemIndicator />
</Menu.Item>
</Menu.Group>
</Menu.Content>
</Menu.Portal>
</Menu>
);
}完整文档与示例见 Menu 组件页。
相关 PR: #312
InputGroup
InputGroup 提供装饰性文本输入,Prefix 与 Suffix 子组件绝对定位,通过 onLayout 自动测量宽度并为 Input 应用匹配的水平内边距。isDecorative 布尔值可一次性处理装饰性附加内容的无障碍与指针事件样板;根级 isDisabled 通过上下文级联到所有子节点。
特性:
- 复合子组件:
InputGroup.Prefix、InputGroup.Suffix、InputGroup.Input - 自动内边距:通过
onLayout测量 Prefix/Suffix 宽度,自动作为 Input 的paddingLeft/paddingRight - Prefix/Suffix 上
isDecorative统一设置pointerEvents="none"、accessibilityElementsHidden与importantForAccessibility - 根级
isDisabled通过上下文级联(Prefix/Suffix 透明度与 pointer-events、Input 可编辑性) InputGroup.Input为直接透传——由使用方在 Input 上管理value/onChangeText
用法:
import { InputGroup } from "heroui-native";
export function SearchInput() {
return (
<InputGroup>
<InputGroup.Prefix isDecorative>
<SearchIcon />
</InputGroup.Prefix>
<InputGroup.Input placeholder="Search..." />
<InputGroup.Suffix isDecorative>
<ChevronIcon />
</InputGroup.Suffix>
</InputGroup>
);
}
export function DisabledInput() {
return (
<InputGroup isDisabled>
<InputGroup.Prefix isDecorative>
<LockIcon />
</InputGroup.Prefix>
<InputGroup.Input placeholder="Disabled input" />
</InputGroup>
);
}完整文档与示例见 InputGroup 组件页。
相关 PR: #313
组件改进
Bottom Sheet Android 返回键支持
Bottom Sheet 共享容器现处理 Android 实体返回键:按下时关闭当前打开的 Bottom Sheet。BackHandler 仅在 Bottom Sheet 打开时注册,避免已关闭实例抢占事件。该修复全局作用于所有基于 Bottom Sheet 的组件。
涉及组件:
实现使用 React Native 的 BackHandler API,在 iOS 上为空操作,无需分平台分支。
相关 PR: #308
Slot 的 combineStyles 修复
Slot 原语的 combineStyles 现返回样式数组,而不再使用 StyleSheet.flatten——后者会通过深拷贝样式对象破坏 Reanimated 的 SharedValue 与 useAnimatedStyle 绑定。
改进:
combineStyles通过返回数组保留 Reanimated 动画样式绑定- React Native 原生支持嵌套样式数组,对使用方行为无影响
- 修复通过 Slot 原语组合的组件上的动画断裂问题
相关 PR: #314
依赖
Expo 55 兼容
依赖版本已更新以兼容 Expo SDK 55:
uniwind:1.2.7 → 1.3.2@gorhom/bottom-sheet:^5 → ^5.2.8
上述 combineStyles 修复是支持 Expo 55 的主要代码变更:此前 StyleSheet.flatten 会在新 SDK 下破坏 Reanimated 样式绑定。
相关 PR: #314
问题修复
本版本包含以下修复:
-
Issue #272:解决
FullWindowOverlay干扰 React Native 元素检查器的问题。 -
Issue #280:修复 Expo 55 下 Avatar 等依赖 Reanimated 的组件失效。
combineStyles曾通过StyleSheet.flatten破坏动画绑定;现改为返回样式数组以保留SharedValue与useAnimatedStyle。
相关 PR:
文档更新
以下文档页面已随本版本更新:
- TagGroup — 新组件文档:用法示例与 API 参考
- Menu — 新组件文档:用法示例与 API 参考
- InputGroup — 新组件文档:用法示例与 API 参考
链接
贡献者
感谢所有为本版本做出贡献的朋友!