Skip to content

Commit be22989

Browse files
fix(select): when no matching option keeps data-highlighted
1 parent 4553203 commit be22989

File tree

2 files changed

+27
-3
lines changed

2 files changed

+27
-3
lines changed

apps/website/src/routes/docs/headless/select/select.spec.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -527,6 +527,19 @@ test.describe('Keyboard Behavior', () => {
527527
const highlightedOpt = getRoot().locator('[data-highlighted]');
528528
await expect(highlightedOpt).toContainText('jessie', { ignoreCase: true });
529529
});
530+
531+
test(`GIVEN an open select with typeahead support and multiple characters
532+
WHEN the user types in a letter that does not match any option
533+
THEN the data-highlighted value should not change.`, async ({ page }) => {
534+
const { getRoot, getTrigger, openListbox } = await setup(
535+
page,
536+
'select-typeahead-test',
537+
);
538+
await openListbox('ArrowDown');
539+
await getTrigger().pressSequentially('am', { delay: 1250 });
540+
const highlightedOpt = getRoot().locator('[data-highlighted]');
541+
await expect(highlightedOpt).toContainText('abby', { ignoreCase: true });
542+
});
530543
});
531544
});
532545

packages/kit-headless/src/components/select/use-select.tsx

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ export function useTypeahead() {
1010
const firstCharOptionsSig = useComputed$(() => {
1111
return context.optionsSig.value.map((opt) => opt.value.slice(0, 1).toLowerCase());
1212
});
13+
const fullStrOptionsSig = useComputed$(() => {
14+
return context.optionsSig.value.map((opt) => opt.value.toLowerCase());
15+
});
1316

1417
const typeahead$ = $((key: string): void => {
1518
inputStrSig.value += key;
@@ -18,8 +21,6 @@ export function useTypeahead() {
1821
}
1922

2023
const firstCharOnly$ = $(() => {
21-
console.log('herehrere');
22-
2324
// First opens the listbox if it is not already displayed and then moves visual focus to the first option that matches the typed character.
2425
const singleInputChar = key.toLowerCase();
2526

@@ -55,12 +56,22 @@ export function useTypeahead() {
5556
});
5657

5758
const multipleChars$ = $(() => {
58-
console.log(inputStrSig.value);
59+
console.log('im running');
5960
// If multiple keys are typed in quick succession, visual focus moves to the first option that matches the full string.
6061
clearTimeout(prevTimeoutSig.value);
6162
prevTimeoutSig.value = setTimeout(() => {
6263
inputStrSig.value = '';
6364
}, 1000);
65+
const firstPossibleOpt = fullStrOptionsSig.value.findIndex((str) => {
66+
const size = inputStrSig.value.length;
67+
return str.substring(0, size) === inputStrSig.value;
68+
});
69+
if (firstPossibleOpt !== -1) {
70+
context.highlightedIndexSig.value = firstPossibleOpt;
71+
return;
72+
}
73+
inputStrSig.value = '';
74+
firstCharOnly$();
6475
});
6576

6677
if (inputStrSig.value.length === 1) {

0 commit comments

Comments
 (0)