MultiSelect Events
This demo showcases all the events that <MultiSelect> emits. Each emitted event is recorded in the event log panel on the right.
Event Log
No events yet. Start clicking around!
<script lang="ts">
import MultiSelect from '$lib'
import { ColorSnippet } from '$site'
import { colors } from '$site/options'
interface EventLogEntry {
event: string
data: string
timestamp: string
}
let events: EventLogEntry[] = $state([])
let selected_options: string[] = $state([])
let allowUserOptions = $state(true)
function log_event(event_name: string, data: unknown): void {
events = [
{
event: event_name,
data: JSON.stringify(data, null, 2),
timestamp: new Date().toLocaleTimeString(),
},
...events.slice(0, 9), // Keep last 10 events
]
}
</script>
<div class="demo-grid">
<section class="demo-section">
Select options, remove them, use "Remove all", create custom options, navigate with
arrow keys, and interact with the input. Try selecting 5 options and adding a 6th to
trigger `onmaxreached`, or selecting the same option twice to see `onduplicate`.
<label style="display: block; margin-block: 1em">
<input type="checkbox" bind:checked={allowUserOptions} />
Allow user options
</label>
<MultiSelect
options={colors}
placeholder="Select colors or type to create custom..."
{allowUserOptions}
createOptionMsg="Create custom color..."
maxSelect={5}
onadd={(data) => log_event('onadd', data)}
onremove={(data) => log_event('onremove', data)}
onremoveAll={(data) => log_event('onremoveAll', data)}
onchange={(data) => log_event('onchange', data)}
oncreate={(data) => log_event('oncreate', data)}
onopen={(data) => log_event('onopen', data)}
onclose={(data) => log_event('onclose', data)}
onsearch={(data) => log_event('onsearch', data)}
onmaxreached={(data) => log_event('onmaxreached', data)}
onduplicate={(data) => log_event('onduplicate', data)}
onactivate={(data) => log_event('onactivate', data)}
onblur={(event: FocusEvent) =>
log_event('onblur', {
type: event.type,
target: (event.target as HTMLElement)?.tagName,
})}
onclick={(event: MouseEvent) =>
log_event('onclick', {
type: event.type,
target: (event.target as HTMLElement)?.tagName,
})}
onfocus={(event: FocusEvent) =>
log_event('onfocus', {
type: event.type,
target: (event.target as HTMLElement)?.tagName,
})}
onkeydown={(event: KeyboardEvent) =>
log_event('onkeydown', {
type: event.type,
key: event.key,
code: event.code,
})}
bind:selected={selected_options}
>
{#snippet children({ idx, option })}
<ColorSnippet {idx} {option} />
{/snippet}
</MultiSelect>
</section>
<section class="event-log">
<header class="log-header">
<h3 style="margin: 0">Event Log</h3>
<button onclick={() => events = []}>Clear</button>
</header>
{#each events as entry}
<article class="log-entry">
<header class="entry-header">
<span class="event-name">{entry.event}</span>
<span class="timestamp">{entry.timestamp}</span>
</header>
<pre class="log-data">{entry.data}</pre>
</article>
{:else}
<p class="no-events">No events yet. Start clicking around!</p>
{/each}
</section>
</div> Event Reference
Custom Events
| Event | Description | Data Structure |
|---|---|---|
onadd | Fired when an option is added to selection | { option: T } |
onremove | Fired when an option is removed from selection | { option: T } |
onremoveAll | Fired when all options are removed | { options: T[] } |
onchange | Fired for any selection change | { option?: T, options?: T[], type: 'add' \| 'remove' \| 'removeAll' } |
oncreate | Fired when user creates a custom option | { option: T } |
onopen | Fired when dropdown opens | { event: Event } |
onclose | Fired when dropdown closes | { event: Event } |
onsearch | Fired (debounced 150ms) when search text changes | { searchText: string, matchingCount: number } |
onmaxreached | Fired when user tries to exceed maxSelect | { selected: T[], maxSelect: number, attemptedOption: T } |
onduplicate | Fired when user tries to add duplicate | { option: T } |
onactivate | Fired on keyboard navigation through options | { option: T \| null, index: number \| null } |
Native DOM Events
| Event | Description |
|---|---|
onblur | Input loses focus |
onclick | Input is clicked |
onfocus | Input gains focus |
onkeydown | Key is pressed down |
onkeyup | Key is released |
onmousedown | Mouse button is pressed |
onmouseenter | Mouse enters input area |
onmouseleave | Mouse leaves input area |
ontouchcancel | Touch event is cancelled |
ontouchend | Touch ends |
ontouchmove | Touch moves |
ontouchstart | Touch begins |
Event Handling Tips
Destructuring Safety: Check for
event.detailbefore destructuring:function handleChange(event) { if (!event.detail) return // Guard against undefined detail const { option, type } = event.detail // ... handle the event }Type Safety: For better type checking in TypeScript projects, use
MultiSelectEventsandMultiSelectNativeEventsinterfaces:<script lang="ts"> import type { MultiSelectEvents, MultiSelectNativeEvents } from '$lib/types' const onadd: MultiSelectEvents['onadd'] = (data) => { console.log(`onadd`, data) } const onblur: MultiSelectNativeEvents['onblur'] = (event) => { console.log(`onblur`, event) } </script> <MultiSelect {onadd} {onblur} options={[{ label: `foo` }]} />Custom Options: The
oncreateevent only fires whenallowUserOptionsis enabled and users type text that doesn’t match existing options.New Events: The
onsearchevent is debounced (150ms) to avoid excessive callbacks while typing.onactivateonly fires during keyboard navigation (arrow keys), not on mouse hover.onduplicateonly fires whenduplicates={false}(the default).