跳到主要内容

Grid 九宫格

主页或分类页的图标入口——3 列 / 4 列网格,每格 icon + label。

实时预览

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

4 列
拜访
3
订单
商品
报表
12
消息
团队
设置
更多
3 列
拜访
3
订单
商品
报表
12
消息
团队
2 列 · 大图标卡片入口
拜访
3
订单
商品
报表
6 列 · 紧凑入口
拜访
3
订单
商品
报表
12
消息
团队
card={false} · 嵌套已有白卡,去掉外层背景
拜访
3
订单
商品
报表

API

来源:src/components/ui/Grid/types.tsGrid.tsx

<Grid>

PropType默认说明
itemsGridItem[]入口列表(见下)
columns1 | 2 | 3 | 4 | 5 | 64列数;类型外的值(如 7)会静默回退到 4 列并打 warn
onPress(item: GridItem) => void点击某格回调;可选,但每格恒挂 Pressable,角色恒为 button
cardbooleantrue是否套白色卡片;false 则背景透明(嵌进已有白卡时用)
testIDstring?容器 testID;每格自动派生为 ${testID}-${item.id}

GridItem

字段Type默认说明
idstring唯一键,也用于派生 testID
iconIconName图标名(图标 catalog
labelstring格子文字,同时作为该格 accessibilityLabel
badgenumber | string?icon 右上角标(用 string 才能写 '99+'
testIDstring?单格 testID(不传则自动用 ${gridTestID}-${id}

视觉规范

来源:src/components/ui/Grid/styles.ts(值取自 src/theme/tokens.ts)。

元素规则
容器(cardc.surface 白底,radius.xl(12)圆角,paddingVertical: space[5](12)/ paddingHorizontal: space[3](8),1px c.outline 边框
列宽等宽,按 columns100% / 50% / 33.3% / 25% / 20% / 16.7%(StyleSheet 预生成)
单格paddingVertical: space[5](12),居中 icon + label,gap: space[2](6)
Iconsize=28(介于 icon.md/icon.lg),色固定 c.foregroundMuted
Labelt.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.tsxtypes.ts

  • 默认 accessibilityRole:每个格子都渲染为 <Pressable accessibilityRole="button">(无论 onPress 是否传 —— onPress 可选,但 Pressable 恒以 onPress={() => onPress?.(item)} 挂载,故角色恒为 button)。
  • a11y props:每格 accessibilityLabel 取自必填的 item.labelGridItem.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) => ...} />