@spaethtech/svelte-ui 0.1.10 → 0.3.1-dev.10.ff03a8d

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 (218) hide show
  1. package/.claude/skills/svelte-ui/SKILL.md +118 -0
  2. package/.claude/skills/themes/SKILL.md +303 -0
  3. package/CLAUDE.md +248 -0
  4. package/README.md +180 -42
  5. package/dist/components/Alert.svelte +119 -0
  6. package/dist/components/Alert.svelte.d.ts +29 -0
  7. package/dist/components/Badge/Badge.svelte +142 -69
  8. package/dist/components/Badge/Badge.svelte.d.ts +26 -6
  9. package/dist/components/Badge/index.d.ts +1 -1
  10. package/dist/components/Badge/index.js +1 -1
  11. package/dist/components/Banner.svelte +133 -0
  12. package/dist/components/Banner.svelte.d.ts +31 -0
  13. package/dist/components/Button.svelte +240 -0
  14. package/dist/components/Button.svelte.d.ts +33 -0
  15. package/dist/components/ButtonDropdown.svelte +145 -0
  16. package/dist/components/ButtonDropdown.svelte.d.ts +31 -0
  17. package/dist/components/Calendar.svelte +259 -0
  18. package/dist/components/Calendar.svelte.d.ts +27 -0
  19. package/dist/components/Card.svelte +79 -0
  20. package/dist/components/Card.svelte.d.ts +17 -0
  21. package/dist/components/CardBody.svelte +41 -0
  22. package/dist/components/CardBody.svelte.d.ts +17 -0
  23. package/dist/components/CardFooter.svelte +51 -0
  24. package/dist/components/CardFooter.svelte.d.ts +16 -0
  25. package/dist/components/CardHeader.svelte +51 -0
  26. package/dist/components/CardHeader.svelte.d.ts +16 -0
  27. package/dist/components/Checkbox.svelte +131 -0
  28. package/dist/components/Checkbox.svelte.d.ts +16 -0
  29. package/dist/components/ConfirmDialog.svelte +103 -0
  30. package/dist/components/ConfirmDialog.svelte.d.ts +33 -0
  31. package/dist/components/DataTable.svelte +518 -0
  32. package/dist/components/DataTable.svelte.d.ts +74 -0
  33. package/dist/components/DatePicker.svelte +312 -0
  34. package/dist/components/DatePicker.svelte.d.ts +32 -0
  35. package/dist/components/DateTimeInput.svelte +93 -0
  36. package/dist/components/DateTimeInput.svelte.d.ts +20 -0
  37. package/dist/components/Dialog.svelte +151 -0
  38. package/dist/components/Dialog.svelte.d.ts +30 -0
  39. package/dist/components/{EmailInput/EmailInput.svelte → EmailInput.svelte} +17 -8
  40. package/dist/components/EmailInput.svelte.d.ts +21 -0
  41. package/dist/components/Input.svelte +369 -0
  42. package/dist/components/Input.svelte.d.ts +35 -0
  43. package/dist/components/{List/List.svelte → List.svelte} +194 -133
  44. package/dist/components/{List/List.svelte.d.ts → List.svelte.d.ts} +9 -1
  45. package/dist/components/Menu.svelte +117 -0
  46. package/dist/components/Menu.svelte.d.ts +20 -0
  47. package/dist/components/NotesEditor.svelte +127 -0
  48. package/dist/components/NotesEditor.svelte.d.ts +17 -0
  49. package/dist/components/{NumberInput/NumberInput.svelte → NumberInput.svelte} +146 -105
  50. package/dist/components/{NumberInput/NumberInput.svelte.d.ts → NumberInput.svelte.d.ts} +11 -4
  51. package/dist/components/PasswordInput.svelte +52 -0
  52. package/dist/components/PasswordInput.svelte.d.ts +20 -0
  53. package/dist/components/Popup.svelte +140 -0
  54. package/dist/components/Popup.svelte.d.ts +31 -0
  55. package/dist/components/Query.svelte +284 -0
  56. package/dist/components/Query.svelte.d.ts +15 -0
  57. package/dist/components/{Rating/Rating.svelte → Rating.svelte} +19 -10
  58. package/dist/components/Rating.svelte.d.ts +13 -0
  59. package/dist/components/{SearchInput/SearchInput.svelte → SearchInput.svelte} +19 -8
  60. package/dist/components/{SearchInput/SearchInput.svelte.d.ts → SearchInput.svelte.d.ts} +9 -2
  61. package/dist/components/{Select/Select.svelte → Select.svelte} +48 -76
  62. package/dist/components/{Select/Select.svelte.d.ts → Select.svelte.d.ts} +11 -1
  63. package/dist/components/SideBarMenu/SideBarMenu.svelte +724 -0
  64. package/dist/components/SideBarMenu/SideBarMenu.svelte.d.ts +109 -0
  65. package/dist/components/SideBarMenu/index.d.ts +2 -0
  66. package/dist/components/SideBarMenu/index.js +1 -0
  67. package/dist/components/TabStrip/TabStrip.svelte +384 -0
  68. package/dist/components/TabStrip/TabStrip.svelte.d.ts +50 -0
  69. package/dist/components/TabStrip/index.d.ts +3 -0
  70. package/dist/components/TabStrip/index.js +2 -0
  71. package/dist/components/{TextArea/TextArea.svelte → TextArea.svelte} +143 -112
  72. package/dist/components/TextArea.svelte.d.ts +38 -0
  73. package/dist/components/ThemeSelector.svelte +81 -0
  74. package/dist/components/ThemeSelector.svelte.d.ts +10 -0
  75. package/dist/components/TimePicker.svelte +148 -0
  76. package/dist/components/TimePicker.svelte.d.ts +28 -0
  77. package/dist/components/TimeRangeInput.svelte +203 -0
  78. package/dist/components/TimeRangeInput.svelte.d.ts +29 -0
  79. package/dist/components/TimeSpinner.svelte +202 -0
  80. package/dist/components/TimeSpinner.svelte.d.ts +26 -0
  81. package/dist/components/Toast/Toaster.svelte +51 -0
  82. package/dist/components/Toast/Toaster.svelte.d.ts +12 -0
  83. package/dist/components/Toast/toast.svelte.d.ts +29 -0
  84. package/dist/components/Toast/toast.svelte.js +27 -0
  85. package/dist/components/Toggle.svelte +93 -0
  86. package/dist/components/Toggle.svelte.d.ts +15 -0
  87. package/dist/data/dataset.d.ts +42 -0
  88. package/dist/data/dataset.js +3 -0
  89. package/dist/data/index.d.ts +3 -0
  90. package/dist/data/index.js +3 -0
  91. package/dist/data/query/ast.d.ts +62 -0
  92. package/dist/data/query/ast.js +12 -0
  93. package/dist/data/query/index.d.ts +3 -0
  94. package/dist/data/query/index.js +3 -0
  95. package/dist/data/query/lexer.d.ts +33 -0
  96. package/dist/data/query/lexer.js +225 -0
  97. package/dist/data/query/parser.d.ts +11 -0
  98. package/dist/data/query/parser.js +252 -0
  99. package/dist/data/table/grid.svelte.d.ts +57 -0
  100. package/dist/data/table/grid.svelte.js +139 -0
  101. package/dist/data/table/index.d.ts +2 -0
  102. package/dist/data/table/index.js +2 -0
  103. package/dist/data/table/types.d.ts +79 -0
  104. package/dist/index.d.ts +49 -22
  105. package/dist/index.js +46 -21
  106. package/dist/positioning/anchored.d.ts +61 -0
  107. package/dist/positioning/anchored.js +122 -0
  108. package/dist/positioning/tooltip.d.ts +41 -0
  109. package/dist/positioning/tooltip.js +147 -0
  110. package/dist/theme.css +205 -0
  111. package/dist/types/breakpoints.d.ts +24 -0
  112. package/dist/types/breakpoints.js +13 -0
  113. package/dist/types/responsive.d.ts +32 -0
  114. package/dist/types/responsive.js +54 -0
  115. package/dist/types/sizes.d.ts +10 -3
  116. package/dist/types/time.d.ts +19 -0
  117. package/dist/types/time.js +10 -0
  118. package/dist/types/variants.d.ts +8 -1
  119. package/dist/types/variants.js +16 -1
  120. package/docs/components.md +255 -0
  121. package/docs/examples.md +323 -0
  122. package/docs/paradigm.md +240 -0
  123. package/docs/themes.md +170 -0
  124. package/docs/usage.md +450 -0
  125. package/package.json +97 -63
  126. package/dist/components/Button/Button.svelte +0 -172
  127. package/dist/components/Button/Button.svelte.d.ts +0 -32
  128. package/dist/components/Button/index.d.ts +0 -1
  129. package/dist/components/Button/index.js +0 -1
  130. package/dist/components/Dialog/Dialog.svelte +0 -101
  131. package/dist/components/Dialog/Dialog.svelte.d.ts +0 -18
  132. package/dist/components/Dialog/index.d.ts +0 -1
  133. package/dist/components/Dialog/index.js +0 -1
  134. package/dist/components/ElementManager/ElementManager.svelte +0 -397
  135. package/dist/components/ElementManager/ElementManager.svelte.d.ts +0 -43
  136. package/dist/components/ElementManager/index.d.ts +0 -1
  137. package/dist/components/ElementManager/index.js +0 -1
  138. package/dist/components/EmailInput/EmailInput.svelte.d.ts +0 -14
  139. package/dist/components/EmailInput/index.d.ts +0 -1
  140. package/dist/components/EmailInput/index.js +0 -1
  141. package/dist/components/Icon/Icon.svelte +0 -74
  142. package/dist/components/Icon/Icon.svelte.d.ts +0 -13
  143. package/dist/components/Icon/index.d.ts +0 -1
  144. package/dist/components/Icon/index.js +0 -1
  145. package/dist/components/Input/Input.svelte +0 -268
  146. package/dist/components/Input/Input.svelte.d.ts +0 -18
  147. package/dist/components/Input/index.d.ts +0 -1
  148. package/dist/components/Input/index.js +0 -1
  149. package/dist/components/List/index.d.ts +0 -1
  150. package/dist/components/List/index.js +0 -1
  151. package/dist/components/ListItem/ListItem.svelte +0 -175
  152. package/dist/components/ListItem/ListItem.svelte.d.ts +0 -24
  153. package/dist/components/ListItem/index.d.ts +0 -2
  154. package/dist/components/ListItem/index.js +0 -2
  155. package/dist/components/ListView/ListView.svelte +0 -463
  156. package/dist/components/ListView/ListView.svelte.d.ts +0 -37
  157. package/dist/components/ListView/index.d.ts +0 -2
  158. package/dist/components/ListView/index.js +0 -2
  159. package/dist/components/NodeGraph/BaseNode.d.ts +0 -57
  160. package/dist/components/NodeGraph/BaseNode.js +0 -30
  161. package/dist/components/NodeGraph/Edge.svelte +0 -60
  162. package/dist/components/NodeGraph/Edge.svelte.d.ts +0 -16
  163. package/dist/components/NodeGraph/ExpressionEvaluator.d.ts +0 -82
  164. package/dist/components/NodeGraph/ExpressionEvaluator.js +0 -152
  165. package/dist/components/NodeGraph/Node.svelte +0 -100
  166. package/dist/components/NodeGraph/Node.svelte.d.ts +0 -10
  167. package/dist/components/NodeGraph/NodeGraph.svelte +0 -52
  168. package/dist/components/NodeGraph/NodeGraph.svelte.d.ts +0 -14
  169. package/dist/components/NodeGraph/NodeInstance.svelte.d.ts +0 -80
  170. package/dist/components/NodeGraph/NodeInstance.svelte.js +0 -241
  171. package/dist/components/NodeGraph/NodePort.svelte +0 -75
  172. package/dist/components/NodeGraph/NodePort.svelte.d.ts +0 -11
  173. package/dist/components/NodeGraph/decorators.d.ts +0 -81
  174. package/dist/components/NodeGraph/decorators.js +0 -148
  175. package/dist/components/NodeGraph/index.d.ts +0 -9
  176. package/dist/components/NodeGraph/index.js +0 -9
  177. package/dist/components/NodeGraph/types.d.ts +0 -94
  178. package/dist/components/NodeGraph/types.js +0 -33
  179. package/dist/components/NotesEditor/NotesEditor.svelte +0 -203
  180. package/dist/components/NotesEditor/NotesEditor.svelte.d.ts +0 -9
  181. package/dist/components/NotesEditor/index.d.ts +0 -1
  182. package/dist/components/NotesEditor/index.js +0 -1
  183. package/dist/components/NumberInput/index.d.ts +0 -1
  184. package/dist/components/NumberInput/index.js +0 -1
  185. package/dist/components/PasswordInput/PasswordInput.svelte +0 -41
  186. package/dist/components/PasswordInput/PasswordInput.svelte.d.ts +0 -13
  187. package/dist/components/PasswordInput/index.d.ts +0 -1
  188. package/dist/components/PasswordInput/index.js +0 -1
  189. package/dist/components/Popup/index.d.ts +0 -1
  190. package/dist/components/Popup/index.js +0 -1
  191. package/dist/components/Rating/Rating.svelte.d.ts +0 -7
  192. package/dist/components/Rating/index.d.ts +0 -1
  193. package/dist/components/Rating/index.js +0 -1
  194. package/dist/components/ScrollView/ScrollView.svelte +0 -285
  195. package/dist/components/ScrollView/ScrollView.svelte.d.ts +0 -19
  196. package/dist/components/ScrollView/index.d.ts +0 -1
  197. package/dist/components/ScrollView/index.js +0 -1
  198. package/dist/components/SearchInput/index.d.ts +0 -1
  199. package/dist/components/SearchInput/index.js +0 -1
  200. package/dist/components/Select/index.d.ts +0 -1
  201. package/dist/components/Select/index.js +0 -1
  202. package/dist/components/TextArea/TextArea.svelte.d.ts +0 -19
  203. package/dist/components/TextArea/index.d.ts +0 -1
  204. package/dist/components/TextArea/index.js +0 -1
  205. package/dist/components/ThemeSelector/ThemeSelector.svelte +0 -64
  206. package/dist/components/ThemeSelector/ThemeSelector.svelte.d.ts +0 -3
  207. package/dist/components/ThemeSelector/index.d.ts +0 -1
  208. package/dist/components/ThemeSelector/index.js +0 -1
  209. package/dist/components/TooltipHandler/TooltipHandler.svelte +0 -593
  210. package/dist/components/TooltipHandler/TooltipHandler.svelte.d.ts +0 -10
  211. package/dist/components/TooltipHandler/index.d.ts +0 -1
  212. package/dist/components/TooltipHandler/index.js +0 -1
  213. package/dist/styles/sizes.d.ts +0 -78
  214. package/dist/styles/sizes.js +0 -120
  215. package/dist/styles/variants.d.ts +0 -106
  216. package/dist/styles/variants.js +0 -194
  217. package/dist/types/ManagerTypes.d.ts +0 -42
  218. /package/dist/{types/ManagerTypes.js → data/table/types.js} +0 -0
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Responsive breakpoint tiers — the single source of truth for any
3
+ * component that accepts per-tier configuration (modes, columns,
4
+ * visibility, etc.). Keys match the tier names defined in
5
+ * `theme.css`, with `base` for the unconditional "no min-width" case.
6
+ *
7
+ * Pixel widths are exposed alongside the type so JS-driven mode
8
+ * resolution (via matchMedia) can stay in sync with the CSS without
9
+ * a second source of truth.
10
+ *
11
+ * - `base` → 0 px (no min-width — the unconditional fallback)
12
+ * - `4xs` → 320 px (iPhone SE class)
13
+ * - `3xs` → 360 px (narrow Android)
14
+ * - `2xs` → 420 px (standard phone)
15
+ * - `xs` → 480 px (large phone / small tablet portrait)
16
+ * - `sm` → 640 px (Tailwind default)
17
+ * - `md` → 768 px (Tailwind default)
18
+ * - `lg` → 1024 px (Tailwind default)
19
+ * - `xl` → 1280 px (Tailwind default)
20
+ * - `2xl` → 1536 px (Tailwind default)
21
+ * - `3xl` → 1920 px (FHD / 1080p ultrawide)
22
+ */
23
+ export type Breakpoint = "base" | "4xs" | "3xs" | "2xs" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "3xl";
24
+ export declare const BREAKPOINT_PX: Record<Breakpoint, number>;
@@ -0,0 +1,13 @@
1
+ export const BREAKPOINT_PX = {
2
+ base: 0,
3
+ "4xs": 320,
4
+ "3xs": 360,
5
+ "2xs": 420,
6
+ xs: 480,
7
+ sm: 640,
8
+ md: 768,
9
+ lg: 1024,
10
+ xl: 1280,
11
+ "2xl": 1536,
12
+ "3xl": 1920,
13
+ };
@@ -0,0 +1,32 @@
1
+ import { type Breakpoint } from "./breakpoints.js";
2
+ /**
3
+ * A value that is either a single `T` (applied at every width) OR a per-breakpoint map.
4
+ * Mobile-first: `base` (or a bare `T`) is the unconditional value; each larger tier present in the
5
+ * map overrides from its min-width upward. Mirrors the DataTable column `breakpoints` shape so the
6
+ * whole library speaks one responsive language.
7
+ *
8
+ * size="lg" // always lg
9
+ * size={{ base: 'lg', xs: 'md' }} // lg on phones, md at >=480px
10
+ */
11
+ export type Responsive<T extends string> = T | Partial<Record<Breakpoint, T>>;
12
+ /**
13
+ * Resolve a `Responsive<T>` into a Tailwind class string, given a per-value class map.
14
+ *
15
+ * - Scalar `T` → the map entry verbatim (today's behaviour, zero overhead).
16
+ * - Map → the `base` entry unprefixed, then each higher tier's entry with its `bp:` prefix applied
17
+ * to EVERY class token (`'h-8 px-4'` at `xs` → `'xs:h-8 xs:px-4'`). Emitted low→high min-width so
18
+ * the CSS cascade lands on the active tier. Works for arbitrary/variant tokens too — the prefix
19
+ * sits in front of the whole chain (`xs:[&_svg]:w-4`, `xs:[background-color:var(--x)]`).
20
+ *
21
+ * The generated `bp:`-prefixed classes are runtime strings Tailwind can't see by scanning source —
22
+ * they are safelisted via `@source inline` in `theme.css` (see the `-- responsive size/variant --`
23
+ * block there); consuming apps inherit it through `@import 'svelte-ui/theme.css'`.
24
+ */
25
+ export declare function responsiveClasses<T extends string>(value: Responsive<T> | undefined, map: Record<T, string>): string;
26
+ /**
27
+ * Collapse a `Responsive<T>` to a single scalar — for the rare bits driven by JS/inline-style rather
28
+ * than a class (e.g. a numeric line-height for autosize math, or a CSS-var set via `style=`). Scalar
29
+ * passes through; a map yields its `base` tier (or `fallback`). Those aspects therefore track the
30
+ * mobile-first tier only — the CLASS-driven visuals still respond at every breakpoint.
31
+ */
32
+ export declare function resolveScalar<T extends string>(value: Responsive<T> | undefined, fallback: T): T;
@@ -0,0 +1,54 @@
1
+ import { BREAKPOINT_PX } from "./breakpoints.js";
2
+ /** Breakpoints ascending by min-width — so prefixed rules emit in cascade order (larger wins). */
3
+ const ASCENDING = Object.keys(BREAKPOINT_PX).sort((a, b) => BREAKPOINT_PX[a] - BREAKPOINT_PX[b]);
4
+ /**
5
+ * Resolve a `Responsive<T>` into a Tailwind class string, given a per-value class map.
6
+ *
7
+ * - Scalar `T` → the map entry verbatim (today's behaviour, zero overhead).
8
+ * - Map → the `base` entry unprefixed, then each higher tier's entry with its `bp:` prefix applied
9
+ * to EVERY class token (`'h-8 px-4'` at `xs` → `'xs:h-8 xs:px-4'`). Emitted low→high min-width so
10
+ * the CSS cascade lands on the active tier. Works for arbitrary/variant tokens too — the prefix
11
+ * sits in front of the whole chain (`xs:[&_svg]:w-4`, `xs:[background-color:var(--x)]`).
12
+ *
13
+ * The generated `bp:`-prefixed classes are runtime strings Tailwind can't see by scanning source —
14
+ * they are safelisted via `@source inline` in `theme.css` (see the `-- responsive size/variant --`
15
+ * block there); consuming apps inherit it through `@import 'svelte-ui/theme.css'`.
16
+ */
17
+ export function responsiveClasses(value, map) {
18
+ if (value == null)
19
+ return "";
20
+ if (typeof value === "string")
21
+ return map[value] ?? "";
22
+ let out = "";
23
+ for (const bp of ASCENDING) {
24
+ const tier = value[bp];
25
+ if (tier == null)
26
+ continue;
27
+ const cls = map[tier];
28
+ if (!cls)
29
+ continue;
30
+ out += out ? " " : "";
31
+ out +=
32
+ bp === "base"
33
+ ? cls
34
+ : cls
35
+ .trim()
36
+ .split(/\s+/)
37
+ .map((t) => `${bp}:${t}`)
38
+ .join(" ");
39
+ }
40
+ return out;
41
+ }
42
+ /**
43
+ * Collapse a `Responsive<T>` to a single scalar — for the rare bits driven by JS/inline-style rather
44
+ * than a class (e.g. a numeric line-height for autosize math, or a CSS-var set via `style=`). Scalar
45
+ * passes through; a map yields its `base` tier (or `fallback`). Those aspects therefore track the
46
+ * mobile-first tier only — the CLASS-driven visuals still respond at every breakpoint.
47
+ */
48
+ export function resolveScalar(value, fallback) {
49
+ if (value == null)
50
+ return fallback;
51
+ if (typeof value === "string")
52
+ return value;
53
+ return value.base ?? fallback;
54
+ }
@@ -1,5 +1,12 @@
1
1
  /**
2
- * Standard size variants used across UI components.
3
- * Ensures consistent heights and spacing throughout the library.
2
+ * Shared sizing axis the cross-cutting counterpart to {@link ./variants.ts | Variant}.
3
+ * Every sizeable component (Button, Input, Select, …) accepts `size` and maps it to a consistent
4
+ * control height / text / padding / icon scale. Default is always `md` (today's look).
5
+ *
6
+ * - `sm` → 24px (`--ui-height-sm`) · dense: table chrome, inline controls
7
+ * - `md` → 32px (`--ui-height`) · default
8
+ * - `lg` → 40px (`--ui-height-lg`) · prominent (0.75× / 1.0× / 1.25× around md)
9
+ *
10
+ * `--ui-height-touch` (44px) is a separate token for explicit touch targets — not `lg`.
4
11
  */
