Skip to content

Commit a66d19a

Browse files
authored
Merge branch 'develop' into rylan/fix/ellipsis
2 parents caf067e + c3d2cd2 commit a66d19a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+1231
-556
lines changed

packages/components/date-picker/base/Footer.tsx

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import React from 'react';
22
import classNames from 'classnames';
3+
import { isFunction } from 'lodash-es';
34
import { useLocaleReceiver } from '../../locale/LocalReceiver';
45
import Button from '../../button';
56
import useConfig from '../../hooks/useConfig';
@@ -34,23 +35,29 @@ const DatePickerFooter = (props: DatePickerFooterProps) => {
3435
`${classPrefix}-date-picker__footer--${presetsPlacement}`,
3536
);
3637

38+
const renderPresets = () => {
39+
if (presets) {
40+
if (React.isValidElement(presets)) return presets;
41+
42+
if (isFunction(presets)) return presets();
43+
44+
return Object.keys(presets).map((key: string) => (
45+
<Button
46+
key={key}
47+
size="small"
48+
variant="text"
49+
onClick={(e) => onPresetClick(presets[key], { e, preset: { [key]: presets[key] } })}
50+
>
51+
{key}
52+
</Button>
53+
));
54+
}
55+
56+
return null;
57+
};
3758
return (
3859
<div className={footerClass}>
39-
{
40-
<div className={`${classPrefix}-date-picker__presets`}>
41-
{presets &&
42-
Object.keys(presets).map((key: string) => (
43-
<Button
44-
key={key}
45-
size="small"
46-
variant="text"
47-
onClick={(e) => onPresetClick(presets[key], { e, preset: { [key]: presets[key] } })}
48-
>
49-
{key}
50-
</Button>
51-
))}
52-
</div>
53-
}
60+
<div className={`${classPrefix}-date-picker__presets`}>{renderPresets()}</div>
5461
{enableTimePicker && needConfirm && (
5562
<Button disabled={!selectedValue} size="small" theme="primary" onClick={(e) => onConfirmClick({ e })}>
5663
{confirmText}

packages/components/date-picker/date-picker.en-US.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ needConfirm | Boolean | true | whether a confirmation button needs to be clicked
2626
placeholder | String / Array | undefined | Typescript: `string` | N
2727
popupProps | Object | - | Typescript: `PopupProps`[Popup API Documents](./popup?tab=api)[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/packages/components/date-picker/type.ts) | N
2828
prefixIcon | TElement | - | Typescript: `TNode`[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/packages/components/common.ts) | N
29-
presets | Object | - | Typescript: `PresetDate` `interface PresetDate { [name: string]: DateValue \| (() => DateValue) }`[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/packages/components/date-picker/type.ts) | N
29+
presets | TNode | - | Typescript: `TNode \| PresetDate` `interface PresetDate { [name: string]: DateValue \| (() => DateValue) }`[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/packages/components/common.ts)[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/packages/components/date-picker/type.ts) | N
3030
presetsPlacement | String | bottom | options: left/top/right/bottom | N
3131
selectInputProps | Object | - | Typescript: `SelectInputProps`[SelectInput API Documents](./select-input?tab=api)[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/packages/components/date-picker/type.ts) | N
3232
size | String | medium | options: small/medium/large。Typescript: `SizeEnum`[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/packages/components/common.ts) | N
@@ -71,8 +71,7 @@ panelPreselection | Boolean | true | \- | N
7171
placeholder | String / Array | - | Typescript: `string \| Array<string>` | N
7272
popupProps | Object | - | Typescript: `PopupProps`[Popup API Documents](./popup?tab=api)[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/packages/components/date-picker/type.ts) | N
7373
prefixIcon | TElement | - | Typescript: `TNode`[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/packages/components/common.ts) | N
74-
presets | Object | - | Typescript: `PresetRange` `interface PresetRange { [range: string]: DateRange \| (() => DateRange)}` `type DateRange = [DateValue, DateValue]`[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/packages/components/date-picker/type.ts) | N
75-
presetsPlacement | String | bottom | options: left/top/right/bottom | N
74+
presets | TNode | - | Typescript: `TNode \| PresetRange` `interface PresetRange { [range: string]: DateRange \| (() => DateRange)}` `type DateRange = [DateValue, DateValue]`[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/packages/components/common.ts)[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/packages/components/date-picker/type.ts) | N
7675
rangeInputProps | Object | - | Typescript: `RangeInputProps`[RangeInput API Documents](./range-input?tab=api)[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/packages/components/date-picker/type.ts) | N
7776
separator | String | - | \- | N
7877
size | String | medium | options: small/medium/large。Typescript: `SizeEnum`[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/packages/components/common.ts) | N

packages/components/date-picker/date-picker.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ needConfirm | Boolean | true | 决定在日期时间选择器的场景下是否
2626
placeholder | String / Array | undefined | 占位符。TS 类型:`string` | N
2727
popupProps | Object | - | 透传给 popup 组件的参数。TS 类型:`PopupProps`[Popup API Documents](./popup?tab=api)[详细类型定义](https://github.com/Tencent/tdesign-react/blob/develop/packages/components/date-picker/type.ts) | N
2828
prefixIcon | TElement | - | 用于自定义组件前置图标。TS 类型:`TNode`[通用类型定义](https://github.com/Tencent/tdesign-react/blob/develop/packages/components/common.ts) | N
29-
presets | Object | - | 预设快捷日期选择,示例:`{ '元旦': '2021-01-01', '昨天': dayjs().subtract(1, 'day').format('YYYY-MM-DD'), '特定日期': () => ['2021-02-01'] }`。TS 类型:`PresetDate` `interface PresetDate { [name: string]: DateValue \| (() => DateValue) }`[详细类型定义](https://github.com/Tencent/tdesign-react/blob/develop/packages/components/date-picker/type.ts) | N
29+
presets | TNode | - | 预设快捷日期选择,示例:`{ '元旦': '2021-01-01', '昨天': dayjs().subtract(1, 'day').format('YYYY-MM-DD'), '特定日期': () => ['2021-02-01'] }`。TS 类型:`TNode \| PresetDate` `interface PresetDate { [name: string]: DateValue \| (() => DateValue) }`[通用类型定义](https://github.com/Tencent/tdesign-react/blob/develop/packages/components/common.ts)[详细类型定义](https://github.com/Tencent/tdesign-react/blob/develop/packages/components/date-picker/type.ts) | N
3030
presetsPlacement | String | bottom | 预设面板展示区域(包含确定按钮)。可选项:left/top/right/bottom | N
3131
selectInputProps | Object | - | 透传 SelectInput 筛选器输入框组件的全部属性。TS 类型:`SelectInputProps`[SelectInput API Documents](./select-input?tab=api)[详细类型定义](https://github.com/Tencent/tdesign-react/blob/develop/packages/components/date-picker/type.ts) | N
3232
size | String | medium | 输入框尺寸。可选项:small/medium/large。TS 类型:`SizeEnum`[通用类型定义](https://github.com/Tencent/tdesign-react/blob/develop/packages/components/common.ts) | N
@@ -70,7 +70,7 @@ panelPreselection | Boolean | true | 在开始日期选中之前,面板是否
7070
placeholder | String / Array | - | 占位符,值为数组表示可分别为开始日期和结束日期设置占位符。TS 类型:`string \| Array<string>` | N
7171
popupProps | Object | - | 透传给 popup 组件的参数。TS 类型:`PopupProps`[Popup API Documents](./popup?tab=api)[详细类型定义](https://github.com/Tencent/tdesign-react/blob/develop/packages/components/date-picker/type.ts) | N
7272
prefixIcon | TElement | - | 组件前置图标。TS 类型:`TNode`[通用类型定义](https://github.com/Tencent/tdesign-react/blob/develop/packages/components/common.ts) | N
73-
presets | Object | - | 预设快捷日期选择,示例:{ '特定日期范围': ['2021-01-01', '2022-01-01'], '本月': [dayjs().startOf('month'), dayjs().endOf('month')] }。TS 类型:`PresetRange` `interface PresetRange { [range: string]: DateRange \| (() => DateRange)}` `type DateRange = [DateValue, DateValue]`[详细类型定义](https://github.com/Tencent/tdesign-react/blob/develop/packages/components/date-picker/type.ts) | N
73+
presets | TNode | - | 预设快捷日期选择,示例:{ '特定日期范围': ['2021-01-01', '2022-01-01'], '本月': [dayjs().startOf('month'), dayjs().endOf('month')] }。TS 类型:`TNode \| PresetRange` `interface PresetRange { [range: string]: DateRange \| (() => DateRange)}` `type DateRange = [DateValue, DateValue]`[通用类型定义](https://github.com/Tencent/tdesign-react/blob/develop/packages/components/common.ts)[详细类型定义](https://github.com/Tencent/tdesign-react/blob/develop/packages/components/date-picker/type.ts) | N
7474
presetsPlacement | String | bottom | 预设面板展示区域(包含确定按钮)。可选项:left/top/right/bottom | N
7575
rangeInputProps | Object | - | 透传给范围输入框 RangeInput 组件的参数。TS 类型:`RangeInputProps`[RangeInput API Documents](./range-input?tab=api)[详细类型定义](https://github.com/Tencent/tdesign-react/blob/develop/packages/components/date-picker/type.ts) | N
7676
separator | String | - | 日期分隔符,支持全局配置,默认为 '-' | N

packages/components/date-picker/type.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ export interface TdDatePickerProps {
9999
/**
100100
* 预设快捷日期选择,示例:`{ '元旦': '2021-01-01', '昨天': dayjs().subtract(1, 'day').format('YYYY-MM-DD'), '特定日期': () => ['2021-02-01'] }`
101101
*/
102-
presets?: PresetDate;
102+
presets?: TNode | PresetDate;
103103
/**
104104
* 预设面板展示区域(包含确定按钮)
105105
* @default bottom
@@ -264,7 +264,7 @@ export interface TdDateRangePickerProps {
264264
/**
265265
* 预设快捷日期选择,示例:{ '特定日期范围': ['2021-01-01', '2022-01-01'], '本月': [dayjs().startOf('month'), dayjs().endOf('month')] }
266266
*/
267-
presets?: PresetRange;
267+
presets?: TNode | PresetRange;
268268
/**
269269
* 预设面板展示区域(包含确定按钮)
270270
* @default bottom

packages/components/dialog/Dialog.tsx

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import { dialogDefaultProps } from './defaultProps';
1717
import DialogCard from './DialogCard';
1818
import useDialogDrag from './hooks/useDialogDrag';
1919
import useDialogEsc from './hooks/useDialogEsc';
20+
import useDialogPosition from './hooks/useDialogPosition';
2021
import useLockStyle from './hooks/useLockStyle';
2122

2223
import type { StyledProps } from '../common';
@@ -51,15 +52,17 @@ export interface DialogProps extends TdDialogProps, StyledProps {
5152
const Dialog = forwardRef<DialogInstance, DialogProps>((originalProps, ref) => {
5253
const props = useDefaultProps<DialogProps>(originalProps, dialogDefaultProps);
5354
const { children, ...restProps } = props;
54-
const { classPrefix } = useConfig();
5555

56+
const { classPrefix } = useConfig();
5657
const componentCls = `${classPrefix}-dialog`;
58+
5759
const wrapRef = useRef<HTMLDivElement>(null);
5860
const maskRef = useRef<HTMLDivElement>(null);
5961
const contentClickRef = useRef(false);
6062
const dialogCardRef = useRef<HTMLDivElement>(null);
6163
const dialogPosition = useRef(null);
6264
const portalRef = useRef(null);
65+
6366
const [state, setState] = useSetState<DialogProps>({ isPlugin: false, ...restProps });
6467
const [local] = useLocaleReceiver('dialog');
6568

@@ -96,15 +99,20 @@ const Dialog = forwardRef<DialogInstance, DialogProps>((originalProps, ref) => {
9699
...restState
97100
} = state;
98101

102+
const isModeless = mode === 'modeless';
103+
const isFullScreen = mode === 'full-screen';
104+
99105
const dialogAttach = useAttach('dialog', attach);
100106
const [animationVisible, setAnimationVisible] = useState(visible);
101107
const [dialogAnimationVisible, setDialogAnimationVisible] = useState(false);
102108

103109
const { focusTopDialog } = useDialogEsc(visible, wrapRef);
104110
useLockStyle({ preventScrollThrough, visible, mode, showInAttachedElement });
105-
useDialogDrag({
111+
useDialogEsc(visible, wrapRef);
112+
useDialogPosition(visible, dialogCardRef);
113+
const { isInputInteracting } = useDialogDrag({
106114
dialogCardRef,
107-
canDraggable: draggable && mode === 'modeless',
115+
canDraggable: !isFullScreen && draggable,
108116
});
109117

110118
useDeepEffect(() => {
@@ -150,7 +158,7 @@ const Dialog = forwardRef<DialogInstance, DialogProps>((originalProps, ref) => {
150158
}
151159

152160
const onMaskClick = (e: React.MouseEvent<HTMLDivElement>) => {
153-
if (!showOverlay) return;
161+
if (!showOverlay || isModeless || isInputInteracting) return;
154162
// 判断点击事件初次点击是否为内容区域
155163
if (contentClickRef.current) {
156164
contentClickRef.current = false;
@@ -256,6 +264,7 @@ const Dialog = forwardRef<DialogInstance, DialogProps>((originalProps, ref) => {
256264
className={classNames(className, `${componentCls}__ctx`, `${componentCls}__${mode}`, {
257265
[`${componentCls}__ctx--fixed`]: !showInAttachedElement,
258266
[`${componentCls}__ctx--absolute`]: showInAttachedElement,
267+
[`${componentCls}__ctx--modeless`]: isModeless,
259268
})}
260269
style={{ zIndex, display: animationVisible ? undefined : 'none' }}
261270
onKeyDown={handleKeyDown}
@@ -265,11 +274,14 @@ const Dialog = forwardRef<DialogInstance, DialogProps>((originalProps, ref) => {
265274
<div className={`${componentCls}__wrap`}>
266275
<div
267276
ref={dialogPosition}
268-
className={classNames(`${componentCls}__position`, {
269-
[`${componentCls}--top`]: !!props.top || props.placement === 'top',
270-
[`${componentCls}--center`]: props.placement === 'center' && !props.top,
271-
})}
272-
style={{ paddingTop: pxCompat(props.top) }}
277+
className={classNames(
278+
isFullScreen ? `${componentCls}__position_fullscreen` : `${componentCls}__position`,
279+
{
280+
[`${componentCls}--top`]: !isFullScreen && (!!props.top || props.placement === 'top'),
281+
[`${componentCls}--center`]: !isFullScreen && props.placement === 'center' && !props.top,
282+
},
283+
)}
284+
style={{ paddingTop: isFullScreen ? undefined : pxCompat(props.top) }}
273285
onClick={onMaskClick}
274286
>
275287
<CSSTransition
@@ -284,6 +296,7 @@ const Dialog = forwardRef<DialogInstance, DialogProps>((originalProps, ref) => {
284296
<DialogCard
285297
ref={dialogCardRef}
286298
{...restState}
299+
mode={mode}
287300
className={dialogClassName}
288301
style={{ ...style, width: pxCompat(width || style?.width) }}
289302
onConfirm={onConfirm}

packages/components/dialog/DialogCard.tsx

Lines changed: 51 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,26 @@
11
import React, { forwardRef, isValidElement } from 'react';
2-
import classNames from 'classnames';
3-
import { isString, isObject, isFunction } from 'lodash-es';
42
import {
3+
CheckCircleFilledIcon as TdCheckCircleFilledIcon,
54
CloseIcon as TdCloseIcon,
65
InfoCircleFilledIcon as TdInfoCircleFilledIcon,
7-
CheckCircleFilledIcon as TdCheckCircleFilledIcon,
86
} from 'tdesign-icons-react';
9-
import Button, { ButtonProps } from '../button';
10-
import { TdDialogCardProps } from './type';
11-
import { StyledProps } from '../common';
7+
import classNames from 'classnames';
8+
import { isFunction, isObject, isString } from 'lodash-es';
9+
1210
import parseTNode from '../_util/parseTNode';
11+
import Button, { type ButtonProps } from '../button';
1312
import useConfig from '../hooks/useConfig';
13+
import useDefaultProps from '../hooks/useDefaultProps';
1414
import useGlobalIcon from '../hooks/useGlobalIcon';
1515
import { useLocaleReceiver } from '../locale/LocalReceiver';
1616
import { dialogCardDefaultProps } from './defaultProps';
17-
import useDefaultProps from '../hooks/useDefaultProps';
17+
18+
import type { StyledProps } from '../common';
19+
import type { TdDialogCardProps, TdDialogProps } from './type';
1820

1921
export interface DialogCardProps extends TdDialogCardProps, StyledProps, React.HTMLAttributes<HTMLDivElement> {
2022
children?: React.ReactNode;
23+
mode?: TdDialogProps['mode'];
2124
}
2225

2326
const renderDialogButton = (btn: DialogCardProps['cancelBtn'], defaultProps: ButtonProps) => {
@@ -28,7 +31,7 @@ const renderDialogButton = (btn: DialogCardProps['cancelBtn'], defaultProps: But
2831
} else if (isValidElement(btn)) {
2932
result = btn;
3033
} else if (isObject(btn)) {
31-
result = <Button {...defaultProps} {...(btn as {})} />;
34+
result = <Button {...defaultProps} {...(btn as ButtonProps)} />;
3235
} else if (isFunction(btn)) {
3336
result = btn();
3437
}
@@ -62,9 +65,12 @@ const DialogCard = forwardRef<HTMLDivElement, DialogCardProps>((props, ref) => {
6265
cancelBtn = cancelText,
6366
confirmBtn = confirmText,
6467
confirmLoading,
68+
mode,
6569
...otherProps
6670
} = useDefaultProps<DialogCardProps>(props, dialogCardDefaultProps);
6771

72+
const isFullScreen = mode === 'full-screen';
73+
6874
const renderHeaderContent = () => {
6975
const iconMap = {
7076
info: <InfoCircleFilledIcon className={`${classPrefix}-is-info`} />,
@@ -92,7 +98,9 @@ const DialogCard = forwardRef<HTMLDivElement, DialogCardProps>((props, ref) => {
9298

9399
return (
94100
<span
95-
className={`${componentCls}__close`}
101+
className={classNames(`${componentCls}__close`, {
102+
[`${componentCls}__close--fullscreen`]: isFullScreen,
103+
})}
96104
style={{
97105
marginLeft: 'auto',
98106
}}
@@ -104,7 +112,11 @@ const DialogCard = forwardRef<HTMLDivElement, DialogCardProps>((props, ref) => {
104112
};
105113

106114
const renderHeader = () => (
107-
<div className={classNames(`${componentCls}__header`)}>
115+
<div
116+
className={classNames(`${componentCls}__header`, {
117+
[`${componentCls}__header--fullscreen`]: isFullScreen,
118+
})}
119+
>
108120
{renderHeaderContent()}
109121
{renderCloseBtn()}
110122
</div>
@@ -132,13 +144,39 @@ const DialogCard = forwardRef<HTMLDivElement, DialogCardProps>((props, ref) => {
132144
);
133145
};
134146

135-
return <div className={`${componentCls}__footer`}>{parseTNode(footer, null, defaultFooter())}</div>;
147+
return (
148+
<div
149+
className={classNames(`${componentCls}__footer`, {
150+
[`${componentCls}__footer--fullscreen`]: isFullScreen,
151+
})}
152+
>
153+
{parseTNode(footer, null, defaultFooter())}
154+
</div>
155+
);
136156
};
137157

138158
return (
139-
<div ref={ref} {...otherProps} className={classNames(componentCls, `${componentCls}--default`, className)}>
159+
<div
160+
ref={ref}
161+
{...otherProps}
162+
className={classNames(
163+
componentCls,
164+
`${componentCls}--default`,
165+
{
166+
[`${componentCls}__fullscreen`]: isFullScreen,
167+
},
168+
className,
169+
)}
170+
>
140171
{!!header && renderHeader()}
141-
<div className={`${componentCls}__body`}>{body || children}</div>
172+
<div
173+
className={classNames(`${componentCls}__body`, {
174+
[`${componentCls}__body--fullscreen`]: isFullScreen && !!footer,
175+
[`${componentCls}__body--fullscreen--without-footer`]: isFullScreen && !footer,
176+
})}
177+
>
178+
{body || children}
179+
</div>
142180
{!!footer && renderFooter()}
143181
</div>
144182
);

0 commit comments

Comments
 (0)