ProComponents, templates & AI tooling
2.3k

RC 3

TagGroup、Menu、InputGroup 组件,Bottom Sheet Android 返回键修复,Expo 55 兼容

2026 年 2 月 26 日

RC 3 带来三个新组件:用于可选标签管理的 TagGroup、基于 Popover/Bottom Sheet 的下拉菜单 Menu,以及带自动测量前后缀槽位的装饰性输入 InputGroup。本版本还为所有基于 Bottom Sheet 的遮罩增加 Android 实体返回键支持;通过关键的 combineStyles 修复保留 Reanimated 动画样式绑定,实现 Expo 55 兼容;并包含若干依赖升级。

安装

升级到最新版本:

npm i heroui-native
pnpm add heroui-native
yarn add heroui-native
bun add heroui-native

使用 AI 助手? 直接提示「Hey Cursor,把 HeroUI Native 升级到最新版本」,助手会自动比对版本并完成必要修改。了解更多请参见 HeroUI Native MCP 服务器

抢先体验

通过预览应用在真机上体验 RC 3 的全部改进!你可以探索 TagGroup、Menu、InputGroup,以及 Bottom Sheet 的 Android 返回键支持与各项修复。

环境要求

请确保手机已安装最新版本的 Expo Go

如何访问

方式一:扫描二维码

使用手机相机或 Expo Go 应用扫描:

Expo Go 二维码

Android 用户请注意: 若使用系统相机或其他扫码应用会跳转到浏览器并出现 404,请先打开 Expo Go,使用其内置扫码功能扫描。

方式二:点击链接

📱 在 Expo Go 中打开演示应用

若设备已安装 Expo Go,将自动在其中打开应用。

更新亮点

新组件

本版本新增 3 个组件:

  • TagGroup:用于展示与管理可选标签的复合组件,支持可选移除、单选/多选及表单字段集成。
  • Menu:下拉菜单系统,支持 Popover 与 Bottom Sheet 呈现、单选/多选、菜单项变体与按压动画反馈。
  • InputGroup:装饰性文本输入,前后缀槽位绝对定位并自动测量宽度,为输入区应用匹配内边距。

TagGroup

TagGroup 以复合组件模式渲染可选标签组,并支持可选移除。支持单选与多选、受控/非受控 API、两种视觉变体(default 与 surface)、三种尺寸、禁用态,以及与 Label、Description、FieldError 的完整表单集成。

特性:

  • 复合子组件:TagGroup.ListTagGroup.ItemTagGroup.ItemLabelTagGroup.ItemRemoveButton
  • 单选/多选模式,受控/非受控 API
  • 两种视觉变体:defaultsurface
  • 三种尺寸:smmdlg
  • 单项禁用与 disabledKeys
  • 通过 onRemoveTagGroup.ItemRemoveButton 实现移除
  • TagGroup.ListrenderEmptyState 渲染空状态
  • 与 Label、Description、FieldError、isInvalidisRequired 的表单集成
  • useTagGroupuseTagGroupItem 供高级用法

用法:

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 提供基于复合组件的下拉菜单,支持 Popover 与 Bottom Sheet 两种呈现。包含基于 Reanimated 的按压动画、单选/多选、菜单项变体(default 与 danger)、指示器样式及可配置 placement。

特性:

  • 复合子组件:Menu.TriggerMenu.PortalMenu.OverlayMenu.ContentMenu.LabelMenu.GroupMenu.ItemMenu.ItemTitleMenu.ItemDescriptionMenu.ItemIndicator
  • 两种呈现:popoverbottom-sheet,placement 可配置(topbottomleftright
  • Menu.Group 上通过 selectedKeys/onSelectionChange 实现单选/多选
  • 菜单项按压动画(缩放 + 背景色),Reanimated 实现,可通过 animation 自定义
  • 菜单项变体:defaultdanger
  • 指示器变体:checkmarkdot 或自定义内容
  • 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 提供装饰性文本输入,PrefixSuffix 子组件绝对定位,通过 onLayout 自动测量宽度并为 Input 应用匹配的水平内边距。isDecorative 布尔值可一次性处理装饰性附加内容的无障碍与指针事件样板;根级 isDisabled 通过上下文级联到所有子节点。

特性:

  • 复合子组件:InputGroup.PrefixInputGroup.SuffixInputGroup.Input
  • 自动内边距:通过 onLayout 测量 Prefix/Suffix 宽度,自动作为 Input 的 paddingLeft/paddingRight
  • Prefix/Suffix 上 isDecorative 统一设置 pointerEvents="none"accessibilityElementsHiddenimportantForAccessibility
  • 根级 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 的 SharedValueuseAnimatedStyle 绑定。

改进:

  • 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 破坏动画绑定;现改为返回样式数组以保留 SharedValueuseAnimatedStyle

相关 PR:

文档更新

以下文档页面已随本版本更新:

  • TagGroup — 新组件文档:用法示例与 API 参考
  • Menu — 新组件文档:用法示例与 API 参考
  • InputGroup — 新组件文档:用法示例与 API 参考

链接

贡献者

感谢所有为本版本做出贡献的朋友!

本页目录