Coves frontend - a photon fork
at main 58 lines 1.5 kB view raw
1<script lang="ts"> 2 import { locale } from '$lib/app/i18n' 3 import { type Snippet, getContext, onDestroy } from 'svelte' 4 import type { IconSource } from 'svelte-hero-icons/dist' 5 import type { HTMLOptionAttributes } from 'svelte/elements' 6 7 interface Props extends Omit<HTMLOptionAttributes, 'prefix'> { 8 children: Snippet 9 icon?: IconSource 10 } 11 let { children, icon, ...rest }: Props = $props() 12 13 let optionElement = $state<HTMLOptionElement>() 14 let option = $derived({ 15 value: optionElement?.value ?? '', 16 label: optionElement?.innerText ?? '', 17 icon: icon, 18 disabled: optionElement?.disabled, 19 isLabel: optionElement?.getAttribute('data-label') == 'true', 20 }) 21 22 interface SelectContext { 23 options: { 24 value: string 25 label: string 26 icon?: IconSource 27 disabled?: boolean 28 isLabel?: boolean 29 }[] 30 } 31 32 const context = getContext<SelectContext>('select') 33 34 $effect(() => { 35 if ($locale || !context.options.find((v) => v == option)) { 36 const index = context.options.findIndex((i) => i.value == option.value) 37 38 if (index != -1) { 39 context.options.splice(index, 1, option) 40 } else { 41 context.options.push(option) 42 } 43 } 44 }) 45 46 onDestroy(() => { 47 const index = context.options.findIndex((i) => i.value == option.value) 48 if (index != -1) { 49 context.options.splice(index, 1) 50 } 51 }) 52</script> 53 54{#key $locale} 55 <option {...rest} bind:this={optionElement}> 56 {@render children()} 57 </option> 58{/key}