ProComponents, templates & AI tooling
2.3k

TagGroup 标签组更新

用于展示与管理可选标签的复合组件,支持可选移除。

导入

import { TagGroup } from 'heroui-native';

结构

<TagGroup>
  <TagGroup.List>
    <TagGroup.Item id="tag-1">
      <TagGroup.ItemLabel>...</TagGroup.ItemLabel>
      <TagGroup.ItemRemoveButton />
    </TagGroup.Item>
  </TagGroup.List>
</TagGroup>
  • TagGroup:主容器,管理标签选中状态、禁用键与移除能力,并向子组件提供尺寸与变体上下文。
  • TagGroup.List:渲染标签列表的容器,可渲染空状态。
  • TagGroup.Item:组内单个标签。支持字符串子节点(自动包在 TagGroup.ItemLabel)、渲染函数子节点或自定义布局。
  • TagGroup.ItemLabel:标签文字。提供字符串子节点时会自动渲染,也可显式使用。
  • TagGroup.ItemRemoveButton:移除按钮;需要移除能力时需显式放置。仅当 TagGroup 传入 onRemove 时生效。

用法

基础用法

展示一个简单的可选标签组。

<TagGroup selectionMode="single">
  <TagGroup.List>
    <TagGroup.Item id="news">新闻</TagGroup.Item>
    <TagGroup.Item id="travel">旅行</TagGroup.Item>
    <TagGroup.Item id="gaming">游戏</TagGroup.Item>
  </TagGroup.List>
</TagGroup>

单选模式

同一时间只能选中一个标签。

<TagGroup selectionMode="single" defaultSelectedKeys={['news']}>
  <TagGroup.List>
    <TagGroup.Item id="news">新闻</TagGroup.Item>
    <TagGroup.Item id="travel">旅行</TagGroup.Item>
    <TagGroup.Item id="gaming">游戏</TagGroup.Item>
  </TagGroup.List>
</TagGroup>

多选模式

允许多个标签同时选中。

<TagGroup selectionMode="multiple" defaultSelectedKeys={['news', 'travel']}>
  <TagGroup.List>
    <TagGroup.Item id="news">新闻</TagGroup.Item>
    <TagGroup.Item id="travel">旅行</TagGroup.Item>
    <TagGroup.Item id="gaming">游戏</TagGroup.Item>
  </TagGroup.List>
</TagGroup>

受控选中

通过 selectedKeysonSelectionChange 控制选中状态。

const [selected, setSelected] = useState(new Set(['news']));

<TagGroup
  selectionMode="single"
  selectedKeys={selected}
  onSelectionChange={setSelected}
>
  <TagGroup.List>
    <TagGroup.Item id="news">新闻</TagGroup.Item>
    <TagGroup.Item id="travel">旅行</TagGroup.Item>
    <TagGroup.Item id="gaming">游戏</TagGroup.Item>
  </TagGroup.List>
</TagGroup>;

变体

为标签应用不同视觉变体。

<TagGroup selectionMode="single" variant="default">
  <TagGroup.List>
    <TagGroup.Item id="news">新闻</TagGroup.Item>
    <TagGroup.Item id="travel">旅行</TagGroup.Item>
  </TagGroup.List>
</TagGroup>

<TagGroup selectionMode="single" variant="surface">
  <TagGroup.List>
    <TagGroup.Item id="news">新闻</TagGroup.Item>
    <TagGroup.Item id="travel">旅行</TagGroup.Item>
  </TagGroup.List>
</TagGroup>

尺寸

控制组内所有标签的尺寸。

<TagGroup selectionMode="single" size="sm">
  <TagGroup.List>
    <TagGroup.Item id="news">新闻</TagGroup.Item>
  </TagGroup.List>
</TagGroup>

<TagGroup selectionMode="single" size="md">
  <TagGroup.List>
    <TagGroup.Item id="news">新闻</TagGroup.Item>
  </TagGroup.List>
</TagGroup>

<TagGroup selectionMode="single" size="lg">
  <TagGroup.List>
    <TagGroup.Item id="news">新闻</TagGroup.Item>
  </TagGroup.List>
