diff --git a/site/mobile/mobile.config.js b/site/mobile/mobile.config.js index d8fcfdec..9ee5f342 100644 --- a/site/mobile/mobile.config.js +++ b/site/mobile/mobile.config.js @@ -68,7 +68,7 @@ export default { { title: 'Radio 单选框', name: 'radio', - component: () => import('tdesign-mobile-react/radio/_example/index.jsx'), + component: () => import('tdesign-mobile-react/radio/_example/index.tsx'), }, { title: 'Rate 评分', diff --git a/src/_common b/src/_common index f9683c1e..89f8f376 160000 --- a/src/_common +++ b/src/_common @@ -1 +1 @@ -Subproject commit f9683c1edee5c09f455ba8cb19cb8ce07d4490be +Subproject commit 89f8f3768417d13c550cf8d98011d78882002bf7 diff --git a/src/radio/Radio.tsx b/src/radio/Radio.tsx index 905899cc..fb379498 100644 --- a/src/radio/Radio.tsx +++ b/src/radio/Radio.tsx @@ -1,11 +1,14 @@ -import React, { createContext, CSSProperties, forwardRef, Ref, useContext, useRef } from 'react'; +import React, { createContext, forwardRef, useContext, useRef } from 'react'; +import type { CSSProperties, Ref } from 'react'; import classNames from 'classnames'; -import { CheckIcon } from 'tdesign-icons-react'; +import { CheckIcon, CheckCircleFilledIcon } from 'tdesign-icons-react'; +import { usePrefixClass } from 'tdesign-mobile-react/hooks/useClass'; import forwardRefWithStatics from '../_util/forwardRefWithStatics'; -import useConfig from '../_util/useConfig'; import useDefault from '../_util/useDefault'; -import { TdRadioProps } from './type'; +import type { TdRadioProps } from './type'; import RadioGroup from './RadioGroup'; +import useDefaultProps from '../hooks/useDefaultProps'; +import { radioDefaultProps } from './defaultProps'; export interface RadioProps extends TdRadioProps { ref?: Ref; @@ -24,35 +27,36 @@ const getLimitRow = (row: number): CSSProperties => ({ }); const Radio = forwardRef((_props: RadioProps, ref: Ref) => { - const { classPrefix: prefix } = useConfig(); - const classPrefix = `${prefix}-radio`; + const radioClass = usePrefixClass('radio'); const inputRef = useRef(); const context = useContext(RadioContext); const props = context ? context.inject(_props) : _props; const { - align = 'left', - allowUncheck = false, - checked = false, - defaultChecked = false, - children, + allowUncheck, + block, + checked, content, + defaultChecked, contentDisabled, + placement, disabled, icon, label, - maxContentRow = 5, - maxLabelRow = 3, + maxContentRow, + maxLabelRow, name, value, - // borderless = false, + borderless, onChange, - } = props; + readonly, + children, + } = useDefaultProps(props, radioDefaultProps); const [radioChecked, setRadioChecked] = useDefault(checked, defaultChecked, onChange); const switchRadioChecked = (area?: string) => { - if (disabled) { + if (disabled || readonly) { return; } if (area === 'content' && contentDisabled) { @@ -66,51 +70,48 @@ const Radio = forwardRef((_props: RadioProps, ref: Ref) => { const renderIcon = () => { if (Array.isArray(icon)) { - return radioChecked ? icon[0] : icon[1] ?? null; + return radioChecked ? icon[0] : (icon[1] ?? null); + } + if (radioChecked) { + if (icon === 'circle') { + return ; + } + if (icon === 'line') { + return ; + } + if (icon === 'dot') { + let dotIconClassName = `${radioClass}__icon-${icon}`; + disabled && (dotIconClassName += ` ${radioClass}__icon-${icon}--disabled`); + return
; + } + } else { + if (icon === 'circle' || icon === 'dot') { + let circleIconClassName = `${radioClass}__icon-circle`; + disabled && (circleIconClassName += ` ${radioClass}__icon-circle--disabled`); + return
; + } + if (icon === 'line') { + return
; + } } - return ( -
- -
- ); - }; - - const labelStyle = { - ...getLimitRow(maxLabelRow), - color: disabled ? '#dcdcdc' : 'inherit', }; - const radioClassName = classNames( - `${classPrefix}`, - { [`${prefix}-is-checked`]: radioChecked }, - { [`${prefix}-is-disabled`]: disabled }, - - ); + const radioClassName = classNames(`${radioClass}`, `${radioClass}--${placement}`, { + [`${radioClass}--block`]: block, + }); - const titleClassName = classNames( - `${prefix}__content-title`, - { [`${prefix}-is-disabled`]: disabled }, - { [`${prefix}__content-right-title`]: align === 'right' }, - ) + const titleClassName = classNames(`${radioClass}__title`, { [`${radioClass}__title--disabled`]: disabled }); const input = ( { e.stopPropagation(); @@ -122,30 +123,31 @@ const Radio = forwardRef((_props: RadioProps, ref: Ref) => { /> ); + const iconClass = classNames(`${radioClass}__icon`, `${radioClass}__icon--${placement}`, { + [`${radioClass}__icon--checked`]: radioChecked, + [`${radioClass}__icon--disabled`]: disabled, + }); return (
switchRadioChecked()}> - - {align === 'left' && - {input} - {renderIcon()} - } - - {label && {label}} - {(children || content) && ( -
- {children || content} -
- )} -
- {align === 'right' && - {input} - {renderIcon()} - } -
- {/* 下边框 */} - {
} - {/* { !borderless &&
} */} -
+ {input} +
{renderIcon()}
+
+ {(label || children) && ( + + {label || children} + + )} + {content && ( +
+ {content} +
+ )} +
+ + {!borderless && block &&
}
); }); diff --git a/src/radio/RadioGroup.tsx b/src/radio/RadioGroup.tsx index 25fa61e9..d03a7ee3 100644 --- a/src/radio/RadioGroup.tsx +++ b/src/radio/RadioGroup.tsx @@ -1,16 +1,18 @@ -import React, { FC, ReactNode, useRef } from 'react'; +import React, { useRef } from 'react'; +import type { FC, ReactNode } from 'react'; import useConfig from '../_util/useConfig'; import Radio, { RadioContext, RadioContextValue, RadioProps } from './Radio'; -import { TdRadioGroupProps } from './type'; import useDefault from '../_util/useDefault'; +import type { TdRadioGroupProps } from './type'; export interface RadioGroupProps extends TdRadioGroupProps { children?: ReactNode; + className: string; } const RadioGroup: FC = (props) => { const { classPrefix } = useConfig(); - const { disabled, options, value, defaultValue, children, onChange } = props; + const { disabled, options, value, defaultValue, children, onChange, allowUncheck, borderless, className } = props; const groupRef = useRef(null); const [internalValue, setInternalValue] = useDefault(value, defaultValue, onChange); @@ -26,6 +28,8 @@ const RadioGroup: FC = (props) => { typeof radioProps.value !== 'undefined' && internalValue === radioProps.value, disabled: radioProps.disabled || disabled, + allowUncheck: radioProps.allowUncheck || allowUncheck, + borderless: radioProps.borderless || borderless, onChange: (checked, { e }) => { if (typeof radioProps.onChange === 'function') { radioProps.onChange(checked, { e }); @@ -38,7 +42,7 @@ const RadioGroup: FC = (props) => { }; const renderOptions = () => - options.map((option) => { + options.map((option, index) => { if (typeof option === 'number' || typeof option === 'string') { return ( @@ -47,18 +51,14 @@ const RadioGroup: FC = (props) => { ); } return ( - + {option.label} ); }); return ( -
-
-
- {options?.length ? renderOptions() : children} -
-
+
+ {options?.length ? renderOptions() : children}
); }; diff --git a/src/radio/_example/base.jsx b/src/radio/_example/base.tsx similarity index 72% rename from src/radio/_example/base.jsx rename to src/radio/_example/base.tsx index 8f34b309..29c0b4d5 100644 --- a/src/radio/_example/base.jsx +++ b/src/radio/_example/base.tsx @@ -8,9 +8,11 @@ export default function Base() { - - 单选单选单选单选单选单选单选单选单选单选单选单选单选单选单选单选单选单选单选单选单选 - + ); } diff --git a/src/radio/_example/card.tsx b/src/radio/_example/card.tsx new file mode 100644 index 00000000..4e6b9cf3 --- /dev/null +++ b/src/radio/_example/card.tsx @@ -0,0 +1,25 @@ +import React, { useState } from 'react'; +import { Radio, RadioGroup } from 'tdesign-mobile-react'; + +export default function () { + const [defaultValue, setDefaultValue] = useState('1'); + const options = [ + { + value: '1', + label: '单选', + }, + { + value: '2', + label: '单选', + }, + { + value: '3', + label: '单选标题多行单选标题多行单选标题多行单选标题多行单选标题多行', + }, + ]; + return ( + + {options.map((opt) => )} + + ); +} diff --git a/src/radio/_example/custom.tsx b/src/radio/_example/custom.tsx new file mode 100644 index 00000000..5fef346e --- /dev/null +++ b/src/radio/_example/custom.tsx @@ -0,0 +1,39 @@ +import React, { useState } from 'react'; +import { Radio, RadioGroup } from 'tdesign-mobile-react'; +import { Icon } from 'tdesign-icons-react'; +import TDemoBlock from '../../../site/mobile/components/DemoBlock'; + +export default function () { + const [defaultValue, setDefaultValue] = useState(0); + const [defaultValueH, setDefaultValueH] = useState(0); + return ( + <> + + setDefaultValue(value)}> + {Array.from(Array(3), (_, key) => ( +
+ {defaultValue === key && } + +
+ ))} +
+
+ + setDefaultValueH(value)}> + {Array.from(Array(3), (_, key) => ( +
+ {defaultValueH === key && } + +
+ ))} +
+
+ + ); +} diff --git a/src/radio/_example/group.jsx b/src/radio/_example/group.jsx deleted file mode 100644 index ec4fe54f..00000000 --- a/src/radio/_example/group.jsx +++ /dev/null @@ -1,40 +0,0 @@ -import React, { useState } from 'react'; -import { RadioGroup, Radio } from 'tdesign-mobile-react'; - -export default function () { - const itemOptions = ['北京', '上海', '广州', '深圳']; - const [city, setCity] = useState('北京'); - const [city2, setCity2] = useState(''); - const [city3, setCity3] = useState(''); - return ( - <> - setCity(`${value}`)}> -
- setCity2(`${value}`)}> - 北京 - 上海 - 广州 - 深圳 - -
-
- setCity2(`${value}`)} disabled> - 北京 - 上海 - 广州 - 深圳 - -
-
- setCity3(`${value}`)}> - 北京 - - 上海 - - 广州 - 深圳 - -
- - ); -} diff --git a/src/radio/_example/horizontal.tsx b/src/radio/_example/horizontal.tsx new file mode 100644 index 00000000..cd44e51e --- /dev/null +++ b/src/radio/_example/horizontal.tsx @@ -0,0 +1,13 @@ +import React, { useState } from 'react'; +import { Radio, RadioGroup } from 'tdesign-mobile-react'; + +export default function Base() { + const [defaultValue, setDefaultValue] = useState('idx0'); + return ( + setDefaultValue(value)}> + + + + + ); +} diff --git a/src/radio/_example/icon.jsx b/src/radio/_example/icon.jsx deleted file mode 100644 index f3bfe874..00000000 --- a/src/radio/_example/icon.jsx +++ /dev/null @@ -1,15 +0,0 @@ -import React, { useState } from 'react'; -import { CheckRectangleFilledIcon, RectangleIcon } from 'tdesign-icons-react'; -import { Radio, RadioGroup } from 'tdesign-mobile-react'; - -export default function () { - const [defaultValue, setDefaultValue] = useState('idx2'); - const icons = [, ]; - - return ( - setDefaultValue(value)}> - - - - ); -} diff --git a/src/radio/_example/icon.tsx b/src/radio/_example/icon.tsx new file mode 100644 index 00000000..14689768 --- /dev/null +++ b/src/radio/_example/icon.tsx @@ -0,0 +1,11 @@ +import React from 'react'; +import { Radio } from 'tdesign-mobile-react'; + +export default function () { + return ( + <> + + + + ); +} diff --git a/src/radio/_example/index.jsx b/src/radio/_example/index.tsx similarity index 59% rename from src/radio/_example/index.jsx rename to src/radio/_example/index.tsx index 76a7e55a..f261c30c 100644 --- a/src/radio/_example/index.jsx +++ b/src/radio/_example/index.tsx @@ -2,57 +2,57 @@ import React from 'react'; import TDemoHeader from '../../../site/mobile/components/DemoHeader'; import TDemoBlock from '../../../site/mobile/components/DemoBlock'; import BaseDemo from './base'; -import RightDemo from './right'; -import LeftStrokeLineDemo from './leftStrokeLine'; -import RightStrokeLineDemo from './rightStrokeLine'; +import HorizontalDemo from './horizontal'; import StatusDemo from './status'; import IconDemo from './icon'; -import SizeDemo from './size'; -import './style/index.less' +import PlacementDemo from './placement'; +import CardDemo from './card'; +import CustomDemo from './custom'; +import './style/index.less'; export default function RadioDemo() { return (
- +
- + +
- +
- +
- +
- +
- +
- - +
- +
- +
- +
- +
- +
diff --git a/src/radio/_example/leftStrokeLine.jsx b/src/radio/_example/leftStrokeLine.jsx deleted file mode 100644 index fb612b75..00000000 --- a/src/radio/_example/leftStrokeLine.jsx +++ /dev/null @@ -1,24 +0,0 @@ -import React, { useState } from 'react'; -import { Radio, RadioGroup } from 'tdesign-mobile-react'; -import { CheckIcon } from 'tdesign-icons-react'; - -export default function Base() { - const [defaultValue, setDefaultValue] = useState('idx0'); - const CheckedIcon = ; - return ( - <> - setDefaultValue(value)}> - - - - - 单选单选单选单选单选单选单选单选单选单选单选单选单选单选单选单选单选单选单选单选单选 - - - - ); -} diff --git a/src/radio/_example/placement.tsx b/src/radio/_example/placement.tsx new file mode 100644 index 00000000..cfeb39c8 --- /dev/null +++ b/src/radio/_example/placement.tsx @@ -0,0 +1,11 @@ +import React from 'react'; +import { Radio } from 'tdesign-mobile-react'; + +export default function () { + return ( + <> + + + + ); +} diff --git a/src/radio/_example/right.jsx b/src/radio/_example/right.jsx deleted file mode 100644 index 3baa08f2..00000000 --- a/src/radio/_example/right.jsx +++ /dev/null @@ -1,19 +0,0 @@ -import React, { useState } from 'react'; -import { Radio, RadioGroup } from 'tdesign-mobile-react'; - -export default function () { - const [defaultValue, setDefaultValue] = useState('idx0'); - return ( - - - - - - - ); -} diff --git a/src/radio/_example/rightStrokeLine.jsx b/src/radio/_example/rightStrokeLine.jsx deleted file mode 100644 index 35462a51..00000000 --- a/src/radio/_example/rightStrokeLine.jsx +++ /dev/null @@ -1,23 +0,0 @@ -import React, { useState } from 'react'; -import { Radio, RadioGroup } from 'tdesign-mobile-react'; -import { CheckIcon } from 'tdesign-icons-react'; - -export default function () { - const [defaultValue, setDefaultValue] = useState('idx1'); - const CheckedIcon = ; - - return ( - - - - - 单选单选单选单选单选单选单选单选单选单选单选单选单选单选单选单选单选单选单选单选单选 - - - ); -} diff --git a/src/radio/_example/size.jsx b/src/radio/_example/size.jsx deleted file mode 100644 index 6bc8bc6c..00000000 --- a/src/radio/_example/size.jsx +++ /dev/null @@ -1,10 +0,0 @@ -import React from 'react'; -import { Radio, RadioGroup } from 'tdesign-mobile-react'; - -export default function () { - return ( - - - - ); -} diff --git a/src/radio/_example/status.jsx b/src/radio/_example/status.jsx deleted file mode 100644 index f117cc5f..00000000 --- a/src/radio/_example/status.jsx +++ /dev/null @@ -1,46 +0,0 @@ -import React from 'react'; -import { CheckIcon } from 'tdesign-icons-react'; -import { Radio, RadioGroup } from 'tdesign-mobile-react'; -import TDemoBlock from '../../../site/mobile/components/DemoBlock'; - -export default function () { - const defaultValue = 'idx2'; - const icon = ; - - return ( - <> -
- - - - - - -
-
- - - - - - -
-
- - - - - - -
-
- - - - - - -
- - ); -} diff --git a/src/radio/_example/status.tsx b/src/radio/_example/status.tsx new file mode 100644 index 00000000..69ea5cb1 --- /dev/null +++ b/src/radio/_example/status.tsx @@ -0,0 +1,21 @@ +import React from 'react'; +import { Radio, RadioGroup } from 'tdesign-mobile-react'; + +export default function () { + const defaultValue = '1'; + const options = [ + { + value: '1', + label: '选项禁用-已选', + }, + { + value: '2', + label: '选项禁用-默认', + }, + ]; + return ( + + {options.map((opt) => )} + + ); +} diff --git a/src/radio/_example/style/index.less b/src/radio/_example/style/index.less index be559a92..1fd3797d 100644 --- a/src/radio/_example/style/index.less +++ b/src/radio/_example/style/index.less @@ -1,4 +1,66 @@ -.radio-demo { - background-color: #fff; +.box { + padding: 16px; + display: flex; + justify-content: space-between; + background-color: var(--bg-color-demo, #fff); } + +.theme-card { + border-radius: 12px; + margin: 16px; + overflow: hidden; +} +.card { + display: block; + position: relative; + margin: 16px; + border-radius: 6px; + overflow: hidden; + box-sizing: border-box; + border: 1.5px solid #fff; +} + +.card--active { + border-color: #0052d9; + z-index: 0; +} + +.card--active::after { + content: ''; + display: block; + position: absolute; + left: 0; + top: 0; + width: 0; + border: 14px solid #0052d9; + border-bottom-color: transparent; + border-right-color: transparent; + z-index: inherit !important; +} + +.card__icon { + display: block; + color: #fff; + position: absolute; + left: 1.5px; + top: 1.5px; + z-index: 1; +} + +/* 横向布局 */ +.horizontal-box { + width: calc(100% - 32px); + display: flex; + align-items: center; + margin: 16px; +} + +.horizontal-box .card { + flex: 1; + margin: 0; +} + +.horizontal-box .card + .card { + margin-left: 12px; +} \ No newline at end of file diff --git a/src/radio/defaultProps.ts b/src/radio/defaultProps.ts new file mode 100644 index 00000000..8beff2f0 --- /dev/null +++ b/src/radio/defaultProps.ts @@ -0,0 +1,29 @@ +/** + * 该文件为脚本自动生成文件,请勿随意修改。如需修改请联系 PMC + * */ + +import { TdRadioProps, TdRadioGroupProps } from './type'; + +export const radioDefaultProps: TdRadioProps = { + align: 'left', + allowUncheck: false, + block: true, + borderless: undefined, + defaultChecked: false, + contentDisabled: false, + disabled: undefined, + icon: 'circle', + maxContentRow: 5, + maxLabelRow: 3, + placement: 'left', + readonly: false, + value: undefined, +}; + +export const radioGroupDefaultProps: TdRadioGroupProps = { + allowUncheck: false, + borderless: false, + disabled: undefined, + icon: 'circle', + placement: 'left', +}; diff --git a/src/radio/radio.en-US.md b/src/radio/radio.en-US.md new file mode 100644 index 00000000..c2911e20 --- /dev/null +++ b/src/radio/radio.en-US.md @@ -0,0 +1,48 @@ +:: BASE_DOC :: + +## API + +### Radio Props + +name | type | default | description | required +-- | -- | -- | -- | -- +className | String | - | className of component | N +style | Object | - | CSS(Cascading Style Sheets),Typescript:`React.CSSProperties` | N +align | String | left | options: left/right | N +allowUncheck | Boolean | false | \- | N +block | Boolean | true | \- | N +borderless | Boolean | undefined | \- | N +checked | Boolean | false | \- | N +defaultChecked | Boolean | false | uncontrolled property | N +children | TNode | - | Typescript:`string \| TNode`。[see more ts definition](https://github.com/Tencent/tdesign-mobile-react/blob/develop/src/common.ts) | N +content | TNode | - | Typescript:`string \| TNode`。[see more ts definition](https://github.com/Tencent/tdesign-mobile-react/blob/develop/src/common.ts) | N +contentDisabled | Boolean | false | \- | N +disabled | Boolean | undefined | \- | N +icon | String / Array | 'circle' | Typescript:`'circle' \| 'line' \| 'dot' \| 'none' \|Array`。[see more ts definition](https://github.com/Tencent/tdesign-mobile-react/blob/develop/src/common.ts) | N +label | TNode | - | Typescript:`string \| TNode`。[see more ts definition](https://github.com/Tencent/tdesign-mobile-react/blob/develop/src/common.ts) | N +maxContentRow | Number | 5 | \- | N +maxLabelRow | Number | 3 | \- | N +name | String | - | \- | N +placement | String | left | options: left/right | N +readonly | Boolean | false | \- | N +value | String / Number / Boolean | undefined | Typescript:`T` | N +onChange | Function | | Typescript:`(checked: boolean, context: { e: ChangeEvent }) => void`
| N + + +### RadioGroup Props + +name | type | default | description | required +-- | -- | -- | -- | -- +className | String | - | className of component | N +style | Object | - | CSS(Cascading Style Sheets),Typescript:`React.CSSProperties` | N +allowUncheck | Boolean | false | \- | N +borderless | Boolean | false | \- | N +disabled | Boolean | undefined | \- | N +icon | String / Array | 'circle' | Typescript:`'circle' \| 'line' \| 'dot' \| Array`。[see more ts definition](https://github.com/Tencent/tdesign-mobile-react/blob/develop/src/common.ts) | N +keys | Object | - | Typescript:`KeysType`。[see more ts definition](https://github.com/Tencent/tdesign-mobile-react/blob/develop/src/common.ts) | N +name | String | - | \- | N +options | Array | - | Typescript:`Array` `type RadioOption = string \| number \| RadioOptionObj` `interface RadioOptionObj { label?: string \| TNode; value?: string \| number \| boolean; disabled?: boolean }`。[see more ts definition](https://github.com/Tencent/tdesign-mobile-react/blob/develop/src/common.ts)。[see more ts definition](https://github.com/Tencent/tdesign-mobile-react/tree/develop/src/radio/type.ts) | N +placement | String | left | options: left/right | N +value | String / Number / Boolean | - | Typescript:`T` `type RadioValue = string \| number \| boolean`。[see more ts definition](https://github.com/Tencent/tdesign-mobile-react/tree/develop/src/radio/type.ts) | N +defaultValue | String / Number / Boolean | - | uncontrolled property。Typescript:`T` `type RadioValue = string \| number \| boolean`。[see more ts definition](https://github.com/Tencent/tdesign-mobile-react/tree/develop/src/radio/type.ts) | N +onChange | Function | | Typescript:`(value: T, context: { e: ChangeEvent; name?: string }) => void`
| N diff --git a/src/radio/radio.md b/src/radio/radio.md index 9a806bd6..832c1a20 100644 --- a/src/radio/radio.md +++ b/src/radio/radio.md @@ -1,37 +1,48 @@ :: BASE_DOC :: ## API + ### Radio Props -名称 | 类型 | 默认值 | 说明 | 必传 +名称 | 类型 | 默认值 | 描述 | 必传 -- | -- | -- | -- | -- className | String | - | 类名 | N style | Object | - | 样式,TS 类型:`React.CSSProperties` | N -align | String | left | 复选框和内容相对位置。可选项:left/right | N +align | String | left | 已废弃。复选框和内容相对位置。可选项:left/right | N allowUncheck | Boolean | false | 是否允许取消选中 | N -checked | Boolean | - | 是否选中 | N -defaultChecked | Boolean | - | 是否选中。非受控属性 | N -children | TNode | - | 单选内容,同 label。TS 类型:`string | TNode`。[通用类型定义](https://github.com/Tencent/tdesign-mobile-react/blob/develop/src/common.ts) | N -content | TNode | - | 单选内容。TS 类型:`string | TNode`。[通用类型定义](https://github.com/Tencent/tdesign-mobile-react/blob/develop/src/common.ts) | N -contentDisabled | Boolean | - | 是否禁用组件内容(content)触发选中 | N -disabled | Boolean | undefined | 是否为禁用态 | N -icon | Array | - | 自定义选中图标和非选中图标。示例:[选中态图标,非选中态图标]。TS 类型:`Array`。[通用类型定义](https://github.com/Tencent/tdesign-mobile-react/blob/develop/src/common.ts) | N -label | TNode | - | 主文案。TS 类型:`string | TNode`。[通用类型定义](https://github.com/Tencent/tdesign-mobile-react/blob/develop/src/common.ts) | N +block | Boolean | true | 是否为块级元素 | N +borderless | Boolean | undefined | 是否开启无边框模式 | N +checked | Boolean | false | 是否选中 | N +defaultChecked | Boolean | false | 是否选中。非受控属性 | N +children | TNode | - | 单选内容,同 label。TS 类型:`string \| TNode`。[通用类型定义](https://github.com/Tencent/tdesign-mobile-react/blob/develop/src/common.ts) | N +content | TNode | - | 单选内容。TS 类型:`string \| TNode`。[通用类型定义](https://github.com/Tencent/tdesign-mobile-react/blob/develop/src/common.ts) | N +contentDisabled | Boolean | false | 是否禁用组件内容(content)触发选中 | N +disabled | Boolean | undefined | 是否为禁用态。如果存在父组件 RadioGroup,默认值由 RadioGroup.disabled 控制。优先级:Radio.disabled > RadioGroup.disabled > Form.disabled | N +icon | String / Array | 'circle' | 自定义选中图标和非选中图标。示例:[选中态图标地址,非选中态图标地址]。使用 String 时,值为 circle 表示填充型图标、值为 line 表示描边型图标、值为 dot 表示圆点图标、值为 'none' 则表示没有图标。TS 类型:`'circle' \| 'line' \| 'dot' \| 'none' \|Array`。[通用类型定义](https://github.com/Tencent/tdesign-mobile-react/blob/develop/src/common.ts) | N +label | TNode | - | 主文案。TS 类型:`string \| TNode`。[通用类型定义](https://github.com/Tencent/tdesign-mobile-react/blob/develop/src/common.ts) | N maxContentRow | Number | 5 | 内容最大行数限制 | N maxLabelRow | Number | 3 | 主文案最大行数限制 | N name | String | - | HTML 元素原生属性 | N -value | String / Number / Boolean | undefined | 单选按钮的值。TS 类型:`RadioValue` `type RadioValue = string | number | boolean`。[详细类型定义](https://github.com/Tencent/tdesign-mobile-react/tree/develop/src/radio/type.ts) | N +placement | String | left | 复选框和内容相对位置。可选项:left/right | N +readonly | Boolean | false | 只读状态 | N +value | String / Number / Boolean | undefined | 单选按钮的值。TS 类型:`T` | N onChange | Function | | TS 类型:`(checked: boolean, context: { e: ChangeEvent }) => void`
选中状态变化时触发 | N + ### RadioGroup Props -名称 | 类型 | 默认值 | 说明 | 必传 +名称 | 类型 | 默认值 | 描述 | 必传 -- | -- | -- | -- | -- className | String | - | 类名 | N style | Object | - | 样式,TS 类型:`React.CSSProperties` | N -disabled | Boolean | undefined | 是否禁用全部子单选框 | N +allowUncheck | Boolean | false | 是否允许取消选中 | N +borderless | Boolean | false | 是否开启无边框模式;优先级低于 Radio | N +disabled | Boolean | undefined | 是否禁用全部子单选框。优先级:Radio.disabled > RadioGroup.disabled > Form.disabled | N +icon | String / Array | 'circle' | 自定义选中图标和非选中图标。示例:[选中态图标地址,非选中态图标地址]。使用 String 时,值为 circle 表示填充型图标、值为 line 表示描边型图标、值为 dot 表示圆点图标。TS 类型:`'circle' \| 'line' \| 'dot' \| Array`。[通用类型定义](https://github.com/Tencent/tdesign-mobile-react/blob/develop/src/common.ts) | N +keys | Object | - | 用来定义 value / label 在 `options` 中对应的字段别名。TS 类型:`KeysType`。[通用类型定义](https://github.com/Tencent/tdesign-mobile-react/blob/develop/src/common.ts) | N name | String | - | HTML 元素原生属性 | N -options | Array | - | 单选组件按钮形式。RadioOption 数据类型为 string 或 number 时,表示 label 和 value 值相同。TS 类型:`Array` `type RadioOption = string | number | RadioOptionObj` `interface RadioOptionObj { label?: string | TNode; value?: string | number; disabled?: boolean }`。[通用类型定义](https://github.com/Tencent/tdesign-mobile-react/blob/develop/src/common.ts)。[详细类型定义](https://github.com/Tencent/tdesign-mobile-react/tree/develop/src/radio/type.ts) | N -value | String / Number / Boolean | undefined | 选中的值。TS 类型:`RadioValue` | N -defaultValue | String / Number / Boolean | undefined | 选中的值。非受控属性。TS 类型:`RadioValue` | N -onChange | Function | | TS 类型:`(value: RadioValue, context: { e: ChangeEvent }) => void`
选中值发生变化时触发 | N +options | Array | - | 单选组件按钮形式。RadioOption 数据类型为 string 或 number 时,表示 label 和 value 值相同。TS 类型:`Array` `type RadioOption = string \| number \| RadioOptionObj` `interface RadioOptionObj { label?: string \| TNode; value?: string \| number \| boolean; disabled?: boolean }`。[通用类型定义](https://github.com/Tencent/tdesign-mobile-react/blob/develop/src/common.ts)。[详细类型定义](https://github.com/Tencent/tdesign-mobile-react/tree/develop/src/radio/type.ts) | N +placement | String | left | 复选框和内容相对位置。可选项:left/right | N +value | String / Number / Boolean | - | 选中的值。TS 类型:`T` `type RadioValue = string \| number \| boolean`。[详细类型定义](https://github.com/Tencent/tdesign-mobile-react/tree/develop/src/radio/type.ts) | N +defaultValue | String / Number / Boolean | - | 选中的值。非受控属性。TS 类型:`T` `type RadioValue = string \| number \| boolean`。[详细类型定义](https://github.com/Tencent/tdesign-mobile-react/tree/develop/src/radio/type.ts) | N +onChange | Function | | TS 类型:`(value: T, context: { e: ChangeEvent; name?: string }) => void`
选中值发生变化时触发, `context.name` 指 RadioGroup 的 name 属性 | N diff --git a/src/radio/style/index.js b/src/radio/style/index.js index f23ec6ac..dab3f1cc 100644 --- a/src/radio/style/index.js +++ b/src/radio/style/index.js @@ -1,4 +1 @@ -import '../../_common/style/mobile/components/radio/_index.less'; -import '../../_common/style/mobile/components/radio-group/_index.less'; - -import './index.less'; +import '../../_common/style/mobile/components/radio/v2/_index.less'; diff --git a/src/radio/style/index.less b/src/radio/style/index.less deleted file mode 100644 index 916806e4..00000000 --- a/src/radio/style/index.less +++ /dev/null @@ -1,9 +0,0 @@ -.t-radio__wrap { - align-self: flex-start; -} - -.t-radio.t-is-checked { - .t-radio__checked__disable-icon { - color: #dcdcdc; - } -} diff --git a/src/radio/type.ts b/src/radio/type.ts index aa000cb9..0972209c 100644 --- a/src/radio/type.ts +++ b/src/radio/type.ts @@ -4,12 +4,12 @@ * 该文件为脚本自动生成文件,请勿随意修改。如需修改请联系 PMC * */ -import { TNode } from '../common'; +import { TNode, KeysType } from '../common'; import { ChangeEvent } from 'react'; -export interface TdRadioProps { +export interface TdRadioProps { /** - * 复选框和内容相对位置 + * 已废弃。复选框和内容相对位置 * @default left */ align?: 'left' | 'right'; @@ -18,12 +18,23 @@ export interface TdRadioProps { * @default false */ allowUncheck?: boolean; + /** + * 是否为块级元素 + * @default true + */ + block?: boolean; + /** + * 是否开启无边框模式 + */ + borderless?: boolean; /** * 是否选中 + * @default false */ checked?: boolean; /** * 是否选中,非受控属性 + * @default false */ defaultChecked?: boolean; /** @@ -36,17 +47,18 @@ export interface TdRadioProps { content?: TNode; /** * 是否禁用组件内容(content)触发选中 + * @default false */ contentDisabled?: boolean; /** - * 是否为禁用态 + * 是否为禁用态。如果存在父组件 RadioGroup,默认值由 RadioGroup.disabled 控制。优先级:Radio.disabled > RadioGroup.disabled > Form.disabled */ disabled?: boolean; /** - * 自定义选中图标和非选中图标。示例:[选中态图标地址,非选中态图标地址]。值为 fill-circle 表示图标为填充型图标,值为 stroke-line 表示图标为描边型图标 - * @default 'fill-circle' + * 自定义选中图标和非选中图标。示例:[选中态图标地址,非选中态图标地址]。使用 String 时,值为 circle 表示填充型图标、值为 line 表示描边型图标、值为 dot 表示圆点图标、值为 'none' 则表示没有图标 + * @default 'circle' */ - icon?: Array; + icon?: 'circle' | 'line' | 'dot' | 'none' | Array; /** * 主文案 */ @@ -66,21 +78,50 @@ export interface TdRadioProps { * @default '' */ name?: string; + /** + * 复选框和内容相对位置 + * @default left + */ + placement?: 'left' | 'right'; + /** + * 只读状态 + * @default false + */ + readonly?: boolean; /** * 单选按钮的值 */ - value?: RadioValue; + value?: T; /** * 选中状态变化时触发 */ onChange?: (checked: boolean, context: { e: ChangeEvent }) => void; } -export interface TdRadioGroupProps { +export interface TdRadioGroupProps { /** - * 是否禁用全部子单选框 + * 是否允许取消选中 + * @default false + */ + allowUncheck?: boolean; + /** + * 是否开启无边框模式;优先级低于 Radio + * @default false + */ + borderless?: boolean; + /** + * 是否禁用全部子单选框。优先级:Radio.disabled > RadioGroup.disabled > Form.disabled */ disabled?: boolean; + /** + * 自定义选中图标和非选中图标。示例:[选中态图标地址,非选中态图标地址]。使用 String 时,值为 circle 表示填充型图标、值为 line 表示描边型图标、值为 dot 表示圆点图标 + * @default 'circle' + */ + icon?: 'circle' | 'line' | 'dot' | Array; + /** + * 用来定义 value / label 在 `options` 中对应的字段别名 + */ + keys?: KeysType; /** * HTML 元素原生属性 * @default '' @@ -90,26 +131,31 @@ export interface TdRadioGroupProps { * 单选组件按钮形式。RadioOption 数据类型为 string 或 number 时,表示 label 和 value 值相同 */ options?: Array; + /** + * 复选框和内容相对位置 + * @default left + */ + placement?: 'left' | 'right'; /** * 选中的值 */ - value?: RadioValue; + value?: T; /** * 选中的值,非受控属性 */ - defaultValue?: RadioValue; + defaultValue?: T; /** - * 选中值发生变化时触发 + * 选中值发生变化时触发, `context.name` 指 RadioGroup 的 name 属性 */ - onChange?: (value: RadioValue, context: { e: ChangeEvent }) => void; + onChange?: (value: T, context: { e: ChangeEvent; name?: string }) => void; } -export type RadioValue = string | number | boolean; - export type RadioOption = string | number | RadioOptionObj; export interface RadioOptionObj { label?: string | TNode; - value?: string | number; + value?: string | number | boolean; disabled?: boolean; } + +export type RadioValue = string | number | boolean; diff --git a/test/snap/__snapshots__/csr.test.jsx.snap b/test/snap/__snapshots__/csr.test.jsx.snap index 400d9c55..3068b3e1 100644 --- a/test/snap/__snapshots__/csr.test.jsx.snap +++ b/test/snap/__snapshots__/csr.test.jsx.snap @@ -31961,6 +31961,1794 @@ exports[`csr snapshot test > csr test src/progress/_example/transition.tsx 1`] =
`; +exports[`csr snapshot test > csr test src/radio/_example/base.tsx 1`] = ` +
+
+
+ +
+ + + +
+
+ + 单选 + +
+
+
+
+ +
+
+
+
+ + 单选 + +
+
+
+
+ +
+
+
+
+ + 单选单选单选单选单选单选单选单选单选单选单选单选单选单选单选单选单选单选 + +
+
+
+
+ +
+
+
+
+ + 单选 + +
+ 描述信息描述信息描述信息描述信息描述信息描述信息描述信息描述信息描述信息描述信息 +
+
+
+
+
+
+`; + +exports[`csr snapshot test > csr test src/radio/_example/card.tsx 1`] = ` +
+
+
+ +
+ + + +
+
+ + 单选 + +
+
+
+
+ +
+
+
+
+ + 单选 + +
+
+
+
+ +
+
+
+
+ + 单选标题多行单选标题多行单选标题多行单选标题多行单选标题多行 + +
+
+
+
+
+`; + +exports[`csr snapshot test > csr test src/radio/_example/custom.tsx 1`] = ` +
+
+
+

+ 单选框尺寸规格 +

+
+
+
+
+ + + +
+ +
+
+ + 单选 + +
+ 描述信息描述信息描述信息描述信息描述信息 +
+
+
+
+
+
+ +
+
+ + 单选 + +
+ 描述信息描述信息描述信息描述信息描述信息 +
+
+
+
+
+
+ +
+
+ + 单选 + +
+ 描述信息描述信息描述信息描述信息描述信息 +
+
+
+
+
+
+
+
+
+

+ 横向卡片单选框 +

+
+
+
+
+ + + +
+ +
+
+ + 单选 + +
+
+
+
+
+ +
+
+ + 单选 + +
+
+
+
+
+ +
+
+ + 单选 + +
+
+
+
+
+
+
+`; + +exports[`csr snapshot test > csr test src/radio/_example/horizontal.tsx 1`] = ` +
+
+
+ +
+ + + +
+
+ + 单选标题 + +
+
+
+ +
+
+
+
+ + 单选标题 + +
+
+
+ +
+
+
+
+ + 单选标题 + +
+
+
+
+`; + +exports[`csr snapshot test > csr test src/radio/_example/icon.tsx 1`] = ` +
+
+ +
+ + + +
+
+ + 单选 + +
+
+
+
+ +
+
+
+
+ + 单选 + +
+
+
+
+`; + +exports[`csr snapshot test > csr test src/radio/_example/index.tsx 1`] = ` +
+
+
+

+ Radio 单选框 +

+

+ 用于在预设的一组选项中执行单项选择,并呈现选择结果。 +

+
+
+
+

+ 01 组件类型 +

+

+ 纵向单选框 +

+
+
+
+
+
+ +
+ + + +
+
+ + 单选 + +
+
+
+
+ +
+
+
+
+ + 单选 + +
+
+
+
+ +
+
+
+
+ + 单选单选单选单选单选单选单选单选单选单选单选单选单选单选单选单选单选单选 + +
+
+
+
+ +
+
+
+
+ + 单选 + +
+ 描述信息描述信息描述信息描述信息描述信息描述信息描述信息描述信息描述信息描述信息 +
+
+
+
+
+
+
+
+
+
+

+ 横向单选框 +

+
+
+
+
+
+ +
+ + + +
+
+ + 单选标题 + +
+
+
+ +
+
+
+
+ + 单选标题 + +
+
+
+ +
+
+
+
+ + 单选标题 + +
+
+
+
+
+
+
+
+

+ 02 组件状态 +

+

+ 单选框禁用状态 +

+
+
+
+
+
+ +
+ + + +
+
+ + 选项禁用-已选 + +
+
+
+
+ +
+
+
+
+ + 选项禁用-默认 + +
+
+
+
+
+
+
+
+
+

+ 03 组件样式 +

+

+ 勾选样式 +

+
+
+
+
+ +
+ + + +
+
+ + 单选 + +
+
+
+
+ +
+
+
+
+ + 单选 + +
+
+
+
+
+
+
+
+

+ 勾选显示位置 +

+
+
+
+
+ +
+ + + +
+
+ + 单选 + +
+
+
+
+ +
+ + + +
+
+ + 单选 + +
+
+
+
+
+
+
+
+

+ 非通栏单选样式 +

+
+
+
+
+
+ +
+ + + +
+
+ + 单选 + +
+
+
+
+ +
+
+
+
+ + 单选 + +
+
+
+
+ +
+
+
+
+ + 单选标题多行单选标题多行单选标题多行单选标题多行单选标题多行 + +
+
+
+
+
+
+
+
+
+

+ 04 特殊样式 +

+
+
+
+
+
+

+ 单选框尺寸规格 +

+
+
+
+
+ + + +
+ +
+
+ + 单选 + +
+ 描述信息描述信息描述信息描述信息描述信息 +
+
+
+
+
+
+ +
+
+ + 单选 + +
+ 描述信息描述信息描述信息描述信息描述信息 +
+
+
+
+
+
+ +
+
+ + 单选 + +
+ 描述信息描述信息描述信息描述信息描述信息 +
+
+
+
+
+
+
+
+
+

+ 横向卡片单选框 +

+
+
+
+
+ + + +
+ +
+
+ + 单选 + +
+
+
+
+
+ +
+
+ + 单选 + +
+
+
+
+
+ +
+
+ + 单选 + +
+
+
+
+
+
+
+
+
+
+
+`; + +exports[`csr snapshot test > csr test src/radio/_example/placement.tsx 1`] = ` +
+
+ +
+ + + +
+
+ + 单选 + +
+
+
+
+ +
+ + + +
+
+ + 单选 + +
+
+
+
+`; + +exports[`csr snapshot test > csr test src/radio/_example/status.tsx 1`] = ` +
+
+
+ +
+ + + +
+
+ + 选项禁用-已选 + +
+
+
+
+ +
+
+
+
+ + 选项禁用-默认 + +
+
+
+
+
+`; + exports[`csr snapshot test > csr test src/result/_example/custom.tsx 1`] = `
ssr test src/progress/_example/plump.tsx 1`] = `" ssr test src/progress/_example/transition.tsx 1`] = `"
88%
"`; +exports[`ssr snapshot test > ssr test src/radio/_example/base.tsx 1`] = `"
单选
单选
单选单选单选单选单选单选单选单选单选单选单选单选单选单选单选单选单选单选
单选
描述信息描述信息描述信息描述信息描述信息描述信息描述信息描述信息描述信息描述信息
"`; + +exports[`ssr snapshot test > ssr test src/radio/_example/card.tsx 1`] = `"
单选
单选
单选标题多行单选标题多行单选标题多行单选标题多行单选标题多行
"`; + +exports[`ssr snapshot test > ssr test src/radio/_example/custom.tsx 1`] = `"

单选框尺寸规格

单选
描述信息描述信息描述信息描述信息描述信息
单选
描述信息描述信息描述信息描述信息描述信息
单选
描述信息描述信息描述信息描述信息描述信息

横向卡片单选框

单选
单选
单选
"`; + +exports[`ssr snapshot test > ssr test src/radio/_example/horizontal.tsx 1`] = `"
单选标题
单选标题
单选标题
"`; + +exports[`ssr snapshot test > ssr test src/radio/_example/icon.tsx 1`] = `"
单选
单选
"`; + +exports[`ssr snapshot test > ssr test src/radio/_example/index.tsx 1`] = `"

Radio 单选框

用于在预设的一组选项中执行单项选择,并呈现选择结果。

01 组件类型

纵向单选框

单选
单选
单选单选单选单选单选单选单选单选单选单选单选单选单选单选单选单选单选单选
单选
描述信息描述信息描述信息描述信息描述信息描述信息描述信息描述信息描述信息描述信息

横向单选框

单选标题
单选标题
单选标题

02 组件状态

单选框禁用状态

选项禁用-已选
选项禁用-默认

03 组件样式

勾选样式

单选
单选

勾选显示位置

单选
单选

非通栏单选样式

单选
单选
单选标题多行单选标题多行单选标题多行单选标题多行单选标题多行

04 特殊样式

单选框尺寸规格

单选
描述信息描述信息描述信息描述信息描述信息
单选
描述信息描述信息描述信息描述信息描述信息
单选
描述信息描述信息描述信息描述信息描述信息

横向卡片单选框

单选
单选
单选
"`; + +exports[`ssr snapshot test > ssr test src/radio/_example/placement.tsx 1`] = `"
单选
单选
"`; + +exports[`ssr snapshot test > ssr test src/radio/_example/status.tsx 1`] = `"
选项禁用-已选
选项禁用-默认
"`; + exports[`ssr snapshot test > ssr test src/result/_example/custom.tsx 1`] = `"
自定义结果
描述文字
"`; exports[`ssr snapshot test > ssr test src/result/_example/index.tsx 1`] = `"

Result 结果

结果反馈

01类型

不同结果反馈

成功状态
描述文字
失败状态
描述文字
警示状态
描述文字
默认状态
描述文字

自定义结果

自定义结果
描述文字

页面位置展示

"`; diff --git a/test/snap/__snapshots__/ssr.test.jsx.snap b/test/snap/__snapshots__/ssr.test.jsx.snap index b3964200..d98d07a7 100644 --- a/test/snap/__snapshots__/ssr.test.jsx.snap +++ b/test/snap/__snapshots__/ssr.test.jsx.snap @@ -282,6 +282,22 @@ exports[`ssr snapshot test > ssr test src/progress/_example/plump.tsx 1`] = `" ssr test src/progress/_example/transition.tsx 1`] = `"
88%
"`; +exports[`ssr snapshot test > ssr test src/radio/_example/base.tsx 1`] = `"
单选
单选
单选单选单选单选单选单选单选单选单选单选单选单选单选单选单选单选单选单选
单选
描述信息描述信息描述信息描述信息描述信息描述信息描述信息描述信息描述信息描述信息
"`; + +exports[`ssr snapshot test > ssr test src/radio/_example/card.tsx 1`] = `"
单选
单选
单选标题多行单选标题多行单选标题多行单选标题多行单选标题多行
"`; + +exports[`ssr snapshot test > ssr test src/radio/_example/custom.tsx 1`] = `"

单选框尺寸规格

单选
描述信息描述信息描述信息描述信息描述信息
单选
描述信息描述信息描述信息描述信息描述信息
单选
描述信息描述信息描述信息描述信息描述信息

横向卡片单选框

单选
单选
单选
"`; + +exports[`ssr snapshot test > ssr test src/radio/_example/horizontal.tsx 1`] = `"
单选标题
单选标题
单选标题
"`; + +exports[`ssr snapshot test > ssr test src/radio/_example/icon.tsx 1`] = `"
单选
单选
"`; + +exports[`ssr snapshot test > ssr test src/radio/_example/index.tsx 1`] = `"

Radio 单选框

用于在预设的一组选项中执行单项选择,并呈现选择结果。

01 组件类型

纵向单选框

单选
单选
单选单选单选单选单选单选单选单选单选单选单选单选单选单选单选单选单选单选
单选
描述信息描述信息描述信息描述信息描述信息描述信息描述信息描述信息描述信息描述信息

横向单选框

单选标题
单选标题
单选标题

02 组件状态

单选框禁用状态

选项禁用-已选
选项禁用-默认

03 组件样式

勾选样式

单选
单选

勾选显示位置

单选
单选

非通栏单选样式

单选
单选
单选标题多行单选标题多行单选标题多行单选标题多行单选标题多行

04 特殊样式

单选框尺寸规格

单选
描述信息描述信息描述信息描述信息描述信息
单选
描述信息描述信息描述信息描述信息描述信息
单选
描述信息描述信息描述信息描述信息描述信息

横向卡片单选框

单选
单选
单选
"`; + +exports[`ssr snapshot test > ssr test src/radio/_example/placement.tsx 1`] = `"
单选
单选
"`; + +exports[`ssr snapshot test > ssr test src/radio/_example/status.tsx 1`] = `"
选项禁用-已选
选项禁用-默认
"`; + exports[`ssr snapshot test > ssr test src/result/_example/custom.tsx 1`] = `"
自定义结果
描述文字
"`; exports[`ssr snapshot test > ssr test src/result/_example/index.tsx 1`] = `"

Result 结果

结果反馈

01类型

不同结果反馈

成功状态
描述文字
失败状态
描述文字
警示状态
描述文字
默认状态
描述文字

自定义结果

自定义结果
描述文字

页面位置展示

"`;