跳到主要内容

Tabs 标签页

页面内分类切换 · 两种风格:下划线 Tabs(页面级)/ 分段控件 Segmented(局部分组)。

实时预览

下方渲染的就是 src/components/ui/Tabs/Tabs.tsxsrc/components/ui/Segmented/Segmented.tsx 本体,通过 react-native-web 翻译成浏览器节点。

下划线 Tabs · 页面级
分段控件 · 局部 · md(默认)
分段控件 · sm(紧凑,模型下拉等局促位)

下划线 Tabs

页面级分类切换,全宽分布。来源:src/components/ui/Tabs/styles.tsTabs.tsx

元素规则
容器高 44px(fixed.hitTarget),背景 c.surface,底部 hairline c.outline
Tab 项flex: 1 平分,14pxtype.sm),激活态 c.primary + 字重 600(非激活 c.foregroundMuted + 500)
下划线2px c.primary,宽 36px(icon.xl,居中、非随 label),底对齐

分段控件

局部分组(如 Filter "全部 / 已完成 / 待跟进")。来源:src/components/ui/Segmented/styles.tsSegmented.tsx

元素规则
容器alignSelf: 'flex-start' 内容自适应宽,背景 c.surfaceContainerHigh(亮色 #F0F0F0),圆角 8(radius.md),内 padding 2
内容宽(非平分);minHeight / 水平 padding / 字号随 sizemd 44 / 16 / 13(fixed.hitTarget·space[7]·type.xs,默认、触控达标)· sm 28 / 12 / 12(高 28pt 物理常量·space[5]·type.xxs,紧凑、触控 < 44px)
激活白底 thumb(暗色 surfaceContainerHighest),圆角 6(radius.sm),亮色态柔阴影

用法

import { Tabs, Segmented } from '@unif/react-native-design';

{/* 页面级 */}
<Tabs
value={tab}
onChange={setTab}
items={[
{ id: 'all', label: '全部' },
{ id: 'pending', label: '待跟进' },
{ id: 'done', label: '已完成' },
]}
/>

{/* 局部分段 */}
<Segmented
value={range}
onChange={setRange}
items={[
{ id: 'day', label: '日' },
{ id: 'week', label: '周' },
{ id: 'month', label: '月' },
]}
/>

API

来源:src/components/ui/Tabs/types.tssrc/components/ui/Segmented/types.tsTabsSegmented props 形状一致,共用 TabItem

TabsProps / SegmentedProps

Prop类型默认说明
valuestring当前选中项的 id(必填)
onChange(id: string) => void切换回调,回传点中项的 id(必填)
itemsTabItem[]列表项(Tabs ≥2 项才有意义;必填)
size'sm' | 'md''md'仅 Segmented'md' 默认(高 44px 触控达标),'sm' 紧凑(高 28px / 字号 12,给模型下拉等局促位用,触控 < 44px)
testIDstring?容器 testID;item testID 自动派生为 ${testID}-${id}

TabItem

字段类型默认说明
idstring唯一标识,用作 key 与选中判定
labelstring显示文本(同时作 accessibilityLabel
testIDstring?单 item testID(默认 ${tabsTestID}-${id}

无障碍(a11y)

来源:src/components/ui/Tabs/Tabs.tsxsrc/components/ui/Segmented/Segmented.tsxtypes.ts(两者 a11y 实现一致,共用 TabItem 形状)。

  • 默认 accessibilityRoleTabsSegmented 的每个项 <Pressable> 上都硬编码 'tab'。外层容器是普通 <View>,源码设置 tablist role(仅作布局)。
  • a11y props:每个项的 accessibilityLabel 取自 item.label,而 labelTabItem 中是必填的——每个 tab 默认都有朗读文案。
  • 状态语义:accessibilityState={{ selected: on }}——selecteditem.id === value 派生。无 disabled 语义(TabItemdisabled 字段)。
// 每个 tab 自动 role=tab、label=item.label、selected 由 value 决定
<Tabs
value={tab}
onChange={setTab}
items={[
{ id: 'all', label: '全部' },
{ id: 'pending', label: '待跟进' },
]}
/>