@@ -30,98 +30,100 @@ Comboboxes are the foundation of accessible autocompletes and command palettes f
30
30
31
31
``` svelte
32
32
<script lang="ts">
33
- import { createCombobox } from 'svelte-headlessui'
34
- import Transition from 'svelte-transition'
35
- import Selector from './Selector.svelte'
36
- import Check from './Check.svelte'
33
+ import { createCombobox } from 'svelte-headlessui'
34
+ import Transition from 'svelte-transition'
35
+ import Selector from '$icons/Selector.svelte'
36
+ import Check from '$icons/Check.svelte'
37
+ import { onMount } from 'svelte'
37
38
38
- // prettier-ignore
39
- const people = [
40
- { name: 'Wade Cooper' },
41
- { name: 'Arlene Mccoy' },
42
- { name: 'Devon Webb' },
43
- { name: 'Tom Cook' },
44
- { name: 'Tanya Fox' },
45
- { name: 'Hellen Schmidt' },
46
- ]
39
+ // prettier-ignore
40
+ const people = [
41
+ { name: 'Wade Cooper' },
42
+ { name: 'Arlene Mccoy' },
43
+ { name: 'Devon Webb' },
44
+ { name: 'Tom Cook' },
45
+ { name: 'Tanya Fox' },
46
+ { name: 'Hellen Schmidt' },
47
+ ]
47
48
48
- const combobox = createCombobox({ label: 'Actions', selected: people[2] })
49
+ const combobox = createCombobox({ label: 'People', selected: people[2] })
50
+ onMount(combobox.open)
49
51
50
- function onChange(e: Event) {
51
- console.log('select', (e as CustomEvent).detail.selected)
52
- }
52
+ function onChange(e: Event) {
53
+ console.log('select', (e as CustomEvent).detail.selected)
54
+ }
53
55
54
- $: filtered = people.filter((person) =>
55
- person.name
56
- .toLowerCase()
57
- .replace(/\s+/g, '')
58
- .includes($combobox.filter.toLowerCase().replace(/\s+/g, '')),
59
- )
56
+ let filtered = $derived(
57
+ people.filter((person) =>
58
+ person.name
59
+ .toLowerCase()
60
+ .replace(/\s+/g, '')
61
+ .includes($combobox.filter.toLowerCase().replace(/\s+/g, '')),
62
+ ),
63
+ )
60
64
</script>
61
65
62
- <div class="flex w-full flex-col items-center justify-center">
63
- <div class="fixed top-16 w-72">
64
- <div class="relative mt-1">
65
- <div
66
- class="relative w-full cursor-default overflow-hidden rounded-lg bg-white text-left text-sm shadow-md focus:outline-none focus-visible:ring-2 focus-visible:ring-white focus-visible:ring-opacity-75 focus-visible:ring-offset-2 focus-visible:ring-offset-teal-300"
67
- >
68
- <input
69
- use:combobox.input
70
- on:change={onChange}
71
- class="w-full border-none py-2 pl-3 pr-10 leading-5 text-gray-900 focus:ring-0"
72
- value={$combobox.selected.name}
73
- />
74
- <!-- <span class="block truncate">{people[$listbox.selected].name}</span> -->
75
- <button
76
- use:combobox.button
77
- class="absolute inset-y-0 right-0 flex items-center pr-2"
78
- type="button"
79
- >
80
- <Selector class="h-5 w-5 text-gray-400" />
81
- </button>
82
- </div>
66
+ <div class="fixed top-16 w-72">
67
+ <div class="relative mt-1">
68
+ <div
69
+ class="relative w-full cursor-default overflow-hidden rounded-lg bg-white text-left text-sm shadow-md focus:outline-hidden focus-visible:ring-2 focus-visible:ring-white/75 focus-visible:ring-offset-2 focus-visible:ring-offset-teal-300"
70
+ >
71
+ <input
72
+ use:combobox.input
73
+ onchange={onChange}
74
+ class="w-full border-none py-2 pr-10 pl-3 text-sm leading-5 text-gray-900 focus:ring-0"
75
+ value={$combobox.selected?.name ?? ''}
76
+ />
77
+ <!-- <span class="block truncate">{people[$listbox.selected].name}</span> -->
78
+ <button
79
+ use:combobox.button
80
+ class="absolute inset-y-0 right-0 flex items-center pr-2"
81
+ type="button"
82
+ >
83
+ <Selector class="h-5 w-5 text-gray-400" />
84
+ </button>
85
+ </div>
83
86
84
- <Transition
85
- show={$combobox.expanded}
86
- leave="transition ease-in duration-100"
87
- leaveFrom="opacity-100"
88
- leaveTo="opacity-0"
89
- on:after-leave={() => combobox.reset()}
90
- >
91
- <ul
92
- use:combobox.items
93
- class="absolute mt-1 max-h-60 w-full overflow-auto rounded-md bg-white py-1 text-sm shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none"
94
- >
95
- {#each filtered as value}
96
- {@const active = $combobox.active === value}
97
- {@const selected = $combobox.selected === value}
98
- <li
99
- class="relative cursor-default select-none py-2 pl-10 pr-4 {active
100
- ? 'bg-teal-600 text-white'
101
- : 'text-gray-900'}"
102
- use:combobox.item={{ value }}
103
- >
104
- <span class="block truncate {selected ? 'font-medium' : 'font-normal'}"
105
- >{value.name}</span
106
- >
107
- {#if selected}
108
- <span
109
- class="absolute inset-y-0 left-0 flex items-center pl-3 {active
110
- ? 'text-white'
111
- : 'text-teal-600'}"
112
- >
113
- <Check class="h-5 w-5" />
114
- </span>
115
- {/if}
116
- </li>
117
- {:else}
118
- <li class="relative cursor-default select-none py-2 pl-10 pr-4 text-gray-900">
119
- <span class="block truncate font-normal">Nothing found</span>
120
- </li>
121
- {/each}
122
- </ul>
123
- </Transition>
124
- </div>
125
- </div>
87
+ <Transition
88
+ show={$combobox.expanded}
89
+ leave="transition ease-in duration-100"
90
+ leaveFrom="opacity-100"
91
+ leaveTo="opacity-0"
92
+ on:after-leave={() => combobox.reset()}
93
+ >
94
+ <ul
95
+ use:combobox.items
96
+ class="absolute mt-1 max-h-60 w-full overflow-auto rounded-md bg-white py-1 text-sm ring-1 shadow-lg ring-black/5 focus:outline-hidden"
97
+ >
98
+ {#each filtered as value}
99
+ {@const active = $combobox.active === value}
100
+ {@const selected = $combobox.selected === value}
101
+ <li
102
+ class="relative cursor-default py-2 pr-4 pl-10 select-none {active
103
+ ? 'bg-teal-600 text-white'
104
+ : 'text-gray-900'}"
105
+ use:combobox.item={{ value }}
106
+ >
107
+ <span class="block truncate {selected ? 'font-medium' : 'font-normal'}"
108
+ >{value.name}</span
109
+ >
110
+ {#if selected}
111
+ <span
112
+ class="absolute inset-y-0 left-0 flex items-center pl-3 {active
113
+ ? 'text-white'
114
+ : 'text-teal-600'}"
115
+ >
116
+ <Check class="h-5 w-5" />
117
+ </span>
118
+ {/if}
119
+ </li>
120
+ {:else}
121
+ <li class="relative cursor-default select-none py-2 pl-10 pr-4 text-gray-900">
122
+ <span class="block truncate font-normal">Nothing found</span>
123
+ </li>
124
+ {/each}
125
+ </ul>
126
+ </Transition>
127
+ </div>
126
128
</div>
127
129
```
0 commit comments