</TagGroup>

带移除按钮

提供 onRemove,并在每个条目中放置 TagGroup.ItemRemoveButton 以显示移除按钮。

const [tags, setTags] = useState([
  { id: 'news', name: '新闻' },
  { id: 'travel', name: '旅行' },
]);

const onRemove = (keys) => {
  setTags((prev) => prev.filter((tag) => !keys.has(tag.id)));
};

<TagGroup selectionMode="single" onRemove={onRemove}>
  <TagGroup.List>
    {tags.map((tag) => (
      <TagGroup.Item key={tag.id} id={tag.id}>
        <TagGroup.ItemLabel>{tag.name}</TagGroup.ItemLabel>
        <TagGroup.ItemRemoveButton />
      </TagGroup.Item>
    ))}
  </TagGroup.List>
</TagGroup>;

渲染函数子节点

使用渲染函数访问 isSelectedisDisabled 以自定义布局。

<TagGroup selectionMode="single">
  <TagGroup.List>
    <TagGroup.Item id="news">
      {({ isSelected }) => (
        <>
          <SquareArticleIcon
            size={16}
            colorClassName={
              isSelected
                ? 'accent-accent-soft-foreground'
                : 'accent-field-foreground'
            }
          />
          <TagGroup.ItemLabel>新闻</TagGroup.ItemLabel>
        </>
      )}
    </TagGroup.Item>
  </TagGroup.List>
</TagGroup>

空状态

列表无标签时渲染自定义内容。

<TagGroup onRemove={onRemove}>
  <TagGroup.List
    renderEmptyState={() => (
      <Text className="text-sm text-muted">暂无分类</Text>
    )}
  >
    {tags.map((tag) => (
      <TagGroup.Item key={tag.id} id={tag.id}>
        <TagGroup.ItemLabel>{tag.name}</TagGroup.ItemLabel>
        <TagGroup.ItemRemoveButton />
      </TagGroup.Item>
    ))}
  </TagGroup.List>
</TagGroup>

禁用标签

禁用单个标签或整个组。

<TagGroup selectionMode="single" disabledKeys={new Set(['travel'])}>
  <TagGroup.List>
    <TagGroup.Item id="news">新闻</TagGroup.Item>
    <TagGroup.Item id="travel">旅行</TagGroup.Item>
    <TagGroup.Item id="gaming" isDisabled>
      游戏
    </TagGroup.Item>
  </TagGroup.List>
</TagGroup>

示例

import { TagGroup, Label, Description, FieldError } from 'heroui-native';
import { useState, useMemo } from 'react';
import { View } from 'react-native';

export default function TagGroupExample() {
  const [selected, setSelected] = useState(new Set());
  const isInvalid = useMemo(
    () => Array.from(selected).length === 0,
    [selected]
  );

  return (
    <View className="gap-4">
      <TagGroup
        selectedKeys={selected}
        selectionMode="multiple"
        onSelectionChange={setSelected}
        isInvalid={isInvalid}
      >
        <Label isInvalid={false}>设施</Label>
        <TagGroup.List>
          <TagGroup.Item id="laundry">洗衣</TagGroup.Item>
          <TagGroup.Item id="fitness">健身房</TagGroup.Item>
          <TagGroup.Item id="parking">停车</TagGroup.Item>
          <TagGroup.Item id="pool">泳池</TagGroup.Item>
          <TagGroup.Item id="breakfast">早餐</TagGroup.Item>
        </TagGroup.List>
        <Description hideOnInvalid>
          {`已选:${Array.from(selected).join('、')}`}
        </Description>
        <FieldError>请至少选择一个分类</FieldError>
      </TagGroup>
    </View>
  );
}

更多示例见 GitHub 仓库

API 参考

TagGroup

