@rokkit/ui 1.4.1 → 1.5.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 (41) hide show
  1. package/dist/components/CodeGroup.svelte +0 -1
  2. package/dist/components/CommandPalette.svelte +2 -1
  3. package/dist/components/CommandPalette.svelte.d.ts +2 -5
  4. package/dist/components/Dropdown.svelte +3 -22
  5. package/dist/components/Dropdown.svelte.d.ts +2 -20
  6. package/dist/components/Grid.svelte +2 -13
  7. package/dist/components/Grid.svelte.d.ts +2 -43
  8. package/dist/components/LazyTree.svelte +2 -15
  9. package/dist/components/LazyTree.svelte.d.ts +2 -28
  10. package/dist/components/List.svelte +3 -19
  11. package/dist/components/List.svelte.d.ts +2 -47
  12. package/dist/components/Menu.svelte +3 -24
  13. package/dist/components/Menu.svelte.d.ts +2 -66
  14. package/dist/components/MultiSelect.svelte +3 -24
  15. package/dist/components/MultiSelect.svelte.d.ts +2 -23
  16. package/dist/components/Select.svelte +3 -25
  17. package/dist/components/Select.svelte.d.ts +2 -24
  18. package/dist/components/Swatch.svelte +1 -26
  19. package/dist/components/Swatch.svelte.d.ts +1 -27
  20. package/dist/components/Tabs.svelte +7 -1
  21. package/dist/components/Tabs.svelte.d.ts +2 -0
  22. package/dist/components/Toggle.svelte +6 -1
  23. package/dist/components/Toggle.svelte.d.ts +2 -0
  24. package/dist/components/Tree.svelte +2 -12
  25. package/dist/components/Tree.svelte.d.ts +2 -29
  26. package/dist/types/chat.d.ts +15 -0
  27. package/dist/types/command-palette.d.ts +18 -0
  28. package/dist/types/command-palette.js +7 -0
  29. package/dist/types/grid.d.ts +37 -0
  30. package/dist/types/grid.js +8 -0
  31. package/dist/types/index.d.ts +4 -0
  32. package/dist/types/index.js +8 -0
  33. package/dist/types/list.d.ts +22 -55
  34. package/dist/types/menu.d.ts +9 -2
  35. package/dist/types/select.d.ts +52 -62
  36. package/dist/types/snippets.d.ts +55 -0
  37. package/dist/types/snippets.js +16 -0
  38. package/dist/types/swatch.d.ts +41 -0
  39. package/dist/types/swatch.js +8 -0
  40. package/dist/types/tree.d.ts +34 -66
  41. package/package.json +9 -8
@@ -1,30 +1,4 @@
1
- import type { Snippet } from 'svelte';
2
- import type { ProxyItem } from '@rokkit/states';
3
- interface SwatchProps {
4
- /** Color options — primitives (hex/name strings) or objects with mapped fields */
5
- options?: Array<string | number | Record<string, unknown>>;
6
- /** Field mapping for object options (value, fill, stroke, …) */
7
- fields?: Record<string, string>;
8
- /** Selected value (bindable). Array when `multiple`. */
9
- value?: unknown;
10
- /** Allow multiple selection */
11
- multiple?: boolean;
12
- /** Swatch shape */
13
- shape?: 'square' | 'circle';
14
- /** Size variant */
15
- size?: 'sm' | 'md' | 'lg';
16
- /** Disable the whole group */
17
- disabled?: boolean;
18
- /** Accessible group label */
19
- label?: string;
20
- /** Additional CSS classes */
21
- class?: string;
22
- /** Called when selection changes */
23
- onchange?: (value: unknown, item: unknown) => void;
24
- /** Custom snippet for rendering a swatch (receives proxy + selected) */
25
- item?: Snippet<[ProxyItem, boolean]>;
26
- [key: string]: unknown;
27
- }
1
+ import type { SwatchProps } from '../types/swatch.js';
28
2
  declare const Swatch: import("svelte").Component<SwatchProps, {}, "value">;
