Skip to content

Commit 370a165

Browse files
committed
chore: new logic of passing
1 parent 0ca69af commit 370a165

File tree

4 files changed

+81
-27
lines changed

4 files changed

+81
-27
lines changed

src/BaseSelect/index.tsx

Lines changed: 40 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -682,25 +682,11 @@ const BaseSelect = React.forwardRef<BaseSelectRef, BaseSelectProps>((props, ref)
682682
const { target } = event;
683683
const popupElement: HTMLDivElement = triggerRef.current?.getPopupElement();
684684

685-
console.log('???');
686-
687685
// We should give focus back to selector if clicked item is not focusable
688-
// if (popupElement?.contains(target as HTMLElement)) {
689-
// const timeoutId = setTimeout(() => {
690-
// const index = activeTimeoutIds.indexOf(timeoutId);
691-
// if (index !== -1) {
692-
// activeTimeoutIds.splice(index, 1);
693-
// }
694-
695-
// cancelSetMockFocused();
696-
697-
// if (!mobile && !popupElement.contains(document.activeElement)) {
698-
// selectorRef.current?.focus();
699-
// }
700-
// });
701-
702-
// activeTimeoutIds.push(timeoutId);
703-
// }
686+
if (popupElement?.contains(target as HTMLElement) && triggerOpen) {
687+
// Tell `open` not to close since it's safe in the popup
688+
triggerOpen(true, true);
689+
}
704690

705691
onMouseDown?.(event, ...restArgs);
706692
};
@@ -881,9 +867,6 @@ const BaseSelect = React.forwardRef<BaseSelectRef, BaseSelectProps>((props, ref)
881867
// </SelectTrigger>
882868
// );
883869

884-
// >>> Render
885-
let renderNode: React.ReactNode;
886-
887870
// Render raw
888871
// if (customizeRawInputElement) {
889872
// renderNode = selectorNode;
@@ -907,7 +890,8 @@ const BaseSelect = React.forwardRef<BaseSelectRef, BaseSelectProps>((props, ref)
907890
// );
908891
// }
909892

910-
renderNode = (
893+
// >>> Render
894+
let renderNode: React.ReactElement = (
911895
<SelectInput
912896
{...restProps}
913897
// Ref
@@ -947,6 +931,39 @@ const BaseSelect = React.forwardRef<BaseSelectRef, BaseSelectProps>((props, ref)
947931
/>
948932
);
949933

934+
// const renderSelectTrigger = (childrenNode?: React.ReactElement) => (
935+
// <SelectTrigger
936+
// ref={triggerRef}
937+
// disabled={disabled}
938+
// prefixCls={prefixCls}
939+
// visible={mergedOpen}
940+
// popupElement={optionList}
941+
// animation={animation}
942+
// transitionName={transitionName}
943+
// popupStyle={popupStyle}
944+
// popupClassName={popupClassName}
945+
// direction={direction}
946+
// popupMatchSelectWidth={popupMatchSelectWidth}
947+
// popupRender={popupRender}
948+
// popupAlign={popupAlign}
949+
// placement={placement}
950+
// builtinPlacements={builtinPlacements}
951+
// getPopupContainer={getPopupContainer}
952+
// empty={emptyOptions}
953+
// // onPopupVisibleChange={onTriggerVisibleChange}
954+
// onPopupMouseEnter={onPopupMouseEnter}
955+
// >
956+
// {childrenNode}
957+
// </SelectTrigger>
958+
// );
959+
960+
// if (components.root) {
961+
// renderNode = renderSelectTrigger(renderSelectInput());
962+
// } else {
963+
// // renderNode = renderSelectInput(renderSelectTrigger());
964+
// renderNode = renderSelectInput(renderSelectTrigger(<a />));
965+
// }
966+
950967
renderNode = (
951968
<SelectTrigger
952969
ref={triggerRef}
@@ -968,6 +985,7 @@ const BaseSelect = React.forwardRef<BaseSelectRef, BaseSelectProps>((props, ref)
968985
empty={emptyOptions}
969986
// onPopupVisibleChange={onTriggerVisibleChange}
970987
onPopupMouseEnter={onPopupMouseEnter}
988+
onPopupMouseDown={onInternalMouseDown}
971989
>
972990
{renderNode}
973991
</SelectTrigger>

src/SelectInput/index.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ export interface SelectInputProps extends Omit<React.HTMLAttributes<HTMLDivEleme
4444
style?: React.CSSProperties;
4545
focused?: boolean;
4646
components: ComponentsConfig;
47+
children?: React.ReactElement;
4748
}
4849

4950
const DEFAULT_OMIT_PROPS = [
@@ -77,6 +78,7 @@ export default React.forwardRef<SelectInputRef, SelectInputProps>(function Selec
7778
prefix,
7879
suffix,
7980
clearIcon,
81+
children,
8082

8183
// Data
8284
multiple,
@@ -281,6 +283,7 @@ export default React.forwardRef<SelectInputRef, SelectInputProps>(function Selec
281283
{clearIcon}
282284
</Affix>
283285
)}
286+
{children}
284287
</div>
285288
</SelectInputContext.Provider>
286289
);

src/SelectTrigger.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ export interface SelectTriggerProps {
7676
onPopupVisibleChange?: (visible: boolean) => void;
7777

7878
onPopupMouseEnter: () => void;
79+
onPopupMouseDown: React.MouseEventHandler<HTMLDivElement>;
7980
}
8081

8182
const SelectTrigger: React.ForwardRefRenderFunction<RefTriggerProps, SelectTriggerProps> = (
@@ -102,6 +103,7 @@ const SelectTrigger: React.ForwardRefRenderFunction<RefTriggerProps, SelectTrigg
102103
empty,
103104
onPopupVisibleChange,
104105
onPopupMouseEnter,
106+
onPopupMouseDown,
105107
...restProps
106108
} = props;
107109

@@ -162,7 +164,11 @@ const SelectTrigger: React.ForwardRefRenderFunction<RefTriggerProps, SelectTrigg
162164
builtinPlacements={mergedBuiltinPlacements}
163165
prefixCls={popupPrefixCls}
164166
popupMotion={{ motionName: mergedTransitionName }}
165-
popup={<div onMouseEnter={onPopupMouseEnter}>{popupNode}</div>}
167+
popup={
168+
<div onMouseEnter={onPopupMouseEnter} onMouseDown={onPopupMouseDown}>
169+
{popupNode}
170+
</div>
171+
}
166172
ref={triggerPopupRef}
167173
stretch={stretch}
168174
popupAlign={popupAlign}

src/hooks/useOpen.ts

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,29 @@
11
import { useControlledState, useEvent } from '@rc-component/util';
22
import { useRef } from 'react';
33

4-
const macroTask = (fn: VoidFunction) => {
4+
const internalMacroTask = (fn: VoidFunction) => {
55
const channel = new MessageChannel();
66
channel.port1.onmessage = fn;
77
channel.port2.postMessage(null);
88
};
99

10+
const macroTask = (fn: VoidFunction, times = 1) => {
11+
if (times <= 0) {
12+
fn();
13+
return;
14+
}
15+
16+
internalMacroTask(() => {
17+
macroTask(fn, times - 1);
18+
});
19+
};
20+
21+
/**
22+
* Trigger by latest open call, if nextOpen is undefined, means toggle.
23+
* ignoreNext will skip next call in the macro task queue.
24+
*/
25+
export type TriggerOpenType = (nextOpen?: boolean, ignoreNext?: boolean) => void;
26+
1027
/**
1128
* When `open` is controlled, follow the controlled value;
1229
* Otherwise use uncontrolled logic.
@@ -17,11 +34,12 @@ export default function useOpen(
1734
propOpen: boolean,
1835
onOpen: (nextOpen: boolean) => void,
1936
postOpen: (nextOpen: boolean) => boolean,
20-
) {
37+
): [boolean, TriggerOpenType] {
2138
const [stateOpen, internalSetOpen] = useControlledState(false, propOpen);
2239
const mergedOpen = postOpen(stateOpen);
2340

2441
const taskIdRef = useRef(0);
42+
const taskLockRef = useRef(false);
2543

2644
const triggerEvent = useEvent((nextOpen: boolean) => {
2745
if (onOpen && mergedOpen !== nextOpen) {
@@ -30,7 +48,7 @@ export default function useOpen(
3048
internalSetOpen(nextOpen);
3149
});
3250

33-
const toggleOpen = useEvent((nextOpen?: boolean) => {
51+
const toggleOpen = useEvent<TriggerOpenType>((nextOpen?: boolean, ignoreNext = false) => {
3452
taskIdRef.current += 1;
3553
const id = taskIdRef.current;
3654

@@ -39,11 +57,20 @@ export default function useOpen(
3957
// Since `mergedOpen` is post-processed, we need to check if the value really changed
4058
if (nextOpenVal) {
4159
triggerEvent(true);
60+
61+
// Lock if needed
62+
if (ignoreNext) {
63+
taskLockRef.current = ignoreNext;
64+
65+
macroTask(() => {
66+
taskLockRef.current = false;
67+
}, 2);
68+
}
4269
return;
4370
}
4471

4572
macroTask(() => {
46-
if (id === taskIdRef.current) {
73+
if (id === taskIdRef.current && !taskLockRef.current) {
4774
triggerEvent(false);
4875
}
4976
});

0 commit comments

Comments
 (0)