@human-kit/svelte-components 1.0.0-alpha.1

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 (140) hide show
  1. package/dist/combobox/TODO.md +175 -0
  2. package/dist/combobox/button/combobox-button.svelte +57 -0
  3. package/dist/combobox/button/combobox-button.svelte.d.ts +9 -0
  4. package/dist/combobox/index.d.ts +14 -0
  5. package/dist/combobox/index.js +18 -0
  6. package/dist/combobox/index.parts.d.ts +10 -0
  7. package/dist/combobox/index.parts.js +11 -0
  8. package/dist/combobox/input/combobox-input.svelte +98 -0
  9. package/dist/combobox/input/combobox-input.svelte.d.ts +13 -0
  10. package/dist/combobox/item/combobox-item-implicit-text-test.svelte +21 -0
  11. package/dist/combobox/item/combobox-item-implicit-text-test.svelte.d.ts +3 -0
  12. package/dist/combobox/item/combobox-listboxitem.svelte +136 -0
  13. package/dist/combobox/item/combobox-listboxitem.svelte.d.ts +18 -0
  14. package/dist/combobox/item-indicator/combobox-item-indicator.svelte +63 -0
  15. package/dist/combobox/item-indicator/combobox-item-indicator.svelte.d.ts +17 -0
  16. package/dist/combobox/list/combobox-listbox.svelte +76 -0
  17. package/dist/combobox/list/combobox-listbox.svelte.d.ts +47 -0
  18. package/dist/combobox/popover/combobox-popover.svelte +69 -0
  19. package/dist/combobox/popover/combobox-popover.svelte.d.ts +12 -0
  20. package/dist/combobox/root/combobox-filtered-test.svelte +51 -0
  21. package/dist/combobox/root/combobox-filtered-test.svelte.d.ts +7 -0
  22. package/dist/combobox/root/combobox-multiselect-test.svelte +76 -0
  23. package/dist/combobox/root/combobox-multiselect-test.svelte.d.ts +13 -0
  24. package/dist/combobox/root/combobox-numeric-string-id-test.svelte +20 -0
  25. package/dist/combobox/root/combobox-numeric-string-id-test.svelte.d.ts +3 -0
  26. package/dist/combobox/root/combobox-test.svelte +43 -0
  27. package/dist/combobox/root/combobox-test.svelte.d.ts +9 -0
  28. package/dist/combobox/root/combobox.svelte +696 -0
  29. package/dist/combobox/root/combobox.svelte.d.ts +58 -0
  30. package/dist/combobox/root/context.d.ts +90 -0
  31. package/dist/combobox/root/context.js +15 -0
  32. package/dist/combobox/tag/combobox-tag.svelte +58 -0
  33. package/dist/combobox/tag/combobox-tag.svelte.d.ts +22 -0
  34. package/dist/combobox/tag/tag-context-provider.svelte +36 -0
  35. package/dist/combobox/tag/tag-context-provider.svelte.d.ts +14 -0
  36. package/dist/combobox/tag-remove/combobox-tag-remove.svelte +53 -0
  37. package/dist/combobox/tag-remove/combobox-tag-remove.svelte.d.ts +14 -0
  38. package/dist/combobox/tags/combobox-tags.svelte +50 -0
  39. package/dist/combobox/tags/combobox-tags.svelte.d.ts +20 -0
  40. package/dist/dialog/content/dialog-content.svelte +121 -0
  41. package/dist/dialog/content/dialog-content.svelte.d.ts +19 -0
  42. package/dist/dialog/index.d.ts +10 -0
  43. package/dist/dialog/index.js +15 -0
  44. package/dist/dialog/index.parts.d.ts +5 -0
  45. package/dist/dialog/index.parts.js +6 -0
  46. package/dist/dialog/overlay/dialog-overlay.svelte +39 -0
  47. package/dist/dialog/overlay/dialog-overlay.svelte.d.ts +12 -0
  48. package/dist/dialog/portal/dialog-portal.svelte +32 -0
  49. package/dist/dialog/portal/dialog-portal.svelte.d.ts +12 -0
  50. package/dist/dialog/root/context.d.ts +25 -0
  51. package/dist/dialog/root/context.js +8 -0
  52. package/dist/dialog/root/dialog-root.svelte +99 -0
  53. package/dist/dialog/root/dialog-root.svelte.d.ts +21 -0
  54. package/dist/dialog/root/dialog-stack.d.ts +32 -0
  55. package/dist/dialog/root/dialog-stack.js +55 -0
  56. package/dist/dialog/root/dialog-test.svelte +38 -0
  57. package/dist/dialog/root/dialog-test.svelte.d.ts +10 -0
  58. package/dist/dialog/root/dialog-with-combobox-test.svelte +61 -0
  59. package/dist/dialog/root/dialog-with-combobox-test.svelte.d.ts +7 -0
  60. package/dist/dialog/root/nested-dialog-test.svelte +63 -0
  61. package/dist/dialog/root/nested-dialog-test.svelte.d.ts +8 -0
  62. package/dist/dialog/root/types.d.ts +10 -0
  63. package/dist/dialog/root/types.js +1 -0
  64. package/dist/dialog/trigger/dialog-trigger.svelte +71 -0
  65. package/dist/dialog/trigger/dialog-trigger.svelte.d.ts +12 -0
  66. package/dist/hooks/use-virtual-focus.svelte.d.ts +55 -0
  67. package/dist/hooks/use-virtual-focus.svelte.js +201 -0
  68. package/dist/index.d.ts +13 -0
  69. package/dist/index.js +19 -0
  70. package/dist/input/index.d.ts +3 -0
  71. package/dist/input/index.js +3 -0
  72. package/dist/input/input.svelte +19 -0
  73. package/dist/input/input.svelte.d.ts +8 -0
  74. package/dist/label/index.d.ts +3 -0
  75. package/dist/label/index.js +3 -0
  76. package/dist/label/label.svelte +21 -0
  77. package/dist/label/label.svelte.d.ts +8 -0
  78. package/dist/listbox/index.d.ts +6 -0
  79. package/dist/listbox/index.js +10 -0
  80. package/dist/listbox/index.parts.d.ts +2 -0
  81. package/dist/listbox/index.parts.js +3 -0
  82. package/dist/listbox/item/listbox-item.svelte +186 -0
  83. package/dist/listbox/item/listbox-item.svelte.d.ts +34 -0
  84. package/dist/listbox/root/context.d.ts +73 -0
  85. package/dist/listbox/root/context.js +249 -0
  86. package/dist/listbox/root/listbox-numeric-id-test.svelte +18 -0
  87. package/dist/listbox/root/listbox-numeric-id-test.svelte.d.ts +3 -0
  88. package/dist/listbox/root/listbox-test.svelte +27 -0
  89. package/dist/listbox/root/listbox-test.svelte.d.ts +8 -0
  90. package/dist/listbox/root/listbox.svelte +146 -0
  91. package/dist/listbox/root/listbox.svelte.d.ts +54 -0
  92. package/dist/popover/content/popover-content-test.svelte +43 -0
  93. package/dist/popover/content/popover-content-test.svelte.d.ts +12 -0
  94. package/dist/popover/content/popover-content.svelte +167 -0
  95. package/dist/popover/content/popover-content.svelte.d.ts +38 -0
  96. package/dist/popover/index.d.ts +8 -0
  97. package/dist/popover/index.js +14 -0
  98. package/dist/popover/index.parts.d.ts +4 -0
  99. package/dist/popover/index.parts.js +5 -0
  100. package/dist/popover/root/context.d.ts +24 -0
  101. package/dist/popover/root/context.js +10 -0
  102. package/dist/popover/root/popover-root.svelte +87 -0
  103. package/dist/popover/root/popover-root.svelte.d.ts +20 -0
  104. package/dist/popover/root/popover-test.svelte +40 -0
  105. package/dist/popover/root/popover-test.svelte.d.ts +11 -0
  106. package/dist/popover/trigger/popover-trigger-button.svelte +42 -0
  107. package/dist/popover/trigger/popover-trigger-button.svelte.d.ts +12 -0
  108. package/dist/popover/trigger/popover-trigger-in-dialog-test.svelte +29 -0
  109. package/dist/popover/trigger/popover-trigger-in-dialog-test.svelte.d.ts +18 -0
  110. package/dist/popover/trigger/popover-trigger.svelte +71 -0
  111. package/dist/popover/trigger/popover-trigger.svelte.d.ts +12 -0
  112. package/dist/portal/index.d.ts +1 -0
  113. package/dist/portal/index.js +1 -0
  114. package/dist/portal/portal.svelte +44 -0
  115. package/dist/portal/portal.svelte.d.ts +10 -0
  116. package/dist/primitives/aria-hide-outside.d.ts +38 -0
  117. package/dist/primitives/aria-hide-outside.js +152 -0
  118. package/dist/primitives/click-outside.d.ts +26 -0
  119. package/dist/primitives/click-outside.js +66 -0
  120. package/dist/primitives/floating.d.ts +57 -0
  121. package/dist/primitives/floating.js +179 -0
  122. package/dist/primitives/focus-trap.d.ts +19 -0
  123. package/dist/primitives/focus-trap.js +102 -0
  124. package/dist/primitives/index.d.ts +6 -0
  125. package/dist/primitives/index.js +7 -0
  126. package/dist/primitives/keyboard-navigation.d.ts +88 -0
  127. package/dist/primitives/keyboard-navigation.js +274 -0
  128. package/dist/primitives/scroll-lock.d.ts +19 -0
  129. package/dist/primitives/scroll-lock.js +62 -0
  130. package/dist/test-mocks/app-environment.d.ts +7 -0
  131. package/dist/test-mocks/app-environment.js +7 -0
  132. package/dist/test-mocks/app-navigation.d.ts +11 -0
  133. package/dist/test-mocks/app-navigation.js +11 -0
  134. package/dist/test-mocks/app-stores.d.ts +16 -0
  135. package/dist/test-mocks/app-stores.js +18 -0
  136. package/dist/utils/cn.d.ts +2 -0
  137. package/dist/utils/cn.js +5 -0
  138. package/dist/utils/index.d.ts +1 -0
  139. package/dist/utils/index.js +1 -0
  140. package/package.json +99 -0
