sveltekitshadcnui

Svelte Shadcn select item data-highlighted isn't added on hover


I added svelte-shadcn to my project and when using Select component data-highlighted property isn't added to Select.Item on hover, hence highlighting css styles aren't added. Added the same way as specified in their example here: https://www.shadcn-svelte.com/docs/components/select This is how I added the select bit:

<Select.Root type="single" name="parallelRun" bind:value={selectedPr}>
    <Select.Trigger class="w-[100%]">
        {triggerContent}
    </Select.Trigger>
    <Select.Content>
        <Select.Group>
            <Select.GroupHeading>Parallel Runs</Select.GroupHeading>
            {#each data.parallelRuns as parallelRun}
                <Select.Item value={parallelRun.id} label={parallelRun.name} class="select-item">
                    {parallelRun.name}
                </Select.Item>
            {/each}
        </Select.Group>
    </Select.Content>
</Select.Root>

I've tried googling to find a solution, but failed. Expected result: data-higlighted property should be added to resulting div for Select.Item and standard Shadcn styles should be applied.


Solution

  • If I'm understanding correctly and you're trying to do something like this:

    <style>
    
    .select-item:hover {
        ...your highlighting styles
    }
    
    </style>
    

    Then your issue is the scoping of the styles by Svelte, which is done by generating a class that will be added to every HTML element in the component. Since you're actually including the <Select.item> component and passing a class name to it instead of giving a class to a rendered HTML element, it will not apply any CSS in your <style> tag since it won't pass the class generated for the scoping to the components. Your solution would be to use the global tag for styles.

    <style>
    
    :global(.select-item:hover) {
        ...your highlighting styles
    }
    
    </style>
    

    But that's not scoped so it will apply to any element in the whole application with that class. So a better way is to leverage the scoping only select stuff inside your current component by wrapping everything in an element like this:

    <div class="wrapper">
        <Select.Root type="single" name="parallelRun" bind:value={selectedPr}>
            <Select.Trigger class="w-[100%]">
                {triggerContent}
            </Select.Trigger>
            <Select.Content>
                <Select.Group>
                    <Select.GroupHeading>Parallel Runs</Select.GroupHeading>
                    {#each data.parallelRuns as parallelRun}
                        <Select.Item value={parallelRun.id} label={parallelRun.name} class="select-item">
                            {parallelRun.name}
                        </Select.Item>
                    {/each}
                </Select.Group>
            </Select.Content>
        </Select.Root>
    </div>
    
    <style>
    
    /* this will only apply to the selected class that descends from .wrapper */
    .wrapper :global(.select-item) {
        your styles here...    
    
    /* this will apply to all selectors inside this that descend from .wrapper */
    .wrapper :global {
        .select-item:hover {
            your styles here...
        }
    
        .any-other-selector {
            more styles... 
        }
    
    </style>