svelte-typeahead 2.4.1 → 4.2.0
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/CHANGELOG.md +30 -0
- package/README.md +56 -42
- package/lib/index.js +414 -213
- package/lib/index.mjs +414 -213
- package/package.json +7 -7
- package/src/Typeahead.svelte +36 -29
- package/types/{Typeahead.d.ts → Typeahead.svelte.d.ts} +27 -20
- package/types/index.d.ts +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "svelte-typeahead",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "4.2.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Accessible, fuzzy search typeahead component",
|
|
6
6
|
"author": "Eric Liu (https://github.com/metonym)",
|
|
@@ -14,17 +14,17 @@
|
|
|
14
14
|
"predeploy": "rollup -c",
|
|
15
15
|
"deploy": "npx gh-pages -d dist",
|
|
16
16
|
"prepack": "BUNDLE=true rollup -c",
|
|
17
|
-
"test": "svelte-check"
|
|
17
|
+
"test": "svelte-check --workspace test"
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
20
|
"fuzzy": "0.1.3",
|
|
21
|
-
"svelte-search": "^1.
|
|
21
|
+
"svelte-search": "^1.1.0"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
|
-
"@rollup/plugin-commonjs": "^
|
|
25
|
-
"svelte": "^3.
|
|
26
|
-
"svelte-check": "^
|
|
27
|
-
"svelte-readme": "^3.
|
|
24
|
+
"@rollup/plugin-commonjs": "^21.0.1",
|
|
25
|
+
"svelte": "^3.44.0",
|
|
26
|
+
"svelte-check": "^2.2.6",
|
|
27
|
+
"svelte-readme": "^3.4.1"
|
|
28
28
|
},
|
|
29
29
|
"repository": {
|
|
30
30
|
"type": "git",
|
package/src/Typeahead.svelte
CHANGED
|
@@ -1,25 +1,21 @@
|
|
|
1
1
|
<script>
|
|
2
2
|
/**
|
|
3
|
-
* @
|
|
4
|
-
* @typedef {{ original: Item; index: number; score: number; string: string; }} FuzzyResult
|
|
5
|
-
* @event {{ searched: string; selected: Item; selectedIndex: number; original: Item; originalIndex: number; }} select
|
|
6
|
-
* @event {any} clear
|
|
7
|
-
* @slot {{ result: FuzzyResult; index: number }}
|
|
3
|
+
* @template TItem = string | number | Record<string, any>
|
|
8
4
|
*/
|
|
9
5
|
|
|
10
6
|
export let id = "typeahead-" + Math.random().toString(36);
|
|
11
7
|
export let value = "";
|
|
12
8
|
|
|
13
|
-
/** @type {
|
|
9
|
+
/** @type {TItem[]} */
|
|
14
10
|
export let data = [];
|
|
15
11
|
|
|
16
|
-
/** @type {(item:
|
|
12
|
+
/** @type {(item: TItem) => any} */
|
|
17
13
|
export let extract = (item) => item;
|
|
18
14
|
|
|
19
|
-
/** @type {(item:
|
|
15
|
+
/** @type {(item: TItem) => boolean} */
|
|
20
16
|
export let disable = (item) => false;
|
|
21
17
|
|
|
22
|
-
/** @type {(item:
|
|
18
|
+
/** @type {(item: TItem) => boolean} */
|
|
23
19
|
export let filter = (item) => false;
|
|
24
20
|
|
|
25
21
|
/** Set to `false` to prevent the first result from being selected */
|
|
@@ -31,7 +27,7 @@
|
|
|
31
27
|
*/
|
|
32
28
|
export let inputAfterSelect = "update";
|
|
33
29
|
|
|
34
|
-
/** @type {
|
|
30
|
+
/** @type {{ original: TItem; index: number; score: number; string: string; }[]} */
|
|
35
31
|
export let results = [];
|
|
36
32
|
|
|
37
33
|
/** Set to `true` to re-focus the input after selecting a result */
|
|
@@ -60,7 +56,7 @@
|
|
|
60
56
|
selectedIndex = 0;
|
|
61
57
|
}
|
|
62
58
|
|
|
63
|
-
if (prevResults !== resultsId) {
|
|
59
|
+
if (prevResults !== resultsId && !$$slots["no-results"]) {
|
|
64
60
|
hideDropdown = results.length === 0;
|
|
65
61
|
}
|
|
66
62
|
|
|
@@ -102,12 +98,7 @@
|
|
|
102
98
|
|
|
103
99
|
<svelte:window
|
|
104
100
|
on:click={({ target }) => {
|
|
105
|
-
if (
|
|
106
|
-
!hideDropdown &&
|
|
107
|
-
results.length > 0 &&
|
|
108
|
-
comboboxRef &&
|
|
109
|
-
!comboboxRef.contains(target)
|
|
110
|
-
) {
|
|
101
|
+
if (!hideDropdown && comboboxRef && !comboboxRef.contains(target)) {
|
|
111
102
|
hideDropdown = true;
|
|
112
103
|
}
|
|
113
104
|
}}
|
|
@@ -125,12 +116,17 @@
|
|
|
125
116
|
>
|
|
126
117
|
<Search
|
|
127
118
|
{id}
|
|
119
|
+
removeFormAriaAttributes={true}
|
|
128
120
|
{...$$restProps}
|
|
129
121
|
bind:ref={searchRef}
|
|
130
122
|
aria-autocomplete="list"
|
|
131
123
|
aria-controls="{id}-listbox"
|
|
132
124
|
aria-labelledby="{id}-label"
|
|
133
|
-
aria-activedescendant=
|
|
125
|
+
aria-activedescendant={selectedIndex >= 0 &&
|
|
126
|
+
!hideDropdown &&
|
|
127
|
+
results.length > 0
|
|
128
|
+
? `${id}-result-${selectedIndex}`
|
|
129
|
+
: null}
|
|
134
130
|
bind:value
|
|
135
131
|
on:type
|
|
136
132
|
on:input
|
|
@@ -146,6 +142,8 @@
|
|
|
146
142
|
on:blur
|
|
147
143
|
on:keydown
|
|
148
144
|
on:keydown={(e) => {
|
|
145
|
+
if (results.length === 0) return;
|
|
146
|
+
|
|
149
147
|
switch (e.key) {
|
|
150
148
|
case "Enter":
|
|
151
149
|
select();
|
|
@@ -173,13 +171,13 @@
|
|
|
173
171
|
}
|
|
174
172
|
}}
|
|
175
173
|
/>
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
>
|
|
174
|
+
<ul
|
|
175
|
+
class:svelte-typeahead-list={true}
|
|
176
|
+
role="listbox"
|
|
177
|
+
aria-labelledby="{id}-label"
|
|
178
|
+
id="{id}-listbox"
|
|
179
|
+
>
|
|
180
|
+
{#if !hideDropdown && results.length > 0}
|
|
183
181
|
{#each results as result, i}
|
|
184
182
|
<li
|
|
185
183
|
role="option"
|
|
@@ -194,13 +192,18 @@
|
|
|
194
192
|
}
|
|
195
193
|
}}
|
|
196
194
|
>
|
|
197
|
-
<slot {result} index={i}>
|
|
195
|
+
<slot {result} index={i} {value}>
|
|
198
196
|
{@html result.string}
|
|
199
197
|
</slot>
|
|
200
198
|
</li>
|
|
201
199
|
{/each}
|
|
202
|
-
|
|
203
|
-
|
|
200
|
+
{/if}
|
|
201
|
+
{#if $$slots["no-results"] && !hideDropdown && value.length > 0 && results.length === 0}
|
|
202
|
+
<div class:no-results={true}>
|
|
203
|
+
<slot name="no-results" {value} />
|
|
204
|
+
</div>
|
|
205
|
+
{/if}
|
|
206
|
+
</ul>
|
|
204
207
|
</div>
|
|
205
208
|
|
|
206
209
|
<style>
|
|
@@ -220,8 +223,12 @@
|
|
|
220
223
|
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
|
|
221
224
|
}
|
|
222
225
|
|
|
223
|
-
li
|
|
226
|
+
li,
|
|
227
|
+
.no-results {
|
|
224
228
|
padding: 0.25rem 1rem;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
li {
|
|
225
232
|
cursor: pointer;
|
|
226
233
|
}
|
|
227
234
|
|
|
@@ -2,16 +2,7 @@
|
|
|
2
2
|
import { SvelteComponentTyped } from "svelte";
|
|
3
3
|
import { SearchProps } from "svelte-search/types/Search";
|
|
4
4
|
|
|
5
|
-
export
|
|
6
|
-
|
|
7
|
-
export interface FuzzyResult {
|
|
8
|
-
original: Item;
|
|
9
|
-
index: number;
|
|
10
|
-
score: number;
|
|
11
|
-
string: string;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export interface TypeaheadProps extends SearchProps {
|
|
5
|
+
export interface TypeaheadProps<TItem> extends SearchProps {
|
|
15
6
|
/**
|
|
16
7
|
* @default "typeahead-" + Math.random().toString(36)
|
|
17
8
|
*/
|
|
@@ -25,22 +16,22 @@ export interface TypeaheadProps extends SearchProps {
|
|
|
25
16
|
/**
|
|
26
17
|
* @default []
|
|
27
18
|
*/
|
|
28
|
-
data?:
|
|
19
|
+
data?: TItem[];
|
|
29
20
|
|
|
30
21
|
/**
|
|
31
22
|
* @default (item) => item
|
|
32
23
|
*/
|
|
33
|
-
extract?: (item:
|
|
24
|
+
extract?: (item: TItem) => any;
|
|
34
25
|
|
|
35
26
|
/**
|
|
36
27
|
* @default (item) => false
|
|
37
28
|
*/
|
|
38
|
-
disable?: (item:
|
|
29
|
+
disable?: (item: TItem) => boolean;
|
|
39
30
|
|
|
40
31
|
/**
|
|
41
32
|
* @default (item) => false
|
|
42
33
|
*/
|
|
43
|
-
filter?: (item:
|
|
34
|
+
filter?: (item: TItem) => boolean;
|
|
44
35
|
|
|
45
36
|
/**
|
|
46
37
|
* Set to `false` to prevent the first result from being selected
|
|
@@ -57,7 +48,12 @@ export interface TypeaheadProps extends SearchProps {
|
|
|
57
48
|
/**
|
|
58
49
|
* @default []
|
|
59
50
|
*/
|
|
60
|
-
results?:
|
|
51
|
+
results?: {
|
|
52
|
+
original: TItem;
|
|
53
|
+
index: number;
|
|
54
|
+
score: number;
|
|
55
|
+
string: string;
|
|
56
|
+
}[];
|
|
61
57
|
|
|
62
58
|
/**
|
|
63
59
|
* Set to `true` to re-focus the input after selecting a result
|
|
@@ -72,14 +68,16 @@ export interface TypeaheadProps extends SearchProps {
|
|
|
72
68
|
limit?: number;
|
|
73
69
|
}
|
|
74
70
|
|
|
75
|
-
export default class Typeahead
|
|
76
|
-
|
|
71
|
+
export default class Typeahead<
|
|
72
|
+
TItem = string | number | Record<string, any>
|
|
73
|
+
> extends SvelteComponentTyped<
|
|
74
|
+
TypeaheadProps<TItem>,
|
|
77
75
|
{
|
|
78
76
|
select: CustomEvent<{
|
|
79
77
|
searched: string;
|
|
80
|
-
selected:
|
|
78
|
+
selected: TItem;
|
|
81
79
|
selectedIndex: number;
|
|
82
|
-
original:
|
|
80
|
+
original: TItem;
|
|
83
81
|
originalIndex: number;
|
|
84
82
|
}>;
|
|
85
83
|
type: CustomEvent<string>;
|
|
@@ -92,8 +90,17 @@ export default class Typeahead extends SvelteComponentTyped<
|
|
|
92
90
|
},
|
|
93
91
|
{
|
|
94
92
|
default: {
|
|
95
|
-
result:
|
|
93
|
+
result: {
|
|
94
|
+
original: TItem;
|
|
95
|
+
index: number;
|
|
96
|
+
score: number;
|
|
97
|
+
string: string;
|
|
98
|
+
};
|
|
96
99
|
index: number;
|
|
100
|
+
value: string;
|
|
101
|
+
};
|
|
102
|
+
"no-results": {
|
|
103
|
+
value: string;
|
|
97
104
|
};
|
|
98
105
|
}
|
|
99
106
|
> {}
|
package/types/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { default as default } from "./Typeahead";
|
|
1
|
+
export { default as default } from "./Typeahead.svelte";
|