UNPKG

@douyinfe/semi-ui

Version:

A modern, comprehensive, flexible design system and UI library. Connect DesignOps & DevOps. Quickly build beautiful React apps. Maintained by Douyin-fe team.

385 lines (319 loc) 16.8 kB
--- localeCode: zh-CN order: 44 category: 输入类 title: Radio 单选框 icon: doc-radio brief: 用户使用单选框来从少量的选项集合中选择单个选项 --- ## 使用场景 单选框(Radio)也叫单选按钮,它允许用户在一组选项中选择其中一个。 当选项很多时,单选下拉菜单(Select)可能比较适合,因为它所占用的画面空间比单选按钮来得要少。 ## 代码演示 ### 如何引入 ```jsx import import { Radio, RadioGroup } from '@douyinfe/semi-ui'; ``` ### 基本用法 ```jsx live=true import React from 'react'; import { Radio } from '@douyinfe/semi-ui'; () => ( <Radio aria-label="单选示例" name="demo-radio">Radio</Radio> ); ``` ### 带辅助文本 通过`extra`设置辅助文本,可以是任意类型的 ReactNode ```jsx live=true import React from 'react'; import { Radio } from '@douyinfe/semi-ui'; () => ( <Radio extra="Semi Design 是由抖音前端团队与 UED 团队共同设计开发并维护的设计系统" aria-label="单选示例" name="demo-radio-extra"> Semi Design </Radio> ); ``` ### 禁用 Radio 不可用 ```jsx live=true import React, { useState } from 'react'; import { Radio, Button } from '@douyinfe/semi-ui'; () => { const [disabled, setDisabled] = useState(true); const toggleDisabled = () => { setDisabled(!disabled); }; return ( <div> <Radio defaultChecked={false} disabled={disabled} aria-label="单选示例" name="demo-radio-disabled"> Disabled </Radio> <br /> <Radio defaultChecked disabled={disabled} aria-label="单选示例" name="demo-radio-defaultChecked-disabled"> Disabled </Radio> <div style={{ marginTop: 20 }}> <Button type="primary" onClick={toggleDisabled}> Toggle disabled </Button> </div> </div> ); }; ``` ### 高级模式 高级模式(mode='advanced')checked 可以通过点击转换为 unchecked。 ```jsx live=true import React, { useState } from 'react'; import { Radio } from '@douyinfe/semi-ui'; () => { const [checked, setChecked] = useState(true); const toggle = (e) => { console.log('radio checked', e.target.checked); setChecked(e.target.checked); }; return ( <Radio checked={checked} mode="advanced" onChange={toggle} aria-label="单选示例" name="demo-radio-advanced" > 允许取消选择 </Radio> ); }; ``` ### 单选组合 一组互斥的 Radio 配合使用 ```jsx live=true import React from 'react'; import { RadioGroup, Radio } from '@douyinfe/semi-ui'; () => { const [value, setValue] = useState(1); const onChange = (e) => { console.log('radio checked', e.target.value); setValue(e.target.value); }; return ( <RadioGroup onChange={onChange} value={value} aria-label="单选组合示例" name="demo-radio-group"> <Radio value={1}>A</Radio> <Radio value={2}>B</Radio> <Radio value={3}>C</Radio> <Radio value={4}>D</Radio> </RadioGroup> ); }; ``` ### 垂直排列 可通过给 RadioGroup 设置 `direction`属性来决定 组内的 radio 元素水平排列或者垂直排列 ```jsx live=true import React from 'react'; import { RadioGroup, Radio } from '@douyinfe/semi-ui'; () => ( <RadioGroup direction="vertical" aria-label="单选组合示例" name="demo-radio-group-vertical"> <Radio value={1}>A</Radio> <Radio value={2}>B</Radio> <Radio value={3}>C</Radio> <Radio value={4}>D</Radio> </RadioGroup> ); ``` ### 按钮样式 可以利用 `type='button'` 来设置 button 样式类型的单选器,并且,button 类型单选器支持三种尺寸大小。 需要注意的是: button 类型的单选器暂不支持辅助文本(`extra`)和垂直排列(`direction='vertical'`)。 ```jsx live=true dir="column" import React from 'react'; import { RadioGroup, Radio, Space } from '@douyinfe/semi-ui'; () => { return ( <Space vertical spacing='loose' align='start'> <RadioGroup type='button' buttonSize='small' defaultValue={1} aria-label="单选组合示例" name="demo-radio-small"> <Radio value={1}>即时推送</Radio> <Radio value={2}>定时推送</Radio> <Radio value={3}>动态推送</Radio> </RadioGroup> <RadioGroup type='button' buttonSize='middle' defaultValue={1} aria-label="单选组合示例" name="demo-radio-middle"> <Radio value={1}>即时推送</Radio> <Radio value={2}>定时推送</Radio> <Radio value={3}>动态推送</Radio> </RadioGroup> <RadioGroup type='button' buttonSize='large' defaultValue={1} aria-label="单选组合示例" name="demo-radio-large"> <Radio value={1}>即时推送</Radio> <Radio value={2}>定时推送</Radio> <Radio value={3}>动态推送</Radio> </RadioGroup> </Space> ); }; ``` ### 卡片样式 可以给 `RadioGroup` 设置 `type='card'` 实现带有背景的卡片样式。 ```jsx live=true dir="column" import React from 'react'; import { RadioGroup, Radio } from '@douyinfe/semi-ui'; () => ( <RadioGroup type='card' defaultValue={2} direction='vertical' aria-label="单选组合示例" name="demo-radio-group-card"> <Radio value={1} disabled extra='Semi Design 是由抖音前端团队与 UED 团队共同设计开发并维护的设计系统' style={{ width: 280 }}> 单选框标题 </Radio> <Radio value={2} extra='Semi Design 是由抖音前端团队与 UED 团队共同设计开发并维护的设计系统' style={{ width: 280 }}> 单选框标题 </Radio> <Radio value={3} extra='Semi Design 是由抖音前端团队与 UED 团队共同设计开发并维护的设计系统' style={{ width: 280 }}> 单选框标题 </Radio> </RadioGroup> ); ``` ### 无 radio 的纯卡片样式 可以给 `RadioGroup` 设置 `type='pureCard'` 实现带有背景且无 radio 的纯卡片样式。 ```jsx live=true dir="column" import React from 'react'; import { RadioGroup, Radio } from '@douyinfe/semi-ui'; () => ( <RadioGroup type='pureCard' defaultValue={2} direction='vertical' aria-label="单选组合示例" name="demo-radio-group-pureCard"> <Radio value={1} disabled extra='Semi Design 是由抖音前端团队与 UED 团队共同设计开发并维护的设计系统' style={{ width: 280 }}> 单选框标题 </Radio> <Radio value={2} extra='Semi Design 是由抖音前端团队与 UED 团队共同设计开发并维护的设计系统' style={{ width: 280 }}> 单选框标题 </Radio> <Radio value={3} extra='Semi Design 是由抖音前端团队与 UED 团队共同设计开发并维护的设计系统' style={{ width: 280 }}> 单选框标题 </Radio> </RadioGroup> ); ``` ### 配置 options 通过配置 options 参数来渲染单选框 ```jsx live=true hideInDSM import React, { useState } from 'react'; import { RadioGroup, Space } from '@douyinfe/semi-ui'; () => { const [value1, setValue1] = useState('Guest'); const [value2, setValue2] = useState('Developer'); const [value3, setValue3] = useState('Maintainer'); const plainOptions = ['Guest', 'Developer', 'Maintainer']; const options = [ { label: 'Guest', value: 'Guest', extra: 'Semi Design', style: { width: 120 } }, { label: 'Developer', value: 'Developer', extra: 'Semi Design', style: { width: 120 } }, { label: 'Maintainer', value: 'Maintainer', extra: 'Semi Design', style: { width: 120 } }, ]; const optionsWithDisabled = [ { label: 'Guest', value: 'Guest' }, { label: 'Developer', value: 'Developer' }, { label: 'Maintainer', value: 'Maintainer', disabled: true }, ]; const onChange1 = (e) => { console.log('radio1 checked', e.target.value); setValue1(e.target.value); }; const onChange2 = (e) => { console.log('radio2 checked', e.target.value); setValue2(e.target.value); }; const onChange3 = (e) => { console.log('radio3 checked', e.target.value); setValue3(e.target.value); }; return ( <Space vertical align='start' spacing='loose'> <RadioGroup options={plainOptions} onChange={onChange1} value={value1} aria-label="单选组合示例" name="demo-radio-group-1" /> <RadioGroup options={optionsWithDisabled} onChange={onChange2} value={value2} aria-label="单选组合示例" name="demo-radio-group-2" /> <RadioGroup options={options} onChange={onChange3} value={value3} aria-label="单选组合示例" name="demo-radio-group-3" /> </Space> ); }; ``` ## API 参考 ### Radio | 属性 | 说明 | 类型 | 默认值 | |----------------|-----------------------------------------------------------------------|------------------|--------| | addonClassName | 包裹内容容器的样式类名 | string | | | addonId | addon 节点 id,aria-labelledby 指向这个 id,若无设置会随机生成一个 id <br/>**v2.11.0 后提供** | string | | | addonStyle | 包裹内容容器的内联样式 | CSSProperties | | | aria-label | Radio 的 label | string | - | | autoFocus | 自动获取焦点 | boolean | false | | checked | 指定当前是否选中 | boolean | false | | className | 样式类名 | string | | | defaultChecked | 初始是否选中 | boolean | false | | disabled | 禁选单选框 |boolean | false | | extra | 副文本,只对type='default'生效<br/> | ReactNode | - | | extraId | 副文本的 id,aria-describedby 指向这个 id,若无设置会随机生成一个 id <br/>**v2.11.0 后提供** | ReactNode | - | | mode | 高级和普通模式,高级模式可以在 checked 时点击变成 unchecked,可选值 advanced | string | - | | name | Radio组件中`input[type="radio"]`的`name`属性,具有相同`name`的Radio属于同一个RadioGroup,`name`属性可参考 [MDN Radio](https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/Input/radio#%E5%80%BC) | string | - | | preventScroll | 指示浏览器是否应滚动文档以显示新聚焦的元素,作用于组件内的 focus 方法 | boolean | | | | style | 内联样式 | CSSProperties | | | type |设置 radio的样式类型,可选值为:`default`、`button`、`card`、`pureCard` <br/>**该 api 在 v2.18.0 后提供** |string|`default`| | value | 根据 value 进行比较,判断是否选中 | string \| number | - | | onChange | 选项变化时的回调函数 | function(e:Event) | - | | onMouseEnter | 鼠标移入选项时的回调函数 | function(e:Event) | - | | onMouseLeave | 鼠标移出选项时的回调函数 | function(e:Event) | - | ### RadioGroup 单选框组合,用于包裹一组 `Radio`。 | 属性 | 说明 | 类型 | 默认值 | | ------------ | ------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------- | ------------ | | aria-label | RadioGroup 的 label | string | - | |buttonSize|type='button'的radio的尺寸大小,可选值为:`small`、`middle`、`large` |string|`middle`| | className | 样式类名 | string | | | defaultValue | 默认选中的值 | string \| number | - | | direction | radio 排列方向, 只对type='default'生效,可选值`horizontal`、`vertical` | string | `horizontal` | | disabled | 禁选所有子单选器 | boolean | false | | mode | 高级和普通模式,可以在 checked 时点击变成 unchecked,可选值 advanced | string | - | | name | RadioGroup 下所有 `input[type="radio"]` 的 `name` 属性 | string | - | | options | 以配置形式设置子元素 | Array | - | | style | 内联样式 | CSSProperties | | | value | 用于设置当前选中的值 | string \| number | - | |type|设置所有radio的样式类型,可选值为:`default`、`button`、`card`、`pureCard` |string|`default`| | onChange | 选项变化时的回调函数 | function(e:Event) | - | ## Methods ### Radio | 名称 | 描述 | | ------- | -------- | | blur() | 移除焦点 | | focus() | 获取焦点 | ## Accessibility ### ARIA - `aria-label`:用于解释 Radio 或 RadioGroup 的作用 - `aria-labelledby` 默认指向 addon 节点,用于解释 Radio 的内容 - `aria-describedby` 默认指向 extra 节点,用于补充解释 Radio 的内容 ### 键盘和焦点 WAI-ARIA: https://www.w3.org/WAI/ARIA/apg/patterns/radiobutton/ - RadioGroup 可以被获取焦点,初始焦点设置: - 当 RadioGroup 中没有被选择项时,初始焦点为第一个 Radio 项上 - 当 RadioGroup 中有选中项时,初始焦点为选中的 Radio 项上 - 在同一个 radiogroup 内 - 可以通过 `右箭头` 或 `下箭头` 将焦点移动到下一个 Radio 项上,同时取消先前的 Radio 项的选中状态,并选中当前聚焦的 Radio 项 - 可以通过 `左箭头` 或 `上箭头` 将焦点移动到上一个 Radio 项上,同时取消先前的 Radio 项的选中状态,并选中当前聚焦的 Radio 项 - 若 RadioGroup 中没有选中项,可以 `Space` 键选中初始焦点 <!-- ## 相关物料 ```material 123 ``` --> ## 文案规范 - 首字母大写 - 不使用标点符号 ## 设计变量 <DesignToken/> ## 相关物料 <semi-material-list code="123"></semi-material-list>