Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support borderless keys #572

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 {...vs} key={`checkAll_${index}`} indeterminate={indeterminate} />
) : (
<Checkbox {...(v as Object)} key={vs.value.toString()} disabled={vs.disabled || disabled} />
<Checkbox
{...vs}
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