create-dalila 1.1.13 → 1.2.0

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 (53) hide show
  1. package/package.json +1 -1
  2. package/template/src/components/ui/accordion/accordion.css +90 -0
  3. package/template/src/components/ui/accordion/index.ts +121 -0
  4. package/template/src/components/ui/alert/alert.css +78 -0
  5. package/template/src/components/ui/avatar/avatar.css +45 -0
  6. package/template/src/components/ui/badge/badge.css +71 -0
  7. package/template/src/components/ui/breadcrumb/breadcrumb.css +41 -0
  8. package/template/src/components/ui/button/button.css +135 -0
  9. package/template/src/components/ui/calendar/calendar.css +96 -0
  10. package/template/src/components/ui/calendar/index.ts +157 -0
  11. package/template/src/components/ui/card/card.css +93 -0
  12. package/template/src/components/ui/checkbox/checkbox.css +57 -0
  13. package/template/src/components/ui/chip/chip.css +62 -0
  14. package/template/src/components/ui/collapsible/collapsible.css +61 -0
  15. package/template/src/components/ui/combobox/combobox.css +85 -0
  16. package/template/src/components/ui/combobox/index.ts +181 -0
  17. package/template/src/components/ui/dalila/dalila.css +42 -0
  18. package/template/src/components/ui/dalila-core/dalila-core.css +14 -0
  19. package/template/src/components/ui/dialog/dialog.css +125 -0
  20. package/template/src/components/ui/dialog/index.ts +68 -0
  21. package/template/src/components/ui/drawer/drawer.css +122 -0
  22. package/template/src/components/ui/drawer/index.ts +53 -0
  23. package/template/src/components/ui/dropdown/dropdown.css +87 -0
  24. package/template/src/components/ui/dropdown/index.ts +57 -0
  25. package/template/src/components/ui/dropzone/dropzone.css +47 -0
  26. package/template/src/components/ui/dropzone/index.ts +114 -0
  27. package/template/src/components/ui/empty-state/empty-state.css +33 -0
  28. package/template/src/components/ui/env.ts +4 -0
  29. package/template/src/components/ui/form/form.css +44 -0
  30. package/template/src/components/ui/index.ts +13 -0
  31. package/template/src/components/ui/input/input.css +106 -0
  32. package/template/src/components/ui/layout/layout.css +62 -0
  33. package/template/src/components/ui/pagination/pagination.css +55 -0
  34. package/template/src/components/ui/popover/index.ts +185 -0
  35. package/template/src/components/ui/popover/popover.css +55 -0
  36. package/template/src/components/ui/radio/radio.css +56 -0
  37. package/template/src/components/ui/runtime.ts +514 -0
  38. package/template/src/components/ui/separator/separator.css +38 -0
  39. package/template/src/components/ui/skeleton/skeleton.css +57 -0
  40. package/template/src/components/ui/slider/slider.css +60 -0
  41. package/template/src/components/ui/spinner/spinner.css +38 -0
  42. package/template/src/components/ui/table/table.css +54 -0
  43. package/template/src/components/ui/tabs/index.ts +128 -0
  44. package/template/src/components/ui/tabs/tabs.css +74 -0
  45. package/template/src/components/ui/toast/index.ts +144 -0
  46. package/template/src/components/ui/toast/toast.css +100 -0
  47. package/template/src/components/ui/toggle/toggle.css +90 -0
  48. package/template/src/components/ui/tokens/tokens.css +161 -0
  49. package/template/src/components/ui/tooltip/tooltip.css +53 -0
  50. package/template/src/components/ui/typography/typography.css +81 -0
  51. package/template/src/components/ui/ui-types.ts +238 -0
  52. package/template/src/components/ui/validate.ts +83 -0
  53. package/template/src/style.css +13 -0
