From 31f063b0052448bb62d2427061fcd76fae7b3882 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?w=C5=AB=20y=C4=81ng?= Date: Thu, 14 Nov 2024 15:40:52 +0800 Subject: [PATCH 01/31] feat(menu): support tooltipProps API (#3201) --- src/menu/MenuItem.tsx | 2 +- src/menu/_example/multi-side.tsx | 2 +- src/menu/menu.en-US.md | 1 + src/menu/menu.md | 1 + src/menu/type.ts | 5 +++++ 5 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/menu/MenuItem.tsx b/src/menu/MenuItem.tsx index f3cc6700e5..0e69ae6ea1 100644 --- a/src/menu/MenuItem.tsx +++ b/src/menu/MenuItem.tsx @@ -67,7 +67,7 @@ const MenuItem: FC = (props) => { // 菜单收起,且只有本身为一级菜单才需要显示 tooltip if (collapsed && !disabled && !/submenu/i.test(className)) { return ( - + {liContent} ); diff --git a/src/menu/_example/multi-side.tsx b/src/menu/_example/multi-side.tsx index 0a0ae6dce0..a311e46981 100644 --- a/src/menu/_example/multi-side.tsx +++ b/src/menu/_example/multi-side.tsx @@ -29,7 +29,7 @@ function MultiSide() { } style={{ marginRight: 20 }} > - }> + } tooltipProps={{ theme: 'light' }}> 仪表盘 资源列表} icon={}> diff --git a/src/menu/menu.en-US.md b/src/menu/menu.en-US.md index cd6566a62c..8b77f31333 100644 --- a/src/menu/menu.en-US.md +++ b/src/menu/menu.en-US.md @@ -65,6 +65,7 @@ disabled | Boolean | - | \- | N href | String | - | \- | N icon | TElement | - | Typescript:`TNode`。[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/src/common.ts) | N target | String | - | options:_blank/_self/_parent/_top | N +tooltipProps | Object | - | Transparent all feature props of the Tooltip。Typescript:`TooltipProps`,[Tooltip API Documents](./tooltip?tab=api)。[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/src/menu/type.ts) | N value | String / Number | - | Typescript:`MenuValue` | N onClick | Function | | Typescript:`(context: { e: MouseEvent }) => void`
trigger on click | N diff --git a/src/menu/menu.md b/src/menu/menu.md index aa53e16781..a03131f7a1 100644 --- a/src/menu/menu.md +++ b/src/menu/menu.md @@ -64,6 +64,7 @@ disabled | Boolean | - | 是否禁用菜单项展开/收起/跳转等功能 | N href | String | - | 跳转链接 | N icon | TElement | - | 图标。TS 类型:`TNode`。[通用类型定义](https://github.com/Tencent/tdesign-react/blob/develop/src/common.ts) | N target | String | - | 链接或路由跳转方式。可选项:_blank/_self/_parent/_top | N +tooltipProps | Object | - | 透传 Tooltip 组件的特性,作用于一级菜单收起下聚焦时出现的节点。TS 类型:`TooltipProps`,[Tooltip API Documents](./tooltip?tab=api)。[详细类型定义](https://github.com/Tencent/tdesign-react/blob/develop/src/menu/type.ts) | N value | String / Number | - | 菜单项唯一标识。TS 类型:`MenuValue` | N onClick | Function | | TS 类型:`(context: { e: MouseEvent, value: MenuValue }) => void`
点击时触发 | N diff --git a/src/menu/type.ts b/src/menu/type.ts index 65e03037b8..6e955c00bd 100644 --- a/src/menu/type.ts +++ b/src/menu/type.ts @@ -7,6 +7,7 @@ import { TNode, TElement } from '../common'; import { MouseEvent } from 'react'; import { PopupProps } from '../popup'; +import { TooltipProps } from '../tooltip'; export interface TdMenuProps { /** @@ -170,6 +171,10 @@ export interface TdMenuItemProps { * 链接或路由跳转方式 */ target?: '_blank' | '_self' | '_parent' | '_top'; + /** + * 透传 Tooltip 组件的特性,作用于一级菜单收起下聚焦时出现的节点 + */ + tooltipProps?: TooltipProps; /** * 菜单项唯一标识 */ From 616edf570694017a6d017cd424b3c6d61560535f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=98=BF=E8=8F=9C=20Cai?= Date: Thu, 14 Nov 2024 16:01:07 +0800 Subject: [PATCH 02/31] feat(Select): `valueDisplay` and `collapsibleItems` params expanded options (#3185) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(select): `valueDisplay` and `collapsible Items` params expanded to option * fix: pass option separately * fix: tag-input 不存在选项 * fix: 修复 valueDisplay 参数问题 --- src/select-input/SelectInput.tsx | 1 + src/select-input/useMultiple.tsx | 8 +++++++- src/select/_example/custom-selected.tsx | 6 +++--- src/select/base/Select.tsx | 3 ++- src/tag-input/TagInput.tsx | 4 +++- src/tag-input/useTagList.tsx | 8 ++++++-- 6 files changed, 22 insertions(+), 8 deletions(-) diff --git a/src/select-input/SelectInput.tsx b/src/select-input/SelectInput.tsx index 76323b52fd..c84cdc0dac 100644 --- a/src/select-input/SelectInput.tsx +++ b/src/select-input/SelectInput.tsx @@ -13,6 +13,7 @@ import { InputRef } from '../input'; export interface SelectInputProps extends TdSelectInputProps, StyledProps { updateScrollTop?: (content: HTMLDivElement) => void; + options?: any[]; // 参数穿透options, 给SelectInput/SelectInput 自定义选中项呈现的内容和多选状态下设置折叠项内容 } const SelectInput = React.forwardRef, SelectInputProps>((originalProps, ref) => { diff --git a/src/select-input/useMultiple.tsx b/src/select-input/useMultiple.tsx index cfe4d98637..e589271d36 100644 --- a/src/select-input/useMultiple.tsx +++ b/src/select-input/useMultiple.tsx @@ -7,6 +7,7 @@ import { SelectInputCommonProperties } from './interface'; import useControlled from '../hooks/useControlled'; import useConfig from '../hooks/useConfig'; import { InputRef } from '../input'; +import { StyledProps } from '../common'; export interface RenderSelectMultipleParams { commonInputProps: SelectInputCommonProperties; @@ -21,7 +22,11 @@ const DEFAULT_KEYS = { children: 'children', }; -export default function useMultiple(props: TdSelectInputProps) { +export interface SelectInputProps extends TdSelectInputProps, StyledProps { + options?: any[]; // 参数穿透options, 给SelectInput/SelectInput 自定义选中项呈现的内容和多选状态下设置折叠项内容 +} + +export default function useMultiple(props: SelectInputProps) { const { value } = props; const { classPrefix } = useConfig(); const tagInputRef = useRef(); @@ -57,6 +62,7 @@ export default function useMultiple(props: TdSelectInputProps) { tag={props.tag} valueDisplay={props.valueDisplay} placeholder={tPlaceholder} + options={props.options} value={tags} inputValue={p.popupVisible && p.allowInput ? tInputValue : ''} onChange={onTagInputChange} diff --git a/src/select/_example/custom-selected.tsx b/src/select/_example/custom-selected.tsx index c3a338f48e..0054b6423a 100644 --- a/src/select/_example/custom-selected.tsx +++ b/src/select/_example/custom-selected.tsx @@ -1,5 +1,5 @@ import React, { useState } from 'react'; -import { Select, Tag, Space } from 'tdesign-react'; +import { Select, Tag, Space, SelectOption } from 'tdesign-react'; const options = [ { label: '选项一', value: '1' }, @@ -51,7 +51,7 @@ const CustomSelected = () => { ]} valueDisplay={({ value, onClose }) => Array.isArray(value) && value.length > 0 - ? value.map((v: string, idx: number) => ( + ? value.map((v: SelectOption, idx: number) => ( { @@ -59,7 +59,7 @@ const CustomSelected = () => { onClose(idx); }} closable - >{`${v}选项`} + >{`${v.label}选项`} )) : null } diff --git a/src/select/base/Select.tsx b/src/select/base/Select.tsx index 26924dccd7..d0a5fe988a 100644 --- a/src/select/base/Select.tsx +++ b/src/select/base/Select.tsx @@ -369,7 +369,7 @@ const Select = forwardRefWithStatics( return valueDisplay; } if (multiple) { - return ({ onClose }) => parseContentTNode(valueDisplay, { value: selectedLabel, onClose }); + return ({ onClose }) => parseContentTNode(valueDisplay, { value: selectedOptions, onClose }); } return parseContentTNode(valueDisplay, { value: selectedLabel, onClose: noop }); }; @@ -434,6 +434,7 @@ const Select = forwardRefWithStatics( allowInput={(filterable ?? local.filterable) || isFunction(filter)} multiple={multiple} value={selectedLabel} + options={props.options} valueDisplay={renderValueDisplay()} clearable={clearable} disabled={disabled} diff --git a/src/tag-input/TagInput.tsx b/src/tag-input/TagInput.tsx index 4c4b121903..875080bd94 100644 --- a/src/tag-input/TagInput.tsx +++ b/src/tag-input/TagInput.tsx @@ -15,7 +15,9 @@ import { StyledProps } from '../common'; import { tagInputDefaultProps } from './defaultProps'; import useDefaultProps from '../hooks/useDefaultProps'; -export interface TagInputProps extends TdTagInputProps, StyledProps {} +export interface TagInputProps extends TdTagInputProps, StyledProps { + options?: any[]; // 参数穿透options, 给SelectInput/SelectInput 自定义选中项呈现的内容和多选状态下设置折叠项内容 +} const TagInput = forwardRef((originalProps, ref) => { const props = useDefaultProps(originalProps, tagInputDefaultProps); diff --git a/src/tag-input/useTagList.tsx b/src/tag-input/useTagList.tsx index 2066100780..721669dd7e 100644 --- a/src/tag-input/useTagList.tsx +++ b/src/tag-input/useTagList.tsx @@ -9,7 +9,9 @@ import { DragSortInnerProps } from '../hooks/useDragSorter'; export type ChangeParams = [TagInputChangeContext]; -interface TagInputProps extends TdTagInputProps, DragSortInnerProps {} +interface TagInputProps extends TdTagInputProps, DragSortInnerProps { + options?: any[]; // 参数穿透options, 给SelectInput/SelectInput 自定义选中项呈现的内容和多选状态下设置折叠项内容 +} // handle tag add and remove export default function useTagList(props: TagInputProps) { @@ -99,11 +101,13 @@ export default function useTagList(props: TagInputProps) { // 超出省略 if (newList.length !== tagValue.length) { const len = tagValue.length - newList.length; + // 这里会从selectInput/SelectInput中传递options参数,用于自定义选中项呈现的内容和多选状态下设置折叠项内容 + const options = Array.isArray(props?.options) ? props.options : tagValue; const params = { value: tagValue, count: tagValue.length - minCollapsedNum, collapsedTags: tagValue.slice(minCollapsedNum, tagValue.length), - collapsedSelectedItems: tagValue.slice(minCollapsedNum, tagValue.length), + collapsedSelectedItems: options.slice(minCollapsedNum, tagValue.length), onClose, }; const more = isFunction(collapsedItems) ? collapsedItems(params) : collapsedItems; From 26278029d7e761a8379fa2f4b38ea478b552c3b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?w=C5=AB=20y=C4=81ng?= Date: Thu, 14 Nov 2024 16:08:29 +0800 Subject: [PATCH 03/31] fix(Table): fix expandedTreeNodes change effect (#3202) --- src/table/hooks/useTreeData.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/table/hooks/useTreeData.tsx b/src/table/hooks/useTreeData.tsx index 4fabd6b0a6..3015bd8c53 100644 --- a/src/table/hooks/useTreeData.tsx +++ b/src/table/hooks/useTreeData.tsx @@ -19,7 +19,7 @@ export interface UseSwapParams extends SwapParams { } export default function useTreeData(props: TdEnhancedTableProps) { - const { data, columns, tree, rowKey, treeExpandAndFoldIcon } = props; + const { data, columns, tree, rowKey, treeExpandAndFoldIcon, expandedTreeNodes } = props; const [store] = useState(new TableTreeStore() as InstanceType); const [treeNodeCol, setTreeNodeCol] = useState(() => getTreeNodeColumnCol()); const [dataSource, setDataSource] = useState(data || []); @@ -70,7 +70,7 @@ export default function useTreeData(props: TdEnhancedTableProps) { } }, // eslint-disable-next-line react-hooks/exhaustive-deps - [data], + [data, expandedTreeNodes], ); useEffect( From 5fe28f3a633ad9f00007c2bfdb791b6c83141bf6 Mon Sep 17 00:00:00 2001 From: moecasts <37169906+moecasts@users.noreply.github.com> Date: Thu, 14 Nov 2024 17:24:59 +0800 Subject: [PATCH 04/31] feat(form): add getValidateMessage api (#3180) re #2885 --- src/form/FormItem.tsx | 6 ++++++ src/form/form.en-US.md | 1 + src/form/form.md | 1 + src/form/hooks/useForm.ts | 3 +++ src/form/hooks/useInstance.tsx | 27 +++++++++++++++++++++++++++ src/form/type.ts | 4 ++++ 6 files changed, 42 insertions(+) diff --git a/src/form/FormItem.tsx b/src/form/FormItem.tsx index 9151499b53..72eb10bfb1 100644 --- a/src/form/FormItem.tsx +++ b/src/form/FormItem.tsx @@ -45,6 +45,7 @@ export interface FormItemInstance { validate?: Function; resetField?: Function; setValidateMessage?: Function; + getValidateMessage?: Function; resetValidate?: Function; validateOnly?: Function; isFormList?: boolean; @@ -382,6 +383,10 @@ const FormItem = forwardRef((originalProps, ref setVerifyStatus(status); } + function getValidateMessage() { + return errorList; + } + useEffect(() => { // 注册自定义更新回调 if (!shouldUpdate || !form) return; @@ -459,6 +464,7 @@ const FormItem = forwardRef((originalProps, ref validateOnly, resetField, setValidateMessage, + getValidateMessage, resetValidate: resetHandler, }; useImperativeHandle(ref, (): FormItemInstance => instance); diff --git a/src/form/form.en-US.md b/src/form/form.en-US.md index 1b1362f802..a3d3a000d3 100644 --- a/src/form/form.en-US.md +++ b/src/form/form.en-US.md @@ -44,6 +44,7 @@ reset | `(params?: FormResetParams)` | \- | required。[see more ts de setFields | `(fields: FieldData[])` | \- | required。Typescript:`(fields: FieldData[]) => void` `interface FieldData { name: NamePath; value?: unknown, status?: string, validateMessage?: { type?: string, message?: string } }`。[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/src/form/type.ts) setFieldsValue | `(field: Data)` | \- | required setValidateMessage | `(message: FormValidateMessage)` | \- | required。[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/src/form/type.ts)。
`type FormValidateMessage = { [field in keyof FormData]: FormItemValidateMessage[] }`

`interface FormItemValidateMessage { type: 'warning' \| 'error'; message: string }`
+getValidateMessage | `(fields?: Array)` | `Array \| void` | required。[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/src/form/type.ts)。
submit | `(params?: { showErrorMessage?: boolean })` | \- | required validate | `(params?: FormValidateParams)` | `Promise>` | required。[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/src/form/type.ts)。
`interface FormValidateParams { fields?: Array; showErrorMessage?: boolean; trigger?: ValidateTriggerType }`

`type ValidateTriggerType = 'blur' \| 'change' \| 'submit' \| 'all'`
validateOnly | `(params?: Pick)` | `Promise>` | required diff --git a/src/form/form.md b/src/form/form.md index 5f5be5414a..90017236f1 100644 --- a/src/form/form.md +++ b/src/form/form.md @@ -126,6 +126,7 @@ reset | `(params?: FormResetParams)` | \- | 必需。重置表单, setFields | `(fields: FieldData[])` | \- | 必需。设置多组字段状态。TS 类型:`(fields: FieldData[]) => void` `interface FieldData { name: NamePath; value?: unknown, status?: string, validateMessage?: { type?: string, message?: string } }`。[详细类型定义](https://github.com/Tencent/tdesign-react/blob/develop/src/form/type.ts) setFieldsValue | `(field: Data)` | \- | 必需。设置表单字段值 setValidateMessage | `(message: FormValidateMessage)` | \- | 必需。设置自定义校验结果,如远程校验信息直接呈现。注意需要在组件挂载结束后使用该方法。`FormData` 指表单数据泛型。[详细类型定义](https://github.com/Tencent/tdesign-react/blob/develop/src/form/type.ts)。
`type FormValidateMessage = { [field in keyof FormData]: FormItemValidateMessage[] }`

`interface FormItemValidateMessage { type: 'warning' \| 'error'; message: string }`
+getValidateMessage | `(fields?: Array)` | `Array \| void` | 必需。获取校验结果,当调用 getValidateMessage() 时返回所有校验结果。[详细类型定义](https://github.com/Tencent/tdesign-react/blob/develop/src/form/type.ts)。
submit | `(params?: { showErrorMessage?: boolean })` | \- | 必需。提交表单,表单里面没有提交按钮` + + + + ); +} diff --git a/src/popup/popup.en-US.md b/src/popup/popup.en-US.md index 2cacf5ccf1..5c0fe3aa55 100644 --- a/src/popup/popup.en-US.md +++ b/src/popup/popup.en-US.md @@ -9,6 +9,20 @@ Support functional calls `PopupPlugin` 。 {{ plugin }} +### Dynamic Adaptation + +When the trigger or popup display content changes dynamically, the position is adjusted adaptively + +{{ dynamic }} + +### popperOptions usage + +https://popper.js.org/docs/v2/constructors/#types + +- `popperOptions` = `Options` + +{{ popper-options }} + ## FAQ ### How to solve the problem of position offset when nesting `Popup` components? diff --git a/src/popup/popup.md b/src/popup/popup.md index 95df45f1b8..0c8afe1496 100644 --- a/src/popup/popup.md +++ b/src/popup/popup.md @@ -15,6 +15,14 @@ {{ dynamic }} +### popperOptions 使用 + +https://popper.js.org/docs/v2/constructors/#types + +- `popperOptions` = `Options` + +{{ popper-options }} + ## FAQ ### `Popup` 组件,嵌套使用可能出现位置偏移的情况,如何解决? diff --git a/test/snap/__snapshots__/csr.test.jsx.snap b/test/snap/__snapshots__/csr.test.jsx.snap index 355d3abef9..a98b95ad25 100644 --- a/test/snap/__snapshots__/csr.test.jsx.snap +++ b/test/snap/__snapshots__/csr.test.jsx.snap @@ -67312,6 +67312,122 @@ exports[`csr snapshot test > csr test src/popup/_example/plugin.tsx 1`] = ` `; +exports[`csr snapshot test > csr test src/popup/_example/popper-options.tsx 1`] = ` +
+
+
+
+
+
+
+ + 请输入横向偏移量: + +
+
+
+
+ +
+
+
+
+
+
+
+
+ + 请输入纵向偏移量: + +
+
+
+
+ +
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+`; + exports[`csr snapshot test > csr test src/popup/_example/style.tsx 1`] = `
ssr test src/popup/_example/placement.tsx 1`] = `"< exports[`ssr snapshot test > ssr test src/popup/_example/plugin.tsx 1`] = `"
这里是一个日志查询的例子,在很长的日志内容中,日志内容存在换行的情况,可以点击链接进行日志查询操作点击此链接,会打开浮层进行跳转操作
"`; +exports[`ssr snapshot test > ssr test src/popup/_example/popper-options.tsx 1`] = `"
请输入横向偏移量:
请输入纵向偏移量:
"`; + exports[`ssr snapshot test > ssr test src/popup/_example/style.tsx 1`] = `"
"`; exports[`ssr snapshot test > ssr test src/popup/_example/trigger.tsx 1`] = `"
"`; diff --git a/test/snap/__snapshots__/ssr.test.jsx.snap b/test/snap/__snapshots__/ssr.test.jsx.snap index f27a5b73ff..25d8a91ac1 100644 --- a/test/snap/__snapshots__/ssr.test.jsx.snap +++ b/test/snap/__snapshots__/ssr.test.jsx.snap @@ -724,6 +724,8 @@ exports[`ssr snapshot test > ssr test src/popup/_example/placement.tsx 1`] = `"< exports[`ssr snapshot test > ssr test src/popup/_example/plugin.tsx 1`] = `"
这里是一个日志查询的例子,在很长的日志内容中,日志内容存在换行的情况,可以点击链接进行日志查询操作点击此链接,会打开浮层进行跳转操作
"`; +exports[`ssr snapshot test > ssr test src/popup/_example/popper-options.tsx 1`] = `"
请输入横向偏移量:
请输入纵向偏移量:
"`; + exports[`ssr snapshot test > ssr test src/popup/_example/style.tsx 1`] = `"
"`; exports[`ssr snapshot test > ssr test src/popup/_example/trigger.tsx 1`] = `"
"`; From 2c28a9054d083667a207f7b72800a310bb5f8223 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=98=BF=E8=8F=9C=20Cai?= Date: Fri, 15 Nov 2024 11:18:06 +0800 Subject: [PATCH 07/31] fix(Drawer): use `FooterButton` props define `confirmBtn` and `closeBtn` are invalid (#3191) * fix(Drawer): use `FooterButton` parm define `confirmBtn` and `closeBtn` are invalid * chore: remove unexpected strings * chore: remove test toMatchSnapshot --- src/drawer/Drawer.tsx | 108 ++++++++++++++++----------- src/drawer/__tests__/drawer.test.tsx | 44 ++++++++++- 2 files changed, 106 insertions(+), 46 deletions(-) diff --git a/src/drawer/Drawer.tsx b/src/drawer/Drawer.tsx index 559574b54b..3d8027d65b 100644 --- a/src/drawer/Drawer.tsx +++ b/src/drawer/Drawer.tsx @@ -1,12 +1,16 @@ -import React, { forwardRef, useState, useEffect, useImperativeHandle, useRef, useMemo } from 'react'; +import React, { forwardRef, useState, useEffect, useImperativeHandle, useRef, useMemo, isValidElement } from 'react'; import classnames from 'classnames'; +import isString from 'lodash/isString'; +import isObject from 'lodash/isObject'; +import isFunction from 'lodash/isFunction'; + import { CSSTransition } from 'react-transition-group'; import { CloseIcon as TdCloseIcon } from 'tdesign-icons-react'; import { useLocaleReceiver } from '../locale/LocalReceiver'; import { TdDrawerProps, DrawerEventSource } from './type'; import { StyledProps } from '../common'; -import Button from '../button'; +import Button, { ButtonProps } from '../button'; import useConfig from '../hooks/useConfig'; import useGlobalIcon from '../hooks/useGlobalIcon'; import { drawerDefaultProps } from './defaultProps'; @@ -14,6 +18,7 @@ import useDrag from './hooks/useDrag'; import Portal from '../common/Portal'; import useLockStyle from './hooks/useLockStyle'; import useDefaultProps from '../hooks/useDefaultProps'; +import parseTNode from '../_util/parseTNode'; export const CloseTriggerType: { [key: string]: DrawerEventSource } = { CLICK_OVERLAY: 'overlay', @@ -25,6 +30,12 @@ export const CloseTriggerType: { [key: string]: DrawerEventSource } = { export interface DrawerProps extends TdDrawerProps, StyledProps {} const Drawer = forwardRef((originalProps, ref) => { + // 国际化文本初始化 + const [local, t] = useLocaleReceiver('drawer'); + const { CloseIcon } = useGlobalIcon({ CloseIcon: TdCloseIcon }); + const confirmText = t(local.confirm); + const cancelText = t(local.cancel); + const props = useDefaultProps(originalProps, drawerDefaultProps); const { className, @@ -49,28 +60,22 @@ const Drawer = forwardRef((originalProps, ref) => { body, footer, closeBtn, - cancelBtn, - confirmBtn, + cancelBtn = cancelText, + confirmBtn = confirmText, zIndex, destroyOnClose, sizeDraggable, forceRender, } = props; - // 国际化文本初始化 - const [local, t] = useLocaleReceiver('drawer'); - const { CloseIcon } = useGlobalIcon({ CloseIcon: TdCloseIcon }); const size = propsSize ?? local.size; - const confirmText = t(local.confirm); - const cancelText = t(local.cancel); - const { classPrefix } = useConfig(); const maskRef = useRef(); const containerRef = useRef(); const drawerWrapperRef = useRef(); // 即最终的 attach dom,默认为 document.body const prefixCls = `${classPrefix}-drawer`; - const closeIcon = React.isValidElement(closeBtn) ? closeBtn : ; + const closeIcon = isValidElement(closeBtn) ? closeBtn : ; const { dragSizeValue, enableDrag, draggableLineStyles } = useDrag(placement, sizeDraggable, onSizeDragEnd); const [animationStart, setAnimationStart] = useState(visible); @@ -119,37 +124,57 @@ const Drawer = forwardRef((originalProps, ref) => { [visible, placement, sizeValue, animationStart], ); - function getFooter(): React.ReactNode { - if (footer !== true) return footer; - - const defaultCancelBtn = ( - - ); - - const defaultConfirmBtn = ( - - ); - - const renderCancelBtn = cancelBtn && React.isValidElement(cancelBtn) ? cancelBtn : defaultCancelBtn; - const renderConfirmBtn = confirmBtn && React.isValidElement(confirmBtn) ? confirmBtn : defaultConfirmBtn; - - const footerStyle = { - display: 'flex', - justifyContent: placement === 'right' ? 'flex-start' : 'flex-end', + const renderDrawerButton = (btn: DrawerProps['cancelBtn'], defaultProps: ButtonProps) => { + let result = null; + + if (isString(btn)) { + result = ; + } else if (isValidElement(btn)) { + result = btn; + } else if (isObject(btn)) { + result =
diff --git a/src/drawer/__tests__/drawer.test.tsx b/src/drawer/__tests__/drawer.test.tsx index caf7022465..6dfa178285 100644 --- a/src/drawer/__tests__/drawer.test.tsx +++ b/src/drawer/__tests__/drawer.test.tsx @@ -65,18 +65,54 @@ describe('test Drawer', () => { fireEvent.click(getByText('Open')); expect(document.querySelector('.t-drawer__mask')).not.toBeInTheDocument(); }); - test('Drawer header and footer', () => { + test('Drawer header and footer custom', () => { const { getByText } = render(自定义头部} footer={
自定义底部
} />); fireEvent.click(getByText('Open')); expect(getByText('自定义头部').parentElement).toHaveClass('t-drawer__header'); expect(getByText('自定义底部').parentElement).toHaveClass('t-drawer__footer'); }); - test('Drawer cancelBtn and confirmBtn', () => { + test('Drawer cancelBtn and confirmBtn custom', () => { const { getByText } = render(cancelBtn} confirmBtn={
confirmBtn
} />); fireEvent.click(getByText('Open')); - expect(getByText('cancelBtn').parentElement.parentElement).toHaveClass('t-drawer__footer'); - expect(getByText('confirmBtn').parentElement.parentElement).toHaveClass('t-drawer__footer'); + + const cancelBtn = getByText('cancelBtn'); + const confirmBtn = getByText('confirmBtn'); + + expect(cancelBtn.parentElement.parentElement).toHaveClass('t-drawer__footer'); + expect(confirmBtn.parentElement.parentElement).toHaveClass('t-drawer__footer'); + }); + + test('Drawer cancelBtn and confirmBtn props', () => { + const { getByText } = render( + , + ); + fireEvent.click(getByText('Open')); + + const confirmBtn = getByText('确认按钮'); + const cancelBtn = getByText('取消按钮'); + + // 是否有这两个元素 + expect(cancelBtn).toBeInTheDocument(); + expect(confirmBtn).toBeInTheDocument(); + + expect(confirmBtn.parentElement).toHaveClass('t-drawer__confirm'); + expect(cancelBtn.parentElement).toHaveClass('t-drawer__cancel'); + expect(confirmBtn.parentElement.parentElement.parentElement).toHaveClass('t-drawer__footer'); + expect(cancelBtn.parentElement.parentElement.parentElement).toHaveClass('t-drawer__footer'); + + expect(confirmBtn.parentElement).toHaveClass(`t-button--theme-success`); + expect(cancelBtn.parentElement).toHaveClass(`t-button--theme-danger`); }); + test('Drawer mode push', () => { const { getByText } = render(); fireEvent.click(getByText('Open')); From d2701efa7b4ded0500ed819ac576fb967bdff37d Mon Sep 17 00:00:00 2001 From: liweijie0812 <674416404@qq.com> Date: Fri, 15 Nov 2024 11:32:25 +0800 Subject: [PATCH 08/31] chore: move ShapeEnum to common.ts (#3206) --- src/avatar/type.ts | 5 ++--- src/common.ts | 2 ++ 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/avatar/type.ts b/src/avatar/type.ts index 30fd72703c..4f08c92248 100644 --- a/src/avatar/type.ts +++ b/src/avatar/type.ts @@ -7,7 +7,8 @@ import { MouseEvent } from 'react'; import { ImageProps } from '../image'; import { PopupProps } from '../popup'; -import { TNode, TElement, ImageEvent } from '../common'; + +import { TNode, TElement, ImageEvent, ShapeEnum } from '../common'; export interface TdAvatarProps { /** @@ -94,6 +95,4 @@ export interface TdAvatarGroupProps { size?: string; } -export type ShapeEnum = 'circle' | 'round'; - export type CascadingValue = 'left-up' | 'right-up'; diff --git a/src/common.ts b/src/common.ts index cd1f07808a..c3ddfb404c 100644 --- a/src/common.ts +++ b/src/common.ts @@ -60,6 +60,8 @@ export type TreeOptionData = { export type SizeEnum = 'small' | 'medium' | 'large'; +export type ShapeEnum = 'circle' | 'round'; + export type HorizontalAlignEnum = 'left' | 'center' | 'right'; export type VerticalAlignEnum = 'top' | 'middle' | 'bottom'; From e8447c66dfc9c8796f4ea826ee55635e4d468e52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?w=C5=AB=20y=C4=81ng?= Date: Fri, 15 Nov 2024 11:45:02 +0800 Subject: [PATCH 09/31] feat(checkbox): support title API (#3207) * feat(checkbox): support title API * feat(checkbox): support title API --- src/checkbox/checkbox.en-US.md | 1 + src/checkbox/checkbox.md | 1 + src/checkbox/type.ts | 5 +++++ src/table/_example/select-multiple.tsx | 2 +- test/snap/__snapshots__/csr.test.jsx.snap | 4 +++- test/snap/__snapshots__/ssr.test.jsx.snap | 2 +- 6 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/checkbox/checkbox.en-US.md b/src/checkbox/checkbox.en-US.md index 116ca2a5a7..9bec6f80fa 100644 --- a/src/checkbox/checkbox.en-US.md +++ b/src/checkbox/checkbox.en-US.md @@ -16,6 +16,7 @@ indeterminate | Boolean | false | \- | N label | TNode | - | Typescript:`string \| TNode`。[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/src/common.ts) | N name | String | - | \- | 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 onClick | Function | | Typescript:`(context: { e: MouseEvent }) => void`
trigger on click | N diff --git a/src/checkbox/checkbox.md b/src/checkbox/checkbox.md index 1393819bab..32b974a349 100644 --- a/src/checkbox/checkbox.md +++ b/src/checkbox/checkbox.md @@ -21,6 +21,7 @@ indeterminate | Boolean | false | 是否为半选 | N label | TNode | - | 主文案。TS 类型:`string \| TNode`。[通用类型定义](https://github.com/Tencent/tdesign-react/blob/develop/src/common.ts) | N name | String | - | HTML 元素原生属性 | N readonly | Boolean | false | 只读状态 | N +title | String | - | HTML 原生属性 | N value | String / Number / Boolean | - | 多选框的值。TS 类型:`string \| number \| boolean` | N onChange | Function | | TS 类型:`(checked: boolean, context: { e: ChangeEvent }) => void`
值变化时触发 | N onClick | Function | | TS 类型:`(context: { e: MouseEvent }) => void`
点击时触发,一般用于外层阻止冒泡场景 | N diff --git a/src/checkbox/type.ts b/src/checkbox/type.ts index 418904b76a..46972166ec 100644 --- a/src/checkbox/type.ts +++ b/src/checkbox/type.ts @@ -50,6 +50,11 @@ export interface TdCheckboxProps { * @default false */ readonly?: boolean; + /** + * HTML 原生属性 + * @default '' + */ + title?: string; /** * 多选框的值 */ diff --git a/src/table/_example/select-multiple.tsx b/src/table/_example/select-multiple.tsx index 32f8953b79..02cafd044f 100644 --- a/src/table/_example/select-multiple.tsx +++ b/src/table/_example/select-multiple.tsx @@ -19,7 +19,7 @@ const columns: TableProps['columns'] = [ // 禁用行选中方式二:使用 checkProps 禁用行(示例代码有效,勿删) // 这种方式禁用行选中,行文本不会变灰 - checkProps: ({ rowIndex }) => ({ disabled: rowIndex % 2 !== 0 }), + checkProps: ({ rowIndex }) => ({ disabled: rowIndex % 2 !== 0, title: rowIndex % 2 !== 0 ? '不可选' : null }), width: 50, }, { colKey: 'applicant', title: '申请人', width: '100' }, diff --git a/test/snap/__snapshots__/csr.test.jsx.snap b/test/snap/__snapshots__/csr.test.jsx.snap index a98b95ad25..ab3516e646 100644 --- a/test/snap/__snapshots__/csr.test.jsx.snap +++ b/test/snap/__snapshots__/csr.test.jsx.snap @@ -110762,6 +110762,7 @@ exports[`csr snapshot test > csr test src/table/_example/select-multiple.tsx 1`] >