@nuykon/basecoat-svelte 0.0.0-stage → 1.0.2

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 (205) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/dist/Accordion.svelte +59 -0
  3. package/dist/Accordion.svelte.d.ts +13 -0
  4. package/dist/AccordionRoot.svelte +20 -0
  5. package/dist/AccordionRoot.svelte.d.ts +8 -0
  6. package/dist/Alert.svelte +33 -0
  7. package/dist/Alert.svelte.d.ts +13 -0
  8. package/dist/AlertDescription.svelte +33 -0
  9. package/dist/AlertDescription.svelte.d.ts +13 -0
  10. package/dist/AlertDialog.svelte +7 -0
  11. package/dist/AlertDialog.svelte.d.ts +17 -0
  12. package/dist/AlertDialogRoot.svelte +20 -0
  13. package/dist/AlertDialogRoot.svelte.d.ts +8 -0
  14. package/dist/AlertTitle.svelte +33 -0
  15. package/dist/AlertTitle.svelte.d.ts +13 -0
  16. package/dist/Avatar.svelte +33 -0
  17. package/dist/Avatar.svelte.d.ts +13 -0
  18. package/dist/AvatarFallback.svelte +33 -0
  19. package/dist/AvatarFallback.svelte.d.ts +13 -0
  20. package/dist/AvatarImage.svelte +31 -0
  21. package/dist/AvatarImage.svelte.d.ts +13 -0
  22. package/dist/Badge.svelte +33 -0
  23. package/dist/Badge.svelte.d.ts +13 -0
  24. package/dist/Breadcrumb.svelte +33 -0
  25. package/dist/Breadcrumb.svelte.d.ts +13 -0
  26. package/dist/BreadcrumbItem.svelte +33 -0
  27. package/dist/BreadcrumbItem.svelte.d.ts +13 -0
  28. package/dist/BreadcrumbLink.svelte +33 -0
  29. package/dist/BreadcrumbLink.svelte.d.ts +13 -0
  30. package/dist/BreadcrumbList.svelte +33 -0
  31. package/dist/BreadcrumbList.svelte.d.ts +13 -0
  32. package/dist/BreadcrumbSeparator.svelte +33 -0
  33. package/dist/BreadcrumbSeparator.svelte.d.ts +13 -0
  34. package/dist/Button.svelte +33 -0
  35. package/dist/Button.svelte.d.ts +13 -0
  36. package/dist/ButtonGroup.svelte +33 -0
  37. package/dist/ButtonGroup.svelte.d.ts +13 -0
  38. package/dist/Card.svelte +33 -0
  39. package/dist/Card.svelte.d.ts +13 -0
  40. package/dist/CardAction.svelte +33 -0
  41. package/dist/CardAction.svelte.d.ts +13 -0
  42. package/dist/CardContent.svelte +33 -0
  43. package/dist/CardContent.svelte.d.ts +13 -0
  44. package/dist/CardDescription.svelte +33 -0
  45. package/dist/CardDescription.svelte.d.ts +13 -0
  46. package/dist/CardFooter.svelte +33 -0
  47. package/dist/CardFooter.svelte.d.ts +13 -0
  48. package/dist/CardHeader.svelte +33 -0
  49. package/dist/CardHeader.svelte.d.ts +13 -0
  50. package/dist/CardTitle.svelte +33 -0
  51. package/dist/CardTitle.svelte.d.ts +13 -0
  52. package/dist/Chart.svelte +39 -0
  53. package/dist/Chart.svelte.d.ts +9 -0
  54. package/dist/ChartRoot.svelte +9 -0
  55. package/dist/ChartRoot.svelte.d.ts +4 -0
  56. package/dist/Checkbox.svelte +43 -0
  57. package/dist/Checkbox.svelte.d.ts +10 -0
  58. package/dist/Collapsible.svelte +36 -0
  59. package/dist/Collapsible.svelte.d.ts +11 -0
  60. package/dist/Combobox.svelte +7 -0
  61. package/dist/Combobox.svelte.d.ts +17 -0
  62. package/dist/ComboboxRoot.svelte +20 -0
  63. package/dist/ComboboxRoot.svelte.d.ts +8 -0
  64. package/dist/Command.svelte +79 -0
  65. package/dist/Command.svelte.d.ts +11 -0
  66. package/dist/CommandRoot.svelte +20 -0
  67. package/dist/CommandRoot.svelte.d.ts +8 -0
  68. package/dist/Dialog.svelte +104 -0
  69. package/dist/Dialog.svelte.d.ts +20 -0
  70. package/dist/DialogContent.svelte +33 -0
  71. package/dist/DialogContent.svelte.d.ts +13 -0
  72. package/dist/DialogDescription.svelte +33 -0
  73. package/dist/DialogDescription.svelte.d.ts +13 -0
  74. package/dist/DialogFooter.svelte +33 -0
  75. package/dist/DialogFooter.svelte.d.ts +13 -0
  76. package/dist/DialogHeader.svelte +33 -0
  77. package/dist/DialogHeader.svelte.d.ts +13 -0
  78. package/dist/DialogRoot.svelte +20 -0
  79. package/dist/DialogRoot.svelte.d.ts +8 -0
  80. package/dist/DialogTitle.svelte +33 -0
  81. package/dist/DialogTitle.svelte.d.ts +13 -0
  82. package/dist/Drawer.svelte +7 -0
  83. package/dist/Drawer.svelte.d.ts +17 -0
  84. package/dist/DrawerRoot.svelte +20 -0
  85. package/dist/DrawerRoot.svelte.d.ts +8 -0
  86. package/dist/DropdownMenu.svelte +133 -0
  87. package/dist/DropdownMenu.svelte.d.ts +15 -0
  88. package/dist/DropdownMenuRoot.svelte +20 -0
  89. package/dist/DropdownMenuRoot.svelte.d.ts +8 -0
  90. package/dist/Empty.svelte +33 -0
  91. package/dist/Empty.svelte.d.ts +13 -0
  92. package/dist/EmptyContent.svelte +33 -0
  93. package/dist/EmptyContent.svelte.d.ts +13 -0
  94. package/dist/EmptyDescription.svelte +33 -0
  95. package/dist/EmptyDescription.svelte.d.ts +13 -0
  96. package/dist/EmptyHeader.svelte +33 -0
  97. package/dist/EmptyHeader.svelte.d.ts +13 -0
  98. package/dist/EmptyTitle.svelte +33 -0
  99. package/dist/EmptyTitle.svelte.d.ts +13 -0
  100. package/dist/Field.svelte +33 -0
  101. package/dist/Field.svelte.d.ts +13 -0
  102. package/dist/FieldDescription.svelte +33 -0
  103. package/dist/FieldDescription.svelte.d.ts +13 -0
  104. package/dist/FieldError.svelte +33 -0
  105. package/dist/FieldError.svelte.d.ts +13 -0
  106. package/dist/FieldLabel.svelte +33 -0
  107. package/dist/FieldLabel.svelte.d.ts +13 -0
  108. package/dist/Input.svelte +31 -0
  109. package/dist/Input.svelte.d.ts +13 -0
  110. package/dist/InputGroup.svelte +33 -0
  111. package/dist/InputGroup.svelte.d.ts +13 -0
  112. package/dist/InputGroupAddon.svelte +33 -0
  113. package/dist/InputGroupAddon.svelte.d.ts +13 -0
  114. package/dist/Item.svelte +33 -0
  115. package/dist/Item.svelte.d.ts +13 -0
  116. package/dist/ItemActions.svelte +33 -0
  117. package/dist/ItemActions.svelte.d.ts +13 -0
  118. package/dist/ItemContent.svelte +33 -0
  119. package/dist/ItemContent.svelte.d.ts +13 -0
  120. package/dist/ItemDescription.svelte +33 -0
  121. package/dist/ItemDescription.svelte.d.ts +13 -0
  122. package/dist/ItemTitle.svelte +33 -0
  123. package/dist/ItemTitle.svelte.d.ts +13 -0
  124. package/dist/Kbd.svelte +33 -0
  125. package/dist/Kbd.svelte.d.ts +13 -0
  126. package/dist/Label.svelte +33 -0
  127. package/dist/Label.svelte.d.ts +13 -0
  128. package/dist/NativeSelect.svelte +33 -0
  129. package/dist/NativeSelect.svelte.d.ts +13 -0
  130. package/dist/Pagination.svelte +37 -0
  131. package/dist/Pagination.svelte.d.ts +9 -0
  132. package/dist/Popover.svelte +80 -0
  133. package/dist/Popover.svelte.d.ts +15 -0
  134. package/dist/PopoverRoot.svelte +20 -0
  135. package/dist/PopoverRoot.svelte.d.ts +8 -0
  136. package/dist/Progress.svelte +20 -0
  137. package/dist/Progress.svelte.d.ts +8 -0
  138. package/dist/RadioGroup.svelte +49 -0
  139. package/dist/RadioGroup.svelte.d.ts +14 -0
  140. package/dist/ScrollArea.svelte +33 -0
  141. package/dist/ScrollArea.svelte.d.ts +13 -0
  142. package/dist/Select.svelte +236 -0
  143. package/dist/Select.svelte.d.ts +20 -0
  144. package/dist/SelectRoot.svelte +20 -0
  145. package/dist/SelectRoot.svelte.d.ts +8 -0
  146. package/dist/Separator.svelte +31 -0
  147. package/dist/Separator.svelte.d.ts +13 -0
  148. package/dist/Sidebar.svelte +35 -0
  149. package/dist/Sidebar.svelte.d.ts +11 -0
  150. package/dist/SidebarContent.svelte +33 -0
  151. package/dist/SidebarContent.svelte.d.ts +13 -0
  152. package/dist/SidebarFooter.svelte +33 -0
  153. package/dist/SidebarFooter.svelte.d.ts +13 -0
  154. package/dist/SidebarGroup.svelte +33 -0
  155. package/dist/SidebarGroup.svelte.d.ts +13 -0
  156. package/dist/SidebarHeader.svelte +33 -0
  157. package/dist/SidebarHeader.svelte.d.ts +13 -0
  158. package/dist/SidebarItem.svelte +33 -0
  159. package/dist/SidebarItem.svelte.d.ts +13 -0
  160. package/dist/SidebarRoot.svelte +20 -0
  161. package/dist/SidebarRoot.svelte.d.ts +8 -0
  162. package/dist/Skeleton.svelte +33 -0
  163. package/dist/Skeleton.svelte.d.ts +13 -0
  164. package/dist/Slider.svelte +47 -0
  165. package/dist/Slider.svelte.d.ts +12 -0
  166. package/dist/Spinner.svelte +33 -0
  167. package/dist/Spinner.svelte.d.ts +13 -0
  168. package/dist/Switch.svelte +7 -0
  169. package/dist/Switch.svelte.d.ts +8 -0
  170. package/dist/Table.svelte +33 -0
  171. package/dist/Table.svelte.d.ts +13 -0
  172. package/dist/TableBody.svelte +33 -0
  173. package/dist/TableBody.svelte.d.ts +13 -0
  174. package/dist/TableCaption.svelte +33 -0
  175. package/dist/TableCaption.svelte.d.ts +13 -0
  176. package/dist/TableCell.svelte +33 -0
  177. package/dist/TableCell.svelte.d.ts +13 -0
  178. package/dist/TableFooter.svelte +33 -0
  179. package/dist/TableFooter.svelte.d.ts +13 -0
  180. package/dist/TableHead.svelte +33 -0
  181. package/dist/TableHead.svelte.d.ts +13 -0
  182. package/dist/TableHeader.svelte +33 -0
  183. package/dist/TableHeader.svelte.d.ts +13 -0
  184. package/dist/TableRow.svelte +33 -0
  185. package/dist/TableRow.svelte.d.ts +13 -0
  186. package/dist/Tabs.svelte +79 -0
  187. package/dist/Tabs.svelte.d.ts +17 -0
  188. package/dist/TabsRoot.svelte +20 -0
  189. package/dist/TabsRoot.svelte.d.ts +8 -0
  190. package/dist/Textarea.svelte +33 -0
  191. package/dist/Textarea.svelte.d.ts +13 -0
  192. package/dist/ThemeSwitcher.svelte +31 -0
  193. package/dist/ThemeSwitcher.svelte.d.ts +9 -0
  194. package/dist/Toast.svelte +52 -0
  195. package/dist/Toast.svelte.d.ts +8 -0
  196. package/dist/Toaster.svelte +23 -0
  197. package/dist/Toaster.svelte.d.ts +9 -0
  198. package/dist/Tooltip.svelte +54 -0
  199. package/dist/Tooltip.svelte.d.ts +11 -0
  200. package/dist/core.d.ts +145 -0
  201. package/dist/core.js +832 -0
  202. package/dist/index.d.ts +99 -0
  203. package/dist/index.js +98 -0
  204. package/package.json +46 -4
  205. package/README.md +0 -3
@@ -0,0 +1,20 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte';
3
+ import type { SvelteHTMLElements } from 'svelte/elements';
4
+ import { attachWidget, cx } from './core.js';
5
+ let {
6
+ children,
7
+ class: className,
8
+ ...rest
9
+ }: SvelteHTMLElements['div'] & { children?: Snippet } = $props();
10
+ let element: HTMLElement;
11
+ $effect(() => attachWidget(element));
12
+ </script>
13
+
14
+ <div
15
+ {...rest}
16
+ bind:this={element}
17
+ class={cx('popover', typeof className === 'string' ? className : undefined)}
18
+ >
19
+ {@render children?.()}
20
+ </div>
@@ -0,0 +1,8 @@
1
+ import type { Snippet } from 'svelte';
2
+ import type { SvelteHTMLElements } from 'svelte/elements';
3
+ type $$ComponentProps = SvelteHTMLElements['div'] & {
4
+ children?: Snippet;
5
+ };
6
+ declare const PopoverRoot: import("svelte").Component<$$ComponentProps, {}, "">;
7
+ type PopoverRoot = ReturnType<typeof PopoverRoot>;
8
+ export default PopoverRoot;
@@ -0,0 +1,20 @@
1
+ <script lang="ts">
2
+ import { percentage } from './core.js';
3
+ let {
4
+ value,
5
+ max = 100,
6
+ label = 'Progress',
7
+ }: { value?: number; max?: number; label?: string } = $props();
8
+ </script>
9
+
10
+ <div
11
+ class="progress"
12
+ role="progressbar"
13
+ aria-label={label}
14
+ aria-valuemin={0}
15
+ aria-valuemax={max}
16
+ aria-valuenow={value}
17
+ aria-busy={value === undefined}
18
+ >
19
+ <span style:width={`${value === undefined ? 100 : percentage(value, 0, max)}%`}></span>
20
+ </div>
@@ -0,0 +1,8 @@
1
+ type $$ComponentProps = {
2
+ value?: number;
3
+ max?: number;
4
+ label?: string;
5
+ };
6
+ declare const Progress: import("svelte").Component<$$ComponentProps, {}, "">;
7
+ type Progress = ReturnType<typeof Progress>;
8
+ export default Progress;
@@ -0,0 +1,49 @@
1
+ <script lang="ts">
2
+ import { formReset, type Option } from './core.js';
3
+ type Props = {
4
+ options: readonly Option[];
5
+ value?: string;
6
+ defaultValue?: string;
7
+ onValueChange?: (value: string) => void;
8
+ name?: string;
9
+ disabled?: boolean;
10
+ required?: boolean;
11
+ label?: string;
12
+ };
13
+ let {
14
+ options,
15
+ value = $bindable(undefined),
16
+ defaultValue = '',
17
+ onValueChange,
18
+ name,
19
+ disabled,
20
+ required,
21
+ label,
22
+ }: Props = $props();
23
+ const id = $props.id();
24
+ let internal = $state((() => defaultValue)()),
25
+ element: HTMLDivElement;
26
+ let current = $derived(value === undefined ? internal : value);
27
+ function set(next: string) {
28
+ if (value === undefined) internal = next;
29
+ else if (!onValueChange) value = next;
30
+ onValueChange?.(next);
31
+ }
32
+ $effect(() => formReset(element, () => set(defaultValue)));
33
+ </script>
34
+
35
+ <div bind:this={element} role="radiogroup" aria-label={label} class="bc-radio-group">
36
+ {#each options as option (option.value)}<label
37
+ ><input
38
+ class="input"
39
+ type="radio"
40
+ name={name ?? id}
41
+ value={option.value}
42
+ checked={current === option.value}
43
+ disabled={disabled || option.disabled}
44
+ {required}
45
+ onchange={() => set(option.value)}
46
+ />
47
+ {option.label}</label
48
+ >{/each}
49
+ </div>
@@ -0,0 +1,14 @@
1
+ import { type Option } from './core.js';
2
+ type Props = {
3
+ options: readonly Option[];
4
+ value?: string;
5
+ defaultValue?: string;
6
+ onValueChange?: (value: string) => void;
7
+ name?: string;
8
+ disabled?: boolean;
9
+ required?: boolean;
10
+ label?: string;
11
+ };
12
+ declare const RadioGroup: import("svelte").Component<Props, {}, "value">;
13
+ type RadioGroup = ReturnType<typeof RadioGroup>;
14
+ export default RadioGroup;
@@ -0,0 +1,33 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte';
3
+ import type { SvelteHTMLElements } from 'svelte/elements';
4
+ import { cx, type Variant, type Size } from './core.js';
5
+ type Props = Omit<SvelteHTMLElements['div'], 'children' | 'size'> & {
6
+ children?: Snippet;
7
+ variant?: Variant;
8
+ size?: Size;
9
+ as?: keyof HTMLElementTagNameMap;
10
+ element?: HTMLElement | null;
11
+ };
12
+ let {
13
+ children,
14
+ variant,
15
+ size,
16
+ as = 'div',
17
+ element = $bindable(null),
18
+ class: className,
19
+ ...rest
20
+ }: Props = $props();
21
+ </script>
22
+
23
+ <svelte:element
24
+ this={as}
25
+ {...{ style: 'overflow:auto' }}
26
+ bind:this={element}
27
+ class={cx('scrollbar', typeof className === 'string' ? className : undefined)}
28
+ data-variant={variant}
29
+ data-size={size}
30
+ {...rest}
31
+ >
32
+ {@render children?.()}
33
+ </svelte:element>
@@ -0,0 +1,13 @@
1
+ import type { Snippet } from 'svelte';
2
+ import type { SvelteHTMLElements } from 'svelte/elements';
3
+ import { type Variant, type Size } from './core.js';
4
+ type Props = Omit<SvelteHTMLElements['div'], 'children' | 'size'> & {
5
+ children?: Snippet;
6
+ variant?: Variant;
7
+ size?: Size;
8
+ as?: keyof HTMLElementTagNameMap;
9
+ element?: HTMLElement | null;
10
+ };
11
+ declare const ScrollArea: import("svelte").Component<Props, {}, "element">;
12
+ type ScrollArea = ReturnType<typeof ScrollArea>;
13
+ export default ScrollArea;
@@ -0,0 +1,236 @@
1
+ <script lang="ts">
2
+ import { tick } from 'svelte';
3
+ import {
4
+ attachFloating,
5
+ createTypeahead,
6
+ dismissableLayer,
7
+ formReset,
8
+ scrollWithin,
9
+ nextIndex,
10
+ type Option,
11
+ } from './core.js';
12
+ type Selection = string | string[];
13
+ type Props = {
14
+ options: readonly Option[];
15
+ value?: Selection;
16
+ defaultValue?: Selection;
17
+ onValueChange?: (value: Selection) => void;
18
+ multiple?: boolean;
19
+ disabled?: boolean;
20
+ required?: boolean;
21
+ name?: string;
22
+ label: string;
23
+ placeholder?: string;
24
+ searchable?: boolean;
25
+ searchPlaceholder?: string;
26
+ emptyLabel?: string;
27
+ };
28
+ let {
29
+ options,
30
+ value = $bindable(undefined),
31
+ defaultValue,
32
+ onValueChange,
33
+ multiple = false,
34
+ disabled,
35
+ required,
36
+ name,
37
+ label,
38
+ placeholder = 'Select…',
39
+ searchable = false,
40
+ searchPlaceholder = 'Search…',
41
+ emptyLabel = 'No results',
42
+ }: Props = $props();
43
+ const id = $props.id(),
44
+ typeahead = createTypeahead();
45
+ let internal = $state((() => defaultValue ?? (multiple ? [] : ''))()),
46
+ current = $derived(value === undefined ? internal : value),
47
+ selected = $derived(Array.isArray(current) ? current : [current]);
48
+ let open = $state(false),
49
+ query = $state(''),
50
+ active = $state(-1),
51
+ visible = $derived(
52
+ options.filter(
53
+ (option) =>
54
+ !searchable || option.label.toLocaleLowerCase().includes(query.toLocaleLowerCase()),
55
+ ),
56
+ );
57
+ let anchor: HTMLButtonElement,
58
+ popup = $state<HTMLDivElement>(),
59
+ list = $state<HTMLDivElement>(),
60
+ search = $state<HTMLInputElement>(),
61
+ native: HTMLSelectElement;
62
+ function set(next: Selection) {
63
+ if (value === undefined) internal = next;
64
+ else if (!onValueChange) value = next;
65
+ onValueChange?.(next);
66
+ }
67
+ function close(restore: boolean) {
68
+ open = false;
69
+ query = '';
70
+ if (restore) anchor.focus();
71
+ }
72
+ function choose(index: number) {
73
+ const option = visible[index];
74
+ if (!option || option.disabled) return;
75
+ set(
76
+ multiple
77
+ ? selected.includes(option.value)
78
+ ? selected.filter((value) => value !== option.value)
79
+ : [...selected.filter(Boolean), option.value]
80
+ : option.value,
81
+ );
82
+ if (!multiple) close(true);
83
+ }
84
+ function keyboard(event: KeyboardEvent) {
85
+ if (['ArrowDown', 'ArrowUp', 'Home', 'End'].includes(event.key)) {
86
+ event.preventDefault();
87
+ active = nextIndex(visible, active, event.key);
88
+ } else if (event.key === 'Enter' || (!searchable && event.key === ' ')) {
89
+ event.preventDefault();
90
+ choose(active);
91
+ } else if (event.key === 'Tab') close(false);
92
+ else if (
93
+ !searchable &&
94
+ event.key.length === 1 &&
95
+ !event.ctrlKey &&
96
+ !event.metaKey &&
97
+ !event.altKey
98
+ ) {
99
+ event.preventDefault();
100
+ active = typeahead(event.key, visible, active);
101
+ }
102
+ }
103
+ $effect(() => {
104
+ if (disabled) close(false);
105
+ });
106
+ $effect(() => {
107
+ if (!open || !popup) return;
108
+ const content = popup,
109
+ position = attachFloating(anchor, content, { matchWidth: true }),
110
+ layer = dismissableLayer(anchor.ownerDocument, {
111
+ elements: () => [anchor, content],
112
+ dismiss: (reason) => close(reason === 'escape'),
113
+ });
114
+ return () => {
115
+ layer();
116
+ position();
117
+ };
118
+ });
119
+ $effect(() => {
120
+ if (open) {
121
+ query;
122
+ active = nextIndex(visible, -1, 'Home');
123
+ void tick().then(() => (searchable ? search : list)?.focus());
124
+ }
125
+ });
126
+ $effect(() => {
127
+ const item = list?.querySelector<HTMLElement>(`[data-index="${active}"]`);
128
+ if (list && item) scrollWithin(list, item);
129
+ });
130
+ $effect(() => formReset(native, () => set(defaultValue ?? (multiple ? [] : ''))));
131
+ </script>
132
+
133
+ <div class={searchable ? 'combobox' : 'select'}>
134
+ <button
135
+ bind:this={anchor}
136
+ type="button"
137
+ class="btn"
138
+ data-variant="outline"
139
+ {disabled}
140
+ role="combobox"
141
+ aria-label={label}
142
+ aria-haspopup="listbox"
143
+ aria-expanded={open}
144
+ aria-controls={`${id}-list`}
145
+ aria-required={required}
146
+ onclick={() => (open = !open)}
147
+ onkeydown={(event) => {
148
+ if (['ArrowDown', 'ArrowUp'].includes(event.key)) {
149
+ event.preventDefault();
150
+ open = true;
151
+ }
152
+ }}
153
+ ><span
154
+ >{options
155
+ .filter((option) => selected.includes(option.value))
156
+ .map((option) => option.label)
157
+ .join(', ') || placeholder}</span
158
+ ><span aria-hidden="true">⌄</span></button
159
+ >
160
+ {#if open}<div bind:this={popup} data-popover="" popover="manual" class="bc-floating">
161
+ {#if searchable}<input
162
+ bind:this={search}
163
+ class="input bc-search"
164
+ value={query}
165
+ role="combobox"
166
+ aria-label={searchPlaceholder}
167
+ aria-autocomplete="list"
168
+ aria-expanded="true"
169
+ aria-controls={`${id}-list`}
170
+ aria-activedescendant={active >= 0 ? `${id}-option-${active}` : undefined}
171
+ placeholder={searchPlaceholder}
172
+ oninput={(event) => (query = event.currentTarget.value)}
173
+ onkeydown={keyboard}
174
+ />{/if}
175
+ <div
176
+ bind:this={list}
177
+ id={`${id}-list`}
178
+ role="listbox"
179
+ tabindex="-1"
180
+ aria-label={label}
181
+ aria-multiselectable={multiple || undefined}
182
+ aria-activedescendant={active >= 0 ? `${id}-option-${active}` : undefined}
183
+ data-empty={emptyLabel}
184
+ onkeydown={searchable ? undefined : keyboard}
185
+ >
186
+ {#each visible as option, index (option.value)}
187
+ <!-- svelte-ignore a11y_click_events_have_key_events a11y_no_noninteractive_element_interactions -->
188
+ <div
189
+ id={`${id}-option-${index}`}
190
+ data-index={index}
191
+ data-value={option.value}
192
+ role="option"
193
+ tabindex="-1"
194
+ aria-selected={selected.includes(option.value)}
195
+ aria-disabled={option.disabled || undefined}
196
+ class:active={active === index}
197
+ onpointermove={(event) => {
198
+ if ((event.movementX || event.movementY) && !option.disabled) active = index;
199
+ }}
200
+ onpointerdown={(event) => event.preventDefault()}
201
+ onclick={() => choose(index)}
202
+ >
203
+ {option.label}
204
+ </div>
205
+ {/each}
206
+ </div>
207
+ </div>{/if}
208
+ <select
209
+ bind:this={native}
210
+ class="bc-form-control"
211
+ tabindex="-1"
212
+ aria-hidden="true"
213
+ {name}
214
+ {disabled}
215
+ {required}
216
+ {multiple}
217
+ value={current}
218
+ onchange={(event) =>
219
+ set(
220
+ multiple
221
+ ? [...event.currentTarget.selectedOptions].map((option) => option.value)
222
+ : event.currentTarget.value,
223
+ )}
224
+ oninvalid={(event) => {
225
+ event.preventDefault();
226
+ anchor.focus();
227
+ anchor.setAttribute('aria-invalid', 'true');
228
+ }}
229
+ >
230
+ {#if !multiple}<option value="">{placeholder}</option
231
+ >{/if}{#each options as option (option.value)}<option
232
+ value={option.value}
233
+ disabled={option.disabled}>{option.label}</option
234
+ >{/each}
235
+ </select>
236
+ </div>
@@ -0,0 +1,20 @@
1
+ import { type Option } from './core.js';
2
+ type Selection = string | string[];
3
+ type Props = {
4
+ options: readonly Option[];
5
+ value?: Selection;
6
+ defaultValue?: Selection;
7
+ onValueChange?: (value: Selection) => void;
8
+ multiple?: boolean;
9
+ disabled?: boolean;
10
+ required?: boolean;
11
+ name?: string;
12
+ label: string;
13
+ placeholder?: string;
14
+ searchable?: boolean;
15
+ searchPlaceholder?: string;
16
+ emptyLabel?: string;
17
+ };
18
+ declare const Select: import("svelte").Component<Props, {}, "value">;
19
+ type Select = ReturnType<typeof Select>;
20
+ export default Select;
@@ -0,0 +1,20 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte';
3
+ import type { SvelteHTMLElements } from 'svelte/elements';
4
+ import { attachWidget, cx } from './core.js';
5
+ let {
6
+ children,
7
+ class: className,
8
+ ...rest
9
+ }: SvelteHTMLElements['div'] & { children?: Snippet } = $props();
10
+ let element: HTMLElement;
11
+ $effect(() => attachWidget(element));
12
+ </script>
13
+
14
+ <div
15
+ {...rest}
16
+ bind:this={element}
17
+ class={cx('select', typeof className === 'string' ? className : undefined)}
18
+ >
19
+ {@render children?.()}
20
+ </div>
@@ -0,0 +1,8 @@
1
+ import type { Snippet } from 'svelte';
2
+ import type { SvelteHTMLElements } from 'svelte/elements';
3
+ type $$ComponentProps = SvelteHTMLElements['div'] & {
4
+ children?: Snippet;
5
+ };
6
+ declare const SelectRoot: import("svelte").Component<$$ComponentProps, {}, "">;
7
+ type SelectRoot = ReturnType<typeof SelectRoot>;
8
+ export default SelectRoot;
@@ -0,0 +1,31 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte';
3
+ import type { SvelteHTMLElements } from 'svelte/elements';
4
+ import { cx, type Variant, type Size } from './core.js';
5
+ type Props = Omit<SvelteHTMLElements['hr'], 'children' | 'size'> & {
6
+ children?: Snippet;
7
+ variant?: Variant;
8
+ size?: Size;
9
+ as?: keyof HTMLElementTagNameMap;
10
+ element?: HTMLElement | null;
11
+ };
12
+ let {
13
+ children,
14
+ variant,
15
+ size,
16
+ as = 'hr',
17
+ element = $bindable(null),
18
+ class: className,
19
+ ...rest
20
+ }: Props = $props();
21
+ </script>
22
+
23
+ <svelte:element
24
+ this={as}
25
+ {...{}}
26
+ bind:this={element}
27
+ class={cx('', typeof className === 'string' ? className : undefined)}
28
+ data-variant={variant}
29
+ data-size={size}
30
+ {...rest}
31
+ />
@@ -0,0 +1,13 @@
1
+ import type { Snippet } from 'svelte';
2
+ import type { SvelteHTMLElements } from 'svelte/elements';
3
+ import { type Variant, type Size } from './core.js';
4
+ type Props = Omit<SvelteHTMLElements['hr'], 'children' | 'size'> & {
5
+ children?: Snippet;
6
+ variant?: Variant;
7
+ size?: Size;
8
+ as?: keyof HTMLElementTagNameMap;
9
+ element?: HTMLElement | null;
10
+ };
11
+ declare const Separator: import("svelte").Component<Props, {}, "element">;
12
+ type Separator = ReturnType<typeof Separator>;
13
+ export default Separator;
@@ -0,0 +1,35 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte';
3
+ let {
4
+ collapsed = $bindable(undefined),
5
+ defaultCollapsed = false,
6
+ onCollapsedChange,
7
+ children,
8
+ label = 'Navigation',
9
+ }: {
10
+ collapsed?: boolean;
11
+ defaultCollapsed?: boolean;
12
+ onCollapsedChange?: (collapsed: boolean) => void;
13
+ children?: Snippet;
14
+ label?: string;
15
+ } = $props();
16
+ let internal = $state((() => defaultCollapsed)()),
17
+ current = $derived(collapsed === undefined ? internal : collapsed);
18
+ function set(next: boolean) {
19
+ if (collapsed === undefined) internal = next;
20
+ else if (!onCollapsedChange) collapsed = next;
21
+ onCollapsedChange?.(next);
22
+ }
23
+ </script>
24
+
25
+ <aside class="bc-sidebar" data-collapsed={current}>
26
+ <button
27
+ type="button"
28
+ class="btn"
29
+ data-variant="ghost"
30
+ aria-label={current ? 'Expand sidebar' : 'Collapse sidebar'}
31
+ aria-expanded={!current}
32
+ onclick={() => set(!current)}>☰</button
33
+ >
34
+ <nav aria-label={label}>{@render children?.()}</nav>
35
+ </aside>
@@ -0,0 +1,11 @@
1
+ import type { Snippet } from 'svelte';
2
+ type $$ComponentProps = {
3
+ collapsed?: boolean;
4
+ defaultCollapsed?: boolean;
5
+ onCollapsedChange?: (collapsed: boolean) => void;
6
+ children?: Snippet;
7
+ label?: string;
8
+ };
9
+ declare const Sidebar: import("svelte").Component<$$ComponentProps, {}, "collapsed">;
10
+ type Sidebar = ReturnType<typeof Sidebar>;
11
+ export default Sidebar;
@@ -0,0 +1,33 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte';
3
+ import type { SvelteHTMLElements } from 'svelte/elements';
4
+ import { cx, type Variant, type Size } from './core.js';
5
+ type Props = Omit<SvelteHTMLElements['section'], 'children' | 'size'> & {
6
+ children?: Snippet;
7
+ variant?: Variant;
8
+ size?: Size;
9
+ as?: keyof HTMLElementTagNameMap;
10
+ element?: HTMLElement | null;
11
+ };
12
+ let {
13
+ children,
14
+ variant,
15
+ size,
16
+ as = 'section',
17
+ element = $bindable(null),
18
+ class: className,
19
+ ...rest
20
+ }: Props = $props();
21
+ </script>
22
+
23
+ <svelte:element
24
+ this={as}
25
+ {...{}}
26
+ bind:this={element}
27
+ class={cx('', typeof className === 'string' ? className : undefined)}
28
+ data-variant={variant}
29
+ data-size={size}
30
+ {...rest}
31
+ >
32
+ {@render children?.()}
33
+ </svelte:element>
@@ -0,0 +1,13 @@
1
+ import type { Snippet } from 'svelte';
2
+ import type { SvelteHTMLElements } from 'svelte/elements';
3
+ import { type Variant, type Size } from './core.js';
4
+ type Props = Omit<SvelteHTMLElements['section'], 'children' | 'size'> & {
5
+ children?: Snippet;
6
+ variant?: Variant;
7
+ size?: Size;
8
+ as?: keyof HTMLElementTagNameMap;
9
+ element?: HTMLElement | null;
10
+ };
11
+ declare const SidebarContent: import("svelte").Component<Props, {}, "element">;
12
+ type SidebarContent = ReturnType<typeof SidebarContent>;
13
+ export default SidebarContent;
@@ -0,0 +1,33 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte';
3
+ import type { SvelteHTMLElements } from 'svelte/elements';
4
+ import { cx, type Variant, type Size } from './core.js';
5
+ type Props = Omit<SvelteHTMLElements['footer'], 'children' | 'size'> & {
6
+ children?: Snippet;
7
+ variant?: Variant;
8
+ size?: Size;
9
+ as?: keyof HTMLElementTagNameMap;
10
+ element?: HTMLElement | null;
11
+ };
12
+ let {
13
+ children,
14
+ variant,
15
+ size,
16
+ as = 'footer',
17
+ element = $bindable(null),
18
+ class: className,
19
+ ...rest
20
+ }: Props = $props();
21
+ </script>
22
+
23
+ <svelte:element
24
+ this={as}
25
+ {...{}}
26
+ bind:this={element}
27
+ class={cx('', typeof className === 'string' ? className : undefined)}
28
+ data-variant={variant}
29
+ data-size={size}
30
+ {...rest}
31
+ >
32
+ {@render children?.()}
33
+ </svelte:element>
@@ -0,0 +1,13 @@
1
+ import type { Snippet } from 'svelte';
2
+ import type { SvelteHTMLElements } from 'svelte/elements';
3
+ import { type Variant, type Size } from './core.js';
4
+ type Props = Omit<SvelteHTMLElements['footer'], 'children' | 'size'> & {
5
+ children?: Snippet;
6
+ variant?: Variant;
7
+ size?: Size;
8
+ as?: keyof HTMLElementTagNameMap;
9
+ element?: HTMLElement | null;
10
+ };
11
+ declare const SidebarFooter: import("svelte").Component<Props, {}, "element">;
12
+ type SidebarFooter = ReturnType<typeof SidebarFooter>;
13
+ export default SidebarFooter;