Skip to content

Commit 2060988

Browse files
committed
chore: enhance logic
1 parent 529377d commit 2060988

File tree

3 files changed

+29
-13
lines changed

3 files changed

+29
-13
lines changed

docs/examples/controlled.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@ class Controlled extends React.Component<{}, ControlledState> {
4747
this.setState({ open });
4848
};
4949

50+
onActive = (value) => {
51+
console.error('onActive', value);
52+
};
53+
5054
render() {
5155
const { open, destroy, value } = this.state;
5256
if (destroy) {
@@ -69,6 +73,7 @@ class Controlled extends React.Component<{}, ControlledState> {
6973
optionFilterProp="text"
7074
onChange={this.onChange}
7175
onPopupVisibleChange={this.onPopupVisibleChange}
76+
onActive={this.onActive}
7277
>
7378
<Option value="01" text="jack" title="jack">
7479
<b

src/OptionList.tsx

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -154,20 +154,22 @@ const OptionList: React.ForwardRefRenderFunction<RefOptionListProps, {}> = (_, r
154154
* `setActive` function will call root accessibility state update which makes re-render.
155155
* So we need to delay to let Input component trigger onChange first.
156156
*/
157-
const timeoutId = setTimeout(() => {
158-
if (!multiple && open && rawValues.size === 1) {
159-
const value: RawValueType = Array.from(rawValues)[0];
160-
// Scroll to the option closest to the searchValue if searching.
161-
const index = memoFlattenOptions.findIndex(({ data }) =>
162-
searchValue ? String(data.value).startsWith(searchValue) : data.value === value,
163-
);
164-
165-
if (index !== -1) {
166-
setActive(index);
157+
let timeoutId: NodeJS.Timeout;
158+
159+
if (!multiple && open && rawValues.size === 1) {
160+
const value: RawValueType = Array.from(rawValues)[0];
161+
// Scroll to the option closest to the searchValue if searching.
162+
const index = memoFlattenOptions.findIndex(({ data }) =>
163+
searchValue ? String(data.value).startsWith(searchValue) : data.value === value,
164+
);
165+
166+
if (index !== -1) {
167+
setActive(index);
168+
timeoutId = setTimeout(() => {
167169
scrollIntoView(index);
168-
}
170+
});
169171
}
170-
});
172+
}
171173

172174
// Force trigger scrollbar visible when open
173175
if (open) {

src/Select.tsx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,8 @@ const Select = React.forwardRef<BaseSelectRef, SelectProps<any, DefaultOptionTyp
495495
const mergedDefaultActiveFirstOption =
496496
defaultActiveFirstOption !== undefined ? defaultActiveFirstOption : mode !== 'combobox';
497497

498+
const activeEventRef = React.useRef<Promise<void>>();
499+
498500
const onActiveValue: OnActiveValue = React.useCallback(
499501
(active, index, { source = 'keyboard' } = {}) => {
500502
setAccessibilityIndex(index);
@@ -503,7 +505,14 @@ const Select = React.forwardRef<BaseSelectRef, SelectProps<any, DefaultOptionTyp
503505
setActiveValue(String(active));
504506
}
505507

506-
onActive?.(active);
508+
// Active will call multiple times.
509+
// We only need trigger the last one.
510+
const promise = Promise.resolve().then(() => {
511+
if (activeEventRef.current === promise) {
512+
onActive?.(active);
513+
}
514+
});
515+
activeEventRef.current = promise;
507516
},
508517
[backfill, mode, onActive],
509518
);

0 commit comments

Comments
 (0)