@@ -0,0 +1,76 @@
1
+ <script lang="ts" generics="T extends object = object">
2
+ import type { ComponentProps, Snippet } from 'svelte';
3
+ import { useComboBoxContext } from '../root/context';
4
+ import { ListBoxRoot as ListBox, type ListBoxContext } from '../../listbox';
5
+
6
+ /**
7
+ * ComboBox.ListBox - The list wrapper with selection management.
8
+ * Extends ListBox props, controlling selection internally.
9
+ * Supports both static children and dynamic items rendering.
10
+ */
11
+ type ComboBoxListBoxProps = Omit<
12
+ ComponentProps<typeof ListBox>,
13
+ // Props controlled internally by ComboBox
14
+ | 'selectionMode'
15
+ | 'selectionBehavior'
16
+ | 'value'
17
+ | 'defaultValue'
18
+ | 'onChange'
19
+ | 'context'
20
+ | 'element'
21
+ | 'children'
22
+ | 'items'
23
+ | 'id'
24
+ > & {
25
+ /** Optional items for dynamic rendering - overrides items from ComboBox context */
26
+ items?: Iterable<T>;
27
+ /** Content of the listbox. Receives item in dynamic mode. */
28
+ children?: Snippet<[T]> | Snippet;
29
+ };
30
+
31
+ let {
32
+ 'aria-label': ariaLabel = 'Options',
33
+ children,
34
+ items,
35
+ ...props
36
+ }: ComboBoxListBoxProps = $props();
37
+
38
+ const ctx = useComboBoxContext();
39
+ let listboxCtx: ListBoxContext | undefined = $state();
40
+ let listboxElement: HTMLElement | undefined = $state();
41
+
42
+ // Wire listbox context to combobox context when available
43
+ $effect(() => {
44
+ if (listboxCtx) {
45
+ ctx.setListboxCtx(listboxCtx);
46
+ }
47
+ });
48
+
49
+ // Wire listbox element ref to combobox context
50
+ $effect(() => {
51
+ if (listboxElement) {
52
+ ctx.setListboxRef(listboxElement);
53
+ }
54
+ });
55
+
56
+ function handleSelectionChange(selection: Set<string | number>) {
57
+ const selectedId = Array.from(selection)[0];
58
+ if (selectedId !== undefined) {
59
+ const label = ctx.itemLabels.get(selectedId) ?? String(selectedId);
60
+ ctx.select(selectedId, label);
61
+ }
62
+ }
63
+ </script>
64
+
65
+ <ListBox
66
+ {...props}
67
+ bind:context={listboxCtx}
68
+ bind:element={listboxElement}
69
+ id={`combobox-listbox-${ctx.instanceId}`}
70
+ items={items ?? (ctx.items as T[] | undefined)}
71
+ {children}
72
+ selectionMode={ctx.selectionMode}
73
+ value={ctx.selectedValue}
74
+ onChange={handleSelectionChange}
75
+ aria-label={ariaLabel}
76
+ />
@@ -0,0 +1,47 @@
1
+ import type { Snippet } from 'svelte';
2
+ import { type ListBoxContext } from '../../listbox';
3
+ declare function $$render<T extends object = object>(): {
4
+ props: Omit<{
5
+ selectionBehavior?: "toggle" | "replace";
6
+ emptyPlaceholder?: string | Snippet;
7
+ items?: Iterable<object> | undefined;
8
+ disabledIds?: Iterable<string | number>;
9
+ selectionMode?: "single" | "multiple";
10
+ value?: Iterable<string | number>;
11
+ defaultValue?: Iterable<string | number>;
12
+ children?: Snippet<[]> | Snippet<[object]> | undefined;
13
+ class?: string;
14
+ id?: string;
15
+ 'aria-label'?: string;
16
+ onChange?: ((value: Set<string | number>) => void) | undefined;
17
+ } & {
18
+ context?: ListBoxContext;
19
+ element?: HTMLElement;
20
+ }, "selectionMode" | "selectionBehavior" | "id" | "value" | "defaultValue" | "onChange" | "items" | "children" | "context" | "element"> & {
21
+ /** Optional items for dynamic rendering - overrides items from ComboBox context */
22
+ items?: Iterable<T>;
23
+ /** Content of the listbox. Receives item in dynamic mode. */
24
+ children?: Snippet<[T]> | Snippet;
25
+ };
26
+ exports: {};
27
+ bindings: "";
28
+ slots: {};
29
+ events: {};
30
+ };
31
+ declare class __sveltets_Render<T extends object = object> {
32
+ props(): ReturnType<typeof $$render<T>>['props'];
33
+ events(): ReturnType<typeof $$render<T>>['events'];
34
+ slots(): ReturnType<typeof $$render<T>>['slots'];
35
+ bindings(): "";
36
+ exports(): {};
37
+ }
38
+ interface $$IsomorphicComponent {
39
+ new <T extends object = object>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<T>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<T>['props']>, ReturnType<__sveltets_Render<T>['events']>, ReturnType<__sveltets_Render<T>['slots']>> & {
40
+ $$bindings?: ReturnType<__sveltets_Render<T>['bindings']>;
41
+ } & ReturnType<__sveltets_Render<T>['exports']>;
42
+ <T extends object = object>(internal: unknown, props: ReturnType<__sveltets_Render<T>['props']> & {}): ReturnType<__sveltets_Render<T>['exports']>;
43
+ z_$$bindings?: ReturnType<__sveltets_Render<any>['bindings']>;
44
+ }
45
+ declare const ComboboxListbox: $$IsomorphicComponent;
46
+ type ComboboxListbox<T extends object = object> = InstanceType<typeof ComboboxListbox<T>>;
47
+ export default ComboboxListbox;
@@ -0,0 +1,69 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte';
3
+ import { useComboBoxContext } from '../root/context';
4
+ import { Popover } from '../../popover';
5
+
6
+ /**
7
+ * ComboBox.Popover - Just the floating container wrapper.
8
+ * Should contain ComboBox.ListBox as a child.
9
+ */
10
+ type ComboBoxPopoverProps = {
11
+ class?: string;
12
+ children?: Snippet;
13
+ };
14
+
15
+ let { class: className = '', children }: ComboBoxPopoverProps = $props();
16
+
17
+ const ctx = useComboBoxContext();
18
+
19
+ function handleOpenChange(open: boolean) {
20
+ ctx.onOpenChange(open);
21
+ }
22
+
23
+ /**
24
+ * Prevent wheel/scroll events from propagating to the page
25
+ * This keeps the page from scrolling when scrolling over the popover
26
+ * But allows internal scrolling when the popover has overflow
27
+ */
28
+ function handleWheel(event: WheelEvent) {
29
+ const element = event.currentTarget as HTMLElement;
30
+ if (!element) return;
31
+
32
+ const { scrollTop, scrollHeight, clientHeight } = element;
33
+ const isScrollingDown = event.deltaY > 0;
34
+ const isScrollingUp = event.deltaY < 0;
35
+
36
+ // Check if we can scroll in the direction of the wheel
37
+ const canScrollDown = scrollTop < scrollHeight - clientHeight;
38
+ const canScrollUp = scrollTop > 0;
39
+
40
+ // If we can scroll internally in this direction, allow it
41
+ if ((isScrollingDown && canScrollDown) || (isScrollingUp && canScrollUp)) {
42
+ // Allow internal scroll, but stop propagation to page
43
+ event.stopPropagation();
44
+ } else {
45
+ // Can't scroll internally, prevent both default and propagation
46
+ event.preventDefault();
47
+ event.stopPropagation();
48
+ }
49
+ }
50
+
51
+ $effect(() => {
52
+ if (ctx.isOpen) {
53
+ ctx.inputRef?.focus();
54
+ }
55
+ });
56
+ </script>
57
+
58
+ <Popover.Root open={ctx.isOpen} triggerRef={ctx.triggerRef} onOpenChange={handleOpenChange}>
59
+ <Popover.Content
60
+ isNonModal={true}
61
+ placement="bottom-start"
62
+ class={className}
63
+ onwheel={handleWheel}
64
+ >
65
+ {#if children}
66
+ {@render children()}
67
+ {/if}
68
+ </Popover.Content>
69
+ </Popover.Root>
@@ -0,0 +1,12 @@
1
+ import type { Snippet } from 'svelte';
2
+ /**
3
+ * ComboBox.Popover - Just the floating container wrapper.
4
+ * Should contain ComboBox.ListBox as a child.
5
+ */
6
+ type ComboBoxPopoverProps = {
7
+ class?: string;
8
+ children?: Snippet;
9
+ };
10
+ declare const ComboboxPopover: import("svelte").Component<ComboBoxPopoverProps, {}, "">;
11
+ type ComboboxPopover = ReturnType<typeof ComboboxPopover>;
12
+ export default ComboboxPopover;
@@ -0,0 +1,51 @@
1
+ <script lang="ts">
2
+ import ComboBox from '../index';
3
+
4
+ type Props = {
5
+ onInputChange?: (value: string) => void;
6
+ trigger?: 'focus' | 'input' | 'press';
7
+ };
8
+
9
+ let { onInputChange, trigger = 'focus' }: Props = $props();
10
+
11
+ const countries = [
12
+ { id: 'ar', name: 'Argentina' },
13
+ { id: 'br', name: 'Brazil' },
14
+ { id: 'ca', name: 'Canada' },
15
+ { id: 'fr', name: 'France' },
16
+ { id: 'de', name: 'Germany' },
17
+ { id: 'it', name: 'Italy' },
18
+ { id: 'jp', name: 'Japan' },
19
+ { id: 'mx', name: 'Mexico' },
20
+ { id: 'es', name: 'Spain' },
21
+ { id: 'us', name: 'United States' }
22
+ ];
23
+
24
+ let filterValue = $state('');
25
+ let selectedValue = $state<string | number | undefined>();
26
+
27
+ const filteredCountries = $derived(
28
+ filterValue === ''
29
+ ? countries
30
+ : countries.filter((c) => c.name.toLowerCase().includes(filterValue.toLowerCase()))
31
+ );
32
+
33
+ function handleInputChange(val: string) {
34
+ filterValue = val;
35
+ onInputChange?.(val);
36
+ }
37
+ </script>
38
+
39
+ <ComboBox.Root bind:value={selectedValue} {trigger} onInputChange={handleInputChange}>
40
+ <ComboBox.Input placeholder="Search countries..." />
41
+
42
+ <ComboBox.Popover>
43
+ <ComboBox.List emptyPlaceholder="No countries found">
44
+ {#each filteredCountries as country (country.id)}
45
+ <ComboBox.Item id={country.id} textValue={country.name}>
46
+ {country.name}
47
+ </ComboBox.Item>
48
+ {/each}
49
+ </ComboBox.List>
50
+ </ComboBox.Popover>
51
+ </ComboBox.Root>
@@ -0,0 +1,7 @@
1
+ type Props = {
2
+ onInputChange?: (value: string) => void;
3
+ trigger?: 'focus' | 'input' | 'press';
4
+ };
5
+ declare const ComboboxFilteredTest: import("svelte").Component<Props, {}, "">;
6
+ type ComboboxFilteredTest = ReturnType<typeof ComboboxFilteredTest>;
7
+ export default ComboboxFilteredTest;
@@ -0,0 +1,76 @@
1
+ <script lang="ts">
2
+ import ComboBox from '../index.js';
3
+
4
+ interface Props {
5
+ items?: { id: string; name: string }[];
6
+ value?: (string | number)[];
7
+ onValueChange?: (value: (string | number)[]) => void;
8
+ trigger?: 'focus' | 'input' | 'press';
9
+ closeOnSelect?: boolean;
10
+ }
11
+
12
+ let {
13
+ items = [
14
+ { id: 'apple', name: 'Apple' },
15
+ { id: 'banana', name: 'Banana' },
16
+ { id: 'cherry', name: 'Cherry' },
17
+ { id: 'date', name: 'Date' },
18
+ { id: 'elderberry', name: 'Elderberry' }
19
+ ],
20
+ value = $bindable([]),
21
+ onValueChange,
22
+ trigger = 'press',
23
+ closeOnSelect = false
24
+ }: Props = $props();
25
+
26
+ function handleChange(newValue: string | number | (string | number)[] | undefined) {
27
+ if (Array.isArray(newValue)) {
28
+ onValueChange?.(newValue);
29
+ }
30
+ }
31
+ </script>
32
+
33
+ <ComboBox.Root
34
+ bind:value
35
+ selectionMode="multiple"
36
+ {trigger}
37
+ {closeOnSelect}
38
+ onChange={handleChange}
39
+ >
40
+ <div class="combobox-container">
41
+ <ComboBox.Tags>
42
+ {#snippet children({ item })}
43
+ <ComboBox.Tag>
44
+ {item.label}
45
+ <ComboBox.TagRemove />
46
+ </ComboBox.Tag>
47
+ {/snippet}
48
+ </ComboBox.Tags>
49
+ <ComboBox.Input placeholder="Search fruits..." />
50
+ <ComboBox.Button>▼</ComboBox.Button>
51
+ </div>
52
+
53
+ <ComboBox.Popover>
54
+ <ComboBox.List>
55
+ {#each items as item (item.id)}
56
+ <ComboBox.Item id={item.id} textValue={item.name}>
57
+ {item.name}
58
+ <ComboBox.ItemIndicator />
59
+ </ComboBox.Item>
60
+ {/each}
61
+ </ComboBox.List>
62
+ </ComboBox.Popover>
63
+ </ComboBox.Root>
64
+
65
+ <style>
66
+ .combobox-container {
67
+ display: flex;
68
+ flex-wrap: wrap;
69
+ align-items: center;
70
+ gap: 4px;
71
+ border: 1px solid #ccc;
72
+ border-radius: 4px;
73
+ padding: 4px;
74
+ min-height: 38px;
75
+ }
76
+ </style>
@@ -0,0 +1,13 @@
1
+ interface Props {
2
+ items?: {
3
+ id: string;
4
+ name: string;
5
+ }[];
6
+ value?: (string | number)[];
7
+ onValueChange?: (value: (string | number)[]) => void;
8
+ trigger?: 'focus' | 'input' | 'press';
9
+ closeOnSelect?: boolean;
10
+ }
11
+ declare const ComboboxMultiselectTest: import("svelte").Component<Props, {}, "value">;
12
+ type ComboboxMultiselectTest = ReturnType<typeof ComboboxMultiselectTest>;
13
+ export default ComboboxMultiselectTest;
@@ -0,0 +1,20 @@
1
+ <script lang="ts">
2
+ import { ComboBox } from '../index';
3
+
4
+ let selected = $state<string | number | undefined>();
5
+ </script>
6
+
7
+ <ComboBox.Root bind:value={selected}>
8
+ <ComboBox.Input placeholder="Search codes..." />
9
+ <ComboBox.Button />
10
+
11
+ <ComboBox.Popover>
12
+ <ComboBox.List emptyPlaceholder="No codes found">
13
+ <ComboBox.Item id="01" textValue="Code 01">Code 01</ComboBox.Item>
14
+ <ComboBox.Item id="02" textValue="Code 02">Code 02</ComboBox.Item>
15
+ </ComboBox.List>
16
+ </ComboBox.Popover>
17
+ </ComboBox.Root>
18
+
19
+ <div data-testid="selected">{selected === undefined ? '' : String(selected)}</div>
20
+ <div data-testid="selected-type">{selected === undefined ? '' : typeof selected}</div>
@@ -0,0 +1,3 @@
1
+ declare const ComboboxNumericStringIdTest: import("svelte").Component<Record<string, never>, {}, "">;
2
+ type ComboboxNumericStringIdTest = ReturnType<typeof ComboboxNumericStringIdTest>;
3
+ export default ComboboxNumericStringIdTest;
@@ -0,0 +1,43 @@
1
+ <script lang="ts">
2
+ import ComboBox from '../index';
3
+
4
+ type Props = {
5
+ id?: string;
6
+ isDisabled?: boolean;
7
+ isReadOnly?: boolean;
8
+ trigger?: 'focus' | 'input' | 'press';
9
+ };
10
+
11
+ let { id, isDisabled = false, isReadOnly = false, trigger = 'press' }: Props = $props();
12
+
13
+ const countries = [
14
+ { id: 'ar', name: 'Argentina' },
15
+ { id: 'br', name: 'Brazil' },
16
+ { id: 'ca', name: 'Canada' },
17
+ { id: 'fr', name: 'France' },
18
+ { id: 'de', name: 'Germany' },
19
+ { id: 'it', name: 'Italy' },
20
+ { id: 'jp', name: 'Japan' },
21
+ { id: 'mx', name: 'Mexico' },
22
+ { id: 'es', name: 'Spain' },
23
+ { id: 'us', name: 'United States' }
24
+ ];
25
+ </script>
26
+
27
+ <ComboBox.Root {id} {isDisabled} {isReadOnly} {trigger}>
28
+ <ComboBox.Input placeholder="Search countries..." />
29
+ <ComboBox.Button />
30
+
31
+ <ComboBox.Popover>
32
+ <ComboBox.List emptyPlaceholder="No countries found">
33
+ {#each countries as country (country.id)}
34
+ <ComboBox.Item id={country.id} textValue={country.name}>
35
+ {country.name}
36
+ </ComboBox.Item>
37
+ {/each}
38
+ </ComboBox.List>
39
+ </ComboBox.Popover>
40
+ </ComboBox.Root>
41
+
42
+ <!-- Button outside the combobox for testing blur behavior -->
43
+ <button type="button" data-testid="outside-button">Outside</button>
@@ -0,0 +1,9 @@
1
+ type Props = {
2
+ id?: string;
3
+ isDisabled?: boolean;
4
+ isReadOnly?: boolean;
5
+ trigger?: 'focus' | 'input' | 'press';
6
+ };
7
+ declare const ComboboxTest: import("svelte").Component<Props, {}, "">;
8
+ type ComboboxTest = ReturnType<typeof ComboboxTest>;
9
+ export default ComboboxTest;