sv5ui 1.3.0 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/README.md +16 -11
  2. package/dist/Collapsible/Collapsible.svelte +69 -0
  3. package/dist/Collapsible/Collapsible.svelte.d.ts +6 -0
  4. package/dist/Collapsible/CollapsibleTestWrapper.svelte +17 -0
  5. package/dist/Collapsible/CollapsibleTestWrapper.svelte.d.ts +4 -0
  6. package/dist/Collapsible/collapsible.types.d.ts +75 -0
  7. package/dist/Collapsible/collapsible.types.js +1 -0
  8. package/dist/Collapsible/collapsible.variants.d.ts +53 -0
  9. package/dist/Collapsible/collapsible.variants.js +21 -0
  10. package/dist/Collapsible/index.d.ts +2 -0
  11. package/dist/Collapsible/index.js +1 -0
  12. package/dist/Command/Command.svelte +183 -0
  13. package/dist/Command/Command.svelte.d.ts +6 -0
  14. package/dist/Command/CommandTestWrapper.svelte +13 -0
  15. package/dist/Command/CommandTestWrapper.svelte.d.ts +4 -0
  16. package/dist/Command/command.types.d.ts +98 -0
  17. package/dist/Command/command.types.js +1 -0
  18. package/dist/Command/command.variants.d.ts +226 -0
  19. package/dist/Command/command.variants.js +86 -0
  20. package/dist/Command/index.d.ts +2 -0
  21. package/dist/Command/index.js +1 -0
  22. package/dist/Select/select.variants.js +1 -1
  23. package/dist/SelectMenu/select-menu.variants.js +1 -1
  24. package/dist/Toast/Toaster.svelte +618 -0
  25. package/dist/Toast/Toaster.svelte.d.ts +5 -0
  26. package/dist/Toast/index.d.ts +4 -0
  27. package/dist/Toast/index.js +2 -0
  28. package/dist/Toast/toast.d.ts +38 -0
  29. package/dist/Toast/toast.js +73 -0
  30. package/dist/Toast/toast.types.d.ts +19 -0
  31. package/dist/Toast/toast.types.js +1 -0
  32. package/dist/Toast/toast.variants.d.ts +7 -0
  33. package/dist/Toast/toast.variants.js +5 -0
  34. package/dist/config.d.ts +1 -0
  35. package/dist/config.js +2 -1
  36. package/dist/index.d.ts +3 -0
  37. package/dist/index.js +3 -0
  38. package/dist/theme.css +36 -0
  39. package/package.json +2 -1
package/README.md CHANGED
@@ -129,17 +129,22 @@ pnpm add sv5ui
129
129
 
130
130
  ### Form
131
131
 
