Skip to content

Commit b225261

Browse files
authored
Merge branch 'Tencent:develop' into fix/calendar
2 parents eed44a7 + 6d625f2 commit b225261

File tree

6 files changed

+67
-29
lines changed

6 files changed

+67
-29
lines changed

packages/components/date-picker/DatePicker.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,6 @@ const DatePicker = forwardRef<HTMLDivElement, DatePickerProps>((originalProps, r
153153
if (enableTimePicker) {
154154
setCacheValue(formatDate(date, { format }));
155155
if (props.needConfirm) return;
156-
handlePopupInvisible();
157156
onChange(formatDate(date, { format, targetFormat: valueType }), {
158157
dayjsValue: parseToDayjs(date, format),
159158
trigger: 'pick',

packages/components/date-picker/DateRangePicker.tsx

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ import { addMonth, extractTimeObj, subtractMonth } from '@tdesign/common-js/date
1313
import log from '@tdesign/common-js/log/index';
1414
import useConfig from '../hooks/useConfig';
1515
import useDefaultProps from '../hooks/useDefaultProps';
16+
import useLatest from '../hooks/useLatest';
17+
import useUpdateEffect from '../hooks/useUpdateEffect';
1618
import { RangeInputPopup } from '../range-input';
1719
import { dateRangePickerDefaultProps } from './defaultProps';
1820
import useRange from './hooks/useRange';
@@ -44,6 +46,7 @@ const DateRangePicker = forwardRef<HTMLDivElement, DateRangePickerProps>((origin
4446
cancelRangeSelectLimit,
4547
onPick,
4648
disableTime,
49+
needConfirm,
4750
} = props;
4851

4952
const {
@@ -97,6 +100,30 @@ const DateRangePicker = forwardRef<HTMLDivElement, DateRangePickerProps>((origin
97100
props.popupProps?.onVisibleChange?.(false, {});
98101
};
99102

103+
const onTriggerNeedConfirm = useLatest(() => {
104+
if (needConfirm || !enableTimePicker || popupVisible) return;
105+
106+
const nextValue = [...inputValue];
107+
const notValidIndex = nextValue.findIndex((v) => !v || !isValidDate(v, format));
108+
109+
// Only proceed when both ends have valid values
110+
if (notValidIndex === -1 && nextValue.length === 2) {
111+
const currentValue = formatDate(value || [], { format });
112+
113+
// Only trigger onChange when value actually changes
114+
if (currentValue[0] !== nextValue[0] || currentValue[1] !== nextValue[1]) {
115+
const formattedValue = formatDate(nextValue, { format, targetFormat: valueType, autoSwap: true });
116+
onChange(formattedValue, {
117+
dayjsValue: nextValue.map((v) => parseToDayjs(v, format)),
118+
trigger: 'confirm',
119+
});
120+
}
121+
} else {
122+
// If there's invalid input, restore to original value
123+
setInputValue(formatDate(value || [], { format }));
124+
}
125+
});
126+
100127
useEffect(() => {
101128
if (value === cacheValue) return;
102129
// 面板展开重置数据
@@ -132,6 +159,11 @@ const DateRangePicker = forwardRef<HTMLDivElement, DateRangePickerProps>((origin
132159
// eslint-disable-next-line
133160
}, [popupVisible]);
134161

162+
// Listen to popupVisible changes, handle auto-confirm for needConfirm=false
163+
useUpdateEffect(() => {
164+
onTriggerNeedConfirm.current();
165+
}, [popupVisible]);
166+
135167
// 日期 hover
136168
function onCellMouseEnter(date: Date) {
137169
setIsHoverCell(true);
@@ -380,6 +412,7 @@ const DateRangePicker = forwardRef<HTMLDivElement, DateRangePickerProps>((origin
380412
activeIndex,
381413
popupVisible,
382414
cancelRangeSelectLimit,
415+
needConfirm,
383416
onCellClick,
384417
onCellMouseEnter,
385418
onCellMouseLeave,

packages/components/hooks/useMouseEvent.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,10 @@ const useMouseEvent = (elementRef: React.RefObject<HTMLElement>, options: MouseE
8282
};
8383

8484
const handleMouseDown = (e: MouseEventLike) => {
85+
// 只处理鼠标左键,忽略中和右键
86+
// 触摸事件没有 button 属性,会正常处理
87+
if ('button' in e && e.button !== 0) return;
88+
8589
isMovingRef.current = true;
8690
emitMouseChange(e, options.onDown);
8791
document.addEventListener('mouseup', handleMouseUp);

packages/components/menu/MenuGroup.tsx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import React from 'react';
22
import classNames from 'classnames';
3-
import { StyledProps, TNode } from '../common';
4-
import { TdMenuGroupProps } from './type';
3+
54
import useConfig from '../hooks/useConfig';
6-
import { cacularPaddingLeft } from './_util/cacularPaddingLeft';
5+
import { calculatePaddingLeft } from './_util/calculatePaddingLeft';
6+
import type { StyledProps, TNode } from '../common';
7+
import type { TdMenuGroupProps } from './type';
78

89
export interface MenuGroupProps extends TdMenuGroupProps, StyledProps {
910
children?: TNode;
@@ -14,7 +15,7 @@ const MenuGroup: React.FC<MenuGroupProps> = ({ title, className, style, children
1415
const { classPrefix } = useConfig();
1516

1617
const itemAndGroupPaddingBias = 28;
17-
const menuPaddingLeft = cacularPaddingLeft(level - 1) - itemAndGroupPaddingBias;
18+
const menuPaddingLeft = calculatePaddingLeft(level - 1) - itemAndGroupPaddingBias;
1819

1920
return (
2021
<div className={classNames(className, `${classPrefix}-menu-group`)} style={style}>

packages/components/menu/SubMenu.tsx

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,22 @@
1-
import React, { FC, useContext, useState, ReactElement, useMemo, useRef } from 'react';
21
import classNames from 'classnames';
2+
import React, { FC, ReactElement, useContext, useMemo, useRef } from 'react';
33
import { CSSTransition } from 'react-transition-group';
4-
import { StyledProps } from '../common';
5-
import type { TdSubmenuProps } from './type';
4+
5+
import parseTNode from '../_util/parseTNode';
6+
import FakeArrow from '../common/FakeArrow';
67
import useConfig from '../hooks/useConfig';
7-
import { MenuContext } from './MenuContext';
8+
import useControlled from '../hooks/useControlled';
89
import useDomRefCallback from '../hooks/useDomRefCallback';
910
import useRipple from '../hooks/useRipple';
10-
import { getSubMenuMaxHeight } from './_util/getSubMenuChildStyle';
11+
import { Popup, type PopupPlacement } from '../popup';
12+
import { calculatePaddingLeft } from './_util/calculatePaddingLeft';
13+
import { checkIsMenuGroup, checkIsSubMenu } from './_util/checkMenuType';
1114
import checkSubMenuChildrenActive from './_util/checkSubMenuChildrenActive';
12-
import FakeArrow from '../common/FakeArrow';
13-
import { checkIsSubMenu, checkIsMenuGroup } from './_util/checkMenuType';
14-
import { cacularPaddingLeft } from './_util/cacularPaddingLeft';
15-
import { Popup, PopupPlacement } from '../popup';
16-
import parseTNode from '../_util/parseTNode';
15+
import { getSubMenuMaxHeight } from './_util/getSubMenuChildStyle';
16+
import { MenuContext } from './MenuContext';
17+
18+
import type { StyledProps } from '../common';
19+
import type { TdSubmenuProps } from './type';
1720

1821
export interface SubMenuProps extends TdSubmenuProps, StyledProps {}
1922

@@ -25,25 +28,24 @@ const SubAccordion: FC<SubMenuWithCustomizeProps> = (props) => {
2528
const { content, children = content, disabled, icon, title, value, className, style, level = 1, popupProps } = props;
2629
const { overlayClassName, overlayInnerClassName, ...restPopupProps } = popupProps || {};
2730

31+
const [open, setOpen] = useControlled(popupProps, 'visible', restPopupProps.onVisibleChange);
32+
2833
const { classPrefix } = useConfig();
2934

30-
// popup 状态下控制开关
31-
const [open, setOpen] = useState(false);
3235
const { expanded = [], onExpand, active, expandType, theme = 'light' } = useContext(MenuContext);
3336

3437
const isPopUp = expandType === 'popup';
35-
3638
// 非 popup 展开
3739
const isExpand = expanded.includes(value) && !disabled && !isPopUp;
3840

3941
const handleClick = (e: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
4042
e.stopPropagation();
4143
onExpand(value, expanded);
42-
setOpen(false);
44+
setOpen(false, {});
4345
};
4446

45-
const handleVisibleChange = (visible: boolean) => {
46-
setOpen(visible);
47+
const handleVisibleChange = (visible: boolean, ctx) => {
48+
setOpen(visible, ctx);
4749
};
4850

4951
const popupChildren = React.Children.map(children, (child) =>
@@ -70,7 +72,7 @@ const SubAccordion: FC<SubMenuWithCustomizeProps> = (props) => {
7072
}, [disabled, isPopUp, open, isExpand]);
7173

7274
// 计算左边距,兼容多层级子菜单
73-
const menuPaddingLeft = cacularPaddingLeft(level - 1);
75+
const menuPaddingLeft = calculatePaddingLeft(level - 1);
7476

7577
const fakeArrowStyle = isPopUp && level > 1 ? { transform: 'rotate(-90deg)' } : {};
7678

@@ -160,9 +162,9 @@ const SubAccordion: FC<SubMenuWithCustomizeProps> = (props) => {
160162
{ [`${classPrefix}-menu-is-nested`]: level > 1 },
161163
overlayClassName,
162164
]}
163-
visible={open}
164165
placement="right-top"
165166
content={pupContent}
167+
visible={open}
166168
onVisibleChange={handleVisibleChange}
167169
>
168170
{submenu}
@@ -175,17 +177,16 @@ const SubAccordion: FC<SubMenuWithCustomizeProps> = (props) => {
175177

176178
const SubTitleMenu: FC<SubMenuWithCustomizeProps> = (props) => {
177179
const { className, style, children, disabled, icon, title, value, level = 1, popupProps } = props;
178-
179180
const { overlayClassName, overlayInnerClassName, ...restPopupProps } = popupProps || {};
180181

182+
const [open, setOpen] = useControlled(popupProps, 'visible', restPopupProps.onVisibleChange);
181183
const { active, onChange, expandType, theme = 'light' } = useContext(MenuContext);
182184
const { classPrefix } = useConfig();
183-
const [open, setOpen] = useState(false);
184185

185186
const handleClick = () => onChange(value);
186187

187-
const handleVisibleChange = (visible: boolean) => {
188-
setOpen(visible);
188+
const handleVisibleChange = (visible: boolean, ctx) => {
189+
setOpen(visible, ctx);
189190
};
190191

191192
// 斜八角动画
@@ -262,9 +263,9 @@ const SubTitleMenu: FC<SubMenuWithCustomizeProps> = (props) => {
262263
{ [`${classPrefix}-menu-is-nested`]: level > 1 },
263264
overlayClassName,
264265
]}
265-
visible={open}
266266
placement={placement as PopupPlacement}
267267
content={pupContent}
268+
visible={open}
268269
onVisibleChange={handleVisibleChange}
269270
>
270271
{submenu}
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
const DEFAULT_SUBMENU_PADDING_LEFT = 44;
22
const INCREASE_SUBMENU_PADDING_LEFT = 16;
33

4-
export const cacularPaddingLeft = (level: number) =>
4+
export const calculatePaddingLeft = (level: number) =>
55
DEFAULT_SUBMENU_PADDING_LEFT + level * INCREASE_SUBMENU_PADDING_LEFT;

0 commit comments

Comments
 (0)