5
- export type Size = 'sm' | 'md' | 'lg';
12
+ export type Size = "sm" | "md" | "lg";
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Step interval for the time spinner columns. A bare number is shorthand for the MINUTE step (the
3
+ * common case); an object sets any column independently. Unspecified columns default to 1.
4
+ *
5
+ * step={15} // minutes step by 15 (hours/seconds by 1)
6
+ * step={{ minute: 15, second: 30 }} // minutes by 15, seconds by 30
7
+ * step={{ hour: 2 }} // hours by 2
8
+ */
9
+ export type StepSpec = number | {
10
+ hour?: number;
11
+ minute?: number;
12
+ second?: number;
13
+ };
14
+ /** Resolve a {@link StepSpec} to a per-column `{ hour, minute, second }` (each ≥ 1). */
15
+ export declare function resolveStep(step: StepSpec | undefined): {
16
+ hour: number;
17
+ minute: number;
18
+ second: number;
19
+ };
@@ -0,0 +1,10 @@
1
+ /** Resolve a {@link StepSpec} to a per-column `{ hour, minute, second }` (each ≥ 1). */
2
+ export function resolveStep(step) {
3
+ if (typeof step === "number")
4
+ return { hour: 1, minute: Math.max(1, step), second: 1 };
5
+ return {
6
+ hour: Math.max(1, step?.hour ?? 1),
7
+ minute: Math.max(1, step?.minute ?? 1),
8
+ second: Math.max(1, step?.second ?? 1),
9
+ };
10
+ }
@@ -1 +1,8 @@
1
- export type Variant = 'primary' | 'secondary' | 'danger' | 'info' | 'success' | 'warning' | 'ghost';
1
+ export type Variant = "neutral" | "primary" | "secondary" | "success" | "info" | "warning" | "danger" | "ghost";
2
+ /** Variant → semantic colour token, used where a variant needs an ACCENT colour (Toggle track,
3
+ * Checkbox, Card border, DataTable accent…). `danger` maps to `--ui-color-error`. The two non-accent
4
+ * variants — `ghost` (transparent, hover-tint only) and `neutral` (text-mix surface tint, = the
5
+ * default DataTable look) — resolve to `--ui-color-text`, so those controls read grey/uncoloured
6
+ * rather than borrowing an accent. The interactive tints (hover/surface/active) are text-mixes by
7
+ * default and re-mix off whichever colour this points at. */
8
+ export declare const variantToken: Record<Variant, string>;
@@ -1 +1,16 @@
1
- export {};
1
+ /** Variant → semantic colour token, used where a variant needs an ACCENT colour (Toggle track,
2
+ * Checkbox, Card border, DataTable accent…). `danger` maps to `--ui-color-error`. The two non-accent
3
+ * variants — `ghost` (transparent, hover-tint only) and `neutral` (text-mix surface tint, = the
4
+ * default DataTable look) — resolve to `--ui-color-text`, so those controls read grey/uncoloured
5
+ * rather than borrowing an accent. The interactive tints (hover/surface/active) are text-mixes by
6
+ * default and re-mix off whichever colour this points at. */
7
+ export const variantToken = {
8
+ neutral: "--ui-color-text",
9
+ primary: "--ui-color-primary",
10
+ secondary: "--ui-color-secondary",
11
+ success: "--ui-color-success",
12
+ info: "--ui-color-info",
13
+ warning: "--ui-color-warning",
14
+ danger: "--ui-color-error",
15
+ ghost: "--ui-color-text",
16
+ };
@@ -0,0 +1,255 @@
1
+ # Component Reference
2
+
3
+ Complete reference for all svelte-ui components. The exported set is whatever
4
+ `src/lib/index.ts` re-exports — this doc tracks it.
5
+
6
+ Icons are **MDI via `unplugin-icons`** — there is **no `Icon` component**. You render an icon by
7
+ importing an MDI component (`import IconHome from '~icons/mdi/home'`) and passing it into a
8
+ component's `icon` **snippet**. See `docs/usage.md`.
9
+
10
+ ## Cross-cutting axes
11
+
12
+ Most sizeable/themeable components share two props (defined in `types/variants.ts` /
13
+ `types/sizes.ts`):
14
+
15
+ - **`variant`** — color/style: `primary`, `secondary`, `danger`, `info`, `success`, `warning`,
16
+ `ghost`, `plain`. `plain` is borderless/transparent — for dense icon controls.
17
+ - **`size`** — `sm` (24px), `md` (32px, **default**), `lg` (40px). Tied to the theme's
18
+ `--ui-height-sm` / `--ui-height` / `--ui-height-lg`.
19
+
20
+ ## Form Components
21
+
22
+ ### Button
23
+
24
+ Flexible button/anchor component.
25
+
26
+ - **Location**: `src/lib/components/Button.svelte`
27
+ - **Axes**: `variant`, `size`
28
+ - **Props**: `text`, `icon` (snippet), `href` (renders an `<a>`), `disabled`, `onclick`, `title`,
29
+ plus native button/anchor attributes
30
+ - **Features**: icon-only sizing, themed tooltip driven from `title` (via `use:tooltip`),
31
+ TypeScript discriminated union for button-vs-anchor
32
+ - **Accessibility**: ARIA attributes, focus-visible outlines
33
+
34
+ ### Input
35
+
36
+ Text input with an icon slot, trailing actions, and validation.
37
+
38
+ - **Location**: `src/lib/components/Input.svelte`
39
+ - **Axes**: `size`
40
+ - **Props**: `value` (bindable), `icon` (snippet), `iconPosition` (`'left' | 'right'`, default
41
+ `'right'`), `iconClickable`, `onIconClick`, `actions` (snippet — trailing controls inside the
42
+ frame), `validate`, `valid`/`touched` (bindable), plus native input attributes
43
+ - **Note**: a single `icon` snippet positioned by `iconPosition` — there is no
44
+ `iconLeft`/`iconRight`.
45
+
46
+ ### Select
47
+
48
+ Custom dropdown built on `Input` + `List`.
49
+
50
+ - **Location**: `src/lib/components/Select.svelte`
51
+ - **Axes**: `size`
52
+ - **Props**: `options` (`{ value, label, ... }[]`), `value` (bindable), `multiSelect`,
53
+ `placeholder`, `itemSnippet`, plus API props (`url`, `searchParam`, `transform`, `debounceMs`,
54
+ `maxResults`, `headers`, `searchTerm`)
55
+ - **Modes**: static `options` or search-as-you-type against `url`
56
+
57
+ ### List
58
+
59
+ Standalone selectable list (Select's dropdown body).
60
+
61
+ - **Location**: `src/lib/components/List.svelte`
62
+ - **Axes**: `size`
63
+ - **Props**: `options` (`{ value, label, ... }[]`), `value` (bindable), `multiSelect`,
64
+ `showCheckboxes`, `maxVisibleItems`, `itemSnippet`, plus the same API props as `Select`
65
+
66
+ ### TextArea
67
+
68
+ Multi-line text input with optional auto-resize.
69
+
70
+ - **Location**: `src/lib/components/TextArea.svelte`
71
+ - **Axes**: `size`
72
+ - **Props**: `value` (bindable), `minRows`, `maxRows`, `lineHeightRem`, `allowCopy` (built-in copy
73
+ control), `validate`, `valid`/`touched`, plus native textarea attributes
74
+ - **Modes**: fixed height (`minRows === maxRows`) or auto-sizing
75
+
76
+ ### Checkbox
77
+
78
+ Small themed checkbox (native control tinted via `accent-color`).
79
+
80
+ - **Location**: `src/lib/components/Checkbox.svelte`
81
+ - **Axes**: `size`
82
+ - **Props**: `checked` (bindable), `indeterminate`, `disabled`, plus native input attributes
83
+
84
+ ### Rating
85
+
86
+ Read-only star-rating display (5-star, from a 10-point average).
87
+
88
+ - **Location**: `src/lib/components/Rating.svelte`
89
+ - **Props**: `average` (number), `count` (number)
90
+
91
+ ## Specialized Input Components
92
+
93
+ Thin wrappers over `Input`, each preconfigured with an MDI icon (rendered into Input's snippet).
94
+
95
+ ### PasswordInput
96
+
97
+ - **Location**: `src/lib/components/PasswordInput.svelte`
98
+ - **Features**: built-in visibility toggle (eye / eye-off MDI icons)
99
+
100
+ ### EmailInput
101
+
102
+ - **Location**: `src/lib/components/EmailInput.svelte`
103
+ - **Features**: email validation, envelope icon
104
+
105
+ ### SearchInput
106
+
107
+ - **Location**: `src/lib/components/SearchInput.svelte`
108
+ - **Features**: search (magnify) icon, clear button when typing
109
+
110
+ ### NumberInput
111
+
112
+ - **Location**: `src/lib/components/NumberInput.svelte`
113
+ - **Features**: number formatting and validation
114
+
115
+ ## Data Components
116
+
117
+ These pair with the headless **`@spaethtech/svelte-ui/data`** layer (query-language parser/AST, `createGrid`,
118
+ `DataSet`). See `docs/usage.md`.
119
+
120
+ ### DataTable
121
+
122
+ Config-driven, responsive 12-column data table over a `DataGrid`.
123
+
124
+ - **Location**: `src/lib/components/DataTable.svelte`
125
+ - **Props**: `grid` (`DataGrid<T>` from `@spaethtech/svelte-ui/data`), `selectable`, `expandable`, `expanded`
126
+ (snippet), `rowActions` (`(row) => MenuItem[]`), `bulkActions`
127
+ - **Features**: selectable + expandable rows, sortable headers, per-row & bulk action menus
128
+ (via `Menu`/`Popup`), paginated footer. A **compound component** — all controls are
129
+ `<Button variant="plain" size="sm">` / `<Select size="sm">` / `<Checkbox>`.
130
+
131
+ ### Query
132
+
133
+ Filter bar over a `DataSet` — monospace input with `$column` + enum-value autocomplete and a help
134
+ dialog.
135
+
136
+ - **Location**: `src/lib/components/Query.svelte`
137
+ - **Props**: `dataset` (`DataSet`), `placeholder`
138
+ - **Note**: URL sync is intentionally not built in — observe `dataset.applied` and sync yourself.
139
+ Built on `Input` + `Button` + `Popup` + `Dialog`.
140
+
141
+ ## Overlays
142
+
143
+ ### Dialog
144
+
145
+ **Pure modal shell** — the mechanics only, no imposed content. Put a `Card` (or anything) inside via
146
+ `children`. For the common confirm pattern use `ConfirmDialog` (below).
147
+
148
+ - **Location**: `src/lib/components/Dialog.svelte`
149
+ - **Props**: `isOpen` (bindable), `width` (any CSS value — `'80%'`, `'80vw'`, `'400px'`; default
150
+ auto, capped at `min(32rem, …)`), `height` (any CSS value; default auto), `dismissible` (default
151
+ `true`), `onClose`, `class`, `children` (snippet). Extra attributes (e.g. `aria-label`) spread onto
152
+ the panel.
153
+ - **Features**: portals to `<body>`, background scroll-lock (scrollbar-width compensated), backdrop
154
+ + Escape dismiss, **focus trap** (initial focus in, Tab wraps, focus restored on close),
155
+ `role="dialog"` + `aria-modal`.
156
+
157
+ ### ConfirmDialog
158
+
159
+ The common title + message + Confirm/Cancel modal, composed from a `Card` on top of the `Dialog`
160
+ shell.
161
+
162
+ - **Location**: `src/lib/components/ConfirmDialog.svelte`
163
+ - **Props**: `isOpen` (bindable), `title`, `message`, `confirmText`, `cancelText`, `onConfirm`,
164
+ `onCancel`, `variant` (`'normal' | 'danger'`), `size`, `showConfirm`, `showCancel`, `dismissible`,
165
+ `width`/`height` (forwarded to the shell), `children` (snippet — replaces `message` as the body).
166
+
167
+ ### Popup
168
+
169
+ Interactive popover anchored to a trigger, rendered in the browser top layer (Popover API) so it's
170
+ never clipped by overflow/stacking contexts. Placement via the shared `anchored` engine.
171
+
172
+ - **Location**: `src/lib/components/Popup.svelte`
173
+ - **Props**: `anchor` (trigger element), `open` (bindable), `side`, `align`, `boundary`
174
+ (`'viewport'` or an element/selector), `offset`, `matchWidth`, `onclose`, `children` (snippet)
175
+ - **Features**: flips against the boundary, dismisses on Escape + outside pointerdown
176
+
177
+ ### Menu
178
+
179
+ Keyboard-navigable action menu rendered inside a `Popup`.
180
+
181
+ - **Location**: `src/lib/components/Menu.svelte`
182
+ - **Props**: `anchor`, `open` (bindable), `items` (`MenuItem[]` from `@spaethtech/svelte-ui/data`), `side`,
183
+ `align`, `boundary`
184
+ - **Features**: renders all items always and disables the invalid ones; aligns labels when any
185
+ item has an icon
186
+
187
+ ### tooltip (action)
188
+
189
+ Themed tooltips as a Svelte action — `use:tooltip` — built on `anchored`. No global handler.
190
+
191
+ - **Location**: `src/lib/positioning/tooltip.ts`
192
+ - **Options** (`TooltipOptions`): `text` (defaults to the element's `title`, which is then
193
+ suppressed), `side` (default `top`), `align`, `offset`, `delay`, `disabled`
194
+ - **Note**: `Button` feeds this from its `title`, so native `title` tooltips are replaced wherever
195
+ a Button is used. Mirrors text to `aria-label` when the element has no accessible name.
196
+
197
+ ## Positioning
198
+
199
+ ### anchored (engine)
200
+
201
+ Shared placement engine — a Svelte action plus `computePlacement` / `resolveBoundary` — used by
202
+ `Popup`, `Menu`, and `tooltip`.
203
+
204
+ - **Location**: `src/lib/positioning/anchored.ts`
205
+ - **Exports**: `anchored`, `computePlacement`, `resolveBoundary`, and the types `Side`, `Align`,
206
+ `Boundary`, `PlaceOptions`, `Placement`, `AnchoredParams`
207
+
208
+ ## Display / Theme
209
+
210
+ ### Badge
211
+
212
+ Status indicator / label.
213
+
214
+ - **Location**: `src/lib/components/Badge/Badge.svelte`
215
+ - **Axes**: `size`
216
+ - **Variants**: `default`, `primary`, `success`, `warning`, `danger`, `info`
217
+ - **Props**: `text`, `variant`, `size`, `dismissible`, `rounded`, `children`; dispatches `dismiss`
218
+
219
+ ### NotesEditor
220
+
221
+ - **Location**: `src/lib/components/NotesEditor.svelte`
222
+
223
+ ### ThemeSelector
224
+
225
+ Theme switcher (Auto / Light / Dark), built on `Select`.
226
+
227
+ - **Location**: `src/lib/components/ThemeSelector.svelte`
228
+ - **Features**: applies `.theme-light` / `.theme-dark` to `<html>`/`<body>`, `auto` follows the
229
+ system preference, persists to `localStorage` (`svelte-ui-theme`)
230
+
231
+ ## Import Pattern
232
+
233
+ ```typescript
234
+ import { Button, Input, Select, DataTable, tooltip } from "@spaethtech/svelte-ui";
235
+ import { createGrid } from "@spaethtech/svelte-ui/data";
236
+ import "@spaethtech/svelte-ui/theme.css"; // via @import in your app.css
237
+ ```
238
+
239
+ ## Component Structure
240
+
241
+ ### Colocated Components
242
+
243
+ ```
244
+ src/lib/components/ComponentName/
245
+ ├── ComponentName.svelte # Implementation
246
+ ├── ComponentName.spec.md # Specification
247
+ ├── ComponentName.test.ts # Tests
248
+ └── index.ts # Export
249
+ ```
250
+
251
+ ### Simple Components
252
+
253
+ ```
254
+ src/lib/components/ComponentName.svelte
255
+ ```