Skip to content

Commit

Permalink
feat: support borderless keys
Browse files Browse the repository at this point in the history
  • Loading branch information
liweijie0812 committed Feb 13, 2025
1 parent 68639f5 commit bd58b5b
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 27 deletions.
53 changes: 37 additions & 16 deletions src/checkbox/CheckboxGroup.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { FC, ReactElement, useEffect, useMemo, useState } from 'react';
import { isNumber } from 'lodash-es';
import { isNumber, get as lodashGet } from 'lodash-es';
import classNames from 'classnames';
import { CheckboxOption, CheckboxOptionObj, TdCheckboxGroupProps } from './type';
import { StyledProps } from '../common';
Expand All @@ -17,7 +17,8 @@ export interface CheckboxGroupProps extends TdCheckboxGroupProps, StyledProps {
// 将 checkBox 的 value 转换为 string|number
const getCheckboxValue = (v: CheckboxOption): string | number => {
switch (typeof v) {
case 'number' || 'string':
case 'number':
case 'string':
return v as string | number;
case 'object': {
const vs = v as CheckboxOptionObj;
Expand All @@ -29,11 +30,22 @@ const getCheckboxValue = (v: CheckboxOption): string | number => {
};

const CheckboxGroup: FC<CheckboxGroupProps> = (props) => {
const checkboxGroulClass = usePrefixClass('checkbox-group');
const { value, defaultValue, disabled, className, max, options, name, style, children, onChange } = useDefaultProps(
props,
checkboxGroupDefaultProps,
);
const checkboxGroupClass = usePrefixClass('checkbox-group');
const {
value,
defaultValue,
disabled,
className,
max,
options,
name,
style,
children,
borderless,
readonly = false,
keys,
onChange,
} = useDefaultProps(props, checkboxGroupDefaultProps);

const internalOptions =
Array.isArray(options) && options.length > 0
Expand Down Expand Up @@ -89,6 +101,8 @@ const CheckboxGroup: FC<CheckboxGroupProps> = (props) => {
checked: checkProps.checkAll ? checkAllChecked || checkedSet.size !== 0 : checkedSet.has(checkValue),
indeterminate: checkProps.checkAll ? indeterminate : checkProps.indeterminate,
disabled: checkProps.disabled || disabled || (checkedSet.size >= localMax && !checkedSet.has(checkValue)),
borderless: checkProps.borderless || borderless,
readonly: checkProps.readonly || readonly,
onChange(checked, { e }) {
if (typeof checkProps.onChange === 'function') {
checkProps.onChange(checked, { e });
Expand Down Expand Up @@ -124,24 +138,31 @@ const CheckboxGroup: FC<CheckboxGroupProps> = (props) => {
const isOptions = Array.isArray(options) && options.length !== 0;

const checkboxNode = () =>
options.map((v, index) => {
const type = typeof v;
options.map((item, index) => {
const type = typeof item;
switch (type) {
case 'number' || 'string': {
const vs = v as number | string;
case 'number':
case 'string': {
const vs = item as number | string;
return (
<Checkbox key={vs} label={vs} value={vs}>
{v}
{item}
</Checkbox>
);
}
case 'object': {
const vs = v as CheckboxOptionObj;
const vs = item as CheckboxOptionObj;
// CheckAll 的 checkBox 不存在 value,故用 checkAll_index 来保证尽量不和用户的 value 冲突.
return vs.checkAll ? (
<Checkbox {...(v as Object)} key={`checkAll_${index}`} indeterminate={indeterminate} />
<Checkbox {...(item as Object)} key={`checkAll_${index}`} indeterminate={indeterminate} />
) : (
<Checkbox {...(v as Object)} key={vs.value.toString()} disabled={vs.disabled || disabled} />
<Checkbox
{...(item as Object)}
key={`${lodashGet(item, keys?.value ?? 'value', '')}${index}`}
label={lodashGet(item, keys?.label ?? 'label', vs.text || '')}
value={lodashGet(item, keys?.value ?? 'value')}
disabled={lodashGet(item, keys?.disabled ?? 'disabled')}
/>
);
}
default:
Expand All @@ -150,7 +171,7 @@ const CheckboxGroup: FC<CheckboxGroupProps> = (props) => {
});

return (
<div className={classNames(checkboxGroulClass, className)} style={style}>
<div className={classNames(checkboxGroupClass, className)} style={style}>
{isOptions ? (
<span>
<CheckContext.Provider value={context}>{checkboxNode()}</CheckContext.Provider>
Expand Down
7 changes: 5 additions & 2 deletions src/checkbox/checkbox.en-US.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ name | type | default | description | required
className | String | - | className of component | N
style | Object | - | CSS(Cascading Style Sheets),Typescript:`React.CSSProperties` | N
block | Boolean | true | \- | N
borderless | Boolean | false | \- | N
borderless | Boolean | undefined | \- | N
checkAll | Boolean | false | \- | N
checked | Boolean | false | \- | N
defaultChecked | Boolean | false | uncontrolled property | N
Expand All @@ -24,7 +24,7 @@ maxContentRow | Number | 5 | \- | N
maxLabelRow | Number | 3 | \- | N
name | String | - | \- | N
placement | String | left | options: left/right | N
readonly | Boolean | false | \- | N
readonly | Boolean | undefined | \- | N
value | String / Number / Boolean | - | value of checkbox。Typescript:`string \| number \| boolean` | N
onChange | Function | | Typescript:`(checked: boolean, context: { e: ChangeEvent }) => void`<br/> | N

Expand All @@ -35,10 +35,13 @@ name | type | default | description | required
-- | -- | -- | -- | --
className | String | - | className of component | N
style | Object | - | CSS(Cascading Style Sheets),Typescript:`React.CSSProperties` | N
borderless | Boolean | false | \- | N
disabled | Boolean | undefined | \- | N
keys | Object | - | Typescript:`KeysType`[see more ts definition](https://github.com/Tencent/tdesign-mobile-react/blob/develop/src/common.ts) | N
max | Number | undefined | \- | N
name | String | - | \- | N
options | Array | - | Typescript:`Array<CheckboxOption>` `type CheckboxOption = string \| number \| CheckboxOptionObj` `interface CheckboxOptionObj extends TdCheckboxProps { text?: string; }`[see more ts definition](https://github.com/Tencent/tdesign-mobile-react/tree/develop/src/checkbox/type.ts) | N
readonly | Boolean | undefined | \- | N
value | Array | [] | Typescript:`T` `type CheckboxGroupValue = Array<string \| number \| boolean>`[see more ts definition](https://github.com/Tencent/tdesign-mobile-react/tree/develop/src/checkbox/type.ts) | N
defaultValue | Array | [] | uncontrolled property。Typescript:`T` `type CheckboxGroupValue = Array<string \| number \| boolean>`[see more ts definition](https://github.com/Tencent/tdesign-mobile-react/tree/develop/src/checkbox/type.ts) | N
onChange | Function | | Typescript:`(value: T, context: CheckboxGroupChangeContext) => void`<br/>[see more ts definition](https://github.com/Tencent/tdesign-mobile-react/tree/develop/src/checkbox/type.ts)。<br/>`interface CheckboxGroupChangeContext { e: Event; current: string \| number; option: CheckboxOption \| TdCheckboxProps; type: 'check' \| 'uncheck' }`<br/> | N
9 changes: 6 additions & 3 deletions src/checkbox/checkbox.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,22 @@
className | String | - | 类名 | N
style | Object | - | 样式,TS 类型:`React.CSSProperties` | N
block | Boolean | true | 是否为块级元素 | N
borderless | Boolean | false | 是否开启无边框模式 | N
borderless | Boolean | undefined | 是否开启无边框模式 | N
checkAll | Boolean | false | 用于标识是否为「全选选项」。单独使用无效,需在 CheckboxGroup 中使用 | 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 | - | 是否禁用组件内容(content)触发选中 | N
disabled | Boolean | undefined | 是否禁用组件。如果父组件存在 CheckboxGroup,默认值由 CheckboxGroup.disabled 控制。优先级:Checkbox.disabled > CheckboxGroup.disabled > Form.disabled | N
icon | String / Boolean / Array | 'circle' | 自定义选中图标和非选中图标。使用 Array 时表示:[选中态图标,非选中态图标]。使用 String 时,值为 circle 表示填充圆形图标、值为 line 表示描边型图标、值为 rectangle 表示填充矩形图标。TS 类型:`'circle' \| 'line' \| 'rectangle' \| boolean \| Array<TNode \| String>`[通用类型定义](https://github.com/Tencent/tdesign-mobile-react/blob/develop/src/common.ts) | N
icon | String / Boolean / Array | 'circle' | 自定义选中图标和非选中图标。使用 Array 时表示:[选中态图标,非选中态图标]。使用 String 时,值为 circle 表示填充圆形图标、值为 line 表示描边型图标、值为 rectangle 表示填充矩形图标。TS 类型:`'circle' \| 'line' \| 'rectangle' \| boolean \| Array<TNode \| String>`[通用类型定义](https://github.com/Tencent/tdesign-mobile-react/blob/develop/src/common.ts) | N
indeterminate | Boolean | false | 是否为半选 | 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
placement | String | left | 多选框和内容相对位置。可选项:left/right | N
readonly | Boolean | false | 只读状态 | N
readonly | Boolean | undefined | 只读状态 | N
value | String / Number / Boolean | - | 多选框的值。TS 类型:`string \| number \| boolean` | N
onChange | Function | | TS 类型:`(checked: boolean, context: { e: ChangeEvent }) => void`<br/>值变化时触发 | N

Expand All @@ -35,10 +35,13 @@ onChange | Function | | TS 类型:`(checked: boolean, context: { e: ChangeEve
-- | -- | -- | -- | --
className | String | - | 类名 | N
style | Object | - | 样式,TS 类型:`React.CSSProperties` | N
borderless | Boolean | false | 是否开启无边框模式。优先级低于 Checkbox.borderless | N
disabled | Boolean | undefined | 是否禁用组件。优先级:Form.disabled < CheckboxGroup.disabled < Checkbox.disabled | N
keys | Object | - | 用来定义 value / label / disabled 在 `options` 中对应的字段别名。TS 类型:`KeysType`[通用类型定义](https://github.com/Tencent/tdesign-mobile-react/blob/develop/src/common.ts) | N
max | Number | undefined | 支持最多选中的数量 | N
name | String | - | 统一设置内部复选框 HTML 属性 | N
options | Array | - | 以配置形式设置子元素。示例1:`['北京', '上海']` ,示例2: `[{ label: '全选', checkAll: true }, { label: '上海', value: 'shanghai' }]`。checkAll 值为 true 表示当前选项为「全选选项」。TS 类型:`Array<CheckboxOption>` `type CheckboxOption = string \| number \| CheckboxOptionObj` `interface CheckboxOptionObj extends TdCheckboxProps { text?: string; }`[详细类型定义](https://github.com/Tencent/tdesign-mobile-react/tree/develop/src/checkbox/type.ts) | N
readonly | Boolean | undefined | 只读状态 | N
value | Array | [] | 选中值。TS 类型:`T` `type CheckboxGroupValue = Array<string \| number \| boolean>`[详细类型定义](https://github.com/Tencent/tdesign-mobile-react/tree/develop/src/checkbox/type.ts) | N
defaultValue | Array | [] | 选中值。非受控属性。TS 类型:`T` `type CheckboxGroupValue = Array<string \| number \| boolean>`[详细类型定义](https://github.com/Tencent/tdesign-mobile-react/tree/develop/src/checkbox/type.ts) | N
onChange | Function | | TS 类型:`(value: T, context: CheckboxGroupChangeContext) => void`<br/>值变化时触发。`context.current` 表示当前变化的数据项,如果是全选则为空;`context.type` 表示引起选中数据变化的是选中或是取消选中,`context.option` 表示当前变化的数据项。[详细类型定义](https://github.com/Tencent/tdesign-mobile-react/tree/develop/src/checkbox/type.ts)。<br/>`interface CheckboxGroupChangeContext { e: Event; current: string \| number; option: CheckboxOption \| TdCheckboxProps; type: 'check' \| 'uncheck' }`<br/> | N
6 changes: 4 additions & 2 deletions src/checkbox/defaultProps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { TdCheckboxProps, TdCheckboxGroupProps } from './type';

export const checkboxDefaultProps: TdCheckboxProps = {
block: true,
borderless: false,
borderless: undefined,
checkAll: false,
defaultChecked: false,
disabled: undefined,
Expand All @@ -15,11 +15,13 @@ export const checkboxDefaultProps: TdCheckboxProps = {
maxContentRow: 5,
maxLabelRow: 3,
placement: 'left',
readonly: false,
readonly: undefined,
};

export const checkboxGroupDefaultProps: TdCheckboxGroupProps = {
borderless: false,
disabled: undefined,
max: undefined,
readonly: undefined,
defaultValue: [],
};
19 changes: 15 additions & 4 deletions src/checkbox/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* 该文件为脚本自动生成文件,请勿随意修改。如需修改请联系 PMC
* */

import { TNode } from '../common';
import { TNode, KeysType } from '../common';
import { ChangeEvent } from 'react';

export interface TdCheckboxProps {
Expand All @@ -15,7 +15,6 @@ export interface TdCheckboxProps {
block?: boolean;
/**
* 是否开启无边框模式
* @default false
*/
borderless?: boolean;
/**
Expand Down Expand Up @@ -50,7 +49,7 @@ export interface TdCheckboxProps {
*/
disabled?: boolean;
/**
* 自定义选中图标和非选中图标。使用 Array 时表示:[选中态图标,非选中态图标]。使用 String 时,值为 circle 表示填充圆形图标、值为 line 表示描边型图标、值为 rectangle 表示填充矩形图标
* 自定义选中图标和非选中图标。使用 Array 时表示:[选中态图标,非选中态图标]。使用 String 时,值为 circle 表示填充圆形图标、值为 line 表示描边型图标、值为 rectangle 表示填充矩形图标
* @default 'circle'
*/
icon?: 'circle' | 'line' | 'rectangle' | boolean | Array<TNode | String>;
Expand Down Expand Up @@ -85,7 +84,6 @@ export interface TdCheckboxProps {
placement?: 'left' | 'right';
/**
* 只读状态
* @default false
*/
readonly?: boolean;
/**
Expand All @@ -99,10 +97,19 @@ export interface TdCheckboxProps {
}

export interface TdCheckboxGroupProps<T = CheckboxGroupValue> {
/**
* 是否开启无边框模式。优先级低于 Checkbox.borderless
* @default false
*/
borderless?: boolean;
/**
* 是否禁用组件。优先级:Form.disabled < CheckboxGroup.disabled < Checkbox.disabled
*/
disabled?: boolean;
/**
* 用来定义 value / label / disabled 在 `options` 中对应的字段别名
*/
keys?: KeysType;
/**
* 支持最多选中的数量
*/
Expand All @@ -116,6 +123,10 @@ export interface TdCheckboxGroupProps<T = CheckboxGroupValue> {
* 以配置形式设置子元素。示例1:`['北京', '上海']` ,示例2: `[{ label: '全选', checkAll: true }, { label: '上海', value: 'shanghai' }]`。checkAll 值为 true 表示当前选项为「全选选项」
*/
options?: Array<CheckboxOption>;
/**
* 只读状态
*/
readonly?: boolean;
/**
* 选中值
* @default []
Expand Down

0 comments on commit bd58b5b

Please sign in to comment.