jvdm-ui 1.0.5

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 (74) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +221 -0
  3. package/bin/jvdm-ui.mjs +49 -0
  4. package/dist/atoms/index.d.ts +343 -0
  5. package/dist/atoms/index.js +3 -0
  6. package/dist/atoms/index.js.map +1 -0
  7. package/dist/chunk-AHE2576G.js +682 -0
  8. package/dist/chunk-AHE2576G.js.map +1 -0
  9. package/dist/chunk-CGDYSB4G.js +3 -0
  10. package/dist/chunk-CGDYSB4G.js.map +1 -0
  11. package/dist/chunk-JYNDKPAH.js +362 -0
  12. package/dist/chunk-JYNDKPAH.js.map +1 -0
  13. package/dist/chunk-WWOXGKLF.js +724 -0
  14. package/dist/chunk-WWOXGKLF.js.map +1 -0
  15. package/dist/client/code-block.d.ts +9 -0
  16. package/dist/client/code-block.js +65 -0
  17. package/dist/client/code-block.js.map +1 -0
  18. package/dist/client/confirm-dialog.d.ts +16 -0
  19. package/dist/client/confirm-dialog.js +181 -0
  20. package/dist/client/confirm-dialog.js.map +1 -0
  21. package/dist/client/date-picker.d.ts +10 -0
  22. package/dist/client/date-picker.js +236 -0
  23. package/dist/client/date-picker.js.map +1 -0
  24. package/dist/client/file-upload.d.ts +12 -0
  25. package/dist/client/file-upload.js +58 -0
  26. package/dist/client/file-upload.js.map +1 -0
  27. package/dist/client/gallery.d.ts +14 -0
  28. package/dist/client/gallery.js +122 -0
  29. package/dist/client/gallery.js.map +1 -0
  30. package/dist/client/menu.d.ts +24 -0
  31. package/dist/client/menu.js +115 -0
  32. package/dist/client/menu.js.map +1 -0
  33. package/dist/client/modal.d.ts +19 -0
  34. package/dist/client/modal.js +147 -0
  35. package/dist/client/modal.js.map +1 -0
  36. package/dist/client/multi-select.d.ts +16 -0
  37. package/dist/client/multi-select.js +84 -0
  38. package/dist/client/multi-select.js.map +1 -0
  39. package/dist/client/number-input.d.ts +6 -0
  40. package/dist/client/number-input.js +59 -0
  41. package/dist/client/number-input.js.map +1 -0
  42. package/dist/client/password-input.d.ts +16 -0
  43. package/dist/client/password-input.js +103 -0
  44. package/dist/client/password-input.js.map +1 -0
  45. package/dist/client/pin-input.d.ts +10 -0
  46. package/dist/client/pin-input.js +55 -0
  47. package/dist/client/pin-input.js.map +1 -0
  48. package/dist/client/theme-toggle.d.ts +8 -0
  49. package/dist/client/theme-toggle.js +126 -0
  50. package/dist/client/theme-toggle.js.map +1 -0
  51. package/dist/client/theme.d.ts +8 -0
  52. package/dist/client/theme.js +32 -0
  53. package/dist/client/theme.js.map +1 -0
  54. package/dist/client/time-picker.d.ts +10 -0
  55. package/dist/client/time-picker.js +140 -0
  56. package/dist/client/time-picker.js.map +1 -0
  57. package/dist/index.d.ts +5 -0
  58. package/dist/index.js +6 -0
  59. package/dist/index.js.map +1 -0
  60. package/dist/molecules/index.d.ts +309 -0
  61. package/dist/molecules/index.js +4 -0
  62. package/dist/molecules/index.js.map +1 -0
  63. package/dist/organisms/index.d.ts +113 -0
  64. package/dist/organisms/index.js +4 -0
  65. package/dist/organisms/index.js.map +1 -0
  66. package/dist/presets/gavel.css +19 -0
  67. package/dist/theme/index.d.ts +60 -0
  68. package/dist/theme/index.js +85 -0
  69. package/dist/theme/index.js.map +1 -0
  70. package/dist/tokens/index.d.ts +8 -0
  71. package/dist/tokens/index.js +3 -0
  72. package/dist/tokens/index.js.map +1 -0
  73. package/dist/tokens.css +129 -0
  74. package/package.json +114 -0