29
3
  type Swatch = ReturnType<typeof Swatch>;
30
4
  export default Swatch;
@@ -22,6 +22,7 @@
22
22
  import { Wrapper, ProxyTree, messages } from '@rokkit/states'
23
23
  import { Navigator } from '@rokkit/actions'
24
24
  import { resolveSnippet, ITEM_SNIPPET, DEFAULT_STATE_ICONS } from '@rokkit/core'
25
+ import type { SelectableItemSnippet } from '../types/snippets.js'
25
26
 
26
27
  let {
27
28
  options = [],
@@ -41,7 +42,12 @@
41
42
  onadd,
42
43
  onremove,
43
44
  ...snippets
44
- }: TabsProps & { labels?: Record<string, string>; [key: string]: unknown } = $props()
45
+ }: TabsProps & {
46
+ labels?: Record<string, string>
47
+ // Tabs renders its content as content(proxy, selected).
48
+ itemContent?: SelectableItemSnippet
49
+ [key: string]: unknown
50
+ } = $props()
45
51
 
46
52
  const labels = $derived({ ...messages.tabs, ...userLabels })
47
53
 
@@ -17,8 +17,10 @@
17
17
  * receives data-panel-active. Navigator ignores panels (no data-path on them).
18
18
  */
19
19
  import type { TabsProps } from '../types/tabs.js';
20
+ import type { SelectableItemSnippet } from '../types/snippets.js';
20
21
  type $$ComponentProps = TabsProps & {
21
22
  labels?: Record<string, string>;
23
+ itemContent?: SelectableItemSnippet;
22
24
  [key: string]: unknown;
23
25
  };
24
26
  declare const Tabs: import("svelte").Component<$$ComponentProps, {}, "value">;
@@ -4,6 +4,7 @@
4
4
  import { Wrapper, ProxyTree, messages } from '@rokkit/states'
5
5
  import { Navigator } from '@rokkit/actions'
6
6
  import { resolveSnippet } from '@rokkit/core'
7
+ import type { SelectableItemSnippet } from '../types/snippets.js'
7
8
 
8
9
  let {
9
10
  variant = 'group',
@@ -17,7 +18,11 @@
17
18
  label = messages.toggle.label,
18
19
  class: className = '',
19
20
  ...snippets
20
- }: ToggleProps & { [key: string]: unknown } = $props()
21
+ }: ToggleProps & {
22
+ // Toggle renders its content as content(proxy, selected).
23
+ itemContent?: SelectableItemSnippet
24
+ [key: string]: unknown
25
+ } = $props()
21
26
 
22
27
  // ─── Wrapper ──────────────────────────────────────────────────────────────
23
28
 
@@ -1,5 +1,7 @@
1
1
  import type { ToggleProps } from '../types/toggle.js';
2
+ import type { SelectableItemSnippet } from '../types/snippets.js';
2
3
  type $$ComponentProps = ToggleProps & {
4
+ itemContent?: SelectableItemSnippet;
3
5
  [key: string]: unknown;
4
6
  };
5
7
  declare const Toggle: import("svelte").Component<$$ComponentProps, {}, "value">;
@@ -17,6 +17,7 @@
17
17
  import { DEFAULT_STATE_ICONS, resolveSnippet, ITEM_SNIPPET } from '@rokkit/core'
18
18
  import ItemContent from './ItemContent.svelte'
19
19
  import Connector from './Connector.svelte'
20
+ import type { TreeProps } from '../types/tree.js'
20
21
 
