Skip to content

Commit a3dda7d

Browse files
committed
fix: don't focus autocomplete after selecting item to avoid performaing async search again
1 parent 2dddb0d commit a3dda7d

File tree

2 files changed

+31
-14
lines changed

2 files changed

+31
-14
lines changed

packages/autocomplete/src/Autocomplete.svelte

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,14 @@
3535
'smui-autocomplete__menu': true,
3636
})}
3737
managed
38-
bind:open={menuOpen}
38+
neverRestoreFocus
39+
open={focused &&
40+
(text !== '' || showMenuWithNoInput) &&
41+
(loading ||
42+
(!combobox && !(matches.length === 1 && matches[0] === value)) ||
43+
(combobox &&
44+
!!matches.length &&
45+
!(matches.length === 1 && matches[0] === value)))}
3946
bind:anchorElement={element}
4047
anchor={menu$anchor}
4148
anchorCorner={menu$anchorCorner}
@@ -203,24 +210,17 @@
203210
let focusedIndex = -1;
204211
let focusedItem: SMUIListItemAccessor | undefined = undefined;
205212
206-
$: menuOpen =
207-
focused &&
208-
(text !== '' || showMenuWithNoInput) &&
209-
(loading ||
210-
(!combobox && !(matches.length === 1 && matches[0] === value)) ||
211-
(combobox &&
212-
!!matches.length &&
213-
!(matches.length === 1 && matches[0] === value)));
214-
215213
let previousText = text;
216214
$: if (previousText !== text) {
217215
if (!combobox && value != null && getOptionLabel(value) !== text) {
218216
deselectOption(value, false);
219217
}
220218
221-
performSearch();
222-
223-
previousText = text;
219+
// Only when we're focused do we need to perform a search.
220+
if (focused) {
221+
performSearch();
222+
previousText = text;
223+
}
224224
}
225225
226226
$: if (options) {
@@ -420,10 +420,20 @@
420420
.map((itemAccessor) => itemAccessor.element)
421421
.indexOf(event.relatedTarget as Element) !== -1
422422
) {
423+
// Wait until the item is selected.
424+
element.addEventListener(
425+
'SMUIAutocomplete:selected',
426+
() => {
427+
// Then clear the focus.
428+
focusedIndex = -1;
429+
focused = false;
430+
},
431+
{ once: true }
432+
);
423433
return;
424434
}
425435
426-
// Else, clear the currently focused item and mark as not focused.
436+
// Clear the focus and input.
427437
focusedIndex = -1;
428438
focused = false;
429439

packages/menu-surface/src/MenuSurface.svelte

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,11 @@
6363
* menu during positioning calculations.
6464
*/
6565
openBottomBias?: number;
66+
/**
67+
* Set this to true to never restore focus to the previously focused element
68+
* when the menu is closed.
69+
*/
70+
neverRestoreFocus?: boolean;
6671
};
6772
type $$Props = OwnProps &
6873
SmuiAttrs<
@@ -101,6 +106,7 @@
101106
export let maxHeight = 0;
102107
export let horizontallyCenteredOnViewport = false;
103108
export let openBottomBias = 0;
109+
export let neverRestoreFocus = false;
104110
105111
let element: HTMLDivElement;
106112
let instance: MDCMenuSurfaceFoundation;
@@ -235,6 +241,7 @@
235241
},
236242
restoreFocus: () => {
237243
if (
244+
!neverRestoreFocus &&
238245
(!element || element.contains(document.activeElement)) &&
239246
previousFocus &&
240247
document.contains(previousFocus) &&

0 commit comments

Comments
 (0)