Grid 九宫格
主页或分类页的图标入口——3 列 / 4 列网格,每格 icon + label。
实时预览
下方渲染的就是 src/components/ui/Grid/Grid.tsx 本体,通过 react-native-web 翻译成浏览器节点。
4 列3 列2 列 · 大图标卡片入口6 列 · 紧凑入口card={false} · 嵌套已有白卡,去掉外层背景
拜访
3
订单
商品
报表
12
消息
团队
设置
更多
拜访
3
订单
商品
报表
12
消息
团队
拜访
3
订单
商品
报表
拜访
3
订单
商品
报表
12
消息
团队
拜访
3
订单
商品
报表
API
来源:src/components/ui/Grid/types.ts、Grid.tsx。
<Grid>
| Prop | Type | 默认 | 说明 |
|---|---|---|---|
items | GridItem[] | — | 入口列表(见下) |
columns | 1 | 2 | 3 | 4 | 5 | 6 | 4 | 列数;类型外的值(如 7)会静默回退到 4 列并打 warn |
onPress | (item: GridItem) => void | — | 点击某格回调;可选,但每格恒挂 Pressable,角色恒为 button |
card | boolean | true | 是否套白色卡片;false 则背景透明(嵌进已有白卡时用) |
testID | string? | — | 容器 testID;每格自动派生为 ${testID}-${item.id} |
GridItem
| 字段 | Type | 默认 | 说明 |
|---|---|---|---|
id | string | — | 唯一键,也用于派生 testID |
icon | IconName | — | 图标名(图标 catalog) |
label | string | — | 格子文字,同时作为该格 accessibilityLabel |
badge | number | string? | — | icon 右上角标(用 string 才能写 '99+') |
testID | string? | — | 单格 testID(不传则自动用 ${gridTestID}-${id}) |
视觉规范
来源:src/components/ui/Grid/styles.ts(值取自 src/theme/tokens.ts)。
| 元素 | 规则 |
|---|---|
容器(card) | c.surface 白底,radius.xl(12)圆角,paddingVertical: space[5](12)/ paddingHorizontal: space[3](8),1px c.outline 边框 |
| 列宽 | 等宽,按 columns 取 100% / 50% / 33.3% / 25% / 20% / 16.7%(StyleSheet 预生成) |
| 单格 | paddingVertical: space[5](12),居中 icon + label,gap: space[2](6) |
| Icon | size=28(介于 icon.md/icon.lg),色固定 c.foregroundMuted |
| Label | t.xxs(12)/ fw.medium(500)/ c.foreground |
| Badge | 叠在 icon 右上的小红角标:c.error 底、c.onError 字、t.nano(10)、fw.bold |
用法
import { Grid } from '@unif/react-native-design';
<Grid
columns={4}
items={[
{ id: 'visit', icon: 'location', label: '拜访' },
{ id: 'orders', icon: 'order', label: '订单', badge: 3 },
{ id: 'sku', icon: 'box-list', label: '商品' },
{ id: 'reports', icon: 'list', label: '报表' },
{ id: 'msg', icon: 'mail', label: '消息' },
{ id: 'team', icon: 'user', label: '团队' },
{ id: 'settings',icon: 'settings', label: '设置' },
{ id: 'more', icon: 'more-h', label: '更多' },
]}
onPress={(item) => navigation.push(item.id)}
/>
无障碍(a11y)
来源:src/components/ui/Grid/Grid.tsx、types.ts。
- 默认
accessibilityRole:每个格子都渲染为<Pressable accessibilityRole="button">(无论onPress是否传 ——onPress可选,但 Pressable 恒以onPress={() => onPress?.(item)}挂载,故角色恒为button)。 - a11y props:每格
accessibilityLabel取自必填的item.label(GridItem.label: string)—— icon 自身对 SR 隐藏(见 图标),label 文本即朗读内容。badge角标未单独纳入 a11y 朗读。 - 状态语义:源码未设
accessibilityState(无 selected/disabled/checked 概念)。
// 每格 role=button、label 取 item.label
<Grid columns={4} items={[{ id: 'visit', icon: 'location', label: '拜访' }]} onPress={(item) => ...} />