21
22
  let {
22
23
  items = [],
@@ -29,18 +30,7 @@
29
30
  onselect,
30
31
  class: className = '',
31
32
  ...snippets
32
- }: {
33
- items?: unknown[]
34
- fields?: Record<string, string>
35
- value?: unknown
36
- size?: string
37
- lineStyle?: 'none' | 'solid' | 'dashed' | 'dotted'
38
- labels?: Record<string, string>
39
- icons?: { opened?: string; closed?: string }
40
- onselect?: (value: unknown, proxy: ProxyItem) => void
41
- class?: string
42
- [key: string]: unknown
43
- } = $props()
33
+ }: TreeProps = $props()
44
34
 
45
35
  const labels = $derived({ ...messages.tree, ...userLabels })
46
36
 
@@ -1,31 +1,4 @@
1
- /**
2
- * Tree — Hierarchical data navigation with tree lines and keyboard navigation.
3
- *
4
- * Architecture:
5
- * LazyWrapper — owns focusedKey $state + flatView $derived (with lineTypes)
6
- * Navigator — attaches DOM event handlers, calls wrapper[action](path)
7
- * flatView — single flat {#each}, connectors rendered from node.lineTypes
8
- *
9
- * Default item content: icon + label + badge + shortcut (no avatar/description).
10
- * Parent nodes hide their icon by default (showIcon=false) so only the
11
- * expand/collapse chevron + label are shown, aligning with leaf icon + label.
12
- */
13
- import type { ProxyItem } from '@rokkit/states';
14
- type $$ComponentProps = {
15
- items?: unknown[];
16
- fields?: Record<string, string>;
17
- value?: unknown;
18
- size?: string;
19
- lineStyle?: 'none' | 'solid' | 'dashed' | 'dotted';
20
- labels?: Record<string, string>;
21
- icons?: {
22
- opened?: string;
23
- closed?: string;
24
- };
25
- onselect?: (value: unknown, proxy: ProxyItem) => void;
26
- class?: string;
27
- [key: string]: unknown;
28
- };
29
- declare const Tree: import("svelte").Component<$$ComponentProps, {}, "value">;
1
+ import type { TreeProps } from '../types/tree.js';
2
+ declare const Tree: import("svelte").Component<TreeProps, {}, "value">;
30
3
  type Tree = ReturnType<typeof Tree>;
31
4
  export default Tree;
@@ -1,6 +1,16 @@
1
1
  import type { Snippet } from 'svelte';
2
2
  export type ChatRole = 'user' | 'assistant' | 'system';
3
3
  export type ChatStatus = 'streaming' | 'error' | 'done';
