---
title: RC 3
description: TagGroup、Menu、InputGroup 组件，Bottom Sheet Android 返回键修复，Expo 55 兼容
github:
  pull: 309
---

<div className="flex items-center gap-3 mb-6">
  <span className="text-sm text-muted">2026 年 2 月 26 日</span>
</div>

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

## 安装

升级到最新版本：

<Tabs items={["npm", "pnpm", "yarn", "bun"]}>
<Tab value="npm">
  ```bash
  npm i heroui-native
  ```
</Tab>
<Tab value="pnpm">
  ``` bash
  pnpm add heroui-native
  ```
</Tab>
<Tab value="yarn">
  ```bash
  yarn add heroui-native
  ```
</Tab>
<Tab value="bun">
  ```bash
  bun add heroui-native
  ```
</Tab>
</Tabs>

<Callout type="info">
  **使用 AI 助手？** 直接提示「Hey Cursor，把 HeroUI Native 升级到最新版本」，助手会自动比对版本并完成必要修改。了解更多请参见 [HeroUI Native MCP 服务器](/docs/native/getting-started/mcp-server)。
</Callout>

## 抢先体验

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

### 环境要求

请确保手机已安装最新版本的 [Expo Go](https://expo.dev/go)。

### 如何访问

**方式一：扫描二维码**

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

<div className="flex justify-center my-6">
  <img
    width="200"
    src="https://heroui-assets.nyc3.cdn.digitaloceanspaces.com/images/qr-code-native.png"
    alt="Expo Go 二维码"
  />
</div>

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

**方式二：点击链接**

**[📱 在 Expo Go 中打开演示应用](https://link.heroui.com/native-demo)**

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

## 更新亮点

### 新组件

本版本新增 **3** 个组件：

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

#### TagGroup

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

<NativeVideoPlayerView
  target="component"
  slug="tag-group"
  srcLight="https://heroui-assets.nyc3.cdn.digitaloceanspaces.com/docs/native/components/videos/tag-group-docs-light.mp4"
  srcDark="https://heroui-assets.nyc3.cdn.digitaloceanspaces.com/docs/native/components/videos/tag-group-docs-dark.mp4"
/>

**特性：**

- 复合子组件：`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` 供高级用法

**用法：**

```tsx
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 组件页](/docs/native/components/tag-group)。

**相关 PR：** [#309](https://github.com/heroui-inc/heroui-native/pull/309)

#### Menu

Menu 提供基于复合组件的下拉菜单，支持 Popover 与 Bottom Sheet 两种呈现。包含基于 Reanimated 的按压动画、单选/多选、菜单项变体（default 与 danger）、指示器样式及可配置 placement。

<NativeVideoPlayerView
  target="component"
  slug="menu"
  srcLight="https://heroui-assets.nyc3.cdn.digitaloceanspaces.com/docs/native/components/videos/menu-docs-light.mp4"
  srcDark="https://heroui-assets.nyc3.cdn.digitaloceanspaces.com/docs/native/components/videos/menu-docs-dark.mp4"
/>

**特性：**

- 复合子组件：`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` 控制

**用法：**

```tsx
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 组件页](/docs/native/components/menu)。

**相关 PR：** [#312](https://github.com/heroui-inc/heroui-native/pull/312)

#### InputGroup

InputGroup 提供装饰性文本输入，`Prefix` 与 `Suffix` 子组件绝对定位，通过 `onLayout` 自动测量宽度并为 Input 应用匹配的水平内边距。`isDecorative` 布尔值可一次性处理装饰性附加内容的无障碍与指针事件样板；根级 `isDisabled` 通过上下文级联到所有子节点。

<NativeVideoPlayerView
  target="component"
  slug="input-group"
  srcLight="https://heroui-assets.nyc3.cdn.digitaloceanspaces.com/docs/native/components/videos/input-group-docs-light.mp4"
  srcDark="https://heroui-assets.nyc3.cdn.digitaloceanspaces.com/docs/native/components/videos/input-group-docs-dark.mp4"
/>

**特性：**

- 复合子组件：`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`

**用法：**

```tsx
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 组件页](/docs/native/components/input-group)。

**相关 PR：** [#313](https://github.com/heroui-inc/heroui-native/pull/313)

## 组件改进

### Bottom Sheet Android 返回键支持

[Bottom Sheet](/docs/native/components/bottom-sheet) 共享容器现处理 Android 实体返回键：按下时关闭当前打开的 Bottom Sheet。`BackHandler` 仅在 Bottom Sheet 打开时注册，避免已关闭实例抢占事件。该修复全局作用于所有基于 Bottom Sheet 的组件。

**涉及组件：**

- [Bottom Sheet](/docs/native/components/bottom-sheet)
- [Popover](/docs/native/components/popover)
- [Select](/docs/native/components/select)

实现使用 React Native 的 `BackHandler` API，在 iOS 上为空操作，无需分平台分支。

**相关 PR：** [#308](https://github.com/heroui-inc/heroui-native/pull/308)

### Slot 的 `combineStyles` 修复

Slot 原语的 `combineStyles` 现返回样式数组，而不再使用 `StyleSheet.flatten`——后者会通过深拷贝样式对象破坏 Reanimated 的 `SharedValue` 与 `useAnimatedStyle` 绑定。

**改进：**

- `combineStyles` 通过返回数组保留 Reanimated 动画样式绑定
- React Native 原生支持嵌套样式数组，对使用方行为无影响
- 修复通过 Slot 原语组合的组件上的动画断裂问题

**相关 PR：** [#314](https://github.com/heroui-inc/heroui-native/pull/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](https://github.com/heroui-inc/heroui-native/pull/314)

## 问题修复

本版本包含以下修复：

- **[Issue #272](https://github.com/heroui-inc/heroui-native/issues/272)**：解决 `FullWindowOverlay` 干扰 React Native 元素检查器的问题。

- **[Issue #280](https://github.com/heroui-inc/heroui-native/issues/280)**：修复 Expo 55 下 Avatar 等依赖 Reanimated 的组件失效。`combineStyles` 曾通过 `StyleSheet.flatten` 破坏动画绑定；现改为返回样式数组以保留 `SharedValue` 与 `useAnimatedStyle`。

**相关 PR：**

- [#308](https://github.com/heroui-inc/heroui-native/pull/308)
- [#314](https://github.com/heroui-inc/heroui-native/pull/314)

## 文档更新

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

- [TagGroup](/docs/native/components/tag-group) — 新组件文档：用法示例与 API 参考
- [Menu](/docs/native/components/menu) — 新组件文档：用法示例与 API 参考
- [InputGroup](/docs/native/components/input-group) — 新组件文档：用法示例与 API 参考

## 链接

- [组件文档](../components)
- [GitHub 仓库](https://github.com/heroui-inc/heroui-native)

## 贡献者

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