Coves frontend - a photon fork
1<script lang="ts">
2 import TabButton from './TabButton.svelte'
3
4 type T = $$Generic
5
6 interface Props {
7 options: T[]
8 disabled?: boolean[]
9 optionNames?: string[]
10 selected: T
11 children?: import('svelte').Snippet<[{ selected: T }]>
12 onselect?: (item: T) => void
13 }
14
15 let {
16 options,
17 disabled = [],
18 optionNames = [],
19 selected = $bindable(),
20 children,
21 onselect,
22 }: Props = $props()
23
24 let selectedIndex = $state(0)
25 let id = $props.id()
26
27 /* you see id like this to be a super simple
28
29 */
30 $effect(() => {
31 const newIndex = options.findIndex((i) => i === selected)
32 if (newIndex !== -1) {
33 selectedIndex = newIndex
34 }
35 })
36
37 $effect(() => {
38 const newSelected = options[selectedIndex]
39 if (newSelected !== undefined && newSelected !== selected) {
40 selected = newSelected
41 onselect?.(newSelected)
42 }
43 })
44</script>
45
46<fieldset
47 class="flex items-center gap-1 w-max max-w-full z-0 relative overflow-auto"
48>
49 {#each options as option, index}
50 <label>
51 <input
52 type="radio"
53 bind:group={selectedIndex}
54 value={index}
55 name={id}
56 id="{id}-{option?.toString()}"
57 class="hidden"
58 />
59 <TabButton
60 selected={selectedIndex == index}
61 disabled={disabled[index]}
62 element="div"
63 >
64 {optionNames[index] || option}
65 </TabButton>
66 </label>
67 {/each}
68</fieldset>
69{@render children?.({ selected })}