4
+ /**
5
+ * A single message in a chat transcript.
6
+ *
7
+ * Also exported as `ChatMessageData`, which is the name consumers should import.
8
+ * The package entry exports a *component* called `ChatMessage` as well, and
9
+ * Svelte's generated component types contribute a type of that name — which
10
+ * shadows this interface, making `ChatMessage<T>` unreachable from outside the
11
+ * package. The alias is the reachable spelling; renaming either the component or
12
+ * this interface is a breaking change, so it waits for a major.
13
+ */
4
14
  export interface ChatMessage<T = unknown> {
5
15
  id: string;
6
16
  role: ChatRole;
@@ -12,6 +22,11 @@ export interface ChatMessage<T = unknown> {
12
22
  /** Arbitrary payload (parts/blocks/chart spec/form schema) the consumer's `message` snippet reads. */
13
23
  data?: T;
14
24
  }
25
+ /**
26
+ * Reachable alias for {@link ChatMessage} — see the note on that interface for
27
+ * why the bare name does not survive the package boundary.
28
+ */
29
+ export type ChatMessageData<T = unknown> = ChatMessage<T>;
15
30
  export interface ConversationSummary {
16
31
  id: string;
17
32
  title: string;
@@ -0,0 +1,18 @@
1
+ /**
2
+ * CommandPalette Component Types
3
+ *
4
+ * Overlay command launcher. It owns its own command source and filtering, so
5
+ * the public surface is just visibility and the search affordance's label.
6
+ */
7
+ /**
8
+ * Props for the CommandPalette component.
9
+ *
10
+ * `CommandPalette.svelte` annotates its own `$props()` with this interface, so
11
+ * the two cannot drift.
12
+ */
13
+ export interface CommandPaletteProps {
14
+ /** Whether the palette is open (bindable) */
15
+ open?: boolean;
16
+ /** Placeholder text for the search input */
17
+ placeholder?: string;
18
+ }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * CommandPalette Component Types
3
+ *
4
+ * Overlay command launcher. It owns its own command source and filtering, so
5
+ * the public surface is just visibility and the search affordance's label.
6
+ */
7
+ export {};
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Grid Component Types
3
+ *
4
+ * Data-driven grid of selectable cards. Same field-mapping and snippet
5
+ * contract as List — items are wrapped in a `ProxyItem` and rendered through
6
+ * `itemContent`, with the grid supplying only the track sizing.
7
+ */
8
+ import type { ProxyItem } from '@rokkit/states';
9
+ import type { ItemSnippets } from './snippets.js';
10
+ /**
11
+ * Props for the Grid component.
12
+ *
13
+ * `Grid.svelte` annotates its own `$props()` with this interface, so the two
14
+ * cannot drift.
15
+ */
16
+ export interface GridProps extends ItemSnippets {
17
+ /** Array of items to render as cells */
18
+ items?: unknown[];
19
+ /** Field mapping configuration */
20
+ fields?: Record<string, string>;
21
+ /** Selected value (bindable) */
22
+ value?: unknown;
23
+ /** Size variant */
24
+ size?: string;
25
+ /** Whether the entire grid is disabled */
26
+ disabled?: boolean;
27
+ /** Minimum track width, fed to `repeat(auto-fill, minmax(…))` */
28
+ minSize?: string;
29
+ /** Gap between cells */
30
+ gap?: string;
31
+ /** Accessible name for the grid */
32
+ label?: string;
33
+ /** Called when a cell is selected, with the item's `ProxyItem` */
34
+ onselect?: (value: unknown, proxy: ProxyItem) => void;
35
+ /** Additional CSS classes */
36
+ class?: string;
37
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Grid Component Types
3
+ *
4
+ * Data-driven grid of selectable cards. Same field-mapping and snippet
5
+ * contract as List — items are wrapped in a `ProxyItem` and rendered through
6
+ * `itemContent`, with the grid supplying only the track sizing.
7
+ */
8
+ export {};
@@ -46,3 +46,7 @@ export * from './stack.js';
46
46
  export * from './stepper.js';
47
47
  export * from './tilt.js';
48
48
  export * from './chat.js';
49
+ export * from './snippets.js';
50
+ export * from './grid.js';
51
+ export * from './command-palette.js';
52
+ export * from './swatch.js';
@@ -91,3 +91,11 @@ export * from './stepper.js';
91
91
  export * from './tilt.js';
92
92
  // Chat Types
93
93
  export * from './chat.js';
94
+ // Shared snippet types for the item-rendering components
95
+ export * from './snippets.js';
96
+ // Grid
97
+ export * from './grid.js';
98
+ // CommandPalette
99
+ export * from './command-palette.js';
100
+ // Swatch
101
+ export * from './swatch.js';
@@ -5,6 +5,8 @@
5
5
  * Supports navigation links, button items, and grouped items with collapsible sections.
6
6
  * Field mapping and data access is handled by ProxyItem from @rokkit/states.
7
7
  */
8
+ import type { ProxyItem } from '@rokkit/states';
9
+ import type { ItemSnippets } from './snippets.js';
8
10
  /**
9
11
  * Field mapping configuration for list data.
10
12
  */
@@ -43,72 +45,37 @@ export declare const defaultListFields: Required<Omit<ListFields, 'fields'>>;
43
45
  */
44
46
  export type ListItem = Record<string, unknown>;
45
47
  /**
46
- * Handlers passed to custom item snippets
47
- */
48
- export interface ListItemHandlers {
49
- /** Call to trigger item selection (for button items) */
50
- onclick: () => void;
51
- /** Forward keyboard events for accessibility */
52
- onkeydown: (event: KeyboardEvent) => void;
53
- }
54
- /**
55
- * Snippet type for rendering list items.
56
- * Parameters: item, fields, handlers, isActive
57
- */
58
- export type ListItemSnippet = import('svelte').Snippet<[
59
- ListItem,
60
- ListFields,
61
- ListItemHandlers,
62
- boolean
63
- ]>;
64
- /**
65
- * Snippet type for rendering group labels
66
- * Parameters: item (group), fields, toggleExpanded, isExpanded
67
- */
68
- export type ListGroupLabelSnippet = import('svelte').Snippet<[
69
- ListItem,
70
- ListFields,
71
- () => void,
72
- boolean
73
- ]>;
74
- /**
75
- * Props for the List component
48
+ * Props for the List component.
49
+ *
50
+ * `List.svelte` annotates its own `$props()` with this interface, so the two
51
+ * cannot drift — which is how the previous version of this type came to
52
+ * describe `item` / `groupLabel` snippets and `multiselect` / `expanded` /
53
+ * `selected` props the component never read.
54
+ *
55
+ * Extends {@link ItemSnippets} for `itemContent` / `groupContent` plus the open
56
+ * index signature that per-item named snippets (`item.snippet = 'name'`) need.
76
57
  */
77
- export interface ListProps {
58
+ export interface ListProps extends ItemSnippets {
78
59
  /** Array of list items or groups */
79
- items?: ListItem[];
60
+ items?: unknown[];
80
61
  /** Field mapping configuration */
81
- fields?: ListFields;
82
- /** Currently selected value (for highlighting button items) */
62
+ fields?: Record<string, string>;
63
+ /** Selected value (bindable) — matched against each item's value field */
83
64
  value?: unknown;
84
65
  /** Size variant */
85
- size?: 'sm' | 'md' | 'lg';
66
+ size?: string;
86
67
  /** Whether the entire list is disabled */
87
68
  disabled?: boolean;
88
69
  /** Whether groups can be collapsed */
89
70
  collapsible?: boolean;
90
- /** Enable multiple item selection (Ctrl+click toggle, Shift+click range) */
91
- multiselect?: boolean;
92
- /** Which groups are expanded (bindable) - keyed by group value/text */
93
- expanded?: Record<string, boolean>;
94
- /** Selected items array (bindable) - populated in multiselect mode */
95
- selected?: unknown[];
96
- /** Active item value - List looks up item by this value to highlight it */
97
- active?: unknown;
98
- /** Called when a button item is selected */
99
- onselect?: (value: unknown, item: ListItem) => void;
100
- /** Called when selected items change in multiselect mode */
101
- onselectedchange?: (selected: unknown[]) => void;
102
- /** Called when expanded state changes (for bindable expanded) */
103
- onexpandedchange?: (expanded: Record<string, boolean>) => void;
104
- /** Additional CSS classes */
105
- class?: string;
71
+ /** Accessible name for the list */
72
+ label?: string;
106
73
  /** Icons for list group states (expand/collapse arrow) */
107
74
  icons?: ListStateIcons;
108
- /** Custom snippet for rendering list items */
109
- item?: ListItemSnippet;
110
- /** Custom snippet for rendering group labels/headers */
111
- groupLabel?: ListGroupLabelSnippet;
75
+ /** Called when an item is selected, with the item's `ProxyItem` */
76
+ onselect?: (value: unknown, proxy: ProxyItem) => void;
77
+ /** Additional CSS classes */
78
+ class?: string;
112
79
  }
113
80
  /**
114
81
  * Icons configuration for list collapsible group states.
@@ -5,12 +5,19 @@
5
5
  * Trigger action manages open/close. Dropdown content is identical to List.
6
6
  */
7
7
  import type { ProxyItem } from '@rokkit/states';
8
+ import type { ItemSnippets } from './snippets.js';
8
9
  /**
9
10
  * Props for the Menu component.
10
11
  * Content props (items, fields, value, size, disabled, collapsible, icons, onselect, class, snippets)
11
12
  * are identical to List. Additional props: label, icon, showArrow, align, direction.
12
13
  */
13
- export interface MenuProps {
14
+ /**
15
+ * Props for the Menu component.
16
+ *
17
+ * `Menu.svelte` annotates its own `$props()` with this interface, so the two
18
+ * cannot drift.
19
+ */
20
+ export interface MenuProps extends ItemSnippets {
14
21
  /** Array of items (same as List: supports groups, separators, nested children) */
15
22
  items?: unknown[];
16
23
  /** Field mapping — overrides BASE_FIELDS defaults (label → 'label', value → 'value', …) */
@@ -18,7 +25,7 @@ export interface MenuProps {
18
25
  /** Current active value (highlights matching item) */
19
26
  value?: unknown;
20
27
  /** Size variant */
21
- size?: 'sm' | 'md' | 'lg';
28
+ size?: string;
22
29
  /** Whether the entire menu is disabled */
23
30
  disabled?: boolean;
24
31
  /** Whether groups are collapsible (same as List) */
@@ -4,94 +4,84 @@
4
4
  * Provides types for the data-driven Select and MultiSelect components.
5
5
  * Field mapping and data access is handled by ProxyItem from @rokkit/states.
6
6
  */
7
- import type { Snippet } from 'svelte';
8
- import type { ProxyItem } from '@rokkit/states';
7
+ import type { ItemSnippets } from './snippets.js';
9
8
  /**
10
9
  * Generic select item - can be any object with mapped fields
11
10
  */
12
11
  export type SelectItem = Record<string, unknown>;
13
- /** @deprecated Legacy handlers — will be removed when PaletteManager migrates to Navigator stack */
14
- export interface SelectItemHandlers {
15
- onclick: () => void;
16
- onkeydown: (event: KeyboardEvent) => void;
17
- }
18
- /**
19
- * Snippet type for rendering a single option in the dropdown.
20
- * The component renders the focusable wrapper; the snippet renders the inner content.
21
- * Navigator handles click selection via data-path — no handlers needed in snippet.
22
- */
23
- export type SelectOptionSnippet = Snippet<[ProxyItem]>;
24
- /**
25
- * Snippet type for rendering a group header label.
26
- */
27
- export type SelectGroupLabelSnippet = Snippet<[ProxyItem]>;
28
- /**
29
- * Snippet type for rendering the selected value display in the trigger button.
30
- */
31
- export type SelectValueSnippet = Snippet<[ProxyItem]>;
32
12
  /**
33
- * Snippet type for rendering selected values in MultiSelect trigger.
34
- * Receives the array of selected ProxyItems.
35
- */
36
- export type MultiSelectValueSnippet = Snippet<[ProxyItem[]]>;
37
- /**
38
- * Common props shared between Select and MultiSelect
13
+ * Common props shared between Select, MultiSelect and Dropdown.
14
+ *
15
+ * Each component annotates its own `$props()` with the derived interface, so
16
+ * they cannot drift — which is how the previous version came to name the data
17
+ * prop `options` when every component takes `items`, and to declare
18
+ * `option` / `groupLabel` snippets the components never read.
39
19
  */
40
20
  export interface SelectBaseProps {
41
- /** Array of select options or groups */
42
- options?: SelectItem[];
43
- /** Field mapping — overrides BASE_FIELDS defaults (text → 'label', value → 'value', …) */
21
+ /** Array of options or groups */
22
+ items?: unknown[];
23
+ /** Field mapping — overrides BASE_FIELDS defaults */
44
24
  fields?: Record<string, string>;
45
25
  /** Placeholder text when no selection */
46
26
  placeholder?: string;
47
27
  /** Size variant */
48
- size?: 'sm' | 'md' | 'lg';
28
+ size?: string;
29
+ /** Whether the control is disabled */
30
+ disabled?: boolean;
49
31
  /** Dropdown alignment relative to trigger */
50
- align?: 'left' | 'right' | 'start' | 'end';
32
+ align?: 'start' | 'end';
51
33
  /** Dropdown slide direction */
52
34
  direction?: 'up' | 'down';
53
- /** Maximum visible rows in dropdown (default: 5) */
54
- maxRows?: number;
55
- /** Whether the select is disabled */
56
- disabled?: boolean;
35
+ /** Icons for dropdown arrow, check and remove */
36
+ icons?: SelectStateIcons;
57
37
  /** Additional CSS classes on root element */
58
38
  class?: string;
59
- /** Icons for select states (dropdown arrow, check, remove) */
60
- icons?: SelectStateIcons;
61
- /** Custom snippet for rendering options in dropdown */
62
- option?: SelectOptionSnippet;
63
- /** Custom snippet for rendering group labels */
64
- groupLabel?: SelectGroupLabelSnippet;
65
- /** Enable typeahead filter input in dropdown header */
66
- filterable?: boolean;
67
- /** Placeholder text for the filter input */
68
- filterPlaceholder?: string;
69
39
  }
70
40
  /**
71
- * Props for the Select component (single selection)
41
+ * Props for the Select component (single selection).
72
42
  */
73
- export interface SelectProps extends SelectBaseProps {
74
- /** Currently selected value (bindable) — extracted via item[fields.value] */
43
+ export interface SelectProps extends SelectBaseProps, ItemSnippets {
44
+ /** Selected value (bindable) — extracted via item[fields.value] */
75
45
  value?: unknown;
76
- /** Currently selected raw item (bindable) — full object from options array */
77
- selected?: SelectItem | null;
46
+ /** Selected raw item (bindable) */
47
+ selected?: unknown;
48
+ /** Enable the typeahead filter input in the dropdown header */
49
+ filterable?: boolean;
50
+ /** Placeholder for the filter input */
51
+ filterPlaceholder?: string;
52
+ /** Maximum visible rows in the dropdown */
53
+ maxRows?: number;
78
54
  /** Called when selection changes */
79
- onchange?: (value: unknown, item: SelectItem) => void;
80
- /** Custom snippet for rendering the selected value in the trigger */
81
- selectedValue?: SelectValueSnippet;
55
+ onchange?: (value: unknown, item: unknown) => void;
82
56
  }
83
57
  /**
84
- * Props for the MultiSelect component (multiple selection)
58
+ * Props for the MultiSelect component (multiple selection).
85
59
  */
86
- export interface MultiSelectProps extends SelectBaseProps {
87
- /** Currently selected values (bindable) - extracted primitives */
60
+ export interface MultiSelectProps extends SelectBaseProps, ItemSnippets {
61
+ /** Selected values (bindable) */
88
62
  value?: unknown[];
89
- /** Currently selected items (bindable) - full item objects for convenience */
90
- selected?: SelectItem[];
91
- /** Called when selection changes */
92
- onchange?: (values: unknown[], items: SelectItem[]) => void;
93
- /** Maximum number of tags to show before collapsing to count */
63
+ /** Selected items (bindable) */
64
+ selected?: unknown[];
65
+ /** Maximum tags shown before collapsing to a count */
94
66
  maxDisplay?: number;
67
+ /** Called when selection changes */
68
+ onchange?: (values: unknown[], items: unknown[]) => void;
69
+ }
70
+ /**
71
+ * Props for the Dropdown component.
72
+ *
73
+ * Unlike Select and MultiSelect it does not spread snippets, so it takes the
74
+ * base props only.
75
+ */
76
+ export interface DropdownProps extends SelectBaseProps {
77
+ /** Selected value (bindable) */
78
+ value?: unknown;
79
+ /** Trigger icon class */
80
+ icon?: string;
81
+ /** Whether to show the dropdown arrow indicator on the trigger */
82
+ showArrow?: boolean;
83
+ /** Called when selection changes */
84
+ onchange?: (value: unknown, item: unknown) => void;
95
85
  }
96
86
  /**
97
87
  * Icons configuration for select expand/collapse and selection states.
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Shared snippet types for the item-rendering components.
3
+ *
4
+ * List / Tree / Menu / Select / Grid and friends collect their snippets with a
5
+ * rest element (`...snippets`) behind an index signature, because a data item
6
+ * can name its own snippet (`item.snippet = 'name'`, resolved by
7
+ * `resolveSnippet`) — so arbitrary keys must stay accepted.
8
+ *
9
+ * The index signature alone typed every snippet as `unknown`, which made each
10
+ * consumer's snippet parameter implicitly `any`: a snippet body could read any
11
+ * property off `proxy` or pass it somewhere expecting a different type, and
12
+ * nothing complained until runtime. Declaring the documented snippets
13
+ * explicitly fixes that — TypeScript prefers an explicit member over the index
14
+ * signature, so the common case is checked while named snippets still work.
15
+ */
16
+ import type { Snippet } from 'svelte';
17
+ import type { ProxyItem } from '@rokkit/states';
18
+ /**
19
+ * Renders one item's inner content, given its `ProxyItem`.
20
+ *
21
+ * This is the shape of `itemContent` and `groupContent` — the fallbacks
22
+ * `resolveSnippet` reaches for (`ITEM_SNIPPET` / `GROUP_SNIPPET`), and the
23
+ * shape any per-item named snippet must also have.
24
+ */
25
+ export type ItemSnippet = Snippet<[ProxyItem]>;
26
+ /**
27
+ * Renders one item's inner content plus whether it is currently selected.
28
+ *
29
+ * Used where selection is part of the item's own rendering rather than the
30
+ * wrapper's — Tabs and Toggle both call their content snippet as
31
+ * `content(proxy, selected)`.
32
+ */
33
+ export type SelectableItemSnippet = Snippet<[ProxyItem, boolean]>;
34
+ /**
35
+ * The snippet bag an item-rendering component accepts.
36
+ *
37
+ * Spread into a component's props type so the documented snippets are typed
38
+ * while `item.snippet = 'name'` keeps working:
39
+ *
40
+ * ```ts
41
+ * let { items = [], ...snippets }: { items?: unknown[] } & ItemSnippets = $props()
42
+ * ```
43
+ */
44
+ export interface ItemSnippets {
45
+ /** Inner content for a leaf item. */
46
+ itemContent?: ItemSnippet;
47
+ /** Inner content for a group/parent item. Falls back to `itemContent`. */
48
+ groupContent?: ItemSnippet;
49
+ /**
50
+ * Per-item named snippets, selected via the item's `snippet` field. Kept as
51
+ * `unknown` rather than `ItemSnippet` because this signature also has to
52
+ * admit every other prop the component spreads through.
53
+ */
54
+ [key: string]: unknown;
55
+ }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Shared snippet types for the item-rendering components.
3
+ *
4
+ * List / Tree / Menu / Select / Grid and friends collect their snippets with a
5
+ * rest element (`...snippets`) behind an index signature, because a data item
6
+ * can name its own snippet (`item.snippet = 'name'`, resolved by
7
+ * `resolveSnippet`) — so arbitrary keys must stay accepted.
8
+ *
9
+ * The index signature alone typed every snippet as `unknown`, which made each
10
+ * consumer's snippet parameter implicitly `any`: a snippet body could read any
11
+ * property off `proxy` or pass it somewhere expecting a different type, and
12
+ * nothing complained until runtime. Declaring the documented snippets
13
+ * explicitly fixes that — TypeScript prefers an explicit member over the index
14
+ * signature, so the common case is checked while named snippets still work.
15
+ */
16
+ export {};