@@ -0,0 +1,161 @@
1
+ /* Dalila UI — Design Tokens (Playground-aligned) */
2
+
3
+ :root,
4
+ [data-theme="light"] {
5
+ --d-bg: #ffffff;
6
+ --d-bg-card: #f8f8f8;
7
+ --d-bg-elevated: #f0f0f0;
8
+ --d-fg: #0a0a0a;
9
+ --d-fg-muted: #6b7280;
10
+ --d-accent: #2563eb;
11
+ --d-accent-hover: #1d4ed8;
12
+ --d-border: #e5e5e5;
13
+
14
+ --d-primary-50: #eff6ff;
15
+ --d-primary-100: #dbeafe;
16
+ --d-primary-200: #bfdbfe;
17
+ --d-primary-300: #93c5fd;
18
+ --d-primary-400: #60a5fa;
19
+ --d-primary-500: #3b82f6;
20
+ --d-primary-600: #2563eb;
21
+ --d-primary-700: #1d4ed8;
22
+ --d-primary-800: #1e40af;
23
+ --d-primary-900: #1e3a8a;
24
+
25
+ --d-accent-50: #fff7ed;
26
+ --d-accent-100: #ffedd5;
27
+ --d-accent-200: #fed7aa;
28
+ --d-accent-300: #fdba74;
29
+ --d-accent-400: #fb923c;
30
+ --d-accent-500: #f97316;
31
+ --d-accent-600: #ea580c;
32
+ --d-accent-700: #c2410c;
33
+
34
+ --d-slate-50: #fafafa;
35
+ --d-slate-100: #f4f4f5;
36
+ --d-slate-200: #e4e4e7;
37
+ --d-slate-300: #d4d4d8;
38
+ --d-slate-400: #a1a1aa;
39
+ --d-slate-500: #71717a;
40
+ --d-slate-600: #52525b;
41
+ --d-slate-700: #3f3f46;
42
+ --d-slate-800: #27272a;
43
+ --d-slate-900: #18181b;
44
+ --d-slate-950: #09090b;
45
+
46
+ /* Backward-compatible aliases expected by old examples */
47
+ --d-stone-50: var(--d-slate-50);
48
+ --d-stone-100: var(--d-slate-100);
49
+ --d-stone-200: var(--d-slate-200);
50
+ --d-stone-300: var(--d-slate-300);
51
+ --d-stone-400: var(--d-slate-400);
52
+ --d-stone-500: var(--d-slate-500);
53
+ --d-stone-600: var(--d-slate-600);
54
+ --d-stone-700: var(--d-slate-700);
55
+ --d-stone-800: var(--d-slate-800);
56
+ --d-stone-900: var(--d-slate-900);
57
+ --d-stone-950: var(--d-slate-950);
58
+
59
+ --d-success: #16a34a;
60
+ --d-success-light: rgba(22, 163, 74, 0.12);
61
+ --d-error: #dc2626;
62
+ --d-error-light: rgba(220, 38, 38, 0.12);
63
+ --d-warning: #d97706;
64
+ --d-warning-light: rgba(217, 119, 6, 0.12);
65
+ --d-info: #0284c7;
66
+ --d-info-light: rgba(2, 132, 199, 0.12);
67
+
68
+ --d-ring: rgba(37, 99, 235, 0.22);
69
+
70
+ --d-font-sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
71
+ --d-font-mono: "JetBrains Mono", "Fira Code", "SF Mono", monospace;
72
+
73
+ --d-text-xs: 0.75rem;
74
+ --d-text-sm: 0.8125rem;
75
+ --d-text-base: 0.875rem;
76
+ --d-text-lg: 1rem;
77
+ --d-text-xl: 1.25rem;
78
+ --d-text-2xl: 1.5rem;
79
+ --d-text-3xl: 2rem;
80
+
81
+ --d-font-normal: 400;
82
+ --d-font-medium: 500;
83
+ --d-font-semibold: 600;
84
+ --d-font-bold: 700;
85
+
86
+ --d-leading: 1.6;
87
+
88
+ --d-space-1: 0.25rem;
89
+ --d-space-2: 0.5rem;
90
+ --d-space-3: 0.75rem;
91
+ --d-space-4: 1rem;
92
+ --d-space-5: 1.25rem;
93
+ --d-space-6: 1.5rem;
94
+ --d-space-8: 2rem;
95
+ --d-space-10: 2.5rem;
96
+ --d-space-12: 3rem;
97
+
98
+ --d-radius-sm: 6px;
99
+ --d-radius-md: 8px;
100
+ --d-radius-lg: 12px;
101
+ --d-radius-xl: 14px;
102
+ --d-radius-full: 9999px;
103
+
104
+ --d-shadow-xs: none;
105
+ --d-shadow-sm: none;
106
+ --d-shadow-md: 0 10px 26px rgba(0, 0, 0, 0.08);
107
+ --d-shadow-lg: 0 18px 42px rgba(0, 0, 0, 0.12);
108
+ --d-shadow-glow: 0 0 0 1px var(--d-accent);
109
+
110
+ --d-ease: cubic-bezier(0.2, 0.8, 0.2, 1);
111
+ --d-ease-bounce: cubic-bezier(0.34, 1.56, 0.64, 1);
112
+ --d-duration-fast: 120ms;
113
+ --d-duration: 180ms;
114
+ --d-duration-slow: 280ms;
115
+
116
+ --d-surface-page: var(--d-bg);
117
+ --d-surface-card: var(--d-bg-card);
118
+ --d-surface-raised: var(--d-bg-elevated);
119
+ --d-surface-overlay: rgba(0, 0, 0, 0.4);
120
+
121
+ --d-text-primary: var(--d-fg);
122
+ --d-text-secondary: var(--d-fg-muted);
123
+ --d-text-muted: var(--d-fg-muted);
124
+ --d-text-inverse: #ffffff;
125
+
126
+ --d-border-color: var(--d-border);
127
+
128
+ --d-gradient-brand: linear-gradient(135deg, var(--d-primary-500), #8b5cf6);
129
+
130
+ --d-z-dropdown: 50;
131
+ --d-z-sticky: 100;
132
+ --d-z-overlay: 200;
133
+ --d-z-modal: 300;
134
+ --d-z-toast: 400;
135
+ --d-z-tooltip: 500;
136
+ }
137
+
138
+ [data-theme="dark"] {
139
+ --d-bg: #0a0a0a;
140
+ --d-bg-card: #141414;
141
+ --d-bg-elevated: #1a1a1a;
142
+ --d-fg: #fafafa;
143
+ --d-fg-muted: #737373;
144
+ --d-accent: #3b82f6;
145
+ --d-accent-hover: #2563eb;
146
+ --d-border: #262626;
147
+
148
+ --d-success: #22c55e;
149
+ --d-success-light: rgba(34, 197, 94, 0.14);
150
+ --d-error: #ef4444;
151
+ --d-error-light: rgba(239, 68, 68, 0.14);
152
+ --d-warning: #f59e0b;
153
+ --d-warning-light: rgba(245, 158, 11, 0.14);
154
+ --d-info: #38bdf8;
155
+ --d-info-light: rgba(56, 189, 248, 0.14);
156
+
157
+ --d-ring: rgba(59, 130, 246, 0.35);
158
+ --d-shadow-md: 0 12px 32px rgba(0, 0, 0, 0.35);
159
+ --d-shadow-lg: 0 20px 48px rgba(0, 0, 0, 0.45);
160
+ --d-surface-overlay: rgba(0, 0, 0, 0.65);
161
+ }
@@ -0,0 +1,53 @@
1
+ /* Dalila UI — Tooltip */
2
+
3
+ .d-tooltip {
4
+ position: relative;
5
+ }
6
+
7
+ .d-tooltip::after {
8
+ content: attr(data-tooltip);
9
+ position: absolute;
10
+ bottom: calc(100% + 6px);
11
+ left: 50%;
12
+ transform: translateX(-50%);
13
+ padding: var(--d-space-1) var(--d-space-2);
14
+ font-family: var(--d-font-sans);
15
+ font-size: var(--d-text-xs);
16
+ font-weight: var(--d-font-medium);
17
+ color: #fff;
18
+ background: var(--d-slate-900);
19
+ border-radius: var(--d-radius-sm);
20
+ white-space: nowrap;
21
+ pointer-events: none;
22
+ opacity: 0;
23
+ transition: opacity var(--d-duration-fast) ease;
24
+ z-index: var(--d-z-tooltip);
25
+ }
26
+
27
+ [data-theme="light"] .d-tooltip::after {
28
+ background: var(--d-slate-800);
29
+ }
30
+
31
+ .d-tooltip:hover::after {
32
+ opacity: 1;
33
+ }
34
+
35
+ .d-tooltip-bottom::after {
36
+ bottom: auto;
37
+ top: calc(100% + 6px);
38
+ }
39
+
40
+ .d-tooltip-left::after {
41
+ bottom: auto;
42
+ top: 50%;
43
+ left: auto;
44
+ right: calc(100% + 6px);
45
+ transform: translateY(-50%);
46
+ }
47
+
48
+ .d-tooltip-right::after {
49
+ bottom: auto;
50
+ top: 50%;
51
+ left: calc(100% + 6px);
52
+ transform: translateY(-50%);
53
+ }
@@ -0,0 +1,81 @@
1
+ /* Dalila UI — Typography */
2
+
3
+ .d-h1, .d-h2, .d-h3, .d-h4, .d-h5, .d-h6 {
4
+ font-family: var(--d-font-sans);
5
+ font-weight: var(--d-font-bold);
6
+ color: var(--d-text-primary);
7
+ line-height: 1.3;
8
+ margin: 0;
9
+ }
10
+
11
+ .d-h1 { font-size: var(--d-text-3xl); letter-spacing: -0.02em; }
12
+ .d-h2 { font-size: var(--d-text-2xl); letter-spacing: -0.01em; }
13
+ .d-h3 { font-size: var(--d-text-xl); }
14
+ .d-h4 { font-size: var(--d-text-lg); }
15
+ .d-h5 { font-size: var(--d-text-base); font-weight: var(--d-font-semibold); }
16
+ .d-h6 { font-size: var(--d-text-sm); font-weight: var(--d-font-semibold); }
17
+
18
+ .d-text {
19
+ font-family: var(--d-font-sans);
20
+ font-size: var(--d-text-base);
21
+ color: var(--d-text-primary);
22
+ line-height: var(--d-leading);
23
+ margin: 0;
24
+ }
25
+
26
+ .d-text-xs { font-size: var(--d-text-xs); }
27
+ .d-text-sm { font-size: var(--d-text-sm); }
28
+ .d-text-lg { font-size: var(--d-text-lg); }
29
+ .d-text-xl { font-size: var(--d-text-xl); }
30
+ .d-text-muted { color: var(--d-text-muted); }
31
+ .d-text-accent { color: var(--d-accent); }
32
+ .d-text-success { color: var(--d-success); }
33
+ .d-text-error { color: var(--d-error); }
34
+ .d-text-warning { color: var(--d-warning); }
35
+ .d-text-mono { font-family: var(--d-font-mono); }
36
+ .d-text-bold { font-weight: var(--d-font-bold); }
37
+ .d-text-semibold { font-weight: var(--d-font-semibold); }
38
+ .d-text-medium { font-weight: var(--d-font-medium); }
39
+
40
+ .d-link {
41
+ color: var(--d-accent);
42
+ text-decoration: none;
43
+ transition: color var(--d-duration-fast) ease;
44
+ }
45
+
46
+ .d-link:hover {
47
+ color: var(--d-accent-hover);
48
+ text-decoration: underline;
49
+ }
50
+
51
+ .d-link-muted {
52
+ color: var(--d-text-muted);
53
+ }
54
+
55
+ .d-link-muted:hover {
56
+ color: var(--d-text-primary);
57
+ }
58
+
59
+ .d-code {
60
+ font-family: var(--d-font-mono);
61
+ font-size: 0.875em;
62
+ padding: 1px 5px;
63
+ background: var(--d-surface-raised);
64
+ border-radius: var(--d-radius-sm);
65
+ color: var(--d-accent);
66
+ }
67
+
68
+ .d-kbd {
69
+ display: inline-flex;
70
+ align-items: center;
71
+ justify-content: center;
72
+ min-width: 1.5em;
73
+ padding: 0.125rem 0.375rem;
74
+ font-family: var(--d-font-mono);
75
+ font-size: var(--d-text-xs);
76
+ color: var(--d-text-muted);
77
+ background: var(--d-surface-raised);
78
+ border: 1px solid var(--d-border-color);
79
+ border-radius: var(--d-radius-sm);
80
+ box-shadow: 0 1px 0 var(--d-border-color);
81
+ }
@@ -0,0 +1,238 @@
1
+ import type { Signal } from "../../core/signal.js";
2
+
3
+ // ── Dialog ──────────────────────────────────────────────────────────
4
+
5
+ export interface DialogOptions {
6
+ closeOnBackdrop?: boolean;
7
+ closeOnEscape?: boolean;
8
+ }
9
+
10
+ export interface Dialog {
11
+ open: Signal<boolean>;
12
+ show(): void;
13
+ close(): void;
14
+ toggle(): void;
15
+ _attachTo(el: HTMLDialogElement): void;
16
+ }
17
+
18
+ // ── Drawer ──────────────────────────────────────────────────────────
19
+
20
+ export type DrawerSide = "right" | "left" | "bottom";
21
+
22
+ export interface DrawerOptions extends DialogOptions {
23
+ side?: DrawerSide;
24
+ }
25
+
26
+ export interface Drawer extends Dialog {
27
+ side: Signal<DrawerSide>;
28
+ }
29
+
30
+ // ── Toast ───────────────────────────────────────────────────────────
31
+
32
+ export type ToastVariant = "success" | "error" | "warning" | "info";
33
+ export type ToastPosition =
34
+ | "top-right"
35
+ | "top-left"
36
+ | "bottom-right"
37
+ | "bottom-left"
38
+ | "top-center"
39
+ | "bottom-center";
40
+
41
+ export interface ToastItem {
42
+ id: string;
43
+ variant: ToastVariant;
44
+ title: string;
45
+ text?: string;
46
+ variantClass: string;
47
+ icon: string;
48
+ }
49
+
50
+ export interface ToastOptions {
51
+ position?: ToastPosition;
52
+ duration?: number;
53
+ maxToasts?: number;
54
+ }
55
+
56
+ export interface Toast {
57
+ items: Signal<ToastItem[]>;
58
+ activeVariant: Signal<ToastVariant | "idle">;
59
+ containerClass: Signal<string>;
60
+ show(variant: ToastVariant, title: string, text?: string, duration?: number): string;
61
+ success(title: string, text?: string): string;
62
+ error(title: string, text?: string): string;
63
+ warning(title: string, text?: string): string;
64
+ info(title: string, text?: string): string;
65
+ dismiss(id: string): void;
66
+ clear(): void;
67
+ }
68
+
69
+ // ── Tabs ────────────────────────────────────────────────────────────
70
+
71
+ export interface TabsOptions {
72
+ initial?: string;
73
+ orientation?: "horizontal" | "vertical";
74
+ }
75
+
76
+ export interface Tabs {
77
+ active: Signal<string>;
78
+ select(tabId: string): void;
79
+ isActive(tabId: string): boolean;
80
+ handleClick(ev: Event): void;
81
+ _attachTo(el: HTMLElement): void;
82
+ }
83
+
84
+ export interface TabBindings {
85
+ tabClass: Signal<string>;
86
+ selected: Signal<string>;
87
+ visible: Signal<boolean>;
88
+ }
89
+
90
+ // ── Dropdown ────────────────────────────────────────────────────────
91
+
92
+ export interface DropdownOptions {
93
+ closeOnSelect?: boolean;
94
+ }
95
+
96
+ export interface Dropdown {
97
+ open: Signal<boolean>;
98
+ toggle(ev?: Event): void;
99
+ close(): void;
100
+ select(ev?: Event): void;
101
+ _attachTo(el: HTMLElement): void;
102
+ }
103
+
104
+ // ── Combobox ────────────────────────────────────────────────────────
105
+
106
+ export interface ComboboxOption {
107
+ value: string;
108
+ label: string;
109
+ }
110
+
111
+ export interface ComboboxOptions {
112
+ options: ComboboxOption[];
113
+ placeholder?: string;
114
+ name?: string;
115
+ }
116
+
117
+ export interface Combobox {
118
+ open: Signal<boolean>;
119
+ query: Signal<string>;
120
+ value: Signal<string>;
121
+ label: Signal<string>;
122
+ filtered: Signal<ComboboxOption[]>;
123
+ highlightedIndex: Signal<number>;
124
+ show(): void;
125
+ close(): void;
126
+ toggle(): void;
127
+ handleInput(ev: Event): void;
128
+ handleSelect(ev: Event): void;
129
+ handleKeydown(ev: KeyboardEvent): void;
130
+ _attachTo(el: HTMLElement): void;
131
+ }
132
+
133
+ // ── Accordion ───────────────────────────────────────────────────────
134
+
135
+ export interface AccordionOptions {
136
+ single?: boolean;
137
+ initial?: string[];
138
+ }
139
+
140
+ export interface Accordion {
141
+ openItems: Signal<Set<string>>;
142
+ toggle(itemId: string): void;
143
+ open(itemId: string): void;
144
+ close(itemId: string): void;
145
+ isOpen(itemId: string): Signal<boolean>;
146
+ _attachTo(el: HTMLElement): void;
147
+ }
148
+
149
+ // ── Calendar ────────────────────────────────────────────────────────
150
+
151
+ export interface CalendarDay {
152
+ date: number;
153
+ month: "prev" | "current" | "next";
154
+ fullDate: Date;
155
+ isToday: boolean;
156
+ isSelected: boolean;
157
+ disabled: boolean;
158
+ }
159
+
160
+ export interface CalendarOptions {
161
+ initial?: Date;
162
+ min?: Date;
163
+ max?: Date;
164
+ dayLabels?: string[];
165
+ monthLabels?: string[];
166
+ }
167
+
168
+ export interface Calendar {
169
+ year: Signal<number>;
170
+ month: Signal<number>;
171
+ selected: Signal<Date | null>;
172
+ title: Signal<string>;
173
+ days: Signal<CalendarDay[]>;
174
+ dayLabels: string[];
175
+ prev(): void;
176
+ next(): void;
177
+ select(date: Date): void;
178
+ handleDayClick(ev: Event): void;
179
+ }
180
+
181
+ // ── Dropzone ────────────────────────────────────────────────────────
182
+
183
+ export interface DropzoneOptions {
184
+ accept?: string;
185
+ multiple?: boolean;
186
+ maxFiles?: number;
187
+ maxSize?: number;
188
+ }
189
+
190
+ export interface Dropzone {
191
+ dragging: Signal<boolean>;
192
+ files: Signal<File[]>;
193
+ browse(): void;
194
+ handleClick(): void;
195
+ handleDragover(ev: DragEvent): void;
196
+ handleDragleave(): void;
197
+ handleDrop(ev: DragEvent): void;
198
+ _attachTo(el: HTMLElement): void;
199
+ }
200
+
201
+ // ── Popover ─────────────────────────────────────────────────────────
202
+
203
+ export type PopoverPlacement =
204
+ | "top"
205
+ | "bottom"
206
+ | "left"
207
+ | "right"
208
+ | "top-start"
209
+ | "bottom-start";
210
+
211
+ export interface PopoverOptions {
212
+ placement?: PopoverPlacement;
213
+ gap?: number;
214
+ viewportPadding?: number;
215
+ }
216
+
217
+ export interface Popover {
218
+ open: Signal<boolean>;
219
+ placement: Signal<PopoverPlacement>;
220
+ show(): void;
221
+ hide(): void;
222
+ toggle(): void;
223
+ position(trigger: HTMLElement, popoverEl: HTMLElement): void;
224
+ _attachTo(trigger: HTMLElement, popoverEl: HTMLElement): void;
225
+ }
226
+
227
+ // ── Mount helpers ───────────────────────────────────────────────────
228
+
229
+ export interface TabsMount {
230
+ api: Tabs;
231
+ bindings: [string, string][];
232
+ }
233
+
234
+ export interface PopoverMount {
235
+ api: Popover;
236
+ triggerId?: string;
237
+ panelId?: string;
238
+ }
@@ -0,0 +1,83 @@
1
+ // ── Prop Validation ─────────────────────────────────────────────────
2
+
3
+ const VALID_TOAST_POSITIONS = new Set([
4
+ "top-right", "top-left", "bottom-right", "bottom-left", "top-center", "bottom-center",
5
+ ]);
6
+
7
+ const VALID_POPOVER_PLACEMENTS = new Set([
8
+ "top", "bottom", "left", "right", "top-start", "bottom-start",
9
+ ]);
10
+
11
+ const VALID_DRAWER_SIDES = new Set(["right", "left", "bottom"]);
12
+
13
+ function warn(component: string, message: string): void {
14
+ console.warn(`[Dalila] ${component}: ${message}`);
15
+ }
16
+
17
+ function warnInvalidType(component: string, prop: string, expected: string, got: unknown): void {
18
+ warn(component, `"${prop}" expected ${expected}, got ${typeof got} (${String(got)})`);
19
+ }
20
+
21
+ export function validateDialogOptions(opts: Record<string, unknown>): void {
22
+ if (opts.closeOnBackdrop !== undefined && typeof opts.closeOnBackdrop !== "boolean") {
23
+ warnInvalidType("createDialog", "closeOnBackdrop", "boolean", opts.closeOnBackdrop);
24
+ }
25
+ if (opts.closeOnEscape !== undefined && typeof opts.closeOnEscape !== "boolean") {
26
+ warnInvalidType("createDialog", "closeOnEscape", "boolean", opts.closeOnEscape);
27
+ }
28
+ }
29
+
30
+ export function validateDrawerOptions(opts: Record<string, unknown>): void {
31
+ validateDialogOptions(opts);
32
+ if (opts.side !== undefined && !VALID_DRAWER_SIDES.has(opts.side as string)) {
33
+ warn("createDrawer", `"side" must be one of "right"|"left"|"bottom", got "${String(opts.side)}"`);
34
+ }
35
+ }
36
+
37
+ export function validateToastOptions(opts: Record<string, unknown>): void {
38
+ if (opts.position !== undefined && !VALID_TOAST_POSITIONS.has(opts.position as string)) {
39
+ warn("createToast", `"position" must be a valid ToastPosition, got "${String(opts.position)}"`);
40
+ }
41
+ if (opts.duration !== undefined && (typeof opts.duration !== "number" || opts.duration < 0)) {
42
+ warn("createToast", `"duration" must be a number >= 0, got ${String(opts.duration)}`);
43
+ }
44
+ if (opts.maxToasts !== undefined && (typeof opts.maxToasts !== "number" || opts.maxToasts <= 0)) {
45
+ warn("createToast", `"maxToasts" must be a number > 0, got ${String(opts.maxToasts)}`);
46
+ }
47
+ }
48
+
49
+ export function validatePopoverOptions(opts: Record<string, unknown>): void {
50
+ if (opts.placement !== undefined && !VALID_POPOVER_PLACEMENTS.has(opts.placement as string)) {
51
+ warn("createPopover", `"placement" must be a valid PopoverPlacement, got "${String(opts.placement)}"`);
52
+ }
53
+ if (opts.gap !== undefined && (typeof opts.gap !== "number" || opts.gap < 0)) {
54
+ warn("createPopover", `"gap" must be a number >= 0, got ${String(opts.gap)}`);
55
+ }
56
+ if (opts.viewportPadding !== undefined && (typeof opts.viewportPadding !== "number" || opts.viewportPadding < 0)) {
57
+ warn("createPopover", `"viewportPadding" must be a number >= 0, got ${String(opts.viewportPadding)}`);
58
+ }
59
+ }
60
+
61
+ export function validateDropzoneOptions(opts: Record<string, unknown>): void {
62
+ if (opts.maxFiles !== undefined && (typeof opts.maxFiles !== "number" || opts.maxFiles <= 0)) {
63
+ warn("createDropzone", `"maxFiles" must be a number > 0, got ${String(opts.maxFiles)}`);
64
+ }
65
+ if (opts.maxSize !== undefined && (typeof opts.maxSize !== "number" || opts.maxSize <= 0)) {
66
+ warn("createDropzone", `"maxSize" must be a number > 0, got ${String(opts.maxSize)}`);
67
+ }
68
+ }
69
+
70
+ export function validateCalendarOptions(opts: Record<string, unknown>): void {
71
+ const min = opts.min as Date | undefined;
72
+ const max = opts.max as Date | undefined;
73
+ if (min && max && min > max) {
74
+ warn("createCalendar", `"min" must be before "max"`);
75
+ }
76
+ }
77
+
78
+ export function validateComboboxOptions(opts: Record<string, unknown>): void {
79
+ const options = opts.options;
80
+ if (!Array.isArray(options) || options.length === 0) {
81
+ warn("createCombobox", `"options" must be a non-empty array`);
82
+ }
83
+ }
@@ -1,3 +1,16 @@
1
+ /**
2
+ * Dalila UI Components
3
+ *
4
+ * To use Dalila UI components, import the necessary styles:
5
+ *
6
+ * @import './components/ui/button/button.css';
7
+ * @import './components/ui/card/card.css';
8
+ * @import './components/ui/dialog/dialog.css';
9
+ *
10
+ * Or import all styles at once:
11
+ * @import './components/ui/dalila/dalila.css';
12
+ */
13
+
1
14
  * {
2
15
  box-sizing: border-box;
3
16
  margin: 0;