Stepper 步进器
数字步进控件——[−][ N ][+] 三段拼接,到达 min/max 自动禁用对应按钮。
实时预览
下方渲染的就是 src/components/ui/Stepper/Stepper.tsx 本体,通过 react-native-web 翻译成浏览器节点。
独立
12
min=1, max=99
下单清单
合计 62 箱 · ¥3,840统一冰红茶
¥120 / 箱 · 库存 50
12
阿萨姆奶茶
¥96 / 箱 · 库存 80
0
老坛酸菜面
¥48 / 箱 · 库存 30
30
视觉规范
来源:src/components/ui/Stepper/styles.ts、Stepper.tsx。
| 元素 | 规则 |
|---|---|
| 高度 | md 32px(默认)/ sm 28px(control.sm) |
| 圆角 | 8px(radius.md,外层左右两角),中间数字框无独立圆角 |
| 按钮 | md 32×32 / sm 28×28,± 字号 18px(type.h1) |
| 数字框 | min-width md 48 / sm 40,1px 上下边线,无左右边线,字号 md 14 / sm 13 |
| 背景 / 描边 | c.surface 底 + 1px c.outline(亮色 #EDEDED)边 |
| 禁用 | 按钮 opacity: 0.4(达到 min/max 或整体 disabled 时;按下 0.7) |
用法
import { Stepper } from '@unif/react-native-design';
const [qty, setQty] = useState(12);
<Stepper value={qty} onChange={setQty} min={1} max={99} />
{/* 自定义步长 */}
<Stepper value={packs} onChange={setPacks} step={6} min={0} max={120} />
{/* 小尺寸 */}
<Stepper size="sm" value={n} onChange={setN} min={0} max={9} />
API
来源:src/components/ui/Stepper/types.ts、Stepper.tsx。
| Prop | Type | 默认 | 说明 |
|---|---|---|---|
value | number | — | 当前值(受控,必填) |
onChange | (value: number) => void | — | 变更回调(已自动夹到 [min, max],必填) |
min | number? | 0 | 下限(达到时 − 禁用) |
max | number? | 99 | 上限(达到时 + 禁用) |
step | number? | 1 | 步长(非正数 / 非有限数回退为 1) |
size | 'sm' | 'md' | 'md' | 高度 28 / 32 |
disabled | boolean? | false | 整体禁用(两个按钮都不可点) |
testID | string? | — | E2E 定位(派生 -decrement / -value / -increment) |
健壮性:
value为NaN时显示为min;±Infinity钳到[min, max];min > max时整体按min渲染(避免写出乱序值)。无styleprop。
无障碍(a11y)
来源:src/components/ui/Stepper/Stepper.tsx、types.ts。
- 默认
accessibilityRole:−/+两个<Pressable>均硬编码'button';中间数字框<View>硬编码'adjustable'(可调整值容器)。根<View>不设 role。 - a11y props:标签由源码硬编码、不可由外部传入——
−为accessibilityLabel="减少"、+为accessibilityLabel="增加",两者各带accessibilityHint(`当前值 ${value},减/加 ${step}`,动态拼当前值与步长)。数字框设accessibilityValue={{ min, max, now }},把范围与当前值暴露给 SR。StepperProps不含任何 a11y prop(仅value/onChange/min/max/step/size/disabled/testID)。 - 状态语义:两个按钮各自
accessibilityState={{ disabled }}——−在disabled || value <= min时禁用,+在disabled || value >= max时禁用(到达边界自动禁用对应按钮)。
// 角色 / 标签 / hint 全部内置,无需额外 a11y prop
<Stepper value={qty} onChange={setQty} min={1} max={99} />
不要
- ❌ 不要在 Stepper 中间放可输入的 TextInput——下单场景请用专门的 InputNumber 控件(待规划)
- ❌ 不要去掉描边或圆角——Stepper 必须看起来"可点击"