Skip to content

Commit 5fed86a

Browse files
committed
refactor: bind onMouseDown to the outer div
1 parent 6775691 commit 5fed86a

4 files changed

Lines changed: 12 additions & 49 deletions

File tree

packages/components/input/Input.tsx

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,6 @@ const Input = forwardRefWithStatics(
122122
// inputPreRef 用于预存输入框宽度,应用在 auto width 模式中
123123
const inputPreRef: React.RefObject<HTMLInputElement> = useRef(null);
124124
const wrapperRef: React.RefObject<HTMLDivElement> = useRef(null);
125-
const isClickingIconRef = useRef(false);
126125

127126
const [isHover, toggleIsHover] = useState(false);
128127
const [isFocused, toggleIsFocused] = useState(false);
@@ -143,7 +142,6 @@ const Input = forwardRefWithStatics(
143142
suffixIconNew = (
144143
<CloseCircleFilledIcon
145144
className={`${classPrefix}-input__suffix-clear`}
146-
onMouseDown={handleMouseDown}
147145
onClick={handleClear}
148146
/>
149147
);
@@ -157,7 +155,6 @@ const Input = forwardRefWithStatics(
157155
suffixIconNew = (
158156
<PasswordIcon
159157
className={`${classPrefix}-input__suffix-clear`}
160-
onMouseDown={handleMouseDown}
161158
onClick={togglePasswordVisible}
162159
/>
163160
);
@@ -273,6 +270,7 @@ const Input = forwardRefWithStatics(
273270
})}
274271
onMouseEnter={handleMouseEnter}
275272
onMouseLeave={handleMouseLeave}
273+
onMouseDown={handleMouseDown}
276274
onWheel={(e) => onWheel?.({ e })}
277275
onClick={(e) => {
278276
inputRef.current?.focus();
@@ -308,7 +306,6 @@ const Input = forwardRefWithStatics(
308306

309307
requestAnimationFrame(() => {
310308
inputEl?.setSelectionRange(cursorPosition, cursorPosition);
311-
isClickingIconRef.current = false;
312309
});
313310
}
314311

@@ -330,18 +327,15 @@ const Input = forwardRefWithStatics(
330327
}
331328
// 添加MouseDown阻止冒泡,防止點擊Clear value會導致彈窗閃爍一下
332329
// https://github.com/Tencent/tdesign-react/issues/2320
333-
function handleMouseDown(e: React.MouseEvent<SVGSVGElement, globalThis.MouseEvent>) {
330+
function handleMouseDown(e: React.MouseEvent<HTMLDivElement, globalThis.MouseEvent>) {
331+
e.preventDefault(); // 阻止默认行为,防止焦点转移
334332
e.stopPropagation();
335333
// 兼容React16
336334
e.nativeEvent.stopImmediatePropagation();
337-
isClickingIconRef.current = true;
338335
}
339336
function handleClear(e: React.MouseEvent<SVGSVGElement>) {
340337
onChange?.('', { e, trigger: 'clear' });
341338
onClear?.({ e });
342-
requestAnimationFrame(() => {
343-
isClickingIconRef.current = false;
344-
});
345339
}
346340
function handleKeyDown(e: React.KeyboardEvent<HTMLInputElement>) {
347341
const {
@@ -382,7 +376,6 @@ const Input = forwardRefWithStatics(
382376
}
383377

384378
function handleFocus(e: React.FocusEvent<HTMLInputElement>) {
385-
if (isClickingIconRef.current) return;
386379
const {
387380
currentTarget: { value },
388381
} = e;
@@ -392,7 +385,6 @@ const Input = forwardRefWithStatics(
392385
}
393386

394387
function handleBlur(e: React.FocusEvent<HTMLInputElement>) {
395-
if (isClickingIconRef.current) return;
396388
const {
397389
currentTarget: { value },
398390
} = e;

packages/components/input/__tests__/input.test.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React from 'react';
2-
import { render, fireEvent, vi, act, mockTimeout } from '@test/utils';
2+
import { render, fireEvent, vi, act } from '@test/utils';
33
import userEvent from '@testing-library/user-event';
44
import Input from '../Input';
55

@@ -47,7 +47,6 @@ describe('Input 组件测试', () => {
4747
fireEvent.mouseUp(clearIcon);
4848
fireEvent.click(clearIcon);
4949
expect(blurFn).toBeCalledTimes(0);
50-
await mockTimeout(() => true);
5150
fireEvent.blur(InputDom);
5251
expect(blurFn).toBeCalledTimes(1);
5352
});

packages/components/select-input/useMultiple.tsx

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ export default function useMultiple(props: SelectInputProps) {
3737
const [tInputValue, setTInputValue] = useControlled(props, 'inputValue', props.onInputChange);
3838

3939
const tagInputRef = useRef<InputRef>(null);
40-
const blurTimeoutRef = useRef(null);
4140

4241
const iKeys: SelectInputKeys = { ...DEFAULT_KEYS, ...props.keys };
4342

@@ -61,30 +60,17 @@ export default function useMultiple(props: SelectInputProps) {
6160

6261
const renderSelectMultiple = (p: RenderSelectMultipleParams) => {
6362
const handleBlur = (value: SelectInputValue, context: { e: React.FocusEvent<HTMLInputElement> }) => {
64-
if (blurTimeoutRef.current) {
65-
clearTimeout(blurTimeoutRef.current);
63+
if (!p.popupVisible) {
64+
p.onInnerBlur(context);
65+
} else if (!props.panel) {
66+
props.onBlur?.(value, { e: context.e, inputValue: tInputValue, tagInputValue: tags });
6667
}
67-
// 强制把 popupVisible 设置为 false 时,点击 input,会出现 blur -> focus 的情况,因此忽略前面短暂的 blur 事件
68-
blurTimeoutRef.current = setTimeout(() => {
69-
if (blurTimeoutRef.current) {
70-
if (!p.popupVisible) {
71-
p.onInnerBlur(context);
72-
} else if (!props.panel) {
73-
props.onBlur?.(value, { e: context.e, inputValue: tInputValue, tagInputValue: tags });
74-
}
75-
}
76-
blurTimeoutRef.current = null;
77-
}, 150);
7868
};
7969

8070
const handleFocus = (
8171
val: TagInputValue,
8272
context: { e: React.FocusEvent<HTMLInputElement>; inputValue: string },
8373
) => {
84-
if (blurTimeoutRef.current) {
85-
clearTimeout(blurTimeoutRef.current);
86-
blurTimeoutRef.current = null;
87-
}
8874
props.onFocus?.(props.value, { ...context, tagInputValue: val });
8975
};
9076

packages/components/select-input/useSingle.tsx

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ export default function useSingle(props: TdSelectInputProps) {
4848
const { classPrefix } = useConfig();
4949

5050
const inputRef = useRef<InputRef>(null);
51-
const blurTimeoutRef = useRef(null);
5251

5352
const [inputValue, setInputValue] = useControlled(props, 'inputValue', props.onInputChange);
5453

@@ -78,27 +77,14 @@ export default function useSingle(props: TdSelectInputProps) {
7877
const displayedValue = popupVisible && props.allowInput ? inputValue : getInputValue(value, keys);
7978

8079
const handleBlur = (value, ctx) => {
81-
if (blurTimeoutRef.current) {
82-
clearTimeout(blurTimeoutRef.current);
80+
if (!popupVisible) {
81+
onInnerBlur(ctx);
82+
} else if (!props.panel) {
83+
props.onBlur?.(value, { e: ctx.e, inputValue: value });
8384
}
84-
// 强制把 popupVisible 设置为 false 时,点击 input,会出现 blur -> focus 的情况,因此忽略前面短暂的 blur 事件
85-
blurTimeoutRef.current = setTimeout(() => {
86-
if (blurTimeoutRef.current) {
87-
if (!popupVisible) {
88-
onInnerBlur(ctx);
89-
} else if (!props.panel) {
90-
props.onBlur?.(value, { e: ctx.e, inputValue: value });
91-
}
92-
}
93-
blurTimeoutRef.current = null;
94-
}, 150);
9585
};
9686

9787
const handleFocus = (val, context) => {
98-
if (blurTimeoutRef.current) {
99-
clearTimeout(blurTimeoutRef.current);
100-
blurTimeoutRef.current = null;
101-
}
10288
props.onFocus?.(value, { ...context, inputValue: val });
10389
// focus might not need to change input value. it will caught some curious errors in tree-select
10490
// !popupVisible && setInputValue(getInputValue(value, keys), { ...context, trigger: 'input' });

0 commit comments

Comments
 (0)