fix ActionSelect stateless, add value prop

This commit is contained in:
Elijah Duffy
2025-07-07 15:49:00 -07:00
parent 2f2b4fcba2
commit 4b81388636
3 changed files with 41 additions and 18 deletions

View File

@@ -1,10 +1,10 @@
<script lang="ts" module>
export type ButtonSelectOption = {
export type ActionSelectOption = {
icon?:
| { component: Component; props: Record<string, any> }
| Snippet<[opt: ButtonSelectOption]>;
title: string | Snippet<[opt: ButtonSelectOption]>;
onchoose?: (opt: ButtonSelectOption) => void;
| Snippet<[opt: ActionSelectOption]>;
title: string | Snippet<[opt: ActionSelectOption]>;
onchoose?: (opt: ActionSelectOption) => void;
};
</script>
@@ -19,32 +19,42 @@
interface Props {
label?: string;
placeholder?: string;
value?: ActionSelectOption;
stateless?: boolean;
options: ButtonSelectOption[];
tabbable?: boolean;
options: ActionSelectOption[];
class?: ClassValue | null | undefined;
}
let {
label,
placeholder = 'Choose an action',
stateless = true,
value = $bindable(undefined),
stateless = false,
tabbable = true,
options,
class: classValue
}: Props = $props();
const select = new Select<ButtonSelectOption>({
onValueChange: (value) => {
value?.onchoose?.(value);
const select = new Select<ActionSelectOption>({
value: () => value,
onValueChange: (val) => {
val?.onchoose?.(val);
if (!stateless) value = val;
}
});
</script>
<div>
<div class={[classValue]}>
{#if label}
<Label {...select.label}>{label}</Label>
{/if}
<Button class={['flex w-full items-center rounded-xl!', classValue]} {...select.trigger}>
<Button
class={['flex w-full items-center rounded-xl!']}
{...select.trigger}
tabindex={tabbable ? 0 : -1}
>
{#if stateless || !select.value}
{placeholder}
{:else}
@@ -92,7 +102,7 @@
</div>
</div>
{#snippet title(opt: ButtonSelectOption)}
{#snippet title(opt: ActionSelectOption)}
{#if typeof opt.title === 'string'}
{opt.title}
{:else}
@@ -100,7 +110,7 @@
{/if}
{/snippet}
{#snippet icon(opt: ButtonSelectOption)}
{#snippet icon(opt: ActionSelectOption)}
{#if opt.icon && typeof opt.icon === 'object'}
<opt.icon.component {...opt.icon.props} />
{:else if opt.icon}

View File

@@ -1,5 +1,5 @@
// Reexport your entry components here
export { default as ActionSelect } from './ActionSelect.svelte';
export { default as ActionSelect, type ActionSelectOption } from './ActionSelect.svelte';
export { default as Button } from './Button.svelte';
export { default as CenterBox } from './CenterBox.svelte';
export { default as Checkbox, type CheckboxState } from './Checkbox.svelte';

View File

@@ -53,10 +53,23 @@
<div class="component">
<p class="title">Button Select</p>
<ActionSelect
label="Action"
options={[{ title: 'Yeet' }, { title: 'Yote' }, { title: 'Yote and Yeet' }]}
/>
<div class="flex gap-2">
<ActionSelect
class="basis-1/2"
stateless
label="Stateless Action"
options={[{ title: 'Yeet' }, { title: 'Yote' }, { title: 'Yote and Yeet' }]}
/>
<ActionSelect
class="basis-1/2"
label="Stateful Action"
value={{ title: 'Initial Action', onchoose: (value) => console.log('Chosen:', value) }}
options={[
{ title: 'Action 1', onchoose: (value) => console.log('Action 1 chosen:', value) },
{ title: 'Action 2', onchoose: (value) => console.log('Action 2 chosen:', value) }
]}
/>
</div>
</div>
<div class="component">