proptypedefaultdescription
childrenReact.ReactNode-渲染在标签组内的子节点
size'sm' | 'md' | 'lg''md'组内所有标签的尺寸
variant'default' | 'surface''default'组内所有标签的视觉变体
selectionMode'none' | 'single' | 'multiple''none'允许的选中类型
selectedKeysIterable<TagKey>-当前选中键(受控)
defaultSelectedKeysIterable<TagKey>-初始选中键(非受控)
disabledKeysIterable<TagKey>-应被禁用的标签键
isDisabledbooleanfalse是否禁用整个标签组
isInvalidbooleanfalse是否处于非法状态
isRequiredbooleanfalse是否必填
classNamestring-标签组容器的额外 class
styleStyleProp<ViewStyle>-标签组容器的额外样式
animation"disable-all" | undefined-设为 "disable-all" 可禁用全部动画(含子级)
onSelectionChange(keys: Set<TagKey>) => void-选中变化时调用
onRemove(keys: Set<TagKey>) => void-移除标签时调用
...ViewPropsViewProps-支持 React Native View 的全部属性

TagKey

string | number — 在 TagGroup 内标识标签的键类型。

Animation

使用 animation="disable-all" 可禁用全部动画(含子级)。省略或使用 undefined 为默认动画。

TagGroup.List

proptypedefaultdescription
childrenReact.ReactNode-列表内的子节点
classNamestring-列表容器的额外 class
styleStyleProp<ViewStyle>-列表容器的额外样式
renderEmptyState() => React.ReactNode-无标签时调用的渲染函数
...ViewPropsViewProps-支持 React Native View 的全部属性

TagGroup.Item

proptypedefaultdescription
childrenReact.ReactNode | ((renderProps: TagRenderProps) => React.ReactNode)-标签内容:字符串、元素,或接收 TagRenderProps 的渲染函数
idTagKey-该标签的唯一标识
isDisabledboolean-是否禁用该标签
classNamestring-标签的额外 class
styleStyleProp<ViewStyle>-标签的额外样式
...PressablePropsPressableProps-支持 React Native Pressable 的全部属性

TagRenderProps

proptypedescription
isSelectedboolean当前是否选中
isDisabledboolean是否禁用(根级、disabledKeys 与条目属性合并后的结果)

TagGroup.ItemLabel

proptypedefaultdescription
childrenReact.ReactNode-要渲染的文字内容
classNamestring-标签文字的额外 class
...TextPropsTextProps-支持 React Native Text 的全部属性

TagGroup.ItemRemoveButton

proptypedefaultdescription
childrenReact.ReactNode-自定义图标或内容;省略时默认为关闭图标
classNamestring-移除按钮的额外 class
iconPropsTagRemoveButtonIconProps-自定义默认关闭图标的属性;仅在没有 children 时生效
hitSlopnumber8扩大可点击区域
...PressablePropsPressableProps-支持 React Native Pressable 的全部属性

TagRemoveButtonIconProps

proptypedefaultdescription
sizenumber12图标尺寸
colorstring-图标颜色

Hooks

useTagGroup

访问标签组根上下文,必须在 TagGroup 内使用。

import { useTagGroup } from 'heroui-native';

const {
  selectedKeys,
  disabledKeys,
  selectionMode,
  onSelectionChange,
  onRemove,
  isDisabled,
  isInvalid,
  isRequired,
} = useTagGroup();

返回值

propertytypedescription
selectionMode'none' | 'single' | 'multiple'允许的选中类型
selectedKeysSet<TagKey>当前选中的标签键
disabledKeysSet<TagKey>被禁用的标签键
onSelectionChange(keys: Set<TagKey>) => void选中变化回调
onRemove((keys: Set<TagKey>) => void) | undefined移除标签回调
isDisabledboolean是否禁用整个标签组
isInvalidboolean是否处于非法状态
isRequiredboolean是否必填

useTagGroupItem

访问单个标签上下文,必须在 TagGroup.Item 内使用。

import { useTagGroupItem } from 'heroui-native';

const { id, isSelected, isDisabled, allowsRemoving } = useTagGroupItem();

返回值

propertytypedescription
idTagKey该标签的唯一标识
isSelectedboolean当前是否选中
isDisabledboolean是否禁用
allowsRemovingboolean是否允许移除(当 TagGroup 提供 onRemove 时为 true)

本页目录