Files
ss-tools/frontend/src/lib/ui/Select.svelte
2026-05-13 14:15:33 +03:00

60 lines
1.6 KiB
Svelte

<!-- #region Select [C:2] [TYPE Component] [SEMANTICS select, dropdown, form, atom, option] -->
<!-- @BRIEF Standardized select dropdown component with label and Tailwind styling. -->
<!-- @LAYER UI -->
<!--
@COMPLEXITY: 2
@SEMANTICS: select, dropdown, form-field, ui-atom
@PURPOSE: Standardized dropdown selection component.
@LAYER: Atom
@RELATION: DEPENDS_ON -> Utils
@UX_STATE: Idle -> Current value is selectable from the provided options.
@UX_STATE: Disabled -> Native disabled state prevents selection changes.
-->
<script>
// [SECTION: IMPORTS]
import { cn } from "$lib/utils.js";
// [/SECTION: IMPORTS]
// [SECTION: PROPS]
let {
label = "",
value = $bindable(""),
options = [],
disabled = false,
class: className = "",
...rest
} = $props();
// [/SECTION: PROPS]
let id = "select-" + Math.random().toString(36).substr(2, 9);
</script>
<!-- [SECTION: TEMPLATE] -->
<div class="flex flex-col gap-1.5 w-full">
{#if label}
<label for={id} class="text-sm font-medium text-gray-700">
{label}
</label>
{/if}
<select
{id}
{disabled}
bind:value
class={cn(
"flex h-10 w-full rounded-md border border-gray-300 bg-white px-3 py-2 text-sm ring-offset-white focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
className,
)}
{...rest}
>
{#each options as option}
<option value={option.value}>{option.label}</option>
{/each}
</select>
</div>
<!-- [/SECTION: TEMPLATE] -->
<!-- #endregion Select -->