Button 按钮
按钮用于触发操作。通过 variant 表达操作层级,支持不同尺寸、图标、加载和禁用状态。
代码演示
Button · 变体
Button · 尺寸
状态
已触发 0 次用法
import { Button } from '@unif/react-native-design';
<Button label="确认" variant="primary" onPress={handleConfirm} />
<Button label="取消" variant="secondary" onPress={handleCancel} />
<Button label="查看详情" variant="outline" onPress={openDetails} />
<Button label="重新发起" variant="text" size="sm" onPress={restart} />
<Button label="提交" variant="primary" block size="lg" onPress={submit} />
API
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
label | string | — | 按钮文字,同时作为业务名称;去除首尾空白后不能为空;空白时不响应点击并提示开发诊断 |
onPress | () => void | — | 必填点击回调;disabled / loading 时组件移除有效 handler |
size | ('sm' | 'md' | 'lg')? | 'md' | 高度 28 / 36 / 44 |
variant | ('primary' | 'secondary' | 'ghost' | 'neutral' | 'outline' | 'danger' | 'text')? | 'primary' | 视觉变体 |
block | boolean? | false | 仅撑满父容器交叉轴(alignSelf: stretch);主轴尺寸由父容器或 style 决定 |
disabled | boolean? | false | 禁用(opacity 0.5 + 不响应 onPress) |
loading | boolean? | false | 加载态:用 ActivityIndicator 替代 label,自动 disabled |
leftIcon | IconName? | — | 左侧图标,与文本同色;尺寸由 Button size 固定,不随 fontScale 放大 |
rightIcon | IconName? | — | 右侧图标,与文本同色;尺寸由 Button size 固定,不随 fontScale 放大 |
style | StyleProp<ViewStyle>? | — | 额外样式覆盖(merge 到末尾) |
testID | string? | — | E2E / 测试定位 |
accessibilityHint | string? | — | SR 行为说明 hint,仅在「行为不显然」时加 |
accessibilityState | Omit<AccessibilityState, 'disabled' | 'busy'>? | — | caller 可补充 selected / expanded 等状态;disabled / busy 由组件接管,类型上禁止覆盖 |
无障碍(a11y)
来源:src/components/ui/Button/ButtonBase.tsx、Button.tsx、types.ts。
- 默认
accessibilityRole:'button'(在ButtonBase中硬编码,accessibilityRole = 'button')。 - a11y props:
accessibilityLabel自动取 trim 后非空的必填label,无需另传;accessibilityHint可选,仅在「行为不显然」时补充(如「切换主题」)。空白label不会留下 unnamed button:组件移除 handler/action 语义,并在 effect 中诊断。 - 状态语义:
disabled或loading任一为真时都会上报accessibilityState.disabled: true并移除有效 handler;loading 还上报busy: true(此时 label 被ActivityIndicator替换)。调用方传入的状态不能覆盖这两个字段。
// label 即 a11y label;hint 仅在行为不显然时补
<Button label="确认" variant="primary" onPress={handleConfirm} />
<Button label="切换" accessibilityHint="切换深浅主题" onPress={toggleTheme} />
主题键(Tokens)
读取来源:src/components/ui/Button/styles.ts、ButtonBase.tsx。
| Token | 来源 | variant / 说明 |
|---|---|---|
c.primary | useColors() | primary 变体背景色;ghost / text 变体文字色 |
c.onPrimary | useColors() | primary 变体文字/图标色 |
c.surfaceContainerHigh | useColors() | secondary 变体背景色 |
c.foreground | useColors() | secondary / neutral / outline 变体文字色 |
c.surface | useColors() | outline 变体背景色 |
c.outline | useColors() | outline 变体边框色 |
c.error | useColors() | danger 变体背景色 |
c.onError | useColors() | danger 变体文字色 |
radius.lg / radius.md / radius.sm | 静态 token | 按 size='lg'/'md'/'sm' 对应圆角 |
control.lg / control.md / control.sm | 静态 token(src/theme) | 按尺寸对应高度(44 / 36 / 28) |
space['6'] / space['4'] | 静态 token | md / sm 水平内边距(lg 用 r(18)) |
space['2'] / space['1'] | 静态 token | 内容 gap(lg/md 用 '2',sm 用 '1') |
fw.semi | 静态 token | 按钮文字字重(600) |
type.body / type.sm / type.xxs | 静态 token | 按 size='lg'/'md'/'sm' 对应字号 |
FAQ
字号变大时,按钮尺寸也会变大吗?
ThemeProvider fontScale 只把 Button label 字号缩放一次。Button 高度、水平 padding、gap、圆角和左右 Icon 尺寸仍由原始 size token 决定,不随字号档位改变。例如 fontScale={1.5} 会放大文字,但 md 仍保持 control.md 的原有几何,Icon 仍使用未缩放的 type.sm + 2。