代码演示
如何引入
import { Tag, TagGroup, SplitTagGroup } from '@fibrous/semi-ui-react';
基本用法
基本标签用法,将内容使用 <Tag> 标签包裹即可。
可以通过添加 closable 属性将其变为可关闭标签。
此时点击 x 关闭会触发 onClose 事件,在 onClose 中阻止默认事件可以使其点击后依然显示不隐藏
代码
import { Tag, Space } from '@fibrous/semi-ui-react';
export default function TagDemo() {
return (
<div>
<Space>
<Tag>default tag</Tag>
<Tag closable>Closable Tag</Tag>
<Tag closable onClose={(_value, e) => e.preventDefault()}>
Closable Tag, Prevent Default
</Tag>
</Space>
</div>
);
}尺寸
默认定义了两种尺寸:大、小(默认)。
代码
import { Tag, Space } from '@fibrous/semi-ui-react';
export default function TagDemo() {
return (
<Space>
<Tag size="small" color="light-blue">
small tag
</Tag>
<Tag size="large" color="cyan">
large tag
</Tag>
</Space>
);
}形状
默认定义了两种形状:square(默认)、circle。
代码
import { Tag, Space } from '@fibrous/semi-ui-react';
export default function TagDemo() {
return (
<Space>
<Tag size="small" shape="circle" color="amber">
small circle tag
</Tag>
<Tag size="large" shape="circle" color="violet">
large circle tag
</Tag>
</Space>
);
}配置图标
通过配置 prefixIcon、suffixIcon,可以在 children 内容前后添加 Icon 图标。
代码
import { IconGithubLogo, IconSemiLogo } from '@fibrous/semi-icons-react';
import { Tag, Space } from '@fibrous/semi-ui-react';
export default function TagDemo() {
return (
<Space>
<Tag color="light-blue" prefixIcon={<IconGithubLogo />} size="large" shape="circle">
Semi Design
</Tag>
<Tag color="cyan" size="large" shape="circle" suffixIcon={<IconSemiLogo />}>
D2C: figma to code in one click
</Tag>
</Space>
);
}颜色
标签支持默认色板的 16 种颜色和白色,包括:amber、 blue、 cyan、 green、 grey、 indigo、 light-blue、 light-green、 lime、 orange、 pink、 purple、 red、 teal、 violet、 yellow、 white,也可以通过 style 来自定义颜色样式。
代码
import { Tag, Space } from '@fibrous/semi-ui-react';
export default function TagDemo() {
return (
<Space wrap>
{(['amber', 'blue', 'cyan', 'green', 'grey', 'indigo', 'light-blue', 'light-green', 'lime', 'orange', 'pink', 'purple', 'red', 'teal', 'violet', 'yellow', 'white'] as const).map((item) => (
<Tag color={item} key={item}>
{item}
</Tag>
))}
</Space>
);
}AI 风格 - 多彩标签
设置 colorful 为 true 即可获得多彩的标签。注意: 多彩标签的字重和非多彩标签字重不同。
多彩标签可通过 gradient 区分是否为渐变色。
代码
import { IconAIFilledLevel1, IconAIFilledLevel3 } from '@fibrous/semi-icons-react';
import { Tag } from '@fibrous/semi-ui-react';
export default function TagDemo() {
return (
<div style={{ display: 'flex', flexDirection: 'column', rowGap: 30 }}>
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(3,1fr)', gridGap: '10px', width: 'fit-content' }}>
<Tag colorful prefixIcon={<IconAIFilledLevel1 size="small" />} type="solid" shape="circle" gradient>
AI
</Tag>
<Tag colorful prefixIcon={<IconAIFilledLevel3 size="small" />} type="light" shape="circle" gradient>
AI
</Tag>
<Tag colorful prefixIcon={<IconAIFilledLevel3 size="small" />} type="ghost" shape="circle" gradient>
AI
</Tag>
<Tag colorful prefixIcon={<IconAIFilledLevel1 size="small" />} type="solid" shape="circle">
AI
</Tag>
<Tag colorful prefixIcon={<IconAIFilledLevel1 size="small" />} type="light" shape="circle">
AI
</Tag>
<Tag colorful prefixIcon={<IconAIFilledLevel1 size="small" />} type="ghost" shape="circle">
AI
</Tag>
</div>
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(3,1fr)', gridGap: '10px', width: 'fit-content' }}>
<Tag colorful prefixIcon={<IconAIFilledLevel1 size="small" />} type="solid" gradient>
AI
</Tag>
<Tag colorful prefixIcon={<IconAIFilledLevel3 size="small" />} type="light" gradient>
AI
</Tag>
<Tag colorful prefixIcon={<IconAIFilledLevel3 size="small" />} type="ghost" gradient>
AI
</Tag>
<Tag colorful prefixIcon={<IconAIFilledLevel1 size="small" />} type="solid">
AI
</Tag>
<Tag colorful prefixIcon={<IconAIFilledLevel1 size="small" />} type="light">
AI
</Tag>
<Tag colorful prefixIcon={<IconAIFilledLevel1 size="small" />} type="ghost">
AI
</Tag>
</div>
</div>
);
}样式类型
标签支持三种样式类型,包括浅色底色 light,白色底色 ghost,深色底色 solid;默认值为 light。通过 type 配置
代码
import { IconGithubLogo, IconSemiLogo } from '@fibrous/semi-icons-react';
import { Tag, Space } from '@fibrous/semi-ui-react';
export default function TagDemo() {
return (
<Space wrap>
<Tag color="light-blue" prefixIcon={<IconGithubLogo />} size="large" shape="circle" type="light">
Semi Design Light Tag
</Tag>
<Tag color="cyan" size="large" shape="circle" suffixIcon={<IconSemiLogo />} type="light">
D2C: figma to code in one click
</Tag>
<Tag color="light-blue" prefixIcon={<IconGithubLogo />} size="large" shape="circle" type="ghost">
Semi Design Ghost Tag
</Tag>
<Tag color="cyan" size="large" shape="circle" type="ghost" suffixIcon={<IconSemiLogo />}>
D2C: figma to code in one click
</Tag>
<Tag color="light-blue" prefixIcon={<IconGithubLogo />} size="large" shape="circle" type="solid">
Semi Design Solid Tag
</Tag>
<Tag color="cyan" size="large" shape="circle" type="solid" suffixIcon={<IconSemiLogo />}>
D2C: figma to code in one click
</Tag>
</Space>
);
}头像标签
设置 avatarSrc 可以生成头像标签。结合 avatarShape 可以调整头像标签的形状,支持 square 和 circle。
代码
import { Tag, Space } from '@fibrous/semi-ui-react';
export default function TagDemo() {
const src = '/assets/placeholder/avatar-a.svg';
return (
<Space vertical align="start">
<Tag avatarSrc={src}>焦锐志</Tag>
<Tag avatarSrc={src} size="large">
焦锐志
</Tag>
<Tag avatarSrc={src} size="large" closable>
焦锐志
</Tag>
<Tag avatarSrc={src} avatarShape="circle">
焦锐志
</Tag>
<Tag avatarSrc={src} avatarShape="circle" size="large">
焦锐志
</Tag>
<Tag avatarSrc={src} avatarShape="circle" size="large" closable>
焦锐志
</Tag>
</Space>
);
}不可见的
通过 visible 属性控制标签是否可见。
代码
import { useState } from 'react';
import { Tag, RadioGroup, Radio } from '@fibrous/semi-ui-react';
export default function TagDemo() {
const [visible, setVisible] = useState(false);
const toggleVisible = () => {
setVisible(!visible);
};
return (
<div>
<RadioGroup type="button" defaultValue={0} onChange={toggleVisible}>
<Radio value={1}>Show</Radio>
<Radio value={0}>Hide</Radio>
</RadioGroup>
<div style={{ marginTop: 10 }}>
<Tag visible={visible} size="large" color="light-blue">
Invisible tag
</Tag>
</div>
</div>
);
}TagGroup 使用
在 TagGroup 内通过 tagList 传入 tags 配置,并且设置 maxTagCount 属性, 超出数量限制后,会显示为 +N
通过设置 showPopover 属性,来控制 hover 到 +N Tag 时,是否通过 Popover 显示剩余内容
代码
import { TagGroup, type TagProps } from '@fibrous/semi-ui-react';
export default function TagDemo() {
const tagList: TagProps[] = [
{ color: 'light-blue', children: '抖音' },
{ color: 'cyan', children: '火山' },
{ color: 'violet', children: '剪映' },
{ color: 'white', children: '醒图' },
];
const src = '/assets/placeholder/avatar-a.svg';
const tagList2: TagProps[] = [
{ color: 'white', children: 'Douyin', avatarSrc: src },
{ color: 'white', children: 'Hotsoon', avatarSrc: src },
{ color: 'white', children: 'Capcut', avatarSrc: src },
{ color: 'white', children: 'Xingtu', avatarSrc: src },
];
const divStyle = {
backgroundColor: 'var(--semi-color-fill-0)',
height: 35,
width: 300,
display: 'flex',
alignItems: 'center',
padding: '0 10px',
marginBottom: 30,
};
const tagGroupStyle = {
display: 'flex',
alignItems: 'center',
width: 350,
};
return (
<>
<div style={divStyle}>
<TagGroup maxTagCount={3} style={tagGroupStyle} tagList={tagList} size="large" />
</div>
<div style={divStyle}>
<TagGroup maxTagCount={2} style={tagGroupStyle} tagList={tagList2} size="large" avatarShape="circle" showPopover />
</div>
</>
);
}如果 TagGroup 中的标签可删除,用户需要在 onTagClose 中处理传递给 TagGroup 的 tagList。从列表移除标签时请为每项提供 tagKey,否则文字相同的标签移除前一个后会错位。
代码
import { useState } from 'react';
import { TagGroup, type TagGroupProps, type TagProps } from '@fibrous/semi-ui-react';
export default function TagDemo() {
const defaultList: TagProps[] = [
{ tagKey: '1', color: 'light-blue', children: '抖音', closable: true },
{ tagKey: '3', color: 'cyan', children: '剪映', closable: true },
{ tagKey: '2', color: 'violet', children: '醒图', closable: true },
{ tagKey: '4', color: 'teal', children: '轻颜相机', closable: true },
{ tagKey: '5', color: 'white', children: '飞书', closable: true },
];
const [tagList, setTagList] = useState(defaultList);
const tagListClick: TagGroupProps['onTagClose'] = (_value, _e, tagKey) => {
const newTagList = [...tagList];
const closeTagIndex = newTagList.findIndex((t) => t.tagKey === tagKey);
newTagList.splice(closeTagIndex, 1);
setTagList(newTagList);
};
return (
<div
style={{
backgroundColor: 'var(--semi-color-fill-0)',
height: 35,
width: 300,
display: 'flex',
alignItems: 'center',
padding: '0 10px',
marginBottom: 30,
}}
>
<TagGroup
maxTagCount={3}
showPopover
style={{
display: 'flex',
alignItems: 'center',
width: 350,
}}
tagList={tagList}
size="large"
onTagClose={tagListClick}
/>
</div>
);
}SplitTagGroup 组合标签
使用 SplitTagGroup 可以将多个标签组合成一个整体,首尾标签会有圆角,中间标签圆角为 0,形成连续的视觉效果。
代码
import { Tag, SplitTagGroup, Space } from '@fibrous/semi-ui-react';
export default function TagDemo() {
return (
<Space vertical align="start">
<SplitTagGroup>
<Tag color="blue" type="solid">
标签一
</Tag>
<Tag color="cyan" type="solid">
标签二
</Tag>
<Tag color="teal" type="solid">
标签三
</Tag>
</SplitTagGroup>
<SplitTagGroup>
<Tag color="violet" shape="circle">
组合
</Tag>
<Tag color="purple" shape="circle">
标签
</Tag>
<Tag color="pink" shape="circle">
示例
</Tag>
<Tag color="red" shape="circle">
效果
</Tag>
</SplitTagGroup>
<SplitTagGroup>
<Tag color="amber" type="light">
浅色
</Tag>
<Tag color="orange" type="light">
组合
</Tag>
<Tag color="yellow" type="light">
标签
</Tag>
</SplitTagGroup>
<SplitTagGroup>
<Tag color="green" type="ghost">
镂空
</Tag>
<Tag color="light-green" type="ghost">
样式
</Tag>
<Tag color="lime" type="ghost">
组合
</Tag>
</SplitTagGroup>
</Space>
);
}API参考
Tag
Props
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| avatarShape | 头像标签中头像的形状,可选 square 和 circle。 | AvatarShape | "square" |
| avatarSrc | 头像的资源地址,设置后生成头像标签。 | string | - |
| children | 标签内容。纯文字或数字超出时省略,其他节点居中显示。 | React.ReactNode | - |
| className | 根元素的类名。 | string | "" |
| closable | 标签是否可以关闭。可关闭的标签也可以通过 Backspace 或 Delete 键关闭。 | boolean | false |
| color | 标签颜色,可选色板中的 16 种颜色和 white。 | TagColor | "grey" |
| colorful | 是否为多彩标签。 | boolean | false |
| gradient | 多彩标签是否为渐变色,需 colorful 为 true。 | boolean | false |
| onClose | 关闭标签时的回调,参数为标签内容、事件与 tagKey。event 为点击关闭图标的 click 事件,或按 Backspace、Delete 时的 keydown 事件。对事件调用 preventDefault 可保持标签显示。 | Type(tagChildren: React.ReactNode, event: React.MouseEvent<HTMLElement> | React.KeyboardEvent<HTMLElement>, tagKey: string | number) => void | - |
| onMouseEnter | 指针移入标签时的回调。 | Type() => void | - |
| prefixIcon | 内容前的图标。 | React.ReactNode | null |
| ref | 根元素的引用。 | TypeReact.Ref<HTMLDivElement> | - |
| shape | 标签形状,可选 square 和 circle。 | TagShape | "square" |
| size | 标签尺寸,可选 default、small 或 large。 | TagSize | "default" |
| style | 根元素的样式。 | React.CSSProperties | {} |
| suffixIcon | 内容后的图标。 | React.ReactNode | null |
| tabIndex | 根元素的 tabIndex,TagInput 用它让方向键而非 Tab 在标签间移动焦点。 | number | - |
| tagKey | 标签的唯一标识,作为 onClose 的第三个参数传出,不允许重复。 | string | number | - |
| type | 样式类型,可选 light、ghost 或 solid。 | TagType | "light" |
| visible | 标签是否可见。不传时关闭标签后会隐藏;传入后由该值决定显示。 | boolean | - |
aria-label、onClick 等原生属性经展开落在根元素(div)上。声明 onClick 或 closable 后,根元素成为可聚焦的按钮(role="button")。
TagGroup
Props
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| avatarShape | 组内头像标签的头像形状,可选 square 和 circle。 | AvatarShape | "square" |
| className | 根元素的类名。 | string | "" |
| maxTagCount | 最多显示的标签数,超出的部分显示为 +N。 | number | - |
| mode | 传 custom 时,tagList 的每一项按原样渲染,不再包装为 Tag。 | 'custom' | - |
| onPlusNMouseEnter | 指针移入 +N 标签时的回调。 | Type() => void | - |
| onTagClose | 组内标签被关闭时的回调,参数为标签内容、事件与该标签的 tagKey;需在回调中更新 tagList。 | Type(tagChildren: React.ReactNode, event: React.MouseEvent<HTMLElement> | React.KeyboardEvent<HTMLElement>, tagKey: string | number) => void | - |
| popoverProps | 传给 Popover 的属性,可设置 position、trigger 等,参见 Popover。 | PopoverProps | - |
| ref | 根元素的引用。 | TypeReact.Ref<HTMLDivElement> | - |
| restCount | +N 中显示的数量,缺省为超出 maxTagCount 的标签数。 | number | - |
| showPopover | 悬停在 +N 上时,是否通过 Popover 显示剩余标签。 | boolean | - |
| size | 组内标签的尺寸,可选 default、small 或 large。 | TagSize | "default" |
| style | 根元素的样式。 | React.CSSProperties | {} |
| tagList | 标签配置数组,每项为 Tag 的属性,children 为标签内容;mode 为 custom 时为 ReactNode 数组。 | React.ReactNode[] | TagProps[] | - |
其他原生属性经展开落在 TagGroup 的根元素(div)上。
SplitTagGroup
Props
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| ref | 根元素的引用。 | TypeReact.Ref<HTMLDivElement> | - |
className、style、children、aria-label 等原生属性经展开落在根元素(div)上,根元素的 role 固定为 group。
Accessibility
ARIA
aria-label用于表示Tag的作用,对于可删除或者可点击的Tag,我们推荐使用此属性
键盘和焦点
- 如果当前
Tag可交互,那么这个Tag可被聚焦到。如:- 使用了
onClick属性(Vue 为@click)时,键盘用户可以通过Enter或空格键激活此Tag closable属性为true时,键盘用户可以通过Delete或Backspace键删除此Tag,焦点会移到相邻的可聚焦Tag
- 使用了
文案规范
- 由于空间有限,标签文本应尽可能简短
- 避免换行
- 使用句子大小写;
设计变量
| Sass 变量 | 值 | 用法 |
|---|---|---|
| $color-tag_avatar-bg-default | var(--semi-color-bg-4) | 头像标签背景颜色 - 默认 |
| $color-tag_avatar-border-default | var(--semi-color-border) | 头像标签描边颜色 - 默认 |
| $color-tag_avatar-text-default | var(--semi-color-text-0) | 头像标签文字颜色 - 默认 |
| $color-tag_white-bg-default | var(--semi-color-bg-4) | 白色标签背景颜色 - 默认 |
| $color-tag_white-border-default | rgb(from var(--semi-grey-2) r g b / 0.7) | 白色标签描边颜色 - 默认 |
| $color-tag_white-text-default | var(--semi-color-text-0) | 白色标签文字颜色 - 默认 |
| $color-tag_white-icon-default | var(--semi-color-text-2) | 白色标签图标颜色 - 默认 |
| $color-tag-outline-focus | $color-focus-ring | 标签轮廓 - 聚焦 |
| $color-tag_colorful_solid-bg | var(--semi-color-ai-purple) | AI Tag深色底色类型背景色 |
| $color-tag_colorful_solid-text | var(--semi-color-white) | AI Tag 深色底色类型字体颜色 |
| $color-tag_colorful_solid_gradient-bg | var(--semi-color-ai-general) | AI Tag深色底色类型渐变背景色 |
| $color-tag_colorful_light-bg | var(--semi-ai-purple-0) | AI Tag 浅色底色类型背景色 |
| $color-tag_colorful_light-text | var(--semi-color-ai-purple) | AI Tag 浅色底色类型字体颜色 |
| $color-tag_colorful_light_gradient-bg | var(--semi-ai-general-0) | AI Tag浅色底色类型背景色-渐变 |
| $color-tag_colorful_light_gradient-text | var(--semi-color-ai-general) | AI Tag浅色底色类型字体色-渐变 |
| $color-tag_colorful_light_gradient-1 | var(--semi-ai-general-5-0) | AI Tag 浅色底色icon渐变色1 |
| $color-tag_colorful_light_gradient-2 | var(--semi-ai-general-5-1) | AI Tag 浅色底色icon渐变色2 |
| $color-tag_colorful_light_gradient-3 | var(--semi-ai-general-5-2) | AI Tag 浅色底色icon渐变色3 |
| $color-tag_colorful_light_gradient-4 | var(--semi-ai-general-5-3) | AI Tag 浅色底色icon渐变色4 |
| $color-tag_colorful_ghost-bg | var(--semi-color-white) | AI Tag 白色底色类型背景色 |
| $color-tag_colorful_ghost-text | var(--semi-color-ai-purple) | AI Tag 白色底色类型字体颜色 |
| $color-tag_colorful_ghost-border | var(--semi-color-ai-general) | AI Tag 白色底色类型描边颜色 |
| $color-tag_colorful_ghost_gradient-text | var(--semi-color-ai-general) | AI Tag 白色底色类型字体色-渐变 |
| $color-tag_colorful_ghost_gradient-1 | var(--semi-ai-general-5-0) | AI Tag 白色底色icon渐变色1 |
| $color-tag_colorful_ghost_gradient-2 | var(--semi-ai-general-5-1) | AI Tag 白色底色icon渐变色2 |
| $color-tag_colorful_ghost_gradient-3 | var(--semi-ai-general-5-2) | AI Tag 白色底色icon渐变色3 |
| $color-tag_colorful_ghost_gradient-4 | var(--semi-ai-general-5-3) | AI Tag 白色底色icon渐变色4 |
| $width-tag_avatar_circle_small | 16px | 头像标签圆角 - 小尺寸 |
| $width-tag_avatar_circle_large | 20px | 头像标签圆角 - 大尺寸 |
| $width-tag-border | 1px | 标签描边宽度 |
| $width-tag_avatar-border | $width-tag-border | 头像标签描边宽度 |
| $width-tag-outline | $width-focus-ring | 标签轮廓宽度 |
| $height-tag_small | 20px | 小尺寸标签高度 |
| $height-tag_large | 24px | 大尺寸标签高度 |
| $radius-tag | var(--semi-border-radius-small) | 标签圆角大小 |
| $radius-tag_circle | var(--semi-border-radius-full) | 胶囊标签圆角大小 |
| $spacing-tag_small-paddingY | 2px | 小尺寸标签垂直方向内边距 |
| $spacing-tag_small-paddingX | $spacing-tight | 小尺寸标签水平方向内边距 |
| $spacing-tag_prefix_icon_paddingRight | $spacing-extra-tight | 后缀图标右侧边距 |
| $spacing-tag_suffix_icon_paddingLeft | $spacing-extra-tight | 后缀图标左侧边距 |
| $spacing-tag_large-paddingY | 4px | 大尺寸标签垂直方向内边距 |
| $spacing-tag_large-paddingX | $spacing-tight | 大尺寸标签水平方向内边距 |
| $color-tag_close-icon-default | var(--semi-color-text-2) | 可删除的标签删除按钮颜色 |
| $color-tag_close-icon-hover | var(--semi-color-text-1) | 可删除的标签删除按钮颜色 - 悬浮 |
| $color-tag_close-icon-active | var(--semi-color-text-0) | 可删除的标签删除按钮颜色 - 按下 |
| $spacing-tag_close-paddingLeft | $spacing-extra-tight | 可删除的标签删除按钮左侧内边距 |
| $spacing-tag_closable-paddingTop | $spacing-extra-tight | 可删除的标签删除按钮顶部内边距 |
| $spacing-tag_closable-paddingRight | $spacing-extra-tight | 可删除的标签删除按钮右侧内边距 |
| $spacing-tag_closable-paddingBottom | $spacing-extra-tight | 可删除的标签删除按钮底部内边距 |
| $spacing-tag_closable-paddingLeft | $spacing-tight | 可删除的标签删除按钮左侧内边距 |
| $spacing-tag_avatar-marginRight | $spacing-extra-tight | 头像标签头像右侧外边距 |
| $spacing-tag_avatar_square-paddingTop | 0 | 方形头像标签头像顶部内边距 |
| $spacing-tag_avatar_square-paddingRight | $spacing-extra-tight | 方形头像标签头像右侧内边距 |
| $spacing-tag_avatar_square-paddingBottom | 0 | 方形头像标签头像底部内边距 |
| $spacing-tag_avatar_square-paddingLeft | 0 | 方形头像标签头像左侧内边距 |
| $spacing-tag_avatar_circle-paddingTop | $spacing-super-tight | 圆型头像标签头像顶部内边距 |
| $spacing-tag_avatar_circle-paddingRight | $spacing-extra-tight | 圆型头像标签头像右侧内边距 |
| $spacing-tag_avatar_circle-paddingBottom | $spacing-super-tight | 圆型头像标签头像底部内边距 |
| $spacing-tag_avatar_circle-paddingLeft | $spacing-super-tight | 圆型头像标签头像左侧内边距 |
| $color-tag_avatar_square_img-bg-default | var(--semi-color-default) | 方形头像标签头像背景色 - 默认 |
| $spacing-tag_group-marginBottom | 0 | 标签组底部外边距 |
| $spacing-tag_group-marginRight | $spacing-tight | 标签组右侧外边距 |
| $font-tag_colorful-fontWeight | $font-weight-bold | AI tag的字重 |