svelte-typeahead 5.0.1 → 5.0.3

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/README.md CHANGED
@@ -97,8 +97,8 @@ Use the default slot to render custom results.
97
97
  Use the "no-results" slot to render a message if the search value does not yield results.
98
98
 
99
99
  ```svelte
100
- <Typeahead value="abcd" {data} {extract} let:value>
101
- <svelte:fragment slot="no-results">
100
+ <Typeahead value="abcd" {data} {extract}>
101
+ <svelte:fragment slot="no-results" let:value>
102
102
  No results found for "{value}"
103
103
  </svelte:fragment>
104
104
  </Typeahead>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "svelte-typeahead",
3
- "version": "5.0.1",
3
+ "version": "5.0.3",
4
4
  "license": "MIT",
5
5
  "description": "Accessible, fuzzy search typeahead component",
6
6
  "author": "Eric Liu (https://github.com/metonym)",
@@ -73,7 +73,7 @@
73
73
  async function select() {
74
74
  const result = results[selectedIndex];
75
75
 
76
- if (result.disabled) return;
76
+ if (!result || result.disabled) return;
77
77
 
78
78
  const selectedValue = extract(result.original);
79
79
  const searchedValue = value;
@@ -97,46 +97,35 @@
97
97
 
98
98
  /** @type {() => number} */
99
99
  function getNextNonDisabledIndex() {
100
- let index = 0;
101
- let disabled = results[index]?.disabled ?? false;
102
-
103
- while (disabled) {
104
- if (index === results.length) {
105
- index = 0;
106
- } else {
107
- index += 1;
108
- }
109
-
110
- disabled = results[index]?.disabled ?? false;
111
- }
112
-
113
- return index;
100
+ return results.findIndex((result) => !result.disabled);
114
101
  }
115
102
 
116
103
  /** @type {(direction: -1 | 1) => void} */
117
104
  function change(direction) {
118
- let index =
119
- direction === 1 && selectedIndex === results.length - 1
120
- ? 0
121
- : selectedIndex + direction;
122
- if (index < 0) index = results.length - 1;
123
-
124
- let disabled = results[index].disabled;
125
-
126
- while (disabled) {
127
- if (index === results.length) {
128
- index = 0;
129
- } else {
130
- index += direction;
131
- }
105
+ const startingIndex = selectedIndex === -1 && direction === -1 ? 0 : selectedIndex;
106
+
107
+ for (let step = 1; step <= results.length; step += 1) {
108
+ const index = (startingIndex + step * direction + results.length) % results.length;
132
109
 
133
- disabled = results[index].disabled;
110
+ if (!results[index].disabled) {
111
+ selectedIndex = index;
112
+ return;
113
+ }
134
114
  }
135
115
 
136
- selectedIndex = index;
116
+ selectedIndex = -1;
137
117
  }
138
118
 
139
- const open = () => (hideDropdown = false);
119
+ const open = () => {
120
+ hideDropdown = false;
121
+ // Reset selected index when reopening menu
122
+ if (autoselect && results.length > 0) {
123
+ selectedIndex = getNextNonDisabledIndex();
124
+ } else {
125
+ selectedIndex = -1;
126
+ }
127
+ };
128
+
140
129
  const close = () => {
141
130
  hideDropdown = true;
142
131
  isFocused = false;
@@ -212,7 +201,15 @@
212
201
  }}
213
202
  on:clear
214
203
  on:clear={open}
215
- on:blur
204
+ on:blur={(e) => {
205
+ // Check if focus is moving to an element within the combobox
206
+ const relatedTarget = e.relatedTarget;
207
+ if (relatedTarget && comboboxRef?.contains(relatedTarget)) {
208
+ return;
209
+ }
210
+ // Close immediately for keyboard navigation (Tab, Shift+Tab)
211
+ close();
212
+ }}
216
213
  on:keydown
217
214
  on:keydown={(e) => {
218
215
  if (results.length === 0) return;
@@ -253,8 +250,9 @@
253
250
  class:selected={selectedIndex === index}
254
251
  class:disabled={result.disabled}
255
252
  aria-selected={selectedIndex === index}
256
- on:click={() => {
253
+ on:mousedown={(e) => {
257
254
  if (result.disabled) return;
255
+ e.preventDefault(); // Prevent input from losing focus
258
256
  selectedIndex = index;
259
257
  select();
260
258
  }}
@@ -283,11 +281,12 @@
283
281
  background-color: #fff;
284
282
  }
285
283
 
286
- ul {
284
+ [data-svelte-typeahead] ul {
287
285
  position: absolute;
288
286
  top: 100%;
289
287
  left: 0;
290
288
  width: 100%;
289
+ max-width: none;
291
290
  margin: 0;
292
291
  padding: 0;
293
292
  list-style: none;