# Radio 单选

- 来源：[E10 UI 组件库](https://www.e-cology.com.cn/ui/radio/freepass)
- 平台：PC
- 维护者：许平源
- 设计稿：http://pd.e-cology.com.cn/pd/E10/interface/e10xiaoguotu/PC/E10zjys/#s6
- Issue：http://gitlab.ecology10.cn/FRONTEND/weapp-ui/-/issues?state=all&search=[Radio]

## 代码演示

### 基础用法

直接引入组件进行使用

```jsx
import React from 'react';
import { constants, Radio, RadioValueType, RadioOptionType, RadioEvent, RadioDataType } from '@weapp/ui';

const prefixCls = `${constants.uiPcClsPrefix}-demo-radio`;

const optionsWithDisabled: RadioDataType = [
  {
    id: 'Apple',
    title: 'Apple',
    content: 'Apple',
    color: '#5D9CEC'
  },
  {
    id: 'Pear',
    title: 'Pear',
    content: 'Pear',
    color: '#FF4D4F'
  },
  {
    id: 'Orange',
    title: 'Orange',
    content: 'Orange',
    disabled: true,
    color: '#52C41A'
  },
];

const defaultValue =
{
  id: 'Apple',
  value: 'Apple',
  content: 'Apple'
};

export default class RadioDemo extends React.Component {

  state = {
    checked: true,
    label: "已选择",
    value: 'Apple'
  }

  onClick = (v: RadioValueType, o: RadioOptionType, e: RadioEvent) => {
    console.log('onClick', v, o, e)
  }
  onBlur = (v: RadioValueType, o: RadioOptionType, e: React.FocusEvent<HTMLInputElement>) => {
    console.log('onBlur', v, o, e)
  }
  onFocus = (v: RadioValueType, o: RadioOptionType, e: React.FocusEvent<HTMLInputElement>) => {
    console.log('onFocus', v, o, e)
  }
  onKeyPress = (v: RadioValueType, o: RadioOptionType, e: React.KeyboardEvent<HTMLInputElement>) => {
    console.log('onKeyPress', v, o, e)
  }
  onKeyDown = (v: RadioValueType, o: RadioOptionType, e: React.KeyboardEvent<HTMLInputElement>) => {
    console.log('onKeyDown', v, o, e)
  }
  onKeyUp = (v: RadioValueType, o: RadioOptionType, e: React.KeyboardEvent<HTMLInputElement>) => {
    console.log('onKeyUp', v, o, e)
  }

  onChange1 = (v: RadioValueType, o: RadioOptionType, e: RadioEvent) => {
    console.log('onChange1', v, o, e)
  }

  onChange = (v: RadioValueType, o: RadioOptionType, e: RadioEvent) => {
    console.log('onChange', v, o, e)
    this.setState({ value: v })
  }
  btnClick = () => {
    this.setState({ value: !this.state.value })
  }

  render() {
    const { checked, value } = this.state;
    return (
      <div className={prefixCls}>
        <h4>基本用法</h4>
        <Radio defaultValue={false}
          onChange={this.onChange1}
          onClick={this.onClick}
          onFocus={this.onFocus}
          onBlur={this.onBlur}
        >AppleAppleAppleAppleAppleAppleAppleAppleAppleAppleAppleAppleAppleAppleAppleAppleAppleAppleAppleApple</Radio>
        <Radio value={checked} onChange={this.onChange1} onFocus={this.onFocus} onBlur={this.onBlur} onKeyPress={this.onKeyPress} onKeyDown={this.onKeyDown} onKeyUp={this.onKeyUp}>受控</Radio>
        <h4>只读状态</h4>
        <Radio readOnly
          onChange={this.onChange}
          onClick={this.onClick}
          onFocus={this.onFocus}
          onBlur={this.onBlur}
        >只读</Radio>
        <Radio readOnly
          value={true}
          onChange={this.onChange}
          onClick={this.onClick}
          onFocus={this.onFocus}
          onBlur={this.onBlur}
        >只读2</Radio>
        <h4>禁用状态</h4>
        <Radio disabled>禁用</Radio>
        <Radio value={true} disabled>禁用</Radio>
        <h4>Radio datas -- value</h4>
        <Radio data={optionsWithDisabled} value={value} onChange={this.onChange} />
        <h4>Radio datas -- defaultValue</h4>
        <Radio data={optionsWithDisabled} defaultValue={'Apple'}
          onChange={this.onChange}
          onFocus={this.onFocus}
          onBlur={this.onBlur}
        />
        <h4>Radio datas -- showDataGroupByType - defaultValue</h4>
        <Radio data={optionsWithDisabled} showDataGroupByType={true} defaultValue={defaultValue} onChange={this.onChange} />
        <h4>Radio datas -- showDataGroupByType - defaultValue（在容器中）</h4>
        <div style={{ height: 40, display: 'flex', alignItems: 'center' }}>
          <Radio data={optionsWithDisabled} showDataGroupByType={true} defaultValue={defaultValue} onChange={this.onChange} />
        </div>

        <h4>Radio datas -- defaultValue(只读)</h4>
        <Radio data={optionsWithDisabled} defaultValue={'Apple'} readOnly
          onChange={this.onChange}
          onClick={this.onClick}
          onFocus={this.onFocus}
          onBlur={this.onBlur}
        />
        <h4>Radio datas -- defaultValue(禁用)</h4>
        <Radio data={optionsWithDisabled} defaultValue={'Apple'} disabled onChange={this.onChange} />
        <h4>Radio datas 垂直</h4>
        <Radio data={optionsWithDisabled} value={value} vertical onChange={this.onChange} />
        <h4>Radio datas 标签样式</h4>
        <Radio data={optionsWithDisabled} defaultValue={value} optionType='tag'
          onChange={this.onChange}
          onClick={this.onClick}
          onFocus={this.onFocus}
          onBlur={this.onBlur}
        />
        <h4>Radio datas 标签样式(不带check框)</h4>
        <Radio data={optionsWithDisabled} value={value} optionType='tag' hideCheck onChange={this.onChange} />
        <h4>showTitle 展示标题</h4>
        <Radio showTitle data={optionsWithDisabled} value={value} optionType='tag' hideCheck onChange={this.onChange} />
        <Radio data={optionsWithDisabled} defaultValue={value}  onChange={this.onChange} isHoldRight/>
        <h4>Checkbox (check框居右)</h4>
        <Radio data={optionsWithDisabled} defaultValue={value}  onChange={this.onChange} isHoldRight/>
        <Radio isHoldRight>不受控（defaultValue）</Radio>
        <h4>Radio (check框居右,竖向,左对齐)</h4>
        <Radio data={optionsWithDisabled} value={value} vertical alignType={'left'} isHoldRight  onChange={this.onChange} />
        <h4>Radio (check框居右,竖向,右对齐)</h4>
        <Radio data={optionsWithDisabled} value={value} vertical alignType={'right'} isHoldRight  onChange={this.onChange} />
        <h4>Radio (check框居右,竖向,两端对齐)</h4>
        <Radio data={optionsWithDisabled} value={value} vertical alignType={'justify'} isHoldRight onChange={this.onChange} />
        <h4>Radio (check框居右,竖向,默认)</h4>
        <Radio data={optionsWithDisabled} value={value} vertical  isHoldRight onChange={this.onChange} />
      </div>
    );
  }
}
```

### 自定义复写

使用 customRender/customOverlayRender/customOptionRender 进行组件复写

```jsx
import React from 'react';
import { constants, Radio, RadioValueType, RadioOptionType, RadioEvent, RadioDataType, RadioOptionProps } from '@weapp/ui';

let RadioCustomDemoPcClsPrefix = `${constants.uiPcClsPrefix}-radio-custom-demo`

const datas: RadioDataType = [
  {
    id: 'A',
    content: '选项A',
    src: '/build/ui/demo/assets/photo-view/5.jpeg',
    disabled: true,
    alt: '选项A'
  },
  {
    id: 'B',
    content: '选项B这是长超长长超超长长超超长长超超长长超超长长超次次次次存文本',
    src: '/build/ui/demo/assets/photo-view/3.jpeg',
    disabled: false,
    alt: '选项b'
  },
  {
    id: 'C',
    content: '选项C',
    src: '/build/ui/demo/assets/photo-view/4.jpeg',
    disabled: false,
    alt: '选项c'
  },
]

interface CustomRadioProps { }
interface CustomRadioState {
  datas: RadioDataType
}

class CustomRadioDemo extends React.PureComponent<CustomRadioProps, CustomRadioState> {

  constructor(props: CustomRadioProps) {
    super(props);
    this.state = {
      datas
    }
  }

  customOptionContenRender = (optionProps: RadioOptionProps, content: any) => {
    console.log('customOptionContenRender')
    console.log(optionProps)
    console.log(content)
    let color = {
      color: '#999'
    }
    if (optionProps.value === 'A') {
      color = { color: 'red' }
    } else if (optionProps.value === 'B') {
      color = { color: 'green' }
    } else if (optionProps.value === 'C') {
      color = { color: 'blur' }
    }
    return <span style={color}>{`${optionProps.value} - ${content}`}</span>
  }

  customOptionRender = (_props: RadioOptionProps, ele: React.ReactNode) => {
    console.log('customOptionRender')
    console.log('_props', _props)
    console.log(' _props.option', _props.option)
    console.log('ele', ele)
    const demoWrapper = {
      background: '#ffffff',
      border: '1px solid #e5e5e5',
      borderRadius: '3px',
      display: 'inline-table',
      margin: '10px'
    }
    const radioWrapper = {
      padding: '10px'
    }
    let content = (
      <div
        style={demoWrapper}
      >
        <div >
          <img alt={'error'} />
        </div>
        <div
          style={radioWrapper}>
          {ele}
        </div>
      </div>
    )
    return content
  }

  onClick = (v: RadioValueType, o: RadioOptionType, e: RadioEvent) => {
    console.log('onClick v', v)
    console.log('onClick o', o)
    console.log('onClick e', e)
  }

  render() {
    return (
      <div className={RadioCustomDemoPcClsPrefix}>
        <h3>修改选项内容</h3>
        <Radio
         
          data={datas}
          onClick={this.onClick}
          customOptionContenRender={this.customOptionContenRender}
        />
        <h3>图片单选</h3>
        <Radio
         
          data={datas}
          optionType={'image'}
        />
        <h3>图片单选(竖直排列)</h3>
        <Radio
         
          data={datas}
          optionType={'image'}
          vertical
        />
        <h3>自定义渲染</h3>
        <Radio
         
          data={datas}
          customOptionRender={this.customOptionRender}
          className={'pic_radio'}
        />
      </div>
    );
  }
}

export default CustomRadioDemo;
```

### 只读模式

只读模式

```jsx
import React from 'react';
import { constants, Radio, RadioValueType, RadioOptionType, RadioEvent, RadioDataType } from '@weapp/ui';

const prefixCls = `${constants.uiPcClsPrefix}-demo-radio`;

const optionsWithDisabled: RadioDataType = [
  {
    id: 'Apple',
    title: 'Apple',
    content: 'Apple',
    color: '#5D9CEC'
  },
  {
    id: 'Pear',
    title: 'Pear',
    content: 'Pear',
    color: '#FF4D4F'
  },
  {
    id: 'Orange',
    title: 'Orange',
    content: 'Orange',
    disabled: true,
    color: '#52C41A'
  }
];

const optionsWithDisabled2: RadioDataType = [
  {
    id: 'Apple',
    title: 'Apple',
    content: 'Apple',
    color: '#5D9CEC'
  },
  {
    id: 'Pear',
    title: 'Pear',
    content: 'Pear',
    color: '#FF4D4F'
  },
  {
    id: 'Orange',
    title: 'Orange',
    content: 'Orange',
    disabled: true,
    color: '#52C41A'
  },
  {
    id: 'Apple_long',
    title: 'Apple_超长Apple_超长Apple_超长Apple_超长Apple_超长Apple_超长Apple_超长Apple_超长Apple_超长Apple_超长Apple_超长Apple_超长Apple_超长Apple_超长',
    content: 'Apple_超长Apple_超长Apple_超长Apple_超长Apple_超长Apple_超长Apple_超长Apple_超长Apple_超长Apple_超长Apple_超长Apple_超长Apple_超长Apple_超长',
    disabled: true,
    color: '#000000'
  },
];

export default class RadioDemo extends React.Component {

  render() {
    return (
      <div className={prefixCls}>
        <h4>单个只读</h4>
        <Radio readOnly>只读</Radio>
        <Radio readOnly value={true}>只读2</Radio>
        <h4>多个数据只读</h4>
        <Radio
          data={optionsWithDisabled}
          defaultValue={'Apple'}
          readOnly
        />
        <h4>多个数据只读(文字超长)</h4>
        <Radio
          data={optionsWithDisabled2}
          defaultValue={'Apple_long'}
          readOnly
          labelMaxWidth={250}
        />
        <h4>多个数据只读(仅字段名称)</h4>
        <Radio
          data={optionsWithDisabled}
          defaultValue={'Apple'}
          readOnly
          readOnlyMode={'string'}
        />
        <h4>多个数据只读(仅字段名称文字超长)</h4>
        <Radio
          data={optionsWithDisabled2}
          defaultValue={'Apple_long'}
          readOnly
          readOnlyMode={'string'}
        />
      </div>
    );
  }
}
```

### 带提示信息

```jsx
import React from 'react';
import { Radio, RadioDataType, constants, } from '@weapp/ui';

const { uiPcClsPrefix } = constants;

const prefixCls = `${uiPcClsPrefix}-demo-checkbox`;

const optionsWithDisabled: RadioDataType = [
  {
    id: 'Apple',
    title: 'Apple',
    content: 'Apple',
    color: '#5D9CEC',
    tips: '可见即可得，组件在前台跟设计器展示效果一致，搭建比较容易上手，布局的样式/排列方式都通过组件来实现。',
  },
  {
    id: 'Pear',
    title: 'Pear',
    content: 'Pear',
    color: '#FF4D4F',
    tips: '可见即可得，组件在前台跟设计器展示效果一致，搭建比较容易上手，布局的样式/排列方式都通过组件来实现。',
  },
  {
    id: 'Orange',
    title: 'Orange',
    content: 'Orange',
    disabled: true,
    color: '#52C41A',
    tips: '可见即可得，组件在前台跟设计器展示效果一致，搭建比较容易上手，布局的样式/排列方式都通过组件来实现。',
  },
];

export default class RadioDemo extends React.Component {

  render() {
    return (
      <div className={prefixCls}>

        <h4>Radio 带提示</h4>
        <Radio
         
          tips={'可见即可得，组件在前台跟设计器展示效果一致，搭建比较容易上手，布局的样式/排列方式都通过组件来实现。'}
        >
          流式布局
        </Radio>
        <h4>Radio data 带提示</h4>
        <Radio
         
          data={optionsWithDisabled}
        >
          content
        </Radio>
        <h4>Radio data tag 带提示</h4>
        <Radio
         
          data={optionsWithDisabled}
          optionType={'tag'}
        >
          content
        </Radio></div>
    );
  }
}
```

## API

### 参数说明如下：

| 参数 | 说明 | 类型 | 是否必填 | 默认值 |
| --- | --- | --- | --- | --- |
| domKey | 单个使用 radio 时，radio 的唯一标识（使用 data 时唯一标识为 data 的 id） | RadioValueType | 否 |  |
| value | 受控（单个使用时传递 Boolean) | RadioValueType | 否 |  |
| defaultValue | 默认值（单个使用时传递 Boolean) | RadioValueType | 否 |  |
| disabled | 禁用 | boolean | 否 | false |
| style | 自定义样式 | CSSProperties | 否 |  |
| className | 自定义 className | string | 否 |  |
| overlayClassName | 选项的样式名 | string | 否 |  |
| onChange | 数据变化回调 | (value: RadioValueType, option: RadioOptionType , e: RadioEvent) => void | 否 |  |
| onClick | 点击回调 | (value: RadioValueType, option: RadioOptionType , e: RadioEvent) => void | 否 |  |
| onFocus | focus 回调 | (value: RadioValueType, option: RadioOptionType , e: React.FocusEvent<HTMLInputElement>) => void | 否 |  |
| onBlur | blur 回调 | (value: RadioValueType, option: RadioOptionType , e: React.FocusEvent<HTMLInputElement>) => void | 否 |  |
| customOptionRender | 自定义每一选项 | (props: RadioOptionProps, ele: ReactNode, eventProps?: any) => ReactNode | 否 |  |
| customOptionContenRender | 复写任一选项的 content 内容 | (props: RadioOptionProps, ele: ReactNode) => ReactNode | 否 |  |
| customOverlayRender | 复写整体 radio | (_: any, ele: ReactNode) => ReactNode | 否 |  |
| vertical | 是否竖直排列（data 存在时生效） | boolean | 否 |  |
| groupStyle | 设置外层 style（data 存在时生效） | CSSProperties | 否 |  |
| groupClassName | 设置外层 groupClassName（data 存在时生效） | string | 否 |  |
| name | radio 的 name 属性 | string | 否 |  |
| hideCheck | 隐藏 check 框 | boolean | 否 | false |
| optionType | 选项类型 | 'default' \| 'tag' | 否 | 'default' |
| canReversedChoose | 是否开启反选 | boolean | 否 | true |
| labelMaxWidth | label 最大宽度 (在表单中，默认生效，宽度 150，传递 0 则不生效,在选框居右模式下不生效) | number | 否 |  |
| showTitle | 控制 title 是否显示 api | boolean | 否 | true |
| readOnlyMode | 只读模式选择（区别普通的radio只读模式和表单中仅显示字段的只读模式） | boolean | 否 | false |
| tips | 提示信息（如果是传递了 data，直接在 data 中设置） | string | false | - |
| isHoldRight | checkbox 是否靠右显示 | boolean |  | false |
