Select
The select
component provides a way to select one or many options from a list of options.
Example
You have selected the value: nothing
Sources
+page.svelte
<script lang="ts">
import Select from './Select.svelte'
import Option from './Option.svelte'
let value: string = ''
</script>
<p class="mb-4 text-sm opacity-60">
You have selected the value: <strong>{value || 'nothing'}</strong>
</p>
<Select bind:value placeholder="Select a transportation method">
<Option value="π">Car</Option>
<Option value="π²">Bike</Option>
<Option value="π">Bus</Option>
<Option value="βοΈ">Plane</Option>
<Option value="π">Train</Option>
<Option value="πΆββοΈ">Walk</Option>
</Select>
Option.svelte
<script lang="ts">
import type { Select } from 'louisette'
import { getContext } from 'svelte'
export let value: string
export let selected: boolean = false
export let disabled: boolean = false
const {
optionAttrs,
select,
selected: selectedList,
activeDescendant,
} = getContext<Select>('select')
if (selected) select(value)
</script>
<div
{...$optionAttrs(value)}
class="flex cursor-pointer items-center justify-between rounded-md p-2 hover:bg-neutral-200 dark:hover:bg-neutral-600"
class:is-active-descendant={$activeDescendant === value}
>
<span>
<slot />
</span>
{#if $selectedList.includes(value)}
<svg
class="text-primary-500 dark:text-primary-400 ml-2 h-4 w-4"
fill="currentColor"
viewBox="0 0 20 20"
aria-hidden="true"
>
<path
clip-rule="evenodd"
d="M10.707 14.707a1 1 0 01-1.414 0L5 10.414A1 1 0 016.414 9l3.293 3.293 6.293-6.293a1 1 0 111.414 1.414l-7 7z"
fill-rule="evenodd"
/>
</svg>
{/if}
</div>
<style lang="postcss">
.is-active-descendant {
@apply bg-neutral-200 dark:bg-neutral-600;
}
</style>
Select.svelte
<script lang="ts">
import { createSelect } from 'louisette'
import { setContext } from 'svelte'
export let multiple: boolean = false
export let value: string | string[] = ''
export let placeholder: string = 'Select an option'
// TODO: implement disabled
export let disabled: boolean = false
const selectContext = createSelect()
setContext('select', selectContext)
const {
opened,
selectAttrs,
buttonAttrs,
listboxAttrs,
selectedLabel,
selected: selectedList,
} = selectContext
$: value = multiple ? $selectedList : $selectedList[0]
</script>
<div {...$selectAttrs} class="relative min-w-[1rem]">
<button
{...$buttonAttrs}
class="flex w-full items-center justify-between gap-4 rounded bg-white px-4 py-2 shadow dark:bg-neutral-700 dark:text-neutral-100"
>
<span class:opacity-50={!$selectedLabel}>
{$selectedLabel || placeholder}
</span>
<span class="ml-auto" class:rotate-180={$opened}>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
class="h-4 w-4"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M19.5 8.25l-7.5 7.5-7.5-7.5"
/>
</svg>
</span>
</button>
<div
{...$listboxAttrs}
class:hidden={!$opened}
class="absolute z-10 mt-1 w-full space-y-2 rounded-b bg-white p-2 text-sm shadow-lg dark:bg-neutral-700 dark:text-neutral-100"
>
<slot />
</div>
</div>