From 9b84ed944c10f6e77c792f17826f8ce2b32b3ea5 Mon Sep 17 00:00:00 2001 From: byq1213 Date: Tue, 3 Sep 2024 20:37:12 +0800 Subject: [PATCH] feat(checkbox): rebuild checkbox & demo fix #459 --- site/mobile/mobile.config.js | 2 +- src/_common | 2 +- src/checkbox-group/checkbox-group.en-US.md | 18 ++ src/checkbox-group/checkbox-group.md | 18 ++ src/checkbox/Checkbox.tsx | 216 ++++++++++++--------- src/checkbox/CheckboxGroup.tsx | 78 +++----- src/checkbox/_example/all.tsx | 20 ++ src/checkbox/_example/base.jsx | 23 --- src/checkbox/_example/base.tsx | 25 +++ src/checkbox/_example/card.tsx | 20 ++ src/checkbox/_example/disable.jsx | 14 -- src/checkbox/_example/group.jsx | 35 ---- src/checkbox/_example/horizontal.tsx | 12 ++ src/checkbox/_example/icon.jsx | 27 --- src/checkbox/_example/indeterminate.jsx | 10 - src/checkbox/_example/index.jsx | 54 ------ src/checkbox/_example/index.tsx | 44 +++++ src/checkbox/_example/max.jsx | 14 -- src/checkbox/_example/right.jsx | 18 -- src/checkbox/_example/right.tsx | 12 ++ src/checkbox/_example/special.tsx | 43 ++++ src/checkbox/_example/status.tsx | 11 ++ src/checkbox/_example/style/index.less | 68 ++++++- src/checkbox/_example/type.tsx | 16 ++ src/checkbox/checkbox.en-US.md | 46 +++++ src/checkbox/checkbox.md | 34 ++-- src/checkbox/defaultProps.ts | 26 +++ src/checkbox/style/index.js | 7 +- src/checkbox/type.ts | 64 ++++-- 29 files changed, 596 insertions(+), 381 deletions(-) create mode 100644 src/checkbox-group/checkbox-group.en-US.md create mode 100644 src/checkbox-group/checkbox-group.md create mode 100644 src/checkbox/_example/all.tsx delete mode 100644 src/checkbox/_example/base.jsx create mode 100644 src/checkbox/_example/base.tsx create mode 100644 src/checkbox/_example/card.tsx delete mode 100644 src/checkbox/_example/disable.jsx delete mode 100644 src/checkbox/_example/group.jsx create mode 100644 src/checkbox/_example/horizontal.tsx delete mode 100644 src/checkbox/_example/icon.jsx delete mode 100644 src/checkbox/_example/indeterminate.jsx delete mode 100644 src/checkbox/_example/index.jsx create mode 100644 src/checkbox/_example/index.tsx delete mode 100644 src/checkbox/_example/max.jsx delete mode 100644 src/checkbox/_example/right.jsx create mode 100644 src/checkbox/_example/right.tsx create mode 100644 src/checkbox/_example/special.tsx create mode 100644 src/checkbox/_example/status.tsx create mode 100644 src/checkbox/_example/type.tsx create mode 100644 src/checkbox/checkbox.en-US.md create mode 100644 src/checkbox/defaultProps.ts diff --git a/site/mobile/mobile.config.js b/site/mobile/mobile.config.js index a915f7dba..5528e98a6 100644 --- a/site/mobile/mobile.config.js +++ b/site/mobile/mobile.config.js @@ -120,7 +120,7 @@ export default { { title: 'Checkbox 多选框', name: 'checkbox', - component: () => import('tdesign-mobile-react/checkbox/_example/index.jsx'), + component: () => import('tdesign-mobile-react/checkbox/_example/index.tsx'), }, { title: 'Dialog 对话框', diff --git a/src/_common b/src/_common index d42b7fc27..861831492 160000 --- a/src/_common +++ b/src/_common @@ -1 +1 @@ -Subproject commit d42b7fc27b4e38a45ba28ff2ad50af060d8dd936 +Subproject commit 861831492f376cc85ed698e0d6ce98c28630c531 diff --git a/src/checkbox-group/checkbox-group.en-US.md b/src/checkbox-group/checkbox-group.en-US.md new file mode 100644 index 000000000..7df7a0a36 --- /dev/null +++ b/src/checkbox-group/checkbox-group.en-US.md @@ -0,0 +1,18 @@ +:: BASE_DOC :: + +## API + +### CheckboxGroup Props + +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 +max | Number | undefined | \- | N +name | String | - | \- | N +options | Array | - | Typescript:`Array` `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 +value | Array | [] | Typescript:`T` `type CheckboxGroupValue = Array`。[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`。[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`
[see more ts definition](https://github.com/Tencent/tdesign-mobile-react/tree/develop/src/checkbox/type.ts)。
`interface CheckboxGroupChangeContext { e: ChangeEvent; current: CheckboxOption \| TdCheckboxProps; option: CheckboxOption \| TdCheckboxProps; type: 'check' \| 'uncheck' }`
| N diff --git a/src/checkbox-group/checkbox-group.md b/src/checkbox-group/checkbox-group.md new file mode 100644 index 000000000..b228cd70c --- /dev/null +++ b/src/checkbox-group/checkbox-group.md @@ -0,0 +1,18 @@ +:: BASE_DOC :: + +## API + +### CheckboxGroup Props + +名称 | 类型 | 默认值 | 描述 | 必传 +-- | -- | -- | -- | -- +className | String | - | 类名 | N +style | Object | - | 样式,TS 类型:`React.CSSProperties` | N +borderless | Boolean | false | 是否开启无边框模式 | N +disabled | Boolean | undefined | 是否禁用组件。优先级:Form.disabled < CheckboxGroup.disabled < Checkbox.disabled | N +max | Number | undefined | 支持最多选中的数量 | N +name | String | - | 统一设置内部复选框 HTML 属性 | N +options | Array | - | 以配置形式设置子元素。示例1:`['北京', '上海']` ,示例2: `[{ label: '全选', checkAll: true }, { label: '上海', value: 'shanghai' }]`。checkAll 值为 true 表示当前选项为「全选选项」。TS 类型:`Array` `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 +value | Array | [] | 选中值。TS 类型:`T` `type CheckboxGroupValue = Array`。[详细类型定义](https://github.com/Tencent/tdesign-mobile-react/tree/develop/src/checkbox/type.ts) | N +defaultValue | Array | [] | 选中值。非受控属性。TS 类型:`T` `type CheckboxGroupValue = Array`。[详细类型定义](https://github.com/Tencent/tdesign-mobile-react/tree/develop/src/checkbox/type.ts) | N +onChange | Function | | TS 类型:`(value: T, context: CheckboxGroupChangeContext) => void`
值变化时触发,`context.current` 表示当前变化的数据值,如果是全选则为空;`context.type` 表示引起选中数据变化的是选中或是取消选中;`context.option` 表示当前变化的数据项;`context.current` 即将废弃,请勿使用。[详细类型定义](https://github.com/Tencent/tdesign-mobile-react/tree/develop/src/checkbox/type.ts)。
`interface CheckboxGroupChangeContext { e: ChangeEvent; current: CheckboxOption \| TdCheckboxProps; option: CheckboxOption \| TdCheckboxProps; type: 'check' \| 'uncheck' }`
| N diff --git a/src/checkbox/Checkbox.tsx b/src/checkbox/Checkbox.tsx index 7fe7eb1b8..641d567a3 100644 --- a/src/checkbox/Checkbox.tsx +++ b/src/checkbox/Checkbox.tsx @@ -1,11 +1,13 @@ -import React, { useContext, useMemo, Ref, forwardRef, CSSProperties } from 'react'; +import React, { useContext, Ref, forwardRef } from 'react'; import classNames from 'classnames'; import { Icon } from 'tdesign-icons-react'; +import useDefaultProps from 'tdesign-mobile-react/hooks/useDefaultProps'; import { TdCheckboxProps } from './type'; import forwardRefWithStatics from '../_util/forwardRefWithStatics'; import CheckboxGroup from './CheckboxGroup'; import useConfig from '../_util/useConfig'; import useDefault from '../_util/useDefault'; +import { checkboxDefaultProps } from './defaultProps'; export interface CheckBoxProps extends TdCheckboxProps { ref: Ref; @@ -17,125 +19,147 @@ export interface CheckContextValue { export const CheckContext = React.createContext(null); -const getLimitRowStyle = (row: number): CSSProperties => ({ - display: '-webkit-box', - overflow: 'hidden', - WebkitBoxOrient: 'vertical', - WebkitLineClamp: row, -}); - -const Checkbox = forwardRef((_props: CheckBoxProps, ref: Ref) => { +const Checkbox = forwardRef((_props: CheckBoxProps) => { const context = useContext(CheckContext); const props = context ? context.inject(_props) : _props; - const { classPrefix } = useConfig(); + const { classPrefix: prefix } = useConfig(); const { name, - align = 'left', + placement, content, - children, disabled, indeterminate, label, onChange, checked, - defaultChecked = false, - readonly, - value, - maxLabelRow = 3, - maxContentRow = 5, + defaultChecked, + maxLabelRow, + maxContentRow, icon, - contentDisabled = false, - // borderless = false, - } = props; - const [internalChecked, setInternalChecked] = useDefault(checked, defaultChecked, onChange); - - const checkboxClassName = classNames(`${classPrefix}-checkbox`, { - [`${classPrefix}-is-checked`]: internalChecked || indeterminate, - [`${classPrefix}-is-disabled`]: disabled, + block, + borderless, + } = useDefaultProps(props, checkboxDefaultProps); + const [internalChecked, setInternalChecked] = useDefault(checked, defaultChecked, onChange); + + const classPrefix = `${prefix}-checkbox`; + + const checkboxClassName = classNames(`${classPrefix}`, { + [`${classPrefix}--checked`]: internalChecked, + [`${classPrefix}--block`]: block, + [`${classPrefix}--${placement}`]: true, }); - const iconName = useMemo(() => { - if (indeterminate) { - return 'minus-circle-filled'; - } - if (internalChecked) { - return 'check-circle-filled'; + + const isIconArray = Array.isArray(icon); + const defaultCheckIcons = [, ]; + const checkIcons = () => { + if (isIconArray && icon.length > 1) { + return icon.map((icon) => + typeof icon === 'string' ? : icon, + ); } - return 'circle'; - }, [indeterminate, internalChecked]); + return defaultCheckIcons; + }; + + const checkedIcon = () => { + if (icon === 'circle' || props.icon === true) return indeterminate ? 'minus-circle-filled' : 'check-circle-filled'; + if (icon === 'rectangle') return indeterminate ? 'minus-rectangle-filled' : 'check-rectangle-filled'; + if (icon === 'line') return indeterminate ? 'minus' : 'check'; + }; + const renderIcon = () => { - if (Array.isArray(icon)) { + if (!icon) { + return null; + } + const renderIconCircle = () => { + const iconCircleClass = `${classPrefix}__icon-circle`; + const iconStringClass = `${classPrefix}__icon-${icon}`; + const iconDisabledClass = `${classPrefix}__icon-${icon}--disabled`; + + return ( +
+ ); + }; + + const renderCheckedIcon = () => ; + + const renderLinePlaceholder = () =>
; + + const renderIcon = () => { + if (Array.isArray(icon)) { + return checkIcons()[internalChecked ? 0 : 1]; + } + if (internalChecked) { - return icon[0]; + return renderCheckedIcon(); } - return icon[1]; - } + + if (icon === 'circle' || icon === true || icon === 'rectangle') { + return renderIconCircle(); + } + + if (icon === 'line') { + return renderLinePlaceholder(); + } + + return null; + }; return ( - + > + {renderIcon()} +
); }; - const labelStyle: CSSProperties = { - color: disabled ? '#dcdcdc' : 'inherit', - ...getLimitRowStyle(maxLabelRow), - }; - const handleClick = (e) => { - if (contentDisabled) { - e.preventDefault(); + const handleChange = (e: React.MouseEvent) => { + if (disabled) { + return; } - - setInternalChecked(!internalChecked, { e }) + setInternalChecked(!internalChecked, { e }); + e.stopPropagation(); }; + const renderCheckBoxContent = () => ( +
{ + event.stopPropagation(); + handleChange(event); + }} + > +
+ {label} +
+
+ {content} +
+
+ ); return ( <> -
-
- { align ==='left' && - e.stopPropagation()} - onChange={(e) => setInternalChecked(e.currentTarget.checked, { e })} - /> - {renderIcon()} - } - - - {label} - - - {children || content} - - - - { align ==='right' && - e.stopPropagation()} - onChange={(e) => setInternalChecked(e.currentTarget.checked, { e })} - /> - {renderIcon()} - } -
- {/* 下边框 */} - {/* { !borderless &&
} */} - {
} +
+ {renderIcon()} + {renderCheckBoxContent()} + {!borderless &&
}
); diff --git a/src/checkbox/CheckboxGroup.tsx b/src/checkbox/CheckboxGroup.tsx index 3af972d82..072a6386e 100644 --- a/src/checkbox/CheckboxGroup.tsx +++ b/src/checkbox/CheckboxGroup.tsx @@ -27,18 +27,7 @@ const getCheckboxValue = (v: CheckboxOption): string | number => { export function CheckboxGroup(props: CheckboxGroupProps) { const { classPrefix } = useConfig(); - const { - value, - defaultValue, - disabled, - className, - max, - options = [], - name, - style, - children, - onChange, - } = props; + const { value, defaultValue, disabled, className, max, options = [], name, style, children, onChange } = props; const internalOptions = Array.isArray(options) && options.length > 0 @@ -116,8 +105,8 @@ export function CheckboxGroup(props: CheckboxGroupProps) { setInternalValue(Array.from(checkedSet), { e, - current: checkProps.checkAll ? undefined : (checkValue as TdCheckboxProps), - type: checked ? 'check' : 'uncheck' + current: checkProps.checkAll ? undefined : (checkValue as TdCheckboxProps), + type: checked ? 'check' : 'uncheck', }); }, }; @@ -126,42 +115,37 @@ export function CheckboxGroup(props: CheckboxGroupProps) { // options 和 children 的抉择,在未明确说明时,暂时以 options 优先 const useOptions = Array.isArray(options) && options.length !== 0; - return (
-
-
- - {useOptions - ? options.map((v, index) => { - const type = typeof v; - switch (type) { - case 'number' || 'string': { - const vs = v as number | string; - return ( - - {v} - - ); - } - case 'object': { - const vs = v as CheckboxOptionObj; - // CheckAll 的 checkBox 不存在 value,故用 checkAll_index 来保证尽量不和用户的 value 冲突. - return vs.checkAll ? ( - - ) : ( - - ); - } - default: - return null; + + {useOptions + ? options.map((v, index) => { + const type = typeof v; + switch (type) { + case 'number' || 'string': { + const vs = v as number | string; + return ( + + {v} + + ); + } + case 'object': { + const vs = v as CheckboxOptionObj; + // CheckAll 的 checkBox 不存在 value,故用 checkAll_index 来保证尽量不和用户的 value 冲突. + return vs.checkAll ? ( + + ) : ( + + ); } - }) - : children} - -
-
+ default: + return null; + } + }) + : children} +
- ) + ); } export default CheckboxGroup; diff --git a/src/checkbox/_example/all.tsx b/src/checkbox/_example/all.tsx new file mode 100644 index 000000000..411b9719f --- /dev/null +++ b/src/checkbox/_example/all.tsx @@ -0,0 +1,20 @@ +import React from 'react'; +import { Checkbox } from 'tdesign-mobile-react'; + +export default function () { + return ( + + ); +} diff --git a/src/checkbox/_example/base.jsx b/src/checkbox/_example/base.jsx deleted file mode 100644 index 1be2b36d6..000000000 --- a/src/checkbox/_example/base.jsx +++ /dev/null @@ -1,23 +0,0 @@ -import React from 'react'; -import { Checkbox } from 'tdesign-mobile-react'; - -export default function () { - return ( - - - - - - - - ); -} diff --git a/src/checkbox/_example/base.tsx b/src/checkbox/_example/base.tsx new file mode 100644 index 000000000..b81e0e8c8 --- /dev/null +++ b/src/checkbox/_example/base.tsx @@ -0,0 +1,25 @@ +import React from 'react'; +import { Checkbox } from 'tdesign-mobile-react'; + +export default function () { + return ( + + ); +} diff --git a/src/checkbox/_example/card.tsx b/src/checkbox/_example/card.tsx new file mode 100644 index 000000000..2d0f337f3 --- /dev/null +++ b/src/checkbox/_example/card.tsx @@ -0,0 +1,20 @@ +import React from 'react'; +import { Checkbox } from 'tdesign-mobile-react'; + +export default function () { + return ( + + ); +} diff --git a/src/checkbox/_example/disable.jsx b/src/checkbox/_example/disable.jsx deleted file mode 100644 index 9d1427a51..000000000 --- a/src/checkbox/_example/disable.jsx +++ /dev/null @@ -1,14 +0,0 @@ -import React from 'react'; -import { Checkbox } from 'tdesign-mobile-react'; - -export default function () { - return ( - <> - - - - - - - ); -} diff --git a/src/checkbox/_example/group.jsx b/src/checkbox/_example/group.jsx deleted file mode 100644 index 820629a51..000000000 --- a/src/checkbox/_example/group.jsx +++ /dev/null @@ -1,35 +0,0 @@ -import React, { useState } from 'react'; -import { Checkbox } from 'tdesign-mobile-react'; - -export default function CheckboxExample() { - const [value, setValue] = useState(['1', '2']); - const options = [ - { - label: '全选', - checkAll: true, - }, - { - label: '多选1', - value: '1', - }, - { - label: '多选2', - value: '2', - }, - { - label: '多选3', - value: '3', - }, - ]; - return ( - <> - { - setValue(v); - }} - options={options} - /> - - ); -} diff --git a/src/checkbox/_example/horizontal.tsx b/src/checkbox/_example/horizontal.tsx new file mode 100644 index 000000000..4d1e36a83 --- /dev/null +++ b/src/checkbox/_example/horizontal.tsx @@ -0,0 +1,12 @@ +import React from 'react'; +import { Checkbox } from 'tdesign-mobile-react'; + +export default function () { + return ( + + + + + + ); +} diff --git a/src/checkbox/_example/icon.jsx b/src/checkbox/_example/icon.jsx deleted file mode 100644 index b1460e674..000000000 --- a/src/checkbox/_example/icon.jsx +++ /dev/null @@ -1,27 +0,0 @@ -import React from 'react'; -import { Icon } from 'tdesign-icons-react'; -import { Checkbox } from 'tdesign-mobile-react'; - -export default function () { - return ( - <> - , ]} - /> - , ]} - /> - , ]} - /> - - ); -} diff --git a/src/checkbox/_example/indeterminate.jsx b/src/checkbox/_example/indeterminate.jsx deleted file mode 100644 index 93ead4e13..000000000 --- a/src/checkbox/_example/indeterminate.jsx +++ /dev/null @@ -1,10 +0,0 @@ -import React from 'react'; -import { Checkbox } from 'tdesign-mobile-react'; - -export default function () { - return ( - <> - - - ); -} diff --git a/src/checkbox/_example/index.jsx b/src/checkbox/_example/index.jsx deleted file mode 100644 index 7447d8a96..000000000 --- a/src/checkbox/_example/index.jsx +++ /dev/null @@ -1,54 +0,0 @@ -import React from 'react'; -import './style/index.less'; -import TDemoBlock from '../../../site/mobile/components/DemoBlock'; -import TDemoHeader from '../../../site/mobile/components/DemoHeader'; -import Base from './base'; -import Right from './right'; -import Disable from './disable'; -import Group from './group'; -import Max from './max'; -import Icon from './icon'; - -export default function CheckboxDemo() { - return ( -
- - - -
- -
-
- - -
- -
-
- - -
- -
-
- - -
- -
-
- - -
- -
-
- - -
- -
-
-
- ); -} diff --git a/src/checkbox/_example/index.tsx b/src/checkbox/_example/index.tsx new file mode 100644 index 000000000..5515d6842 --- /dev/null +++ b/src/checkbox/_example/index.tsx @@ -0,0 +1,44 @@ +import React from 'react'; +import './style/index.less'; +import TDemoBlock from '../../../site/mobile/components/DemoBlock'; +import TDemoHeader from '../../../site/mobile/components/DemoHeader'; +import BaseDemo from './base'; +import HorizontalDemo from './horizontal'; +import AllDemo from './all'; +import RightDemo from './right'; +import StatusDemo from './status'; +import TypeDemo from './type'; +import SpecialDemo from './special'; +import CardDemo from './card'; + +export default function CheckboxDemo() { + return ( + <> + + + + + + + + + + + + + + + + + + + + + + + + + + + ); +} diff --git a/src/checkbox/_example/max.jsx b/src/checkbox/_example/max.jsx deleted file mode 100644 index 5bcdc270f..000000000 --- a/src/checkbox/_example/max.jsx +++ /dev/null @@ -1,14 +0,0 @@ -import React from 'react'; -import { Checkbox } from 'tdesign-mobile-react'; - -export default function () { - return ( - <> - - - - - - - ); -} diff --git a/src/checkbox/_example/right.jsx b/src/checkbox/_example/right.jsx deleted file mode 100644 index 013074abc..000000000 --- a/src/checkbox/_example/right.jsx +++ /dev/null @@ -1,18 +0,0 @@ -import React from 'react'; -import { Checkbox } from 'tdesign-mobile-react'; - -export default function () { - return ( - - - - - - - ); -} diff --git a/src/checkbox/_example/right.tsx b/src/checkbox/_example/right.tsx new file mode 100644 index 000000000..11a4f901d --- /dev/null +++ b/src/checkbox/_example/right.tsx @@ -0,0 +1,12 @@ +import React from 'react'; +import { Checkbox } from 'tdesign-mobile-react'; + +export default function () { + return ( + <> + +
+ + + ); +} diff --git a/src/checkbox/_example/special.tsx b/src/checkbox/_example/special.tsx new file mode 100644 index 000000000..c42339440 --- /dev/null +++ b/src/checkbox/_example/special.tsx @@ -0,0 +1,43 @@ +import React, { useState } from 'react'; +import { Checkbox } from 'tdesign-mobile-react'; +import { Icon } from 'tdesign-icons-react'; + +export default function () { + const [defaultValue, setDefaultValue] = useState([0, 1]); + const [defaultValue1, setDefaultValue1] = useState([0, 1]); + return ( + <> + setDefaultValue(e)}> + {Array.from(Array(3)).map((_, key) => ( +
+ {defaultValue.includes(key) && } + +
+ ))} +
+ +
+ 横向卡片多选框 +
+ + setDefaultValue1(e)} + > + {Array.from(Array(3)).map((_, key) => ( +
+ {defaultValue1.includes(key) && } + +
+ ))} +
+ + ); +} diff --git a/src/checkbox/_example/status.tsx b/src/checkbox/_example/status.tsx new file mode 100644 index 000000000..5bda0258c --- /dev/null +++ b/src/checkbox/_example/status.tsx @@ -0,0 +1,11 @@ +import React from 'react'; +import { Checkbox } from 'tdesign-mobile-react'; + +export default function () { + return ( + + + + + ); +} diff --git a/src/checkbox/_example/style/index.less b/src/checkbox/_example/style/index.less index a9736a8b2..bfdd28bb8 100644 --- a/src/checkbox/_example/style/index.less +++ b/src/checkbox/_example/style/index.less @@ -1,3 +1,67 @@ -.checkbox-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: 0 16px; + overflow: hidden; +} + +.card { + position: relative; + margin: 16px; + border-radius: 6px; + overflow: hidden; + box-sizing: border-box; + border: 1.5px solid var(--bg-color-demo, #fff); +} +.card--active { + border-color: #0052d9; +} +.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; +} +.card__icon { + 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; +} + +.horizontal-box .card::after { + border-width: 12px; +} + +.horizontal-box .card__icon { + font-size: 12px; +} \ No newline at end of file diff --git a/src/checkbox/_example/type.tsx b/src/checkbox/_example/type.tsx new file mode 100644 index 000000000..cd7607af1 --- /dev/null +++ b/src/checkbox/_example/type.tsx @@ -0,0 +1,16 @@ +import React from 'react'; +import { Checkbox } from 'tdesign-mobile-react'; + +export default function () { + const activeImage = 'https://tdesign.gtimg.com/mobile/demos/checkbox-checked.png'; + const inActiveImage = 'https://tdesign.gtimg.com/mobile/demos/checkbox.png'; + return ( + <> + +
+ +
+ + + ); +} diff --git a/src/checkbox/checkbox.en-US.md b/src/checkbox/checkbox.en-US.md new file mode 100644 index 000000000..33f15325b --- /dev/null +++ b/src/checkbox/checkbox.en-US.md @@ -0,0 +1,46 @@ +:: BASE_DOC :: + +## API + +### Checkbox Props + +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 +checkAll | Boolean | false | \- | 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 | - | \- | N +disabled | Boolean | undefined | \- | N +icon | String / Boolean / Array | 'circle' | Typescript:`'circle' \| 'line' \| 'rectangle' \| boolean \| Array`。[see more ts definition](https://github.com/Tencent/tdesign-mobile-react/blob/develop/src/common.ts) | N +indeterminate | Boolean | false | \- | 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 +title | String | - | html attribute | N +value | String / Number / Boolean | - | value of checkbox。Typescript:`string \| number \| boolean` | N +onChange | Function | | Typescript:`(checked: boolean, context: { e: ChangeEvent }) => void`
| N + + +### CheckboxGroup Props + +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 +max | Number | undefined | \- | N +name | String | - | \- | N +options | Array | - | Typescript:`Array` `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 +value | Array | [] | Typescript:`T` `type CheckboxGroupValue = Array`。[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`。[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`
[see more ts definition](https://github.com/Tencent/tdesign-mobile-react/tree/develop/src/checkbox/type.ts)。
`interface CheckboxGroupChangeContext { e: ChangeEvent; current: CheckboxOption \| TdCheckboxProps; option: CheckboxOption \| TdCheckboxProps; type: 'check' \| 'uncheck' }`
| N diff --git a/src/checkbox/checkbox.md b/src/checkbox/checkbox.md index 975161552..47fb2702f 100644 --- a/src/checkbox/checkbox.md +++ b/src/checkbox/checkbox.md @@ -1,40 +1,46 @@ :: BASE_DOC :: ## API + ### Checkbox Props -名称 | 类型 | 默认值 | 说明 | 必传 +名称 | 类型 | 默认值 | 描述 | 必传 -- | -- | -- | -- | -- className | String | - | 类名 | N style | Object | - | 样式,TS 类型:`React.CSSProperties` | N -align | String | left | 多选框和内容相对位置。可选项:left/right | N +block | Boolean | true | 是否为块级元素 | N +borderless | Boolean | false | 是否开启无边框模式 | 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 +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 +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`。[通用类型定义](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 +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 -value | String / Number | - | 多选框的值。TS 类型:`string | number` | N +title | String | - | HTML 原生属性 | N +value | String / Number / Boolean | - | 多选框的值。TS 类型:`string \| number \| boolean` | N onChange | Function | | TS 类型:`(checked: boolean, context: { e: ChangeEvent }) => void`
值变化时触发 | N + ### CheckboxGroup Props -名称 | 类型 | 默认值 | 说明 | 必传 +名称 | 类型 | 默认值 | 描述 | 必传 -- | -- | -- | -- | -- className | String | - | 类名 | N style | Object | - | 样式,TS 类型:`React.CSSProperties` | N -disabled | Boolean | false | 是否禁用组件 | N +borderless | Boolean | false | 是否开启无边框模式 | N +disabled | Boolean | undefined | 是否禁用组件。优先级:Form.disabled < CheckboxGroup.disabled < Checkbox.disabled | N max | Number | undefined | 支持最多选中的数量 | N name | String | - | 统一设置内部复选框 HTML 属性 | N -options | Array | [] | 以配置形式设置子元素。示例1:`['北京', '上海']` ,示例2: `[{ label: '全选', checkAll: true }, { label: '上海', value: 'shanghai' }]`。checkAll 值为 true 表示当前选项为「全选选项」。TS 类型:`Array` `type CheckboxOption = string | number | CheckboxOptionObj` `interface CheckboxOptionObj { label?: string | TNode; value?: string | number; disabled?: boolean; name?: string; checkAll?: true }`。[通用类型定义](https://github.com/Tencent/tdesign-mobile-react/blob/develop/src/common.ts)。[详细类型定义](https://github.com/Tencent/tdesign-mobile-react/tree/develop/src/checkbox/type.ts) | N -value | Array | [] | 选中值。TS 类型:`CheckboxGroupValue` `type CheckboxGroupValue = Array`。[详细类型定义](https://github.com/Tencent/tdesign-mobile-react/tree/develop/src/checkbox/type.ts) | N -defaultValue | Array | [] | 选中值。非受控属性。TS 类型:`CheckboxGroupValue` `type CheckboxGroupValue = Array`。[详细类型定义](https://github.com/Tencent/tdesign-mobile-react/tree/develop/src/checkbox/type.ts) | N -onChange | Function | | TS 类型:`(value: CheckboxGroupValue, context: CheckboxGroupChangeContext) => void`
值变化时触发,`context.current` 表示当前变化的数据项,如果是全选则为空;`context.type` 表示引起选中数据变化的是选中或是取消选中。[详细类型定义](https://github.com/Tencent/tdesign-mobile-react/tree/develop/src/checkbox/type.ts)。
`interface CheckboxGroupChangeContext { e: ChangeEvent; current: CheckboxOption | TdCheckboxProps; type: 'check' | 'uncheck' }`
| N +options | Array | - | 以配置形式设置子元素。示例1:`['北京', '上海']` ,示例2: `[{ label: '全选', checkAll: true }, { label: '上海', value: 'shanghai' }]`。checkAll 值为 true 表示当前选项为「全选选项」。TS 类型:`Array` `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 +value | Array | [] | 选中值。TS 类型:`T` `type CheckboxGroupValue = Array`。[详细类型定义](https://github.com/Tencent/tdesign-mobile-react/tree/develop/src/checkbox/type.ts) | N +defaultValue | Array | [] | 选中值。非受控属性。TS 类型:`T` `type CheckboxGroupValue = Array`。[详细类型定义](https://github.com/Tencent/tdesign-mobile-react/tree/develop/src/checkbox/type.ts) | N +onChange | Function | | TS 类型:`(value: T, context: CheckboxGroupChangeContext) => void`
值变化时触发,`context.current` 表示当前变化的数据值,如果是全选则为空;`context.type` 表示引起选中数据变化的是选中或是取消选中;`context.option` 表示当前变化的数据项;`context.current` 即将废弃,请勿使用。[详细类型定义](https://github.com/Tencent/tdesign-mobile-react/tree/develop/src/checkbox/type.ts)。
`interface CheckboxGroupChangeContext { e: ChangeEvent; current: CheckboxOption \| TdCheckboxProps; option: CheckboxOption \| TdCheckboxProps; type: 'check' \| 'uncheck' }`
| N diff --git a/src/checkbox/defaultProps.ts b/src/checkbox/defaultProps.ts new file mode 100644 index 000000000..4a31534e6 --- /dev/null +++ b/src/checkbox/defaultProps.ts @@ -0,0 +1,26 @@ +/** + * 该文件为脚本自动生成文件,请勿随意修改。如需修改请联系 PMC + * */ + +import { TdCheckboxProps, TdCheckboxGroupProps } from './type'; + +export const checkboxDefaultProps: TdCheckboxProps = { + block: true, + borderless: false, + checkAll: false, + defaultChecked: false, + disabled: undefined, + icon: 'circle', + indeterminate: false, + maxContentRow: 5, + maxLabelRow: 3, + placement: 'left', + readonly: false, +}; + +export const checkboxGroupDefaultProps: TdCheckboxGroupProps = { + borderless: false, + disabled: undefined, + max: undefined, + defaultValue: [], +}; diff --git a/src/checkbox/style/index.js b/src/checkbox/style/index.js index 61286c46d..8fb62ee4c 100644 --- a/src/checkbox/style/index.js +++ b/src/checkbox/style/index.js @@ -1,7 +1,2 @@ // index.js -import '../../_common/style/mobile/components/checkbox/_index.less'; -import '../../_common/style/mobile/components/checkbox-group/_index.less'; - -// css.js -import './index.less'; - +import '../../_common/style/mobile/components/checkbox/v2/_index.less'; diff --git a/src/checkbox/type.ts b/src/checkbox/type.ts index 32670b57f..3af151baa 100644 --- a/src/checkbox/type.ts +++ b/src/checkbox/type.ts @@ -5,14 +5,19 @@ * */ import { TNode } from '../common'; -import { ChangeEvent, MouseEvent } from 'react'; +import { ChangeEvent } from 'react'; export interface TdCheckboxProps { /** - * 多选框和内容相对位置 - * @default left + * 是否为块级元素 + * @default true + */ + block?: boolean; + /** + * 是否开启无边框模式 + * @default false */ - align?: 'left' | 'right'; + borderless?: boolean; /** * 用于标识是否为「全选选项」。单独使用无效,需在 CheckboxGroup 中使用 * @default false @@ -41,13 +46,14 @@ export interface TdCheckboxProps { */ contentDisabled?: boolean; /** - * 是否禁用组件 + * 是否禁用组件。如果父组件存在 CheckboxGroup,默认值由 CheckboxGroup.disabled 控制。优先级:Checkbox.disabled > CheckboxGroup.disabled > Form.disabled */ disabled?: boolean; /** - * 自定义选中图标和非选中图标。示例:[选中态图标,非选中态图标] + * 自定义选中图标和非选中图标。使用 Array 时表示:[选中态图标,非选中态图标]。使用 String 时,值为 circle 表示填充圆形图标、值为 line 表示描边型图标、值为 rectangle 表示填充矩形图标。 + * @default 'circle' */ - icon?: Array; + icon?: 'circle' | 'line' | 'rectangle' | boolean | Array; /** * 是否为半选 * @default false @@ -72,26 +78,40 @@ export interface TdCheckboxProps { * @default '' */ name?: string; + /** + * 多选框和内容相对位置 + * @default left + */ + placement?: 'left' | 'right'; /** * 只读状态 * @default false */ readonly?: boolean; + /** + * HTML 原生属性 + * @default '' + */ + title?: string; /** * 多选框的值 */ - value?: string | number; + value?: string | number | boolean; /** * 值变化时触发 */ - onChange?: (checked: boolean, context: { e: ChangeEvent | MouseEvent }) => void; + onChange?: (checked: boolean, context: { e: ChangeEvent }) => void; } -export interface TdCheckboxGroupProps { +export interface TdCheckboxGroupProps { /** - * 是否禁用组件 + * 是否开启无边框模式 * @default false */ + borderless?: boolean; + /** + * 是否禁用组件。优先级:Form.disabled < CheckboxGroup.disabled < Checkbox.disabled + */ disabled?: boolean; /** * 支持最多选中的数量 @@ -104,29 +124,35 @@ export interface TdCheckboxGroupProps { name?: string; /** * 以配置形式设置子元素。示例1:`['北京', '上海']` ,示例2: `[{ label: '全选', checkAll: true }, { label: '上海', value: 'shanghai' }]`。checkAll 值为 true 表示当前选项为「全选选项」 - * @default [] */ options?: Array; /** * 选中值 * @default [] */ - value?: CheckboxGroupValue; + value?: T; /** * 选中值,非受控属性 * @default [] */ - defaultValue?: CheckboxGroupValue; + defaultValue?: T; /** - * 值变化时触发,`context.current` 表示当前变化的数据项,如果是全选则为空;`context.type` 表示引起选中数据变化的是选中或是取消选中 + * 值变化时触发,`context.current` 表示当前变化的数据值,如果是全选则为空;`context.type` 表示引起选中数据变化的是选中或是取消选中;`context.option` 表示当前变化的数据项;`context.current` 即将废弃,请勿使用 */ - onChange?: (value: CheckboxGroupValue, context: CheckboxGroupChangeContext) => void; + onChange?: (value: T, context: CheckboxGroupChangeContext) => void; } export type CheckboxOption = string | number | CheckboxOptionObj; -export interface CheckboxOptionObj { label?: string | TNode; value?: string | number; disabled?: boolean; name?: string; checkAll?: true }; +export interface CheckboxOptionObj extends TdCheckboxProps { + text?: string; +} -export type CheckboxGroupValue = Array; +export type CheckboxGroupValue = Array; -export interface CheckboxGroupChangeContext { e: ChangeEvent | MouseEvent; current: | TdCheckboxProps; type: 'check' | 'uncheck' }; +export interface CheckboxGroupChangeContext { + e: ChangeEvent; + current: CheckboxOption | TdCheckboxProps; + option: CheckboxOption | TdCheckboxProps; + type: 'check' | 'uncheck'; +}