132
- | Component | Description |
133
- | :----------------------------------- | :------------------------------------------------------------------------------------------------------ |
134
- | [**Input**](src/lib/Input) | Text input with 5 variants, icons, avatar, loading state, and FormField integration |
135
- | [**Textarea**](src/lib/Textarea) | Multi-line text input with 5 variants, icons, autoresize with maxrows, and FormField integration |
136
- | [**Select**](src/lib/Select) | Dropdown select with 5 variants, icons, avatars, groups, descriptions, and FormField support |
137
- | [**Switch**](src/lib/Switch) | Toggle switch with 8 colors, 5 sizes, checked/unchecked icons, loading state, and FormField integration |
138
- | [**Checkbox**](src/lib/Checkbox) | Checkbox with 8 colors, 5 sizes, indeterminate state, custom icons, and FormField integration |
139
- | [**RadioGroup**](src/lib/RadioGroup) | Radio group for single-selection with items API, legend, orientation, and FormField integration |
140
- | [**FormField**](src/lib/FormField) | Form control wrapper providing label, description, hint, help, and error handling |
141
- | [**FieldGroup**](src/lib/FieldGroup) | Groups buttons and inputs with seamless borders and shared size/orientation context |
142
- | [**Calendar**](src/lib/Calendar) | Date picker calendar with single, multiple, and range selection modes |
132
+ | Component | Description |
133
+ | :----------------------------------------- | :------------------------------------------------------------------------------------------------------ |
134
+ | [**Input**](src/lib/Input) | Text input with 5 variants, icons, avatar, loading state, and FormField integration |
135
+ | [**Textarea**](src/lib/Textarea) | Multi-line text input with 5 variants, icons, autoresize with maxrows, and FormField integration |
136
+ | [**Select**](src/lib/Select) | Dropdown select with 5 variants, icons, avatars, groups, descriptions, and FormField support |
137
+ | [**SelectMenu**](src/lib/SelectMenu) | Searchable multi-select menu with chips, groups, and FormField integration |
138
+ | [**Switch**](src/lib/Switch) | Toggle switch with 8 colors, 5 sizes, checked/unchecked icons, loading state, and FormField integration |
139
+ | [**Checkbox**](src/lib/Checkbox) | Checkbox with 8 colors, 5 sizes, indeterminate state, custom icons, and FormField integration |
140
+ | [**CheckboxGroup**](src/lib/CheckboxGroup) | Grouped checkboxes with single/multiple selection, per-item disabled, and FormField integration |
141
+ | [**RadioGroup**](src/lib/RadioGroup) | Radio group for single-selection with items API, legend, orientation, and FormField integration |
142
+ | [**Slider**](src/lib/Slider) | Range slider with single/range values, step, orientation, tooltip labels, and FormField integration |
143
+ | [**PinInput**](src/lib/PinInput) | PIN/OTP input with masking, numeric filtering, OTP autocomplete, and FormField integration |
144
+ | [**FileUpload**](src/lib/FileUpload) | Drag-and-drop file upload with preview list, image thumbnails, accept filter, and multiple files |
145
+ | [**FormField**](src/lib/FormField) | Form control wrapper providing label, description, hint, help, and error handling |
146
+ | [**FieldGroup**](src/lib/FieldGroup) | Groups buttons and inputs with seamless borders and shared size/orientation context |
147
+ | [**Calendar**](src/lib/Calendar) | Date picker calendar with single, multiple, and range selection modes |
143
148
 
144
149
  ## Theming
145
150
 
