rob-balfre / svelte-select

Svelte Select. A select component for Svelte
https://svelte-select-examples.vercel.app
Other
1.25k stars 175 forks source link

How would I extend the Select and allow pass-through of the slots? #616

Closed lipe-dev closed 11 months ago

lipe-dev commented 11 months ago

Not sure this is the right place to ask, but here it goes:

I have my own Select component, which is supposed to just be a wrapper on svelte-select. It just adds a custom chevron-icon, a div around it and some custom CSS.

<script lang="ts">
    import Icon from 'svelte-icons-pack';
    import BsChevronDown from 'svelte-icons-pack/bs/BsChevronDown';
    import Select from 'svelte-select';
    import type { SelectProps } from 'svelte-select/Select.svelte';

    interface $$Props extends SelectProps {}
</script>

<div class={`custom-select ${$$props.class}`}>
    <Select listAutoWidth showChevron {...$$restProps}>
        <div slot="chevron-icon" class="chevron flex items-center justify-center">
            <Icon src={BsChevronDown} />
        </div>
    </Select>
</div>

<style lang="postcss">
    .custom-select {
        --border-focused: 2px solid theme(colors.primary.300);
        --item-hover-bg: theme(colors.primary.100);
        --item-is-active-bg: theme(colors.primary.500);

        @media (prefers-color-scheme: dark) {
            --border-focused: 2px solid theme(colors.primary.300);
            --item-hover-bg: theme(colors.neutral.800);
            --item-hover-color: theme(colors.neutral.100);
            --item-is-active-bg: theme(colors.primary.500);
            --list-background: theme(colors.neutral.700);
            --item-color: theme(colors.neutral.100);
            --background: theme(colors.neutral.800);
            --selected-item-color: theme(colors.neutral.100);
            --chevron-color: theme(colors.neutral.100);
            --clear-icon-color: theme(colors.neutral.100);
        }
    }

    .chevron {
        height: 100%;
        width: 100%;
        border-left: 1px solid theme(colors.neutral.200);
    }
</style>

When I use my own Select, I want to be able to pass down all slots that svelte-select supports, like so:

<Select
    placeholder="Select Provider"
    class="basis-1/2 grow md:grow-0 min-w-[200px]"
    items={$items}
>
       <!-- I want this slot to be passed down to svelte-select! -->
    <div slot="item" let:item>
        <div class="flex flex-row items-center gap-x-md">
            <div class="flex flex-col">
                <div class="text-heading-h6 text-neutral-900 dark:text-neutral-50 font-medium">
                    {item?.name}
                </div>
            </div>
        </div>
    </div>
</Select>
lipe-dev commented 11 months ago

I figured it out, just declare a new slot with both slot and name props:

<slot name="item" slot="item" let:item let:index {item} {index}>
            <span class="text-neutral-600 font-medium text-paragraph-medium">
                {capitalizeFirstLetterOfEachWord(item[$$props.label || 'label'])}
            </span>
        </slot>