@rc-component/select 1.2.6 → 1.2.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/es/BaseSelect/index.js +12 -11
- package/es/Select.d.ts +1 -1
- package/es/SelectInput/index.js +2 -3
- package/es/hooks/useOpen.d.ts +3 -2
- package/es/hooks/useOpen.js +21 -17
- package/es/hooks/useSelectTriggerControl.d.ts +1 -2
- package/es/hooks/useSelectTriggerControl.js +1 -4
- package/lib/BaseSelect/index.js +12 -11
- package/lib/Select.d.ts +1 -1
- package/lib/SelectInput/index.js +2 -3
- package/lib/hooks/useOpen.d.ts +3 -2
- package/lib/hooks/useOpen.js +21 -17
- package/lib/hooks/useSelectTriggerControl.d.ts +1 -2
- package/lib/hooks/useSelectTriggerControl.js +1 -4
- package/package.json +1 -1
package/es/BaseSelect/index.js
CHANGED
|
@@ -9,7 +9,7 @@ import useSelectTriggerControl, { isInside } from "../hooks/useSelectTriggerCont
|
|
|
9
9
|
import SelectTrigger from "../SelectTrigger";
|
|
10
10
|
import { getSeparatedContent, isValidCount } from "../utils/valueUtil";
|
|
11
11
|
import Polite from "./Polite";
|
|
12
|
-
import useOpen from "../hooks/useOpen";
|
|
12
|
+
import useOpen, { macroTask } from "../hooks/useOpen";
|
|
13
13
|
import { useEvent } from '@rc-component/util';
|
|
14
14
|
import SelectInput from "../SelectInput";
|
|
15
15
|
import useComponents from "../hooks/useComponents";
|
|
@@ -309,12 +309,11 @@ const BaseSelect = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
|
309
309
|
}
|
|
310
310
|
};
|
|
311
311
|
const onRootBlur = () => {
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
}
|
|
312
|
+
macroTask(() => {
|
|
313
|
+
if (!isInside(getSelectElements(), document.activeElement)) {
|
|
314
|
+
triggerOpen(false);
|
|
315
|
+
}
|
|
316
|
+
});
|
|
318
317
|
};
|
|
319
318
|
const onInternalBlur = event => {
|
|
320
319
|
setFocused(false);
|
|
@@ -336,7 +335,7 @@ const BaseSelect = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
|
336
335
|
onBlur?.(event);
|
|
337
336
|
}
|
|
338
337
|
};
|
|
339
|
-
const
|
|
338
|
+
const onInternalMouseDown = (event, ...restArgs) => {
|
|
340
339
|
const {
|
|
341
340
|
target
|
|
342
341
|
} = event;
|
|
@@ -345,7 +344,9 @@ const BaseSelect = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
|
345
344
|
// We should give focus back to selector if clicked item is not focusable
|
|
346
345
|
if (popupElement?.contains(target) && triggerOpen) {
|
|
347
346
|
// Tell `open` not to close since it's safe in the popup
|
|
348
|
-
triggerOpen(true
|
|
347
|
+
triggerOpen(true, {
|
|
348
|
+
ignoreNext: true
|
|
349
|
+
});
|
|
349
350
|
}
|
|
350
351
|
onMouseDown?.(event, ...restArgs);
|
|
351
352
|
};
|
|
@@ -473,7 +474,7 @@ const BaseSelect = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
|
473
474
|
tokenWithEnter: tokenWithEnter
|
|
474
475
|
// Open
|
|
475
476
|
,
|
|
476
|
-
onMouseDown:
|
|
477
|
+
onMouseDown: onInternalMouseDown
|
|
477
478
|
// Components
|
|
478
479
|
,
|
|
479
480
|
components: mergedComponents
|
|
@@ -498,7 +499,7 @@ const BaseSelect = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
|
498
499
|
empty: emptyOptions,
|
|
499
500
|
onPopupVisibleChange: onTriggerVisibleChange,
|
|
500
501
|
onPopupMouseEnter: onPopupMouseEnter,
|
|
501
|
-
onPopupMouseDown:
|
|
502
|
+
onPopupMouseDown: onInternalMouseDown,
|
|
502
503
|
onPopupBlur: onRootBlur
|
|
503
504
|
}, renderNode);
|
|
504
505
|
return /*#__PURE__*/React.createElement(BaseSelectContext.Provider, {
|
package/es/Select.d.ts
CHANGED
|
@@ -125,7 +125,7 @@ export interface SelectProps<ValueType = any, OptionType extends BaseOptionType
|
|
|
125
125
|
classNames?: Partial<Record<SemanticName, string>>;
|
|
126
126
|
styles?: Partial<Record<SemanticName, React.CSSProperties>>;
|
|
127
127
|
}
|
|
128
|
-
declare const TypedSelect: (<ValueType = any, OptionType extends
|
|
128
|
+
declare const TypedSelect: (<ValueType = any, OptionType extends BaseOptionType | DefaultOptionType = DefaultOptionType>(props: React.PropsWithChildren<SelectProps<ValueType, OptionType>> & React.RefAttributes<BaseSelectRef>) => React.ReactElement) & {
|
|
129
129
|
Option: typeof Option;
|
|
130
130
|
OptGroup: typeof OptGroup;
|
|
131
131
|
};
|
package/es/SelectInput/index.js
CHANGED
|
@@ -105,13 +105,12 @@ export default /*#__PURE__*/React.forwardRef(function SelectInput(props, ref) {
|
|
|
105
105
|
// ====================== Open ======================
|
|
106
106
|
const onInternalMouseDown = useEvent(event => {
|
|
107
107
|
if (!disabled) {
|
|
108
|
-
const inputDOM = getDOM(inputRef.current);
|
|
109
|
-
|
|
110
108
|
// https://github.com/ant-design/ant-design/issues/56002
|
|
111
109
|
// Tell `useSelectTriggerControl` to ignore this event
|
|
112
110
|
// When icon is dynamic render, the parentNode will miss
|
|
113
111
|
// so we need to mark the event directly
|
|
114
|
-
event.nativeEvent.
|
|
112
|
+
event.nativeEvent._ignore_global_close = true;
|
|
113
|
+
const inputDOM = getDOM(inputRef.current);
|
|
115
114
|
if (inputDOM && event.target !== inputDOM && !inputDOM.contains(event.target)) {
|
|
116
115
|
event.preventDefault();
|
|
117
116
|
}
|
package/es/hooks/useOpen.d.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
export declare const macroTask: (fn: VoidFunction, times?: number) => void;
|
|
2
2
|
/**
|
|
3
3
|
* Trigger by latest open call, if nextOpen is undefined, means toggle.
|
|
4
|
-
*
|
|
4
|
+
* ignoreNext will skip next call in the macro task queue.
|
|
5
5
|
*/
|
|
6
6
|
export type TriggerOpenType = (nextOpen?: boolean, config?: {
|
|
7
|
-
|
|
7
|
+
ignoreNext?: boolean;
|
|
8
|
+
lazy?: boolean;
|
|
8
9
|
}) => void;
|
|
9
10
|
/**
|
|
10
11
|
* When `open` is controlled, follow the controlled value;
|
package/es/hooks/useOpen.js
CHANGED
|
@@ -17,7 +17,7 @@ export const macroTask = (fn, times = 1) => {
|
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
19
|
* Trigger by latest open call, if nextOpen is undefined, means toggle.
|
|
20
|
-
*
|
|
20
|
+
* ignoreNext will skip next call in the macro task queue.
|
|
21
21
|
*/
|
|
22
22
|
|
|
23
23
|
/**
|
|
@@ -41,6 +41,7 @@ export default function useOpen(propOpen, onOpen, postOpen) {
|
|
|
41
41
|
const ssrSafeOpen = rendered ? stateOpen : false;
|
|
42
42
|
const mergedOpen = postOpen(ssrSafeOpen);
|
|
43
43
|
const taskIdRef = useRef(0);
|
|
44
|
+
const taskLockRef = useRef(false);
|
|
44
45
|
const triggerEvent = useEvent(nextOpen => {
|
|
45
46
|
if (onOpen && mergedOpen !== nextOpen) {
|
|
46
47
|
onOpen(nextOpen);
|
|
@@ -49,29 +50,32 @@ export default function useOpen(propOpen, onOpen, postOpen) {
|
|
|
49
50
|
});
|
|
50
51
|
const toggleOpen = useEvent((nextOpen, config = {}) => {
|
|
51
52
|
const {
|
|
52
|
-
|
|
53
|
+
ignoreNext = false
|
|
53
54
|
} = config;
|
|
54
55
|
taskIdRef.current += 1;
|
|
55
56
|
const id = taskIdRef.current;
|
|
56
57
|
const nextOpenVal = typeof nextOpen === 'boolean' ? nextOpen : !mergedOpen;
|
|
57
|
-
function triggerUpdate() {
|
|
58
|
-
if (
|
|
59
|
-
// Always check if id is match
|
|
60
|
-
id === taskIdRef.current &&
|
|
61
|
-
// Check if need to cancel
|
|
62
|
-
!cancelFun?.()) {
|
|
63
|
-
triggerEvent(nextOpenVal);
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
58
|
|
|
67
|
-
//
|
|
59
|
+
// Since `mergedOpen` is post-processed, we need to check if the value really changed
|
|
68
60
|
if (nextOpenVal) {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
61
|
+
if (!taskLockRef.current) {
|
|
62
|
+
triggerEvent(nextOpenVal);
|
|
63
|
+
|
|
64
|
+
// Lock if needed
|
|
65
|
+
if (ignoreNext) {
|
|
66
|
+
taskLockRef.current = ignoreNext;
|
|
67
|
+
macroTask(() => {
|
|
68
|
+
taskLockRef.current = false;
|
|
69
|
+
}, 3);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return;
|
|
74
73
|
}
|
|
74
|
+
macroTask(() => {
|
|
75
|
+
if (id === taskIdRef.current && !taskLockRef.current) {
|
|
76
|
+
triggerEvent(nextOpenVal);
|
|
77
|
+
}
|
|
78
|
+
});
|
|
75
79
|
});
|
|
76
80
|
return [mergedOpen, toggleOpen];
|
|
77
81
|
}
|
|
@@ -1,3 +1,2 @@
|
|
|
1
|
-
import type { TriggerOpenType } from './useOpen';
|
|
2
1
|
export declare function isInside(elements: (HTMLElement | SVGElement | undefined)[], target: HTMLElement): boolean;
|
|
3
|
-
export default function useSelectTriggerControl(elements: () => (HTMLElement | SVGElement | undefined)[], open: boolean, triggerOpen:
|
|
2
|
+
export default function useSelectTriggerControl(elements: () => (HTMLElement | SVGElement | undefined)[], open: boolean, triggerOpen: (open: boolean) => void, customizedTrigger: boolean): void;
|
|
@@ -13,12 +13,9 @@ export default function useSelectTriggerControl(elements, open, triggerOpen, cus
|
|
|
13
13
|
if (target.shadowRoot && event.composed) {
|
|
14
14
|
target = event.composedPath()[0] || target;
|
|
15
15
|
}
|
|
16
|
-
if (event._ori_target) {
|
|
17
|
-
target = event._ori_target;
|
|
18
|
-
}
|
|
19
16
|
if (open &&
|
|
20
17
|
// Marked by SelectInput mouseDown event
|
|
21
|
-
!isInside(elements(), target)) {
|
|
18
|
+
!event._ignore_global_close && !isInside(elements(), target)) {
|
|
22
19
|
// Should trigger close
|
|
23
20
|
triggerOpen(false);
|
|
24
21
|
}
|
package/lib/BaseSelect/index.js
CHANGED
|
@@ -14,7 +14,7 @@ var _useSelectTriggerControl = _interopRequireWildcard(require("../hooks/useSele
|
|
|
14
14
|
var _SelectTrigger = _interopRequireDefault(require("../SelectTrigger"));
|
|
15
15
|
var _valueUtil = require("../utils/valueUtil");
|
|
16
16
|
var _Polite = _interopRequireDefault(require("./Polite"));
|
|
17
|
-
var _useOpen =
|
|
17
|
+
var _useOpen = _interopRequireWildcard(require("../hooks/useOpen"));
|
|
18
18
|
var _util = require("@rc-component/util");
|
|
19
19
|
var _SelectInput = _interopRequireDefault(require("../SelectInput"));
|
|
20
20
|
var _useComponents = _interopRequireDefault(require("../hooks/useComponents"));
|
|
@@ -318,12 +318,11 @@ const BaseSelect = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
|
318
318
|
}
|
|
319
319
|
};
|
|
320
320
|
const onRootBlur = () => {
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
}
|
|
321
|
+
(0, _useOpen.macroTask)(() => {
|
|
322
|
+
if (!(0, _useSelectTriggerControl.isInside)(getSelectElements(), document.activeElement)) {
|
|
323
|
+
triggerOpen(false);
|
|
324
|
+
}
|
|
325
|
+
});
|
|
327
326
|
};
|
|
328
327
|
const onInternalBlur = event => {
|
|
329
328
|
setFocused(false);
|
|
@@ -345,7 +344,7 @@ const BaseSelect = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
|
345
344
|
onBlur?.(event);
|
|
346
345
|
}
|
|
347
346
|
};
|
|
348
|
-
const
|
|
347
|
+
const onInternalMouseDown = (event, ...restArgs) => {
|
|
349
348
|
const {
|
|
350
349
|
target
|
|
351
350
|
} = event;
|
|
@@ -354,7 +353,9 @@ const BaseSelect = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
|
354
353
|
// We should give focus back to selector if clicked item is not focusable
|
|
355
354
|
if (popupElement?.contains(target) && triggerOpen) {
|
|
356
355
|
// Tell `open` not to close since it's safe in the popup
|
|
357
|
-
triggerOpen(true
|
|
356
|
+
triggerOpen(true, {
|
|
357
|
+
ignoreNext: true
|
|
358
|
+
});
|
|
358
359
|
}
|
|
359
360
|
onMouseDown?.(event, ...restArgs);
|
|
360
361
|
};
|
|
@@ -482,7 +483,7 @@ const BaseSelect = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
|
482
483
|
tokenWithEnter: tokenWithEnter
|
|
483
484
|
// Open
|
|
484
485
|
,
|
|
485
|
-
onMouseDown:
|
|
486
|
+
onMouseDown: onInternalMouseDown
|
|
486
487
|
// Components
|
|
487
488
|
,
|
|
488
489
|
components: mergedComponents
|
|
@@ -507,7 +508,7 @@ const BaseSelect = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
|
507
508
|
empty: emptyOptions,
|
|
508
509
|
onPopupVisibleChange: onTriggerVisibleChange,
|
|
509
510
|
onPopupMouseEnter: onPopupMouseEnter,
|
|
510
|
-
onPopupMouseDown:
|
|
511
|
+
onPopupMouseDown: onInternalMouseDown,
|
|
511
512
|
onPopupBlur: onRootBlur
|
|
512
513
|
}, renderNode);
|
|
513
514
|
return /*#__PURE__*/React.createElement(_useBaseProps.BaseSelectContext.Provider, {
|
package/lib/Select.d.ts
CHANGED
|
@@ -125,7 +125,7 @@ export interface SelectProps<ValueType = any, OptionType extends BaseOptionType
|
|
|
125
125
|
classNames?: Partial<Record<SemanticName, string>>;
|
|
126
126
|
styles?: Partial<Record<SemanticName, React.CSSProperties>>;
|
|
127
127
|
}
|
|
128
|
-
declare const TypedSelect: (<ValueType = any, OptionType extends
|
|
128
|
+
declare const TypedSelect: (<ValueType = any, OptionType extends BaseOptionType | DefaultOptionType = DefaultOptionType>(props: React.PropsWithChildren<SelectProps<ValueType, OptionType>> & React.RefAttributes<BaseSelectRef>) => React.ReactElement) & {
|
|
129
129
|
Option: typeof Option;
|
|
130
130
|
OptGroup: typeof OptGroup;
|
|
131
131
|
};
|
package/lib/SelectInput/index.js
CHANGED
|
@@ -114,13 +114,12 @@ var _default = exports.default = /*#__PURE__*/React.forwardRef(function SelectIn
|
|
|
114
114
|
// ====================== Open ======================
|
|
115
115
|
const onInternalMouseDown = (0, _util.useEvent)(event => {
|
|
116
116
|
if (!disabled) {
|
|
117
|
-
const inputDOM = (0, _findDOMNode.getDOM)(inputRef.current);
|
|
118
|
-
|
|
119
117
|
// https://github.com/ant-design/ant-design/issues/56002
|
|
120
118
|
// Tell `useSelectTriggerControl` to ignore this event
|
|
121
119
|
// When icon is dynamic render, the parentNode will miss
|
|
122
120
|
// so we need to mark the event directly
|
|
123
|
-
event.nativeEvent.
|
|
121
|
+
event.nativeEvent._ignore_global_close = true;
|
|
122
|
+
const inputDOM = (0, _findDOMNode.getDOM)(inputRef.current);
|
|
124
123
|
if (inputDOM && event.target !== inputDOM && !inputDOM.contains(event.target)) {
|
|
125
124
|
event.preventDefault();
|
|
126
125
|
}
|
package/lib/hooks/useOpen.d.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
export declare const macroTask: (fn: VoidFunction, times?: number) => void;
|
|
2
2
|
/**
|
|
3
3
|
* Trigger by latest open call, if nextOpen is undefined, means toggle.
|
|
4
|
-
*
|
|
4
|
+
* ignoreNext will skip next call in the macro task queue.
|
|
5
5
|
*/
|
|
6
6
|
export type TriggerOpenType = (nextOpen?: boolean, config?: {
|
|
7
|
-
|
|
7
|
+
ignoreNext?: boolean;
|
|
8
|
+
lazy?: boolean;
|
|
8
9
|
}) => void;
|
|
9
10
|
/**
|
|
10
11
|
* When `open` is controlled, follow the controlled value;
|
package/lib/hooks/useOpen.js
CHANGED
|
@@ -24,7 +24,7 @@ const macroTask = (fn, times = 1) => {
|
|
|
24
24
|
|
|
25
25
|
/**
|
|
26
26
|
* Trigger by latest open call, if nextOpen is undefined, means toggle.
|
|
27
|
-
*
|
|
27
|
+
* ignoreNext will skip next call in the macro task queue.
|
|
28
28
|
*/
|
|
29
29
|
exports.macroTask = macroTask;
|
|
30
30
|
/**
|
|
@@ -48,6 +48,7 @@ function useOpen(propOpen, onOpen, postOpen) {
|
|
|
48
48
|
const ssrSafeOpen = rendered ? stateOpen : false;
|
|
49
49
|
const mergedOpen = postOpen(ssrSafeOpen);
|
|
50
50
|
const taskIdRef = (0, _react.useRef)(0);
|
|
51
|
+
const taskLockRef = (0, _react.useRef)(false);
|
|
51
52
|
const triggerEvent = (0, _util.useEvent)(nextOpen => {
|
|
52
53
|
if (onOpen && mergedOpen !== nextOpen) {
|
|
53
54
|
onOpen(nextOpen);
|
|
@@ -56,29 +57,32 @@ function useOpen(propOpen, onOpen, postOpen) {
|
|
|
56
57
|
});
|
|
57
58
|
const toggleOpen = (0, _util.useEvent)((nextOpen, config = {}) => {
|
|
58
59
|
const {
|
|
59
|
-
|
|
60
|
+
ignoreNext = false
|
|
60
61
|
} = config;
|
|
61
62
|
taskIdRef.current += 1;
|
|
62
63
|
const id = taskIdRef.current;
|
|
63
64
|
const nextOpenVal = typeof nextOpen === 'boolean' ? nextOpen : !mergedOpen;
|
|
64
|
-
function triggerUpdate() {
|
|
65
|
-
if (
|
|
66
|
-
// Always check if id is match
|
|
67
|
-
id === taskIdRef.current &&
|
|
68
|
-
// Check if need to cancel
|
|
69
|
-
!cancelFun?.()) {
|
|
70
|
-
triggerEvent(nextOpenVal);
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
65
|
|
|
74
|
-
//
|
|
66
|
+
// Since `mergedOpen` is post-processed, we need to check if the value really changed
|
|
75
67
|
if (nextOpenVal) {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
68
|
+
if (!taskLockRef.current) {
|
|
69
|
+
triggerEvent(nextOpenVal);
|
|
70
|
+
|
|
71
|
+
// Lock if needed
|
|
72
|
+
if (ignoreNext) {
|
|
73
|
+
taskLockRef.current = ignoreNext;
|
|
74
|
+
macroTask(() => {
|
|
75
|
+
taskLockRef.current = false;
|
|
76
|
+
}, 3);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return;
|
|
81
80
|
}
|
|
81
|
+
macroTask(() => {
|
|
82
|
+
if (id === taskIdRef.current && !taskLockRef.current) {
|
|
83
|
+
triggerEvent(nextOpenVal);
|
|
84
|
+
}
|
|
85
|
+
});
|
|
82
86
|
});
|
|
83
87
|
return [mergedOpen, toggleOpen];
|
|
84
88
|
}
|
|
@@ -1,3 +1,2 @@
|
|
|
1
|
-
import type { TriggerOpenType } from './useOpen';
|
|
2
1
|
export declare function isInside(elements: (HTMLElement | SVGElement | undefined)[], target: HTMLElement): boolean;
|
|
3
|
-
export default function useSelectTriggerControl(elements: () => (HTMLElement | SVGElement | undefined)[], open: boolean, triggerOpen:
|
|
2
|
+
export default function useSelectTriggerControl(elements: () => (HTMLElement | SVGElement | undefined)[], open: boolean, triggerOpen: (open: boolean) => void, customizedTrigger: boolean): void;
|
|
@@ -22,12 +22,9 @@ function useSelectTriggerControl(elements, open, triggerOpen, customizedTrigger)
|
|
|
22
22
|
if (target.shadowRoot && event.composed) {
|
|
23
23
|
target = event.composedPath()[0] || target;
|
|
24
24
|
}
|
|
25
|
-
if (event._ori_target) {
|
|
26
|
-
target = event._ori_target;
|
|
27
|
-
}
|
|
28
25
|
if (open &&
|
|
29
26
|
// Marked by SelectInput mouseDown event
|
|
30
|
-
!isInside(elements(), target)) {
|
|
27
|
+
!event._ignore_global_close && !isInside(elements(), target)) {
|
|
31
28
|
// Should trigger close
|
|
32
29
|
triggerOpen(false);
|
|
33
30
|
}
|