@@ -0,0 +1,309 @@
1
+ import * as react from 'react';
2
+ import { ReactNode } from 'react';
3
+
4
+ type AccordionItem = {
5
+ id: string;
6
+ title: ReactNode;
7
+ content: ReactNode;
8
+ defaultOpen?: boolean;
9
+ };
10
+ declare function Accordion({ items, exclusive, name, className, }: {
11
+ items: readonly AccordionItem[];
12
+ exclusive?: boolean;
13
+ name?: string;
14
+ className?: string;
15
+ }): react.JSX.Element;
16
+
17
+ declare const TONES$2: {
18
+ readonly info: "border-info/40 bg-info-soft text-info";
19
+ readonly ok: "border-ok/40 bg-ok-soft text-ok";
20
+ readonly warn: "border-warn/40 bg-warn-soft text-warn";
21
+ readonly danger: "border-danger/40 bg-danger-soft text-danger";
22
+ };
23
+ type BannerTone = keyof typeof TONES$2;
24
+ declare function Banner({ tone, title, children, action, className, }: {
25
+ tone?: BannerTone;
26
+ title: string;
27
+ children?: ReactNode;
28
+ action?: ReactNode;
29
+ className?: string;
30
+ }): react.JSX.Element;
31
+
32
+ type Crumb = {
33
+ id: string;
34
+ label: ReactNode;
35
+ href?: string;
36
+ };
37
+ declare function Breadcrumb({ items, label, className, }: {
38
+ items: readonly Crumb[];
39
+ label?: string;
40
+ className?: string;
41
+ }): react.JSX.Element;
42
+
43
+ declare const TONES$1: {
44
+ readonly info: "border-info/35 bg-info-soft text-info";
45
+ readonly ok: "border-ok/35 bg-ok-soft text-ok";
46
+ readonly warn: "border-warn/35 bg-warn-soft text-warn";
47
+ readonly danger: "border-danger/35 bg-danger-soft text-danger";
48
+ };
49
+ type CalloutTone = keyof typeof TONES$1;
50
+ declare function Callout({ tone, title, children, className, }: {
51
+ tone?: CalloutTone;
52
+ title: string;
53
+ children: ReactNode;
54
+ className?: string;
55
+ }): react.JSX.Element;
56
+
57
+ declare function CardTitle({ children, hint }: {
58
+ children: ReactNode;
59
+ hint?: ReactNode;
60
+ }): react.JSX.Element;
61
+
62
+ declare function CodeBlock({ code, language, className, }: {
63
+ code: string;
64
+ language?: string;
65
+ className?: string;
66
+ }): react.JSX.Element;
67
+
68
+ type CommandItem = {
69
+ id: string;
70
+ label: string;
71
+ description?: string;
72
+ icon?: ReactNode;
73
+ };
74
+ declare function CommandMenu({ items, onSelect, label, global, }: {
75
+ items: readonly CommandItem[];
76
+ onSelect?: (item: CommandItem) => void;
77
+ label?: string;
78
+ global?: boolean;
79
+ }): react.JSX.Element;
80
+
81
+ declare function ConfirmDialog({ open, title, description, confirmLabel, cancelLabel, pending, children, onConfirm, onCancel, }: {
82
+ open: boolean;
83
+ title: string;
84
+ description?: string;
85
+ confirmLabel: string;
86
+ cancelLabel: string;
87
+ pending?: boolean;
88
+ children?: ReactNode;
89
+ onConfirm: () => void;
90
+ onCancel: () => void;
91
+ }): react.JSX.Element;
92
+
93
+ declare function Drawer({ isOpen, onClose, title, children, closeLabel, }: {
94
+ isOpen: boolean;
95
+ onClose: () => void;
96
+ title: ReactNode;
97
+ children: ReactNode;
98
+ closeLabel?: string;
99
+ }): react.JSX.Element;
100
+
101
+ declare function DropdownMenu({ trigger, children, align, className, }: {
102
+ trigger: ReactNode;
103
+ children: ReactNode;
104
+ align?: "start" | "end";
105
+ className?: string;
106
+ }): react.JSX.Element;
107
+
108
+ declare function Empty({ title, description }: {
109
+ title: string;
110
+ description?: ReactNode;
111
+ }): react.JSX.Element;
112
+
113
+ declare function Field({ label, htmlFor, error, action, className, children, }: {
114
+ label: string;
115
+ htmlFor?: string;
116
+ error?: string;
117
+ action?: ReactNode;
118
+ className?: string;
119
+ children: ReactNode;
120
+ }): react.JSX.Element;
121
+
122
+ declare function FilterBar({ children, resultLabel, onClear, className, }: {
123
+ children: ReactNode;
124
+ resultLabel?: string;
125
+ onClear?: () => void;
126
+ className?: string;
127
+ }): react.JSX.Element;
128
+
129
+ declare function Gallery({ photos, alt, fallback, photoLabel, previousLabel, nextLabel, className, }: {
130
+ photos: string[];
131
+ alt: string;
132
+ fallback?: ReactNode;
133
+ photoLabel?: (index: number, total: number) => string;
134
+ previousLabel?: string;
135
+ nextLabel?: string;
136
+ className?: string;
137
+ }): react.JSX.Element;
138
+
139
+ declare function LoadError({ message, onRetry, retryLabel, }: {
140
+ message: string;
141
+ onRetry?: () => void;
142
+ retryLabel?: string;
143
+ }): react.JSX.Element;
144
+
145
+ declare function ImagePreview({ src, alt, fallback, className, }: {
146
+ src?: string;
147
+ alt: string;
148
+ fallback?: ReactNode;
149
+ className?: string;
150
+ }): react.JSX.Element;
151
+
152
+ type TreeNode = {
153
+ id: string;
154
+ label: ReactNode;
155
+ children?: readonly TreeNode[];
156
+ };
157
+ declare function TreeView({ nodes, className, }: {
158
+ nodes: readonly TreeNode[];
159
+ className?: string;
160
+ }): react.JSX.Element;
161
+
162
+ declare function MetricCard({ label, value, change, trend, hint, children, className, }: {
163
+ label: string;
164
+ value: ReactNode;
165
+ change?: string;
166
+ trend?: "neutral" | "up" | "down";
167
+ hint?: string;
168
+ children?: ReactNode;
169
+ className?: string;
170
+ }): react.JSX.Element;
171
+
172
+ declare const SIZE_CLASSES: {
173
+ sm: string;
174
+ md: string;
175
+ lg: string;
176
+ xl: string;
177
+ };
178
+ declare function Modal({ isOpen, onClose, title, children, size, closeLabel, }: {
179
+ isOpen: boolean;
180
+ onClose: () => void;
181
+ title?: ReactNode;
182
+ children: ReactNode;
183
+ size?: keyof typeof SIZE_CLASSES;
184
+ closeLabel?: string;
185
+ }): react.JSX.Element;
186
+
187
+ declare const ALIGNS: {
188
+ readonly start: "left-0";
189
+ readonly end: "right-0";
190
+ };
191
+ declare const WIDTHS: {
192
+ readonly sm: "w-48";
193
+ readonly md: "w-56";
194
+ readonly lg: "w-72";
195
+ };
196
+ type MenuAlign = keyof typeof ALIGNS;
197
+ type MenuWidth = keyof typeof WIDTHS;
198
+ declare function Menu({ label, trigger, align, width, className, children, }: {
199
+ label: string;
200
+ trigger: ReactNode;
201
+ align?: MenuAlign;
202
+ width?: MenuWidth;
203
+ className?: string;
204
+ children: ReactNode;
205
+ }): react.JSX.Element;
206
+
207
+ type MenuItemTone = "neutral" | "danger";
208
+ type MenuItemOptions = {
209
+ tone?: MenuItemTone;
210
+ className?: string;
211
+ };
212
+ declare function menuItemClass({ tone, className }?: MenuItemOptions): string;
213
+
214
+ declare function PageHeader({ title, subtitle, children, className, }: {
215
+ title: ReactNode;
216
+ subtitle?: ReactNode;
217
+ children?: ReactNode;
218
+ className?: string;
219
+ }): react.JSX.Element;
220
+
221
+ declare function Pagination({ page, pages, onPageChange, previousLabel, nextLabel, pageLabel, label, className, }: {
222
+ page: number;
223
+ pages: number;
224
+ onPageChange: (page: number) => void;
225
+ previousLabel?: string;
226
+ nextLabel?: string;
227
+ pageLabel?: (page: number) => string;
228
+ label?: string;
229
+ className?: string;
230
+ }): react.JSX.Element;
231
+
232
+ type Snackbar = {
233
+ id: string;
234
+ title: string;
235
+ message?: ReactNode;
236
+ tone?: "neutral" | "ok" | "warn" | "danger";
237
+ };
238
+ declare function SnackbarStack({ items, onDismiss, className, }: {
239
+ items: readonly Snackbar[];
240
+ onDismiss?: (id: string) => void;
241
+ className?: string;
242
+ }): react.JSX.Element;
243
+
244
+ declare function StatCard({ label, value, hint, color, attention, className, }: {
245
+ label: string;
246
+ value: ReactNode;
247
+ hint?: string;
248
+ color?: string;
249
+ attention?: boolean;
250
+ className?: string;
251
+ }): react.JSX.Element;
252
+
253
+ type Step = {
254
+ id: string;
255
+ label: string;
256
+ description?: string;
257
+ };
258
+ declare function Stepper({ steps, current, className, }: {
259
+ steps: readonly Step[];
260
+ current: number;
261
+ className?: string;
262
+ }): react.JSX.Element;
263
+
264
+ type Tab = {
265
+ value: string;
266
+ label: ReactNode;
267
+ content: ReactNode;
268
+ disabled?: boolean;
269
+ };
270
+ declare function Tabs({ items, value, onValueChange, label, className, }: {
271
+ items: Tab[];
272
+ value: string;
273
+ onValueChange: (value: string) => void;
274
+ label?: string;
275
+ className?: string;
276
+ }): react.JSX.Element;
277
+
278
+ declare const SIDES: {
279
+ readonly top: "bottom-full left-1/2 mb-2 -translate-x-1/2";
280
+ readonly bottom: "top-full left-1/2 mt-2 -translate-x-1/2";
281
+ readonly left: "right-full top-1/2 mr-2 -translate-y-1/2";
282
+ readonly right: "left-full top-1/2 ml-2 -translate-y-1/2";
283
+ };
284
+ type TooltipSide = keyof typeof SIDES;
285
+ declare function Tooltip({ id, content, side, children, className, }: {
286
+ id: string;
287
+ content: ReactNode;
288
+ side?: TooltipSide;
289
+ children: ReactNode;
290
+ className?: string;
291
+ }): react.JSX.Element;
292
+
293
+ declare const TONES: {
294
+ readonly info: "border-info/35 bg-surface";
295
+ readonly ok: "border-ok/35 bg-surface";
296
+ readonly warn: "border-warn/35 bg-surface";
297
+ readonly danger: "border-danger/35 bg-surface";
298
+ };
299
+ type ToastTone = keyof typeof TONES;
300
+ declare function Toast({ tone, title, children, onDismiss, dismissLabel, className, }: {
301
+ tone?: ToastTone;
302
+ title: string;
303
+ children?: ReactNode;
304
+ onDismiss?: () => void;
305
+ dismissLabel?: string;
306
+ className?: string;
307
+ }): react.JSX.Element;
308
+
309
+ export { Accordion, type AccordionItem, Banner, type BannerTone, Breadcrumb, Callout, type CalloutTone, CardTitle, CodeBlock, type CommandItem, CommandMenu, ConfirmDialog, type Crumb, Drawer, DropdownMenu, Empty, Field, FilterBar, Gallery, ImagePreview, LoadError, Menu, type MenuAlign, type MenuItemOptions, type MenuItemTone, MetricCard, Modal, PageHeader, Pagination, type Snackbar, SnackbarStack, StatCard, type Step, Stepper, type Tab, Tabs, Toast, type ToastTone, Tooltip, type TooltipSide, type TreeNode, TreeView, menuItemClass };
@@ -0,0 +1,4 @@
1
+ export { Accordion, Banner, Breadcrumb, Callout, CardTitle, CommandMenu, Drawer, DropdownMenu, Empty, Field, FilterBar, Gallery, ImagePreview, LoadError, Menu, MetricCard, PageHeader, Pagination, SnackbarStack, StatCard, Stepper, Tabs, Toast, Tooltip, TreeView, menuItemClass } from '../chunk-AHE2576G.js';
2
+ import '../chunk-WWOXGKLF.js';
3
+ //# sourceMappingURL=index.js.map
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
@@ -0,0 +1,113 @@
1
+ import * as react from 'react';
2
+ import { ReactNode } from 'react';
3
+
4
+ type Bar = {
5
+ key: string;
6
+ label: string;
7
+ value: number;
8
+ };
9
+
10
+ declare function BarChart({ data, top, ticks, describe, tooltip, peakKey, zeroStub, }: {
11
+ data: Bar[];
12
+ top: number;
13
+ ticks: number[];
14
+ describe: (bar: Bar) => string;
15
+ tooltip: (bar: Bar) => ReactNode;
16
+ peakKey?: string;
17
+ zeroStub?: boolean;
18
+ }): react.JSX.Element;
19
+
20
+ declare function LineChart({ data, top, ticks, describe, tooltip, area, }: {
21
+ data: Bar[];
22
+ top: number;
23
+ ticks: number[];
24
+ describe: (point: Bar) => string;
25
+ tooltip: (point: Bar) => ReactNode;
26
+ area?: boolean;
27
+ }): react.JSX.Element;
28
+
29
+ type DonutDatum = {
30
+ id: string;
31
+ label: string;
32
+ value: number;
33
+ color: string;
34
+ };
35
+ declare function DonutChart({ data, total, label, children, }: {
36
+ data: readonly DonutDatum[];
37
+ total: number;
38
+ label: string;
39
+ children?: ReactNode;
40
+ }): react.JSX.Element;
41
+
42
+ type AreaPoint = {
43
+ label: string;
44
+ value: number;
45
+ };
46
+ declare function AreaChart({ data, top, label, }: {
47
+ data: readonly AreaPoint[];
48
+ top: number;
49
+ label: string;
50
+ }): react.JSX.Element;
51
+
52
+ declare function Sparkline({ data, describe }: {
53
+ data: Bar[];
54
+ describe: (bar: Bar) => string;
55
+ }): react.JSX.Element;
56
+
57
+ type Column<T = unknown> = {
58
+ key: string;
59
+ label: string;
60
+ width: string;
61
+ align?: "left" | "right";
62
+ render: (item: T) => ReactNode;
63
+ sortable?: boolean;
64
+ sortValue?: (item: T) => string | number;
65
+ };
66
+ declare const GRID_ROW = "grid grid-cols-[var(--cols)] items-center";
67
+ declare function DataTable<T>({ columns, items, rowKey, headerClassName, bodyClassName, loading, empty, className, filter, onFilterChange, sort, onSortChange, }: {
68
+ columns: Column<T>[];
69
+ items?: T[];
70
+ rowKey: (item: T) => string;
71
+ headerClassName?: string;
72
+ bodyClassName?: string;
73
+ loading?: ReactNode;
74
+ empty?: ReactNode;
75
+ className?: string;
76
+ filter?: string;
77
+ onFilterChange?: (value: string) => void;
78
+ sort?: {
79
+ key: string;
80
+ direction: "asc" | "desc";
81
+ };
82
+ onSortChange?: (key: string) => void;
83
+ }): react.JSX.Element;
84
+
85
+ type KanbanCard = {
86
+ id: string;
87
+ title: string;
88
+ description?: ReactNode;
89
+ meta?: ReactNode;
90
+ };
91
+ type KanbanColumn = {
92
+ id: string;
93
+ title: string;
94
+ cards: readonly KanbanCard[];
95
+ };
96
+ declare function KanbanBoard({ columns, className, }: {
97
+ columns: readonly KanbanColumn[];
98
+ className?: string;
99
+ }): react.JSX.Element;
100
+
101
+ type TimelineItem = {
102
+ id: string;
103
+ title: string;
104
+ meta: string;
105
+ children?: ReactNode;
106
+ tone?: "neutral" | "accent" | "ok" | "warn" | "danger";
107
+ };
108
+ declare function Timeline({ items, className, }: {
109
+ items: readonly TimelineItem[];
110
+ className?: string;
111
+ }): react.JSX.Element;
112
+
113
+ export { AreaChart, type AreaPoint, type Bar, BarChart, type Column, DataTable, DonutChart, type DonutDatum, GRID_ROW, KanbanBoard, type KanbanCard, type KanbanColumn, LineChart, Sparkline, Timeline, type TimelineItem };
@@ -0,0 +1,4 @@
1
+ export { AreaChart, BarChart, DataTable, DonutChart, GRID_ROW, KanbanBoard, LineChart, Sparkline, Timeline } from '../chunk-JYNDKPAH.js';
2
+ import '../chunk-WWOXGKLF.js';
3
+ //# sourceMappingURL=index.js.map
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
@@ -0,0 +1,19 @@
1
+ @theme {
2
+ --color-app: light-dark(oklch(0.972 0.006 255), oklch(0.19 0.032 255));
3
+ --color-rail: light-dark(oklch(0.948 0.009 255), oklch(0.15 0.03 255));
4
+ --color-panel: light-dark(oklch(0.948 0.009 255), oklch(0.17 0.03 255));
5
+ --color-surface: light-dark(oklch(1 0 0), oklch(0.235 0.033 255));
6
+ --color-field: light-dark(oklch(0.985 0.004 255), oklch(0.215 0.032 255));
7
+ --color-raised: light-dark(oklch(0.928 0.011 255), oklch(0.3 0.032 255));
8
+ --color-line: light-dark(oklch(0.902 0.013 255), oklch(0.275 0.032 255));
9
+ --color-line-strong: light-dark(oklch(0.845 0.018 255), oklch(0.35 0.031 255));
10
+ --color-ink: light-dark(oklch(0.24 0.04 255), oklch(0.96 0.008 255));
11
+ --color-ink-soft: light-dark(oklch(0.37 0.035 255), oklch(0.82 0.015 255));
12
+ --color-ink-muted: light-dark(oklch(0.52 0.032 255), oklch(0.65 0.022 255));
13
+ --color-ink-dim: light-dark(oklch(0.57 0.028 255), oklch(0.57 0.025 255));
14
+ --color-accent: light-dark(oklch(0.56 0.12 74), oklch(0.79 0.14 80));
15
+ --color-accent-ink: light-dark(oklch(0.47 0.1 72), oklch(0.86 0.13 82));
16
+ --color-accent-soft: light-dark(oklch(0.94 0.045 82), oklch(0.31 0.06 80));
17
+ --color-on-accent: light-dark(oklch(1 0 0), oklch(0.15 0.03 255));
18
+ --font-sans: "Space Grotesk", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
19
+ }
@@ -0,0 +1,60 @@
1
+ type ColorToken = "app" | "rail" | "panel" | "surface" | "field" | "raised" | "line" | "line-strong" | "ink" | "ink-soft" | "ink-muted" | "ink-dim" | "accent" | "accent-ink" | "accent-soft" | "on-accent" | "ok" | "ok-soft" | "warn" | "warn-soft" | "danger" | "danger-soft" | "info" | "info-soft";
2
+ type TextStep = "2xs" | "xs" | "sm" | "base" | "lg" | "xl" | "2xl" | "display";
3
+ type RadiusStep = "xs" | "sm" | "md" | "lg" | "xl";
4
+ type WeightStep = "normal" | "medium" | "bold";
5
+ type TrackingStep = "caps" | "code" | "tight" | "display";
6
+ type ShadowStep = "raised" | "popover" | "modal";
7
+ type EaseStep = "out" | "in-out" | "over";
8
+ type DurationStep = "instant" | "fast" | "base" | "slow";
9
+ type ColorValue = string | {
10
+ light: string;
11
+ dark: string;
12
+ };
13
+ type TypographyConfig = {
14
+ font?: {
15
+ sans?: string;
16
+ mono?: string;
17
+ };
18
+ text?: {
19
+ [K in TextStep]?: string | [string, string | number];
20
+ };
21
+ tracking?: {
22
+ [K in TrackingStep]?: string;
23
+ };
24
+ weight?: {
25
+ [K in WeightStep]?: number;
26
+ };
27
+ };
28
+ type TokenConfig = {
29
+ spacing?: string;
30
+ radius?: {
31
+ [K in RadiusStep]?: string;
32
+ };
33
+ shadow?: {
34
+ [K in ShadowStep]?: string;
35
+ };
36
+ ease?: {
37
+ [K in EaseStep]?: string;
38
+ };
39
+ duration?: {
40
+ [K in DurationStep]?: string;
41
+ };
42
+ };
43
+ type ThemeConfig = {
44
+ colors?: {
45
+ [K in ColorToken]?: ColorValue;
46
+ } & {
47
+ [key: string]: ColorValue | undefined;
48
+ };
49
+ typography?: TypographyConfig;
50
+ tokens?: TokenConfig;
51
+ };
52
+
53
+ type DefineThemeOptions = {
54
+ selector?: string;
55
+ };
56
+ declare function defineTheme(config: ThemeConfig, options?: DefineThemeOptions): string;
57
+
58
+ declare const gavel: ThemeConfig;
59
+
60
+ export { type ColorToken, type ColorValue, type DefineThemeOptions, type DurationStep, type EaseStep, type RadiusStep, type ShadowStep, type TextStep, type ThemeConfig, type TokenConfig, type TrackingStep, type TypographyConfig, type WeightStep, defineTheme, gavel };
@@ -0,0 +1,85 @@
1
+ // src/theme/define-theme.ts
2
+ function color(value) {
3
+ if (typeof value === "string") return value;
4
+ return `light-dark(${value.light}, ${value.dark})`;
5
+ }
6
+ function entries(source) {
7
+ if (!source) return [];
8
+ return Object.entries(source).filter(([, value]) => value !== void 0);
9
+ }
10
+ function defineTheme(config, options = {}) {
11
+ const lines = [];
12
+ const typography = config.typography ?? {};
13
+ const tokens = config.tokens ?? {};
14
+ for (const [name, value] of entries(config.colors)) {
15
+ lines.push(` --color-${name}: ${color(value)};`);
16
+ }
17
+ for (const [name, value] of entries(typography.font)) {
18
+ lines.push(` --font-${name}: ${value};`);
19
+ }
20
+ for (const [step, value] of entries(typography.text)) {
21
+ const [size, lineHeight] = Array.isArray(value) ? value : [value, void 0];
22
+ lines.push(` --text-${step}: ${size};`);
23
+ if (lineHeight !== void 0) {
24
+ lines.push(` --text-${step}--line-height: ${lineHeight};`);
25
+ }
26
+ }
27
+ if (tokens.spacing !== void 0) {
28
+ lines.push(` --spacing: ${tokens.spacing};`);
29
+ }
30
+ for (const [name, value] of entries(typography.tracking)) {
31
+ lines.push(` --tracking-${name}: ${value};`);
32
+ }
33
+ for (const [step, value] of entries(typography.weight)) {
34
+ lines.push(` --font-weight-${step}: ${value};`);
35
+ }
36
+ for (const [step, value] of entries(tokens.radius)) {
37
+ lines.push(` --radius-${step}: ${value};`);
38
+ }
39
+ for (const [step, value] of entries(tokens.shadow)) {
40
+ lines.push(` --shadow-${step}: ${value};`);
41
+ }
42
+ for (const [step, value] of entries(tokens.ease)) {
43
+ lines.push(` --ease-${step}: ${value};`);
44
+ }
45
+ for (const [step, value] of entries(tokens.duration)) {
46
+ lines.push(` --duration-${step}: ${value};`);
47
+ }
48
+ if (lines.length === 0) return "";
49
+ const wrapper = options.selector ?? "@theme";
50
+ return `${wrapper} {
51
+ ${lines.join("\n")}
52
+ }
53
+ `;
54
+ }
55
+
56
+ // src/theme/presets/gavel.ts
57
+ var gavel = {
58
+ typography: {
59
+ font: {
60
+ sans: '"Space Grotesk", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif'
61
+ }
62
+ },
63
+ colors: {
64
+ app: { light: "oklch(0.972 0.006 255)", dark: "oklch(0.19 0.032 255)" },
65
+ rail: { light: "oklch(0.948 0.009 255)", dark: "oklch(0.15 0.03 255)" },
66
+ panel: { light: "oklch(0.948 0.009 255)", dark: "oklch(0.17 0.03 255)" },
67
+ surface: { light: "oklch(1 0 0)", dark: "oklch(0.235 0.033 255)" },
68
+ field: { light: "oklch(0.985 0.004 255)", dark: "oklch(0.215 0.032 255)" },
69
+ raised: { light: "oklch(0.928 0.011 255)", dark: "oklch(0.3 0.032 255)" },
70
+ line: { light: "oklch(0.902 0.013 255)", dark: "oklch(0.275 0.032 255)" },
71
+ "line-strong": { light: "oklch(0.845 0.018 255)", dark: "oklch(0.35 0.031 255)" },
72
+ ink: { light: "oklch(0.24 0.04 255)", dark: "oklch(0.96 0.008 255)" },
73
+ "ink-soft": { light: "oklch(0.37 0.035 255)", dark: "oklch(0.82 0.015 255)" },
74
+ "ink-muted": { light: "oklch(0.52 0.032 255)", dark: "oklch(0.65 0.022 255)" },
75
+ "ink-dim": { light: "oklch(0.57 0.028 255)", dark: "oklch(0.57 0.025 255)" },
76
+ accent: { light: "oklch(0.56 0.12 74)", dark: "oklch(0.79 0.14 80)" },
77
+ "accent-ink": { light: "oklch(0.47 0.1 72)", dark: "oklch(0.86 0.13 82)" },
78
+ "accent-soft": { light: "oklch(0.94 0.045 82)", dark: "oklch(0.31 0.06 80)" },
79
+ "on-accent": { light: "oklch(1 0 0)", dark: "oklch(0.15 0.03 255)" }
80
+ }
81
+ };
82
+
83
+ export { defineTheme, gavel };
84
+ //# sourceMappingURL=index.js.map
85
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/theme/define-theme.ts","../../src/theme/presets/gavel.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import type { ColorValue, ThemeConfig } from \"./types\";\n\nfunction color(value: ColorValue): string {\n if (typeof value === \"string\") return value;\n return `light-dark(${value.light}, ${value.dark})`;\n}\n\nfunction entries<T extends object>(source: T | undefined): [string, unknown][] {\n if (!source) return [];\n return Object.entries(source).filter(([, value]) => value !== undefined);\n}\n\nexport type DefineThemeOptions = { selector?: string };\n\nexport function defineTheme(config: ThemeConfig, options: DefineThemeOptions = {}): string {\n const lines: string[] = [];\n const typography = config.typography ?? {};\n const tokens = config.tokens ?? {};\n\n for (const [name, value] of entries(config.colors)) {\n lines.push(` --color-${name}: ${color(value as ColorValue)};`);\n }\n\n for (const [name, value] of entries(typography.font)) {\n lines.push(` --font-${name}: ${value as string};`);\n }\n\n for (const [step, value] of entries(typography.text)) {\n const [size, lineHeight] = Array.isArray(value) ? value : [value as string, undefined];\n lines.push(` --text-${step}: ${size};`);\n if (lineHeight !== undefined) {\n lines.push(` --text-${step}--line-height: ${lineHeight};`);\n }\n }\n\n if (tokens.spacing !== undefined) {\n lines.push(` --spacing: ${tokens.spacing};`);\n }\n\n for (const [name, value] of entries(typography.tracking)) {\n lines.push(` --tracking-${name}: ${value as string};`);\n }\n\n for (const [step, value] of entries(typography.weight)) {\n lines.push(` --font-weight-${step}: ${value as number};`);\n }\n\n for (const [step, value] of entries(tokens.radius)) {\n lines.push(` --radius-${step}: ${value as string};`);\n }\n\n for (const [step, value] of entries(tokens.shadow)) {\n lines.push(` --shadow-${step}: ${value as string};`);\n }\n\n for (const [step, value] of entries(tokens.ease)) {\n lines.push(` --ease-${step}: ${value as string};`);\n }\n\n for (const [step, value] of entries(tokens.duration)) {\n lines.push(` --duration-${step}: ${value as string};`);\n }\n\n if (lines.length === 0) return \"\";\n\n const wrapper = options.selector ?? \"@theme\";\n\n return `${wrapper} {\\n${lines.join(\"\\n\")}\\n}\\n`;\n}\n","import type { ThemeConfig } from \"../types\";\n\nexport const gavel: ThemeConfig = {\n typography: {\n font: {\n sans: '\"Space Grotesk\", ui-sans-serif, system-ui, -apple-system, \"Segoe UI\", sans-serif',\n },\n },\n colors: {\n app: { light: \"oklch(0.972 0.006 255)\", dark: \"oklch(0.19 0.032 255)\" },\n rail: { light: \"oklch(0.948 0.009 255)\", dark: \"oklch(0.15 0.03 255)\" },\n panel: { light: \"oklch(0.948 0.009 255)\", dark: \"oklch(0.17 0.03 255)\" },\n surface: { light: \"oklch(1 0 0)\", dark: \"oklch(0.235 0.033 255)\" },\n field: { light: \"oklch(0.985 0.004 255)\", dark: \"oklch(0.215 0.032 255)\" },\n raised: { light: \"oklch(0.928 0.011 255)\", dark: \"oklch(0.3 0.032 255)\" },\n\n line: { light: \"oklch(0.902 0.013 255)\", dark: \"oklch(0.275 0.032 255)\" },\n \"line-strong\": { light: \"oklch(0.845 0.018 255)\", dark: \"oklch(0.35 0.031 255)\" },\n\n ink: { light: \"oklch(0.24 0.04 255)\", dark: \"oklch(0.96 0.008 255)\" },\n \"ink-soft\": { light: \"oklch(0.37 0.035 255)\", dark: \"oklch(0.82 0.015 255)\" },\n \"ink-muted\": { light: \"oklch(0.52 0.032 255)\", dark: \"oklch(0.65 0.022 255)\" },\n \"ink-dim\": { light: \"oklch(0.57 0.028 255)\", dark: \"oklch(0.57 0.025 255)\" },\n\n accent: { light: \"oklch(0.56 0.12 74)\", dark: \"oklch(0.79 0.14 80)\" },\n \"accent-ink\": { light: \"oklch(0.47 0.1 72)\", dark: \"oklch(0.86 0.13 82)\" },\n \"accent-soft\": { light: \"oklch(0.94 0.045 82)\", dark: \"oklch(0.31 0.06 80)\" },\n \"on-accent\": { light: \"oklch(1 0 0)\", dark: \"oklch(0.15 0.03 255)\" },\n },\n};\n"]}
@@ -0,0 +1,8 @@
1
+ type Theme = "dark" | "light";
2
+ declare function applyStoredTheme(): void;
3
+ declare function useTheme(): {
4
+ theme: Theme;
5
+ toggle: () => void;
6
+ };
7
+
8
+ export { type Theme, applyStoredTheme, useTheme };
@@ -0,0 +1,3 @@
1
+ export { applyStoredTheme, useTheme } from '../chunk-CGDYSB4G.js';
2
+ //# sourceMappingURL=index.js.map
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}