Skip to content

Commit

Permalink
feat(radio): support readonly (#3431)
Browse files Browse the repository at this point in the history
* feat(radio): support readonly

* docs: api update
  • Loading branch information
liweijie0812 authored and uyarn committed Dec 30, 2024
1 parent 923bdd4 commit 728475e
Show file tree
Hide file tree
Showing 9 changed files with 82 additions and 45 deletions.
2 changes: 1 addition & 1 deletion src/radio/_usage/props.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"options": []
},
{
"name": "value",
"name": "readonly",
"type": "Boolean",
"defaultValue": false,
"options": []
Expand Down
2 changes: 1 addition & 1 deletion src/radio/instance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ import { RadioValue } from './type';

export type RadioButtonInstance = InstanceType<typeof RadioButton>;
export type RadioGroupInstance = InstanceType<typeof RadioGroup> & {
handleRadioChange: (value: RadioValue, context: { e: Event }) => void;
handleRadioChange: (value: RadioValue, context: { e: Event; name?: string }) => void;
};
12 changes: 10 additions & 2 deletions src/radio/props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,17 @@ export default {
/** 是否允许取消选中 */
allowUncheck: Boolean,
/** 是否选中 */
checked: Boolean,
checked: {
type: Boolean,
default: undefined,
},
/** 是否选中,非受控属性 */
defaultChecked: Boolean,
/** 单选按钮内容,同 label */
default: {
type: [String, Function] as PropType<TdRadioProps['default']>,
},
/** 是否为禁用态 */
/** 是否为禁用态。如果存在父组件 RadioGroup,默认值由 RadioGroup.disabled 控制。优先级:Radio.disabled > RadioGroup.disabled > Form.disabled */
disabled: {
type: Boolean,
default: undefined,
Expand All @@ -32,6 +35,11 @@ export default {
type: String,
default: '',
},
/** 只读状态 */
readonly: {
type: Boolean,
default: undefined,
},
/** 单选按钮的值 */
value: {
type: [String, Number, Boolean] as PropType<TdRadioProps['value']>,
Expand Down
1 change: 1 addition & 0 deletions src/radio/radio-button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export default (Vue as VueConstructor<RadioButtonInstance>).extend({
if (radioGroup) {
radioProps.props.checked = $props.value === radioGroup.value;
radioProps.props.disabled = $props.disabled === undefined ? radioGroup.disabled : $props.disabled;
radioProps.props.readonly = $props.readonly === undefined ? radioGroup.readonly : $props.readonly;
radioProps.props.name = radioGroup.name;
}

Expand Down
25 changes: 16 additions & 9 deletions src/radio/radio-group-props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { PropType } from 'vue';
export default {
/** 是否允许取消选中 */
allowUncheck: Boolean,
/** 是否禁用全部子单选框 */
/** 是否禁用全部子单选框。优先级:Radio.disabled > RadioGroup.disabled > Form.disabled */
disabled: {
type: Boolean,
default: undefined,
Expand All @@ -24,13 +24,10 @@ export default {
options: {
type: Array as PropType<TdRadioGroupProps['options']>,
},
/** 组件风格 */
theme: {
type: String as PropType<TdRadioGroupProps['theme']>,
default: 'radio' as TdRadioGroupProps['theme'],
validator(val: TdRadioGroupProps['theme']): boolean {
return ['radio', 'button'].includes(val);
},
/** 只读状态 */
readonly: {
type: Boolean,
default: undefined,
},
/** 组件尺寸【讨论中】 */
size: {
Expand All @@ -41,9 +38,19 @@ export default {
return ['small', 'medium', 'large'].includes(val);
},
},
/** 组件风格 */
theme: {
type: String as PropType<TdRadioGroupProps['theme']>,
default: 'radio' as TdRadioGroupProps['theme'],
validator(val: TdRadioGroupProps['theme']): boolean {
if (!val) return true;
return ['radio', 'button'].includes(val);
},
},
/** 选中的值 */
value: {
type: [String, Number, Boolean] as PropType<TdRadioGroupProps['value']>,
default: undefined,
},
/** 选中的值,非受控属性 */
defaultValue: {
Expand All @@ -58,6 +65,6 @@ export default {
return ['outline', 'primary-filled', 'default-filled'].includes(val);
},
},
/** 选中值发生变化时触发 */
/** 选中值发生变化时触发, `context.name` 指 RadioGroup 的 name 属性 */
onChange: Function as PropType<TdRadioGroupProps['onChange']>,
};
20 changes: 12 additions & 8 deletions src/radio/radio.en-US.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
:: BASE_DOC ::

## API

### Radio Props

name | type | default | description | required
Expand All @@ -12,6 +13,7 @@ default | String / Slot / Function | - | Typescript:`string \| TNode`。[see m
disabled | Boolean | undefined | \- | N
label | String / Slot / Function | - | Typescript:`string \| TNode`[see more ts definition](https://github.com/Tencent/tdesign-vue/blob/develop/src/common.ts) | N
name | String | - | \- | N
readonly | Boolean | undefined | \- | N
value | String / Number / Boolean | undefined | Typescript:`T` | N
onChange | Function | | Typescript:`(checked: boolean, context: { e: Event }) => void`<br/> | N
onClick | Function | | Typescript:`(context: { e: MouseEvent }) => void`<br/>trigger on click | N
Expand All @@ -23,23 +25,25 @@ name | params | description
change | `(checked: boolean, context: { e: Event })` | \-
click | `(context: { e: MouseEvent })` | trigger on click


### RadioGroup Props

name | type | default | description | required
-- | -- | -- | -- | --
allowUncheck | Boolean | false | \- | N
disabled | Boolean | undefined | \- | N
name | String | - | \- | N
options | Array | - | Typescript:`Array<RadioOption>` `type RadioOption = string \| number \| RadioOptionObj` `interface RadioOptionObj { label?: string \| TNode; value?: string \| number; disabled?: boolean }`[see more ts definition](https://github.com/Tencent/tdesign-vue/blob/develop/src/common.ts)[see more ts definition](https://github.com/Tencent/tdesign-vue/tree/develop/src/radio/type.ts) | N
theme | String | radio | options:radio/button。 | N
size | String | medium | options:small/medium/large。Typescript:`SizeEnum`[see more ts definition](https://github.com/Tencent/tdesign-vue/blob/develop/src/common.ts) | N
value | String / Number / Boolean | - | `v-model` is supported。Typescript:`T` | N
defaultValue | String / Number / Boolean | - | uncontrolled property。Typescript:`T` | N
variant | String | outline | options:outline/primary-filled/default-filled | N
onChange | Function | | Typescript:`(value: T, context: { e: Event }) => void`<br/> | N
options | Array | - | Typescript:`Array<RadioOption>` `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-vue/blob/develop/src/common.ts)[see more ts definition](https://github.com/Tencent/tdesign-vue/tree/develop/src/radio/type.ts) | N
readonly | Boolean | undefined | \- | N
size | String | medium | options: small/medium/large。Typescript:`SizeEnum`[see more ts definition](https://github.com/Tencent/tdesign-vue/blob/develop/src/common.ts) | N
theme | String | radio | options: radio/button | N
value | String / Number / Boolean | - | `v-model` is supported。Typescript:`T` `type RadioValue = string \| number \| boolean`[see more ts definition](https://github.com/Tencent/tdesign-vue/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-vue/tree/develop/src/radio/type.ts) | N
variant | String | outline | options: outline/primary-filled/default-filled | N
onChange | Function | | Typescript:`(value: T, context: { e: Event; name?:string }) => void`<br/> | N

### RadioGroup Events

name | params | description
-- | -- | --
change | `(value: T, context: { e: Event })` | \-
change | `(value: T, context: { e: Event; name?:string })` | \-
24 changes: 14 additions & 10 deletions src/radio/radio.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
:: BASE_DOC ::

## API

### Radio Props

名称 | 类型 | 默认值 | 说明 | 必传
名称 | 类型 | 默认值 | 描述 | 必传
-- | -- | -- | -- | --
allowUncheck | Boolean | false | 是否允许取消选中 | N
checked | Boolean | false | 是否选中。支持语法糖 `v-model` | N
defaultChecked | Boolean | false | 是否选中。非受控属性 | N
default | String / Slot / Function | - | 单选按钮内容,同 label。TS 类型:`string \| TNode`[通用类型定义](https://github.com/Tencent/tdesign-vue/blob/develop/src/common.ts) | N
disabled | Boolean | undefined | 是否为禁用态 | N
disabled | Boolean | undefined | 是否为禁用态。如果存在父组件 RadioGroup,默认值由 RadioGroup.disabled 控制。优先级:Radio.disabled > RadioGroup.disabled > Form.disabled | N
label | String / Slot / Function | - | 主文案。TS 类型:`string \| TNode`[通用类型定义](https://github.com/Tencent/tdesign-vue/blob/develop/src/common.ts) | N
name | String | - | HTML 元素原生属性 | N
readonly | Boolean | undefined | 只读状态 | N
value | String / Number / Boolean | undefined | 单选按钮的值。TS 类型:`T` | N
onChange | Function | | TS 类型:`(checked: boolean, context: { e: Event }) => void`<br/>选中状态变化时触发 | N
onClick | Function | | TS 类型:`(context: { e: MouseEvent }) => void`<br/>点击时触发,一般用于外层阻止冒泡场景 | N
Expand All @@ -23,23 +25,25 @@ onClick | Function | | TS 类型:`(context: { e: MouseEvent }) => void`<br/>
change | `(checked: boolean, context: { e: Event })` | 选中状态变化时触发
click | `(context: { e: MouseEvent })` | 点击时触发,一般用于外层阻止冒泡场景


### RadioGroup Props

名称 | 类型 | 默认值 | 说明 | 必传
名称 | 类型 | 默认值 | 描述 | 必传
-- | -- | -- | -- | --
allowUncheck | Boolean | false | 是否允许取消选中 | N
disabled | Boolean | undefined | 是否禁用全部子单选框 | N
disabled | Boolean | undefined | 是否禁用全部子单选框。优先级:Radio.disabled > RadioGroup.disabled > Form.disabled | N
name | String | - | HTML 元素原生属性 | N
options | Array | - | 单选组件按钮形式。RadioOption 数据类型为 string 或 number 时,表示 label 和 value 值相同。TS 类型:`Array<RadioOption>` `type RadioOption = string \| number \| RadioOptionObj` `interface RadioOptionObj { label?: string \| TNode; value?: string \| number; disabled?: boolean }`[通用类型定义](https://github.com/Tencent/tdesign-vue/blob/develop/src/common.ts)[详细类型定义](https://github.com/Tencent/tdesign-vue/tree/develop/src/radio/type.ts) | N
theme | String | radio | 组件风格,可选项:radio/button。 | N
options | Array | - | 单选组件按钮形式。RadioOption 数据类型为 string 或 number 时,表示 label 和 value 值相同。TS 类型:`Array<RadioOption>` `type RadioOption = string \| number \| RadioOptionObj` `interface RadioOptionObj { label?: string \| TNode; value?: string \| number \| boolean; disabled?: boolean }`[通用类型定义](https://github.com/Tencent/tdesign-vue/blob/develop/src/common.ts)[详细类型定义](https://github.com/Tencent/tdesign-vue/tree/develop/src/radio/type.ts) | N
readonly | Boolean | undefined | 只读状态 | N
size | String | medium | 组件尺寸【讨论中】。可选项:small/medium/large。TS 类型:`SizeEnum`[通用类型定义](https://github.com/Tencent/tdesign-vue/blob/develop/src/common.ts) | N
value | String / Number / Boolean | - | 选中的值。支持语法糖 `v-model`。TS 类型:`T` | N
defaultValue | String / Number / Boolean | - | 选中的值。非受控属性。TS 类型:`T` | N
theme | String | radio | 组件风格。可选项:radio/button | N
value | String / Number / Boolean | - | 选中的值。支持语法糖 `v-model`。TS 类型:`T` `type RadioValue = string \| number \| boolean`[详细类型定义](https://github.com/Tencent/tdesign-vue/tree/develop/src/radio/type.ts) | N
defaultValue | String / Number / Boolean | - | 选中的值。非受控属性。TS 类型:`T` `type RadioValue = string \| number \| boolean`[详细类型定义](https://github.com/Tencent/tdesign-vue/tree/develop/src/radio/type.ts) | N
variant | String | outline | 单选组件按钮形式。可选项:outline/primary-filled/default-filled | N
onChange | Function | | TS 类型:`(value: T, context: { e: Event }) => void`<br/>选中值发生变化时触发 | N
onChange | Function | | TS 类型:`(value: T, context: { e: Event; name?:string }) => void`<br/>选中值发生变化时触发, `context.name` 指 RadioGroup 的 name 属性 | N

### RadioGroup Events

名称 | 参数 | 描述
-- | -- | --
change | `(value: T, context: { e: Event })` | 选中值发生变化时触发
change | `(value: T, context: { e: Event; name?:string })` | 选中值发生变化时触发, `context.name` 指 RadioGroup 的 name 属性
9 changes: 7 additions & 2 deletions src/radio/radio.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -81,13 +81,18 @@ export default mixins(Vue as VueConstructor<RadioParentInjectInstance>, classPre
return Boolean((this.formDisabled || this.disabled) ?? this.radioGroup?.disabled);
},

getReadonly() {
return Boolean(this.readonly ?? this.radioGroup?.readonly);
},

onInputClick(e: MouseEvent) {
e.stopPropagation();
},

handleRadioClick(e: MouseEvent) {
const tDisabled = this.getDisabled();
if (tDisabled) return;
const tReadonly = this.getReadonly();
if (tDisabled || tReadonly) return;
this.$emit('click', { e });
this.checkRadio(e);
},
Expand All @@ -100,7 +105,7 @@ export default mixins(Vue as VueConstructor<RadioParentInjectInstance>, classPre

if (this.radioGroup) {
const value = tChecked && allowUncheck ? undefined : this.value;
this.radioGroup.handleRadioChange(value, { e });
this.radioGroup.handleRadioChange(value, { e, name: this.radioGroup.name });
} else {
const value = allowUncheck ? !tChecked : true;
emitEvent<Parameters<TdRadioProps['onChange']>>(this, 'change', value, { e });
Expand Down
32 changes: 20 additions & 12 deletions src/radio/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export interface TdRadioProps<T = RadioValue> {
*/
default?: string | TNode;
/**
* 是否为禁用态
* 是否为禁用态。如果存在父组件 RadioGroup,默认值由 RadioGroup.disabled 控制。优先级:Radio.disabled > RadioGroup.disabled > Form.disabled
*/
disabled?: boolean;
/**
Expand All @@ -39,6 +39,10 @@ export interface TdRadioProps<T = RadioValue> {
* @default ''
*/
name?: string;
/**
* 只读状态
*/
readonly?: boolean;
/**
* 单选按钮的值
*/
Expand All @@ -60,7 +64,7 @@ export interface TdRadioGroupProps<T = RadioValue> {
*/
allowUncheck?: boolean;
/**
* 是否禁用全部子单选框
* 是否禁用全部子单选框。优先级:Radio.disabled > RadioGroup.disabled > Form.disabled
*/
disabled?: boolean;
/**
Expand All @@ -72,11 +76,20 @@ export interface TdRadioGroupProps<T = RadioValue> {
* 单选组件按钮形式。RadioOption 数据类型为 string 或 number 时,表示 label 和 value 值相同
*/
options?: Array<RadioOption>;
/**
* 只读状态
*/
readonly?: boolean;
/**
* 组件尺寸【讨论中】
* @default medium
*/
size?: SizeEnum;
/**
* 组件风格
* @default radio
*/
theme?: 'radio' | 'button';
/**
* 选中的值
*/
Expand All @@ -90,23 +103,18 @@ export interface TdRadioGroupProps<T = RadioValue> {
* @default outline
*/
variant?: 'outline' | 'primary-filled' | 'default-filled';

/**
* 组件风格
*/
theme?: 'radio' | 'button';
/**
* 选中值发生变化时触发
* 选中值发生变化时触发, `context.name` 指 RadioGroup 的 name 属性
*/
onChange?: (value: T, context: { e: Event }) => void;
onChange?: (value: T, context: { e: Event; 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;

0 comments on commit 728475e

Please sign in to comment.