@@ -0,0 +1,69 @@
1
+ <script lang="ts" module>
2
+ import type { CollapsibleProps } from './collapsible.types.js'
3
+
4
+ export type Props = CollapsibleProps
5
+ </script>
6
+
7
+ <script lang="ts">
8
+ import { Collapsible } from 'bits-ui'
9
+ import { collapsibleVariants, collapsibleDefaults } from './collapsible.variants.js'
10
+ import { getComponentConfig } from '../config.js'
11
+
12
+ const config = getComponentConfig('collapsible', collapsibleDefaults)
13
+
14
+ let {
15
+ ref = $bindable(null),
16
+ open = $bindable(false),
17
+ onOpenChange,
18
+ onOpenChangeComplete,
19
+ disabled = false,
20
+ trigger: triggerSlot,
21
+ content: contentSlot,
22
+ children,
23
+ ui,
24
+ class: className,
25
+ ...restProps
26
+ }: Props = $props()
27
+
28
+ const slots = $derived(collapsibleVariants({ disabled }))
29
+ const classes = $derived.by(() => {
30
+ const u = ui ?? {}
31
+ return {
32
+ root: slots.root({ class: [config.slots.root, className, u.root] }),
33
+ content: slots.content({ class: [config.slots.content, u.content] })
34
+ }
35
+ })
36
+
37
+ function handleOpenChange(value: boolean) {
38
+ open = value
39
+ onOpenChange?.(value)
40
+ }
41
+ </script>
42
+
43
+ <Collapsible.Root
44
+ {...restProps}
45
+ bind:ref
46
+ {open}
47
+ onOpenChange={handleOpenChange}
48
+ {onOpenChangeComplete}
49
+ {disabled}
50
+ class={classes.root}
51
+ >
52
+ {#if triggerSlot}
53
+ <Collapsible.Trigger>
54
+ {#snippet child({ props })}
55
+ {@render triggerSlot({ open, props })}
56
+ {/snippet}
57
+ </Collapsible.Trigger>
58
+ {/if}
59
+
60
+ {#if contentSlot}
61
+ <Collapsible.Content class={classes.content}>
62
+ {@render contentSlot()}
63
+ </Collapsible.Content>
64
+ {/if}
65
+
66
+ {#if children}
67
+ {@render children()}
68
+ {/if}
69
+ </Collapsible.Root>
@@ -0,0 +1,6 @@
1
+ import type { CollapsibleProps } from './collapsible.types.js';
2
+ export type Props = CollapsibleProps;
3
+ import { Collapsible } from 'bits-ui';
4
+ declare const Collapsible: import("svelte").Component<CollapsibleProps, {}, "ref" | "open">;
5
+ type Collapsible = ReturnType<typeof Collapsible>;
6
+ export default Collapsible;
@@ -0,0 +1,17 @@
1
+ <script lang="ts">
2
+ import Collapsible from './Collapsible.svelte'
3
+ import type { CollapsibleProps } from './collapsible.types.js'
4
+
5
+ let { ...props }: Omit<CollapsibleProps, 'trigger' | 'content' | 'children'> = $props()
6
+ </script>
7
+
8
+ <Collapsible {...props}>
9
+ {#snippet trigger({ open, props: triggerProps })}
10
+ <button type="button" {...triggerProps}>
11
+ {open ? 'Close' : 'Open'}
12
+ </button>
13
+ {/snippet}
14
+ {#snippet content()}
15
+ <div data-testid="collapsible-body">Collapsible content</div>
16
+ {/snippet}
17
+ </Collapsible>
@@ -0,0 +1,4 @@
1
+ import type { CollapsibleProps } from './collapsible.types.js';
2
+ declare const CollapsibleTestWrapper: import("svelte").Component<Omit<CollapsibleProps, "children" | "content" | "trigger">, {}, "">;
3
+ type CollapsibleTestWrapper = ReturnType<typeof CollapsibleTestWrapper>;
4
+ export default CollapsibleTestWrapper;
@@ -0,0 +1,75 @@
1
+ import type { Snippet } from 'svelte';
2
+ import type { ClassNameValue } from 'tailwind-merge';
3
+ import type { CollapsibleRootPropsWithoutHTML } from 'bits-ui';
4
+ import type { CollapsibleSlots } from './collapsible.variants.js';
5
+ /**
6
+ * Props for the Collapsible component.
7
+ *
8
+ * Wraps bits-ui's Collapsible primitives with a themed, slot-based API.
9
+ *
10
+ * @example
11
+ * ```svelte
12
+ * <Collapsible>
13
+ * {#snippet trigger({ open })}
14
+ * <Button>{open ? 'Hide' : 'Show'}</Button>
15
+ * {/snippet}
16
+ * {#snippet content()}
17
+ * <p>Collapsible content here</p>
18
+ * {/snippet}
19
+ * </Collapsible>
20
+ * ```
21
+ *
22
+ * @see https://bits-ui.com/docs/components/collapsible
23
+ */
24
+ export interface CollapsibleProps extends Pick<CollapsibleRootPropsWithoutHTML, 'open' | 'onOpenChange' | 'onOpenChangeComplete' | 'disabled'> {
25
+ /**
26
+ * Bindable reference to the root DOM element.
27
+ */
28
+ ref?: HTMLElement | null;
29
+ /**
30
+ * Override classes for collapsible component slots.
31
+ *
32
+ * @example
33
+ * ```ts
34
+ * ui={{ root: 'border rounded-lg', content: 'p-4' }}
35
+ * ```
36
+ */
37
+ ui?: Partial<Record<CollapsibleSlots, ClassNameValue>>;
38
+ /**
39
+ * Additional CSS classes for the root element.
40
+ */
41
+ class?: ClassNameValue;
42
+ /**
43
+ * Snippet for the trigger element that toggles the collapsible.
44
+ * Receives `{ open }` to reflect the current state.
45
+ *
46
+ * @example
47
+ * ```svelte
48
+ * {#snippet trigger({ open })}
49
+ * <Button variant="ghost">
50
+ * {open ? 'Collapse' : 'Expand'}
51
+ * </Button>
52
+ * {/snippet}
53
+ * ```
54
+ */
55
+ trigger?: Snippet<[{
56
+ open: boolean;
57
+ props: Record<string, unknown>;
58
+ }]>;
59
+ /**
60
+ * Snippet for the collapsible content area.
61
+ *
62
+ * @example
63
+ * ```svelte
64
+ * {#snippet content()}
65
+ * <p>Hidden content revealed on expand.</p>
66
+ * {/snippet}
67
+ * ```
68
+ */
69
+ content?: Snippet;
70
+ /**
71
+ * Default slot children. If provided, rendered inside the root
72
+ * for full custom layouts using bits-ui primitives directly.
73
+ */
74
+ children?: Snippet;
75
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,53 @@
1
+ import { type VariantProps } from 'tailwind-variants';
2
+ export declare const collapsibleVariants: import("tailwind-variants").TVReturnType<{
3
+ disabled: {
4
+ true: {
5
+ root: string;
6
+ };
7
+ };
8
+ }, {
9
+ root: string;
10
+ content: string;
11
+ }, undefined, {
12
+ disabled: {
13
+ true: {
14
+ root: string;
15
+ };
16
+ };
17
+ }, {
18
+ root: string;
19
+ content: string;
20
+ }, import("tailwind-variants").TVReturnType<{
21
+ disabled: {
22
+ true: {
23
+ root: string;
24
+ };
25
+ };
26
+ }, {
27
+ root: string;
28
+ content: string;
29
+ }, undefined, unknown, unknown, undefined>>;
30
+ export type CollapsibleVariantProps = VariantProps<typeof collapsibleVariants>;
31
+ export type CollapsibleSlots = keyof ReturnType<typeof collapsibleVariants>;
32
+ export declare const collapsibleDefaults: {
33
+ defaultVariants: import("tailwind-variants").TVDefaultVariants<{
34
+ disabled: {
35
+ true: {
36
+ root: string;
37
+ };
38
+ };
39
+ }, {
40
+ root: string;
41
+ content: string;
42
+ }, {
43
+ disabled: {
44
+ true: {
45
+ root: string;
46
+ };
47
+ };
48
+ }, {
49
+ root: string;
50
+ content: string;
51
+ }>;
52
+ slots: Partial<Record<CollapsibleSlots, string>>;
53
+ };
@@ -0,0 +1,21 @@
1
+ import { tv } from 'tailwind-variants';
2
+ export const collapsibleVariants = tv({
3
+ slots: {
4
+ root: '',
5
+ content: 'data-[state=open]:animate-[collapsible-down_200ms_ease-out] data-[state=closed]:animate-[collapsible-up_200ms_ease-out] overflow-hidden'
6
+ },
7
+ variants: {
8
+ disabled: {
9
+ true: {
10
+ root: 'opacity-75 cursor-not-allowed'
11
+ }
12
+ }
13
+ },
14
+ defaultVariants: {
15
+ disabled: false
16
+ }
17
+ });
18
+ export const collapsibleDefaults = {
19
+ defaultVariants: collapsibleVariants.defaultVariants,
20
+ slots: {}
21
+ };
@@ -0,0 +1,2 @@
1
+ export { default as Collapsible } from './Collapsible.svelte';
2
+ export type { CollapsibleProps } from './collapsible.types.js';
@@ -0,0 +1 @@
1
+ export { default as Collapsible } from './Collapsible.svelte';
@@ -0,0 +1,183 @@
1
+ <script lang="ts" module>
2
+ import type { CommandProps } from './command.types.js'
3
+
4
+ export type Props = CommandProps
5
+ </script>
6
+
7
+ <script lang="ts">
8
+ import { Command } from 'bits-ui'
9
+ import { commandVariants, commandDefaults } from './command.variants.js'
10
+ import { getComponentConfig, iconsDefaults } from '../config.js'
11
+ import Icon from '../Icon/Icon.svelte'
12
+
13
+ const config = getComponentConfig('command', commandDefaults)
14
+ const icons = getComponentConfig('icons', iconsDefaults)
15
+
16
+ let {
17
+ ref = $bindable(null),
18
+ value = $bindable(''),
19
+ search = $bindable(''),
20
+ onValueChange,
21
+ groups = [],
22
+ placeholder = 'Type a command or search...',
23
+ loading = false,
24
+ emptyText = 'No results found.',
25
+ icon,
26
+ label,
27
+ filter,
28
+ shouldFilter = true,
29
+ loop = false,
30
+ vimBindings = true,
31
+ size = config.defaultVariants.size,
32
+ item: itemSlot,
33
+ itemLeading: itemLeadingSlot,
34
+ itemLabel: itemLabelSlot,
35
+ itemTrailing: itemTrailingSlot,
36
+ empty: emptySlot,
37
+ footer: footerSlot,
38
+ ui,
39
+ class: className,
40
+ ...restProps
41
+ }: Props = $props()
42
+
43
+ const slots = $derived(commandVariants({ size }))
44
+ const classes = $derived.by(() => {
45
+ const u = ui ?? {}
46
+ return {
47
+ root: slots.root({ class: [config.slots.root, className, u.root] }),
48
+ inputWrapper: slots.inputWrapper({
49
+ class: [config.slots.inputWrapper, u.inputWrapper]
50
+ }),
51
+ inputIcon: slots.inputIcon({ class: [config.slots.inputIcon, u.inputIcon] }),
52
+ input: slots.input({ class: [config.slots.input, u.input] }),
53
+ list: slots.list({ class: [config.slots.list, u.list] }),
54
+ empty: slots.empty({ class: [config.slots.empty, u.empty] }),
55
+ loading: slots.loading({ class: [config.slots.loading, u.loading] }),
56
+ group: slots.group({ class: [config.slots.group, u.group] }),
57
+ groupHeading: slots.groupHeading({
58
+ class: [config.slots.groupHeading, u.groupHeading]
59
+ }),
60
+ groupItems: slots.groupItems({ class: [config.slots.groupItems, u.groupItems] }),
61
+ separator: slots.separator({ class: [config.slots.separator, u.separator] }),
62
+ item: slots.item({ class: [config.slots.item, u.item] }),
63
+ itemIcon: slots.itemIcon({ class: [config.slots.itemIcon, u.itemIcon] }),
64
+ itemWrapper: slots.itemWrapper({ class: [config.slots.itemWrapper, u.itemWrapper] }),
65
+ itemLabel: slots.itemLabel({ class: [config.slots.itemLabel, u.itemLabel] }),
66
+ itemDescription: slots.itemDescription({
67
+ class: [config.slots.itemDescription, u.itemDescription]
68
+ }),
69
+ itemTrailing: slots.itemTrailing({
70
+ class: [config.slots.itemTrailing, u.itemTrailing]
71
+ }),
72
+ footer: slots.footer({ class: [config.slots.footer, u.footer] })
73
+ }
74
+ })
75
+
76
+ function handleValueChange(v: string) {
77
+ value = v
78
+ onValueChange?.(v)
79
+ }
80
+ </script>
81
+
82
+ <Command.Root
83
+ {...restProps}
84
+ bind:ref
85
+ {value}
86
+ {label}
87
+ onValueChange={handleValueChange}
88
+ {filter}
89
+ {shouldFilter}
90
+ {loop}
91
+ {vimBindings}
92
+ class={classes.root}
93
+ >
94
+ <div class={classes.inputWrapper}>
95
+ <Icon name={icon ?? icons.search ?? 'lucide:search'} class={classes.inputIcon} />
96
+ <Command.Input bind:value={search} {placeholder} class={classes.input} />
97
+ </div>
98
+
99
+ <Command.List class={classes.list}>
100
+ {#if loading}
101
+ <Command.Loading class={classes.loading}>
102
+ <Icon name={icons.loading} class="mx-auto size-5 animate-spin" />
103
+ </Command.Loading>
104
+ {:else}
105
+ <Command.Empty class={classes.empty}>
106
+ {#if emptySlot}
107
+ {@render emptySlot({ search })}
108
+ {:else}
109
+ {emptyText}
110
+ {/if}
111
+ </Command.Empty>
112
+
113
+ {#each groups as group, gi (group.id)}
114
+ {#if gi > 0}
115
+ <Command.Separator class={classes.separator} />
116
+ {/if}
117
+
118
+ <Command.Group value={group.id} class={classes.group}>
119
+ {#if group.label}
120
+ <Command.GroupHeading class={classes.groupHeading}>
121
+ {group.label}
122
+ </Command.GroupHeading>
123
+ {/if}
124
+
125
+ <Command.GroupItems class={classes.groupItems}>
126
+ {#each group.items as cmdItem, i (cmdItem.value)}
127
+ {#if itemSlot}
128
+ {@render itemSlot({ item: cmdItem, index: i })}
129
+ {:else}
130
+ <Command.Item
131
+ value={cmdItem.value}
132
+ keywords={cmdItem.keywords}
133
+ disabled={cmdItem.disabled}
134
+ onSelect={cmdItem.onSelect}
135
+ class={cmdItem.class
136
+ ? slots.item({
137
+ class: [config.slots.item, ui?.item, cmdItem.class]
138
+ })
139
+ : classes.item}
140
+ >
141
+ {#if itemLeadingSlot}
142
+ {@render itemLeadingSlot({ item: cmdItem, index: i })}
143
+ {:else if cmdItem.icon}
144
+ <Icon name={cmdItem.icon} class={classes.itemIcon} />
145
+ {/if}
146
+
147
+ {#if itemLabelSlot}
148
+ {@render itemLabelSlot({ item: cmdItem, index: i })}
149
+ {:else}
150
+ <div class={classes.itemWrapper}>
151
+ {#if cmdItem.label}
152
+ <span class={classes.itemLabel}
153
+ >{cmdItem.label}</span
154
+ >
155
+ {/if}
156
+ {#if cmdItem.description}
157
+ <span class={classes.itemDescription}
158
+ >{cmdItem.description}</span
159
+ >
160
+ {/if}
161
+ </div>
162
+ {/if}
163
+
164
+ {#if itemTrailingSlot}
165
+ <span class={classes.itemTrailing}>
166
+ {@render itemTrailingSlot({ item: cmdItem, index: i })}
167
+ </span>
168
+ {/if}
169
+ </Command.Item>
170
+ {/if}
171
+ {/each}
172
+ </Command.GroupItems>
173
+ </Command.Group>
174
+ {/each}
175
+ {/if}
176
+ </Command.List>
177
+
178
+ {#if footerSlot}
179
+ <div class={classes.footer}>
180
+ {@render footerSlot()}
181
+ </div>
182
+ {/if}
183
+ </Command.Root>
@@ -0,0 +1,6 @@
1
+ import type { CommandProps } from './command.types.js';
2
+ export type Props = CommandProps;
3
+ import { Command } from 'bits-ui';
4
+ declare const Command: import("svelte").Component<CommandProps, {}, "search" | "ref" | "value">;
5
+ type Command = ReturnType<typeof Command>;
6
+ export default Command;
@@ -0,0 +1,13 @@
1
+ <script lang="ts">
2
+ import Command from './Command.svelte'
3
+ import type { CommandProps } from './command.types.js'
4
+
5
+ let {
6
+ ...props
7
+ }: Omit<
8
+ CommandProps,
9
+ 'item' | 'itemLeading' | 'itemLabel' | 'itemTrailing' | 'empty' | 'footer'
10
+ > = $props()
11
+ </script>
12
+
13
+ <Command {...props} />
@@ -0,0 +1,4 @@
1
+ import type { CommandProps } from './command.types.js';
2
+ declare const CommandTestWrapper: import("svelte").Component<Omit<CommandProps, "footer" | "item" | "empty" | "itemLabel" | "itemTrailing" | "itemLeading">, {}, "">;
3
+ type CommandTestWrapper = ReturnType<typeof CommandTestWrapper>;
4
+ export default CommandTestWrapper;
@@ -0,0 +1,98 @@
1
+ import type { Snippet } from 'svelte';
2
+ import type { ClassNameValue } from 'tailwind-merge';
3
+ import type { CommandRootPropsWithoutHTML } from 'bits-ui';
4
+ import type { CommandSlots, CommandVariantProps } from './command.variants.js';
5
+ /**
6
+ * Configuration for an individual command item.
7
+ */
8
+ export interface CommandItem {
9
+ /** Unique identifier and search value for this item. */
10
+ value: string;
11
+ /** Display label. */
12
+ label?: string;
13
+ /** Optional description shown below the label. */
14
+ description?: string;
15
+ /** Leading icon name (Iconify). */
16
+ icon?: string;
17
+ /** Additional search aliases for filtering. */
18
+ keywords?: string[];
19
+ /** Whether this item is disabled. */
20
+ disabled?: boolean;
21
+ /** Callback when item is selected. */
22
+ onSelect?: () => void;
23
+ /** Additional CSS classes for this item. */
24
+ class?: ClassNameValue;
25
+ }
26
+ /**
27
+ * Configuration for a command group.
28
+ */
29
+ export interface CommandGroup {
30
+ /** Unique group identifier. */
31
+ id: string;
32
+ /** Group heading label. */
33
+ label?: string;
34
+ /** Items in this group. */
35
+ items: CommandItem[];
36
+ }
37
+ export interface CommandItemSlotProps {
38
+ item: CommandItem;
39
+ index: number;
40
+ }
41
+ /**
42
+ * Props for the Command component.
43
+ *
44
+ * Wraps bits-ui Command primitives with a themed, items-based API.
45
+ *
46
+ * @example
47
+ * ```svelte
48
+ * <Command
49
+ * placeholder="Search..."
50
+ * groups={[
51
+ * { id: 'actions', label: 'Actions', items: [
52
+ * { value: 'new-file', label: 'New File', icon: 'lucide:file-plus' }
53
+ * ]}
54
+ * ]}
55
+ * />
56
+ * ```
57
+ *
58
+ * @see https://bits-ui.com/docs/components/command
59
+ */
60
+ export interface CommandProps extends Pick<CommandRootPropsWithoutHTML, 'value' | 'onValueChange' | 'filter' | 'shouldFilter' | 'loop' | 'vimBindings' | 'label'> {
61
+ /** Bindable reference to the root DOM element. */
62
+ ref?: HTMLElement | null;
63
+ /** Array of grouped command items. */
64
+ groups?: CommandGroup[];
65
+ /** Placeholder text for the search input. */
66
+ placeholder?: string;
67
+ /**
68
+ * The current search term. Use `bind:search` for two-way binding.
69
+ * @default ''
70
+ */
71
+ search?: string;
72
+ /** Loading state — shows a loading indicator instead of items. */
73
+ loading?: boolean;
74
+ /** Text shown when no results match the search query. */
75
+ emptyText?: string;
76
+ /** Leading icon for the search input. */
77
+ icon?: string;
78
+ /** Size variant. */
79
+ size?: NonNullable<CommandVariantProps['size']>;
80
+ /** Override classes for component slots. */
81
+ ui?: Partial<Record<CommandSlots, ClassNameValue>>;
82
+ /** Additional CSS classes for the root element. */
83
+ class?: ClassNameValue;
84
+ /** Custom snippet for rendering each item. Replaces default item rendering. */
85
+ item?: Snippet<[CommandItemSlotProps]>;
86
+ /** Custom snippet for the item leading section (icon area). */
87
+ itemLeading?: Snippet<[CommandItemSlotProps]>;
88
+ /** Custom snippet for the item label section. */
89
+ itemLabel?: Snippet<[CommandItemSlotProps]>;
90
+ /** Custom snippet for the item trailing section. */
91
+ itemTrailing?: Snippet<[CommandItemSlotProps]>;
92
+ /** Custom snippet for the empty state. */
93
+ empty?: Snippet<[{
94
+ search: string;
95
+ }]>;
96
+ /** Custom snippet for the footer area below the list. */
97
+ footer?: Snippet;
98
+ }
@@ -0,0 +1 @@
1
+ export {};