Add reusable segmented inbox filters
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
<script lang="ts">
|
||||
import GameIcon from './GameIcon.svelte';
|
||||
import type { GameIconName } from '$lib/game-icons';
|
||||
|
||||
export type SegmentedChoiceOption = {
|
||||
value: string;
|
||||
label: string;
|
||||
className?: string;
|
||||
icon?: GameIconName;
|
||||
};
|
||||
|
||||
let {
|
||||
legend,
|
||||
name,
|
||||
options,
|
||||
mode = 'radio',
|
||||
value = $bindable(''),
|
||||
selected = $bindable([]),
|
||||
columns = options.length,
|
||||
required = false,
|
||||
onchange
|
||||
}: {
|
||||
legend: string;
|
||||
name: string;
|
||||
options: SegmentedChoiceOption[];
|
||||
mode?: 'radio' | 'checkbox';
|
||||
value?: string;
|
||||
selected?: string[];
|
||||
columns?: number;
|
||||
required?: boolean;
|
||||
onchange?: (values: string[]) => void;
|
||||
} = $props();
|
||||
|
||||
function change(optionValue: string, checked: boolean) {
|
||||
if (mode === 'radio') {
|
||||
value = optionValue;
|
||||
onchange?.([optionValue]);
|
||||
return;
|
||||
}
|
||||
selected = checked ? [...selected, optionValue] : selected.filter((current) => current !== optionValue);
|
||||
onchange?.(selected);
|
||||
}
|
||||
</script>
|
||||
|
||||
<fieldset class:multi={mode === 'checkbox'} class="segmented-choice">
|
||||
<legend>{legend}</legend>
|
||||
<div style={`--segmented-columns:${columns}`}>
|
||||
{#each options as option}
|
||||
<label>
|
||||
<input
|
||||
type={mode}
|
||||
{name}
|
||||
value={option.value}
|
||||
checked={mode === 'radio' ? value === option.value : selected.includes(option.value)}
|
||||
{required}
|
||||
onchange={(event) => change(option.value, event.currentTarget.checked)}
|
||||
/>
|
||||
<span class={option.className ?? ''}>
|
||||
{#if option.icon}<GameIcon name={option.icon} decorative/>{:else}<i aria-hidden="true"></i>{/if}
|
||||
<b>{option.label}</b>
|
||||
</span>
|
||||
</label>
|
||||
{/each}
|
||||
</div>
|
||||
</fieldset>
|
||||
Reference in New Issue
Block a user