CaptainCodeman / svelte-headlessui

HeadlessUI components for Svelte
https://captaincodeman.github.io/svelte-headlessui/
MIT License
539 stars 26 forks source link

Consider dispatching event for ListBox #34

Closed winston0410 closed 1 year ago

winston0410 commented 1 year ago

Right now I am using createListbox to create a custom <select> element with styling. One issue that I bumped into is, the custom select element does not fire any change event, and no event is dispatched once the value has been selected. If a event is dispatched once an element is selected, I can at least do something programatically there.

This is how my component looks like:

<script lang="ts" context="module">
    import { createListbox } from 'svelte-headlessui'
</script>

<script lang="ts">
    export let name: string;
    export let options: Array<{
        label: string,
        value: string
    }>;

    const listbox = createListbox({
        selected: options[0]
    })
</script>

<div class="listbox">
    <!-- Option1. This would work best with form library like Felte, as it would trigger a Change event -->
    <select class="hidden" {name}>
        {#each options as unit}
            <option value={unit.value} selected={unit.value === $listbox.selected.value}>{unit.label}</option>
        {/each}
    </select>
    <!-- Option2. The value is also avaliable on:submit, but it will not trigger and Change event -->
    <!-- <input type="hidden" {name} value={$listbox.selected.value}/> -->
    <button type="button" use:listbox.button>
        <slot name="button" label={$listbox.selected.label}/>
    </button>
    {#if $listbox.expanded}
    <ul class="listbox-panel" use:listbox.items>
    {#each options as unit, i}
        {@const active = $listbox.active === unit}
        {@const selected = $listbox.selected === unit}
        <li
            use:listbox.item={{
                value: unit
            }}
        >
            <slot name="option" item={unit}>
                <span>
                    {unit.label}
                </span>
            </slot>
        </li>
    {/each}
    </ul>
    {/if}
</div>

<style lang="scss">
    .hidden {
        display: none;
    }
</style>

Since I can see from doc no event is dispatched this library, is there a way originally designed to handle issue like this?

winston0410 commented 1 year ago

My bad just read the doc again, seems like I have missed on:select event, sorry!

Still I wonder how would you create a Listbox if it is going to be using in a form library like felte, and only input elements will be pick up automatically? Which approach is more preferrable in your opionion?