@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,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['thead'], '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 = 'thead',
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['thead'], 'children' | 'size'> & {
5
+ children?: Snippet;
6
+ variant?: Variant;
7
+ size?: Size;
8
+ as?: keyof HTMLElementTagNameMap;
9
+ element?: HTMLElement | null;
10
+ };
11
+ declare const TableHeader: import("svelte").Component<Props, {}, "element">;
12
+ type TableHeader = ReturnType<typeof TableHeader>;
13
+ export default TableHeader;
@@ -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['tr'], '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 = 'tr',
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['tr'], 'children' | 'size'> & {
5
+ children?: Snippet;
6
+ variant?: Variant;
7
+ size?: Size;
8
+ as?: keyof HTMLElementTagNameMap;
9
+ element?: HTMLElement | null;
10
+ };
11
+ declare const TableRow: import("svelte").Component<Props, {}, "element">;
12
+ type TableRow = ReturnType<typeof TableRow>;
13
+ export default TableRow;
@@ -0,0 +1,79 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte';
3
+ import { nextIndex, type Option } from './core.js';
4
+ type Props = {
5
+ items: readonly Option[];
6
+ value?: string;
7
+ defaultValue?: string;
8
+ onValueChange?: (value: string) => void;
9
+ orientation?: 'horizontal' | 'vertical';
10
+ activation?: 'automatic' | 'manual';
11
+ variant?: 'default' | 'line';
12
+ panel: Snippet<[Option]>;
13
+ keepMounted?: boolean;
14
+ label?: string;
15
+ };
16
+ let {
17
+ items,
18
+ value = $bindable(undefined),
19
+ defaultValue,
20
+ onValueChange,
21
+ orientation = 'horizontal',
22
+ activation = 'automatic',
23
+ variant,
24
+ panel,
25
+ keepMounted = false,
26
+ label = 'Tabs',
27
+ }: Props = $props();
28
+ const id = $props.id();
29
+ let internal = $state(
30
+ (() => defaultValue ?? items.find((item) => !item.disabled)?.value ?? '')(),
31
+ );
32
+ let current = $derived(value === undefined ? internal : value),
33
+ active = $derived(items.findIndex((item) => item.value === current && !item.disabled)),
34
+ selected = $derived(active >= 0 ? active : items.findIndex((item) => !item.disabled));
35
+ const elements: HTMLButtonElement[] = [];
36
+ function set(next: string) {
37
+ if (value === undefined) internal = next;
38
+ else if (!onValueChange) value = next;
39
+ onValueChange?.(next);
40
+ }
41
+ function keyboard(event: KeyboardEvent, index: number) {
42
+ const arrows =
43
+ orientation === 'vertical' ? ['ArrowUp', 'ArrowDown'] : ['ArrowLeft', 'ArrowRight'];
44
+ if (!arrows.includes(event.key) && !['Home', 'End'].includes(event.key)) return;
45
+ event.preventDefault();
46
+ let key = event.key;
47
+ if (orientation === 'horizontal' && (event.currentTarget as HTMLElement).closest('[dir="rtl"]'))
48
+ key = key === 'ArrowLeft' ? 'ArrowRight' : key === 'ArrowRight' ? 'ArrowLeft' : key;
49
+ const next = nextIndex(items, index, key);
50
+ elements[next]?.focus();
51
+ if (activation === 'automatic' && next >= 0) set(items[next].value);
52
+ }
53
+ </script>
54
+
55
+ <div class="tabs">
56
+ <div role="tablist" aria-label={label} aria-orientation={orientation} data-variant={variant}>
57
+ {#each items as item, index (item.value)}<button
58
+ bind:this={elements[index]}
59
+ type="button"
60
+ role="tab"
61
+ id={`${id}-tab-${index}`}
62
+ aria-controls={`${id}-panel-${index}`}
63
+ aria-selected={selected === index}
64
+ disabled={item.disabled}
65
+ tabindex={selected === index ? 0 : -1}
66
+ onclick={() => set(item.value)}
67
+ onkeydown={(event) => keyboard(event, index)}>{item.label}</button
68
+ >{/each}
69
+ </div>
70
+ {#each items as item, index (item.value)}<div
71
+ role="tabpanel"
72
+ id={`${id}-panel-${index}`}
73
+ aria-labelledby={`${id}-tab-${index}`}
74
+ tabindex="0"
75
+ hidden={selected !== index}
76
+ >
77
+ {#if keepMounted || selected === index}{@render panel(item)}{/if}
78
+ </div>{/each}
79
+ </div>
@@ -0,0 +1,17 @@
1
+ import type { Snippet } from 'svelte';
2
+ import { type Option } from './core.js';
3
+ type Props = {
4
+ items: readonly Option[];
5
+ value?: string;
6
+ defaultValue?: string;
7
+ onValueChange?: (value: string) => void;
8
+ orientation?: 'horizontal' | 'vertical';
9
+ activation?: 'automatic' | 'manual';
10
+ variant?: 'default' | 'line';
11
+ panel: Snippet<[Option]>;
12
+ keepMounted?: boolean;
13
+ label?: string;
14
+ };
15
+ declare const Tabs: import("svelte").Component<Props, {}, "value">;
16
+ type Tabs = ReturnType<typeof Tabs>;
17
+ export default Tabs;
@@ -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('tabs', 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 TabsRoot: import("svelte").Component<$$ComponentProps, {}, "">;
7
+ type TabsRoot = ReturnType<typeof TabsRoot>;
8
+ export default TabsRoot;
@@ -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['textarea'], '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 = 'textarea',
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('textarea', 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['textarea'], 'children' | 'size'> & {
5
+ children?: Snippet;
6
+ variant?: Variant;
7
+ size?: Size;
8
+ as?: keyof HTMLElementTagNameMap;
9
+ element?: HTMLElement | null;
10
+ };
11
+ declare const Textarea: import("svelte").Component<Props, {}, "element">;
12
+ type Textarea = ReturnType<typeof Textarea>;
13
+ export default Textarea;
@@ -0,0 +1,31 @@
1
+ <script lang="ts">
2
+ let {
3
+ value = $bindable(undefined),
4
+ defaultValue = 'light',
5
+ onValueChange,
6
+ label = 'Dark mode',
7
+ }: {
8
+ value?: 'light' | 'dark';
9
+ defaultValue?: 'light' | 'dark';
10
+ onValueChange?: (theme: 'light' | 'dark') => void;
11
+ label?: string;
12
+ } = $props();
13
+ let internal = $state((() => defaultValue)()),
14
+ current = $derived(value === undefined ? internal : value);
15
+ function set(next: 'light' | 'dark') {
16
+ if (value === undefined) internal = next;
17
+ else if (!onValueChange) value = next;
18
+ onValueChange?.(next);
19
+ }
20
+ </script>
21
+
22
+ <button
23
+ type="button"
24
+ class="btn"
25
+ data-variant="outline"
26
+ role="switch"
27
+ aria-label={label}
28
+ aria-checked={current === 'dark'}
29
+ onclick={() => set(current === 'dark' ? 'light' : 'dark')}
30
+ >{current === 'dark' ? '☾' : '☀'}</button
31
+ >
@@ -0,0 +1,9 @@
1
+ type $$ComponentProps = {
2
+ value?: 'light' | 'dark';
3
+ defaultValue?: 'light' | 'dark';
4
+ onValueChange?: (theme: 'light' | 'dark') => void;
5
+ label?: string;
6
+ };
7
+ declare const ThemeSwitcher: import("svelte").Component<$$ComponentProps, {}, "value">;
8
+ type ThemeSwitcher = ReturnType<typeof ThemeSwitcher>;
9
+ export default ThemeSwitcher;
@@ -0,0 +1,52 @@
1
+ <script lang="ts">
2
+ import { onMount } from 'svelte';
3
+ import type { ToastMessage } from './core.js';
4
+ let { message, onDismiss }: { message: ToastMessage; onDismiss: () => void } = $props();
5
+ let timer: ReturnType<typeof setTimeout> | undefined,
6
+ remaining = 5000,
7
+ started = 0;
8
+ function pause() {
9
+ clearTimeout(timer);
10
+ if (started) remaining = Math.max(0, remaining - (Date.now() - started));
11
+ started = 0;
12
+ }
13
+ function resume() {
14
+ if ((message.duration ?? 5000) <= 0 || started) return;
15
+ started = Date.now();
16
+ timer = setTimeout(onDismiss, remaining);
17
+ }
18
+ onMount(() => {
19
+ remaining = message.duration ?? 5000;
20
+ resume();
21
+ return pause;
22
+ });
23
+ </script>
24
+
25
+ <div
26
+ class="toast"
27
+ role="group"
28
+ data-variant={message.variant}
29
+ onpointerenter={pause}
30
+ onpointerleave={resume}
31
+ onfocusin={pause}
32
+ onfocusout={(event) => {
33
+ if (!event.currentTarget.contains(event.relatedTarget as Node)) resume();
34
+ }}
35
+ >
36
+ <div class="toast-content">
37
+ <section>
38
+ <h2>{message.title}</h2>
39
+ {#if message.description}<p>{message.description}</p>{/if}
40
+ </section>
41
+ <footer>
42
+ <button
43
+ type="button"
44
+ class="btn"
45
+ data-variant="ghost"
46
+ data-size="icon-sm"
47
+ aria-label="Dismiss notification"
48
+ onclick={onDismiss}>×</button
49
+ >
50
+ </footer>
51
+ </div>
52
+ </div>
@@ -0,0 +1,8 @@
1
+ import type { ToastMessage } from './core.js';
2
+ type $$ComponentProps = {
3
+ message: ToastMessage;
4
+ onDismiss: () => void;
5
+ };
6
+ declare const Toast: import("svelte").Component<$$ComponentProps, {}, "">;
7
+ type Toast = ReturnType<typeof Toast>;
8
+ export default Toast;
@@ -0,0 +1,23 @@
1
+ <script lang="ts">
2
+ import type { ToastMessage } from './core.js';
3
+ import Toast from './Toast.svelte';
4
+ let {
5
+ messages,
6
+ onDismiss,
7
+ label = 'Notifications',
8
+ }: {
9
+ messages: readonly ToastMessage[];
10
+ onDismiss: (id: string) => void;
11
+ label?: string;
12
+ } = $props();
13
+ </script>
14
+
15
+ <section class="toaster" aria-label={label}>
16
+ <div class="bc-live" role="status" aria-live="polite" aria-atomic="true">
17
+ {messages.at(-1)?.title}
18
+ </div>
19
+ {#each messages as message (message.id)}<Toast
20
+ {message}
21
+ onDismiss={() => onDismiss(message.id)}
22
+ />{/each}
23
+ </section>
@@ -0,0 +1,9 @@
1
+ import type { ToastMessage } from './core.js';
2
+ type $$ComponentProps = {
3
+ messages: readonly ToastMessage[];
4
+ onDismiss: (id: string) => void;
5
+ label?: string;
6
+ };
7
+ declare const Toaster: import("svelte").Component<$$ComponentProps, {}, "">;
8
+ type Toaster = ReturnType<typeof Toaster>;
9
+ export default Toaster;
@@ -0,0 +1,54 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte';
3
+ import { attachFloating, dismissableLayer, type Side } from './core.js';
4
+ let {
5
+ content,
6
+ children,
7
+ delay = 300,
8
+ side = 'top',
9
+ }: { content: string; children: Snippet; delay?: number; side?: Side } = $props();
10
+ const id = $props.id();
11
+ let open = $state(false),
12
+ anchor: HTMLSpanElement,
13
+ popup = $state<HTMLDivElement>();
14
+ let timer: ReturnType<typeof setTimeout>;
15
+ function close() {
16
+ clearTimeout(timer);
17
+ open = false;
18
+ }
19
+ $effect(() => {
20
+ if (!open || !popup) return;
21
+ const content = popup,
22
+ position = attachFloating(anchor, content, { side, align: 'center' }),
23
+ layer = dismissableLayer(anchor.ownerDocument, {
24
+ elements: () => [anchor, content],
25
+ dismiss: close,
26
+ });
27
+ return () => {
28
+ layer();
29
+ position();
30
+ };
31
+ });
32
+ $effect(() => () => clearTimeout(timer));
33
+ </script>
34
+
35
+ <!-- svelte-ignore a11y_no_noninteractive_tabindex -->
36
+ <span
37
+ bind:this={anchor}
38
+ role="group"
39
+ tabindex="0"
40
+ aria-describedby={open ? id : undefined}
41
+ onpointerenter={() => (timer = setTimeout(() => (open = true), delay))}
42
+ onpointerleave={close}
43
+ onfocusin={() => (open = true)}
44
+ onfocusout={close}
45
+ >{@render children()}{#if open}<div
46
+ bind:this={popup}
47
+ {id}
48
+ role="tooltip"
49
+ popover="manual"
50
+ class="bc-floating tooltip"
51
+ >
52
+ {content}
53
+ </div>{/if}</span
54
+ >
@@ -0,0 +1,11 @@
1
+ import type { Snippet } from 'svelte';
2
+ import { type Side } from './core.js';
3
+ type $$ComponentProps = {
4
+ content: string;
5
+ children: Snippet;
6
+ delay?: number;
7
+ side?: Side;
8
+ };
9
+ declare const Tooltip: import("svelte").Component<$$ComponentProps, {}, "">;
10
+ type Tooltip = ReturnType<typeof Tooltip>;
11
+ export default Tooltip;
package/dist/core.d.ts ADDED
@@ -0,0 +1,145 @@
1
+ /** Composition adapter for Basecoat's semantic markup. Frameworks own mount/unmount. */
2
+ declare function attachWidget(root: HTMLElement): () => void;
3
+
4
+ type Variant = 'default' | 'secondary' | 'outline' | 'ghost' | 'destructive' | 'link';
5
+ type Size = 'default' | 'xs' | 'sm' | 'lg' | 'icon' | 'icon-xs' | 'icon-sm' | 'icon-lg';
6
+ type Side = 'top' | 'bottom' | 'left' | 'right';
7
+ type Align = 'start' | 'center' | 'end';
8
+ type StylePack = 'vega' | 'nova' | 'maia' | 'lyra' | 'mira' | 'luma' | 'sera' | 'rhea';
9
+ interface Option {
10
+ value: string;
11
+ label: string;
12
+ disabled?: boolean;
13
+ group?: string;
14
+ }
15
+ interface TabItem extends Option {
16
+ }
17
+ interface AccordionItem extends Option {
18
+ }
19
+ interface MenuItem extends Option {
20
+ href?: string;
21
+ shortcut?: string;
22
+ separator?: boolean;
23
+ onSelect?: () => void;
24
+ }
25
+ interface ToastMessage {
26
+ id: string;
27
+ title: string;
28
+ description?: string;
29
+ variant?: 'default' | 'destructive';
30
+ duration?: number;
31
+ }
32
+ interface ChartPoint {
33
+ label: string;
34
+ value: number;
35
+ }
36
+ declare const stylePacks: readonly StylePack[];
37
+ declare function cx(...values: (string | undefined | false | null)[]): string;
38
+ declare function percentage(value: number, min?: number, max?: number): number;
39
+ declare function nextIndex(items: readonly {
40
+ disabled?: boolean;
41
+ }[], current: number, key: string, loop?: boolean): number;
42
+ declare function createTypeahead(): (key: string, items: readonly Option[], current: number) => number;
43
+ type Layer = {
44
+ elements: () => (HTMLElement | null)[];
45
+ dismiss: (reason: 'escape' | 'outside') => void;
46
+ };
47
+ declare function dismissableLayer(doc: Document, layer: Layer): () => void;
48
+ interface FloatingOptions {
49
+ side?: Side;
50
+ align?: Align;
51
+ offset?: number;
52
+ matchWidth?: boolean;
53
+ }
54
+ declare function floatingPosition(anchor: DOMRect, popup: DOMRect, width: number, height: number, options?: FloatingOptions): {
55
+ x: number;
56
+ y: number;
57
+ side: Side;
58
+ maxHeight: number;
59
+ };
60
+ declare function attachFloating(anchor: HTMLElement, popup: HTMLElement, options?: FloatingOptions): () => void;
61
+ declare function lockScroll(doc: Document): () => void;
62
+ declare function focusFirst(root: HTMLElement): void;
63
+ declare function scrollWithin(container: HTMLElement, item: HTMLElement): void;
64
+ declare function formReset(element: HTMLElement, reset: () => void): () => void;
65
+ declare const primitiveDefinitions: {
66
+ readonly ChartRoot: readonly ["canvas", "chart-canvas"];
67
+ readonly SelectRoot: readonly ["div", "select"];
68
+ readonly ComboboxRoot: readonly ["div", "combobox"];
69
+ readonly DropdownMenuRoot: readonly ["div", "dropdown-menu"];
70
+ readonly PopoverRoot: readonly ["div", "popover"];
71
+ readonly TabsRoot: readonly ["div", "tabs"];
72
+ readonly AccordionRoot: readonly ["div", "accordion"];
73
+ readonly CommandRoot: readonly ["div", "command"];
74
+ readonly SidebarRoot: readonly ["div", "sidebar"];
75
+ readonly DialogRoot: readonly ["dialog", "dialog"];
76
+ readonly DrawerRoot: readonly ["dialog", "drawer"];
77
+ readonly AlertDialogRoot: readonly ["dialog", "alert-dialog"];
78
+ readonly Button: readonly ["button", "btn"];
79
+ readonly Badge: readonly ["span", "badge"];
80
+ readonly Card: readonly ["article", "card"];
81
+ readonly CardHeader: readonly ["header", ""];
82
+ readonly CardTitle: readonly ["h3", "card-title"];
83
+ readonly CardDescription: readonly ["p", ""];
84
+ readonly CardContent: readonly ["section", ""];
85
+ readonly CardFooter: readonly ["footer", ""];
86
+ readonly CardAction: readonly ["div", "card-action"];
87
+ readonly Alert: readonly ["div", "alert"];
88
+ readonly AlertTitle: readonly ["h2", ""];
89
+ readonly AlertDescription: readonly ["section", ""];
90
+ readonly Avatar: readonly ["span", "avatar"];
91
+ readonly AvatarImage: readonly ["img", ""];
92
+ readonly AvatarFallback: readonly ["span", ""];
93
+ readonly Breadcrumb: readonly ["nav", "breadcrumb"];
94
+ readonly BreadcrumbList: readonly ["ol", ""];
95
+ readonly BreadcrumbItem: readonly ["li", ""];
96
+ readonly BreadcrumbLink: readonly ["a", ""];
97
+ readonly BreadcrumbSeparator: readonly ["li", ""];
98
+ readonly ButtonGroup: readonly ["div", "button-group"];
99
+ readonly Field: readonly ["div", "field"];
100
+ readonly FieldLabel: readonly ["label", "label"];
101
+ readonly FieldDescription: readonly ["p", ""];
102
+ readonly FieldError: readonly ["p", ""];
103
+ readonly Label: readonly ["label", "label"];
104
+ readonly Input: readonly ["input", "input"];
105
+ readonly Textarea: readonly ["textarea", "textarea"];
106
+ readonly NativeSelect: readonly ["select", "select"];
107
+ readonly InputGroup: readonly ["div", "input-group"];
108
+ readonly InputGroupAddon: readonly ["div", ""];
109
+ readonly Empty: readonly ["div", "empty"];
110
+ readonly EmptyHeader: readonly ["header", ""];
111
+ readonly EmptyTitle: readonly ["h3", ""];
112
+ readonly EmptyDescription: readonly ["p", ""];
113
+ readonly EmptyContent: readonly ["section", ""];
114
+ readonly Item: readonly ["div", "item"];
115
+ readonly ItemContent: readonly ["section", ""];
116
+ readonly ItemTitle: readonly ["h3", ""];
117
+ readonly ItemDescription: readonly ["p", ""];
118
+ readonly ItemActions: readonly ["div", ""];
119
+ readonly Kbd: readonly ["kbd", "kbd"];
120
+ readonly ScrollArea: readonly ["div", "scrollbar"];
121
+ readonly Skeleton: readonly ["div", "skeleton"];
122
+ readonly Spinner: readonly ["span", "bc-spinner"];
123
+ readonly Separator: readonly ["hr", ""];
124
+ readonly Table: readonly ["table", "table"];
125
+ readonly TableHeader: readonly ["thead", ""];
126
+ readonly TableBody: readonly ["tbody", ""];
127
+ readonly TableFooter: readonly ["tfoot", ""];
128
+ readonly TableRow: readonly ["tr", ""];
129
+ readonly TableHead: readonly ["th", ""];
130
+ readonly TableCell: readonly ["td", ""];
131
+ readonly TableCaption: readonly ["caption", ""];
132
+ readonly DialogHeader: readonly ["header", ""];
133
+ readonly DialogTitle: readonly ["h2", ""];
134
+ readonly DialogDescription: readonly ["p", ""];
135
+ readonly DialogContent: readonly ["section", ""];
136
+ readonly DialogFooter: readonly ["footer", ""];
137
+ readonly SidebarHeader: readonly ["header", ""];
138
+ readonly SidebarContent: readonly ["section", ""];
139
+ readonly SidebarFooter: readonly ["footer", ""];
140
+ readonly SidebarGroup: readonly ["section", ""];
141
+ readonly SidebarItem: readonly ["a", ""];
142
+ };
143
+ type PrimitiveName = keyof typeof primitiveDefinitions;
144
+
145
+ export { type AccordionItem, type Align, type ChartPoint, type FloatingOptions, type MenuItem, type Option, type PrimitiveName, type Side, type Size, type StylePack, type TabItem, type ToastMessage, type Variant, attachFloating, attachWidget, createTypeahead, cx, dismissableLayer, floatingPosition, focusFirst, formReset, lockScroll, nextIndex, percentage, primitiveDefinitions, scrollWithin, stylePacks };