11<script >
2- import { Input , Dropdown , DropdownMenu , DropdownItem , Spinner , DropdownToggle } from ' @sveltestrap/sveltestrap' ;
3- import { debounce } from ' lodash' ;
4-
5- /** @type {{id: string, name: string} | null} */
6- export let selectedValue;
7- export let disabled = false ;
8- export let placeholder = ' ' ;
9- /**
2+ import {
3+ Input ,
4+ Dropdown ,
5+ DropdownMenu ,
6+ DropdownItem ,
7+ Spinner ,
8+ DropdownToggle
9+ } from ' @sveltestrap/sveltestrap' ;
10+ import { debounce } from ' lodash' ;
1011
11- * @type {(arg0: any) => any[] | PromiseLike<any[]>}
12- */
13- export let onSearch;
14- export let loading = false ;
12+ /** @type {string} */
13+ export let value;
14+ export let disabled = false ;
15+ export let placeholder = ' ' ;
16+ /**
17+ * @type {(query: string) => Promise<({id: string; name: string} | string)[]>}
18+ */
19+ export let onSearch;
20+ export let loading = false ;
1521
16- /** @type {any []} */
17- let searchResults = [];
18- let isOpen = false ;
22+ /** @type {({id: string; name: string} | string) []} */
23+ let searchResults = [];
24+ let isOpen = false ;
1925
20- // @ts-ignore
21- const debouncedSearch = debounce (async (query ) => {
22- if (query .length ) {
23- loading = true ;
24- searchResults = await onSearch (query);
25- loading = false ;
26- isOpen = true ;
27- } else {
28- searchResults = [];
29- isOpen = false ;
30- }
31- }, 500 );
26+ // @ts-ignore
27+ const debouncedSearch = debounce (async (query ) => {
28+ if (query .length ) {
29+ loading = true ;
30+ searchResults = await onSearch (query);
31+ loading = false ;
32+ } else {
33+ searchResults = [];
34+ isOpen = false ;
35+ }
36+ }, 500 );
3237
33- /**
34- * @param {any} e
35- */
36- async function handleInput (e ) {
37- const query = e .target .value ;
38- selectedValue = { id: query, name: query };
39- await debouncedSearch (query);
40- }
38+ /**
39+ * @param {any} e
40+ */
41+ async function handleInput (e ) {
42+ const query = e .target .value ;
43+ isOpen = true ;
44+ value = query;
45+ await debouncedSearch (query);
46+ }
4147
42- /**
43- * @param {{ id: string; name: string; }} result
44- */
45- function selectResult (result ) {
46- selectedValue = result;
47- }
48-
49- export function clearSearchResults () {
50- searchResults = [];
51- }
48+ /**
49+ * @param { {id: string; name: string} | string } result
50+ */
51+ function selectResult (result ) {
52+ value = typeof result === ' string' ? result : result? .id ;
53+ }
5254
55+ export function clearSearchResults () {
56+ searchResults = [];
57+ }
5358< / script>
5459
5560< div class = " position-relative" >
56- <Dropdown class ="scrollable-dropdown" isOpen ={isOpen && (searchResults .length > 0 || loading )} toggle ={() => isOpen = ! isOpen }>
57- <DropdownToggle tag =" div" >
58- <Input
59- type =" text"
60- value ={selectedValue ?.name }
61- on:input ={handleInput }
62- {disabled }
63- {placeholder }
64- />
65- </DropdownToggle >
66- <DropdownMenu class =" w-100" >
67- {#if loading }
68- <DropdownItem >
69- <Spinner size =" sm" />
70- </DropdownItem >
71- {:else }
72- {#each searchResults as result , index }
73- <DropdownItem
74- active ={selectedValue ?.id === result .id }
75- on:click ={() => selectResult (result )}
76- title ={result .name }
77- >
78- {result .name }
79- </DropdownItem >
80- {/each }
81- {/if }
82- </DropdownMenu >
83- </Dropdown >
84- </div >
61+ < Dropdown
62+ class = " scrollable-dropdown"
63+ isOpen= {isOpen && (searchResults .length > 0 || loading)}
64+ toggle= {() => (isOpen = ! isOpen)}
65+ >
66+ < DropdownToggle tag= " div" >
67+ < Input type= " text" {value} on: input= {handleInput} {disabled} {placeholder} / >
68+ < / DropdownToggle>
69+ < DropdownMenu class = " w-100" >
70+ {#if loading}
71+ < li class = " text-center" >< Spinner size= " sm" / >< / li>
72+ {: else }
73+ {#each searchResults as result, index}
74+ < DropdownItem
75+ active= {value === (typeof result === ' string' ? result : result? .id )}
76+ on: click= {() => selectResult (result)}
77+ title= {typeof result === ' string' ? result : result? .name }
78+ >
79+ {typeof result === ' string' ? result : result? .name }
80+ < / DropdownItem>
81+ {/ each}
82+ {/ if }
83+ < / DropdownMenu>
84+ < / Dropdown>
85+ < / div>
0 commit comments