@jameskabz/nextcraft-ui 0.4.0 → 0.6.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 (59) hide show
  1. package/README.md +94 -0
  2. package/dist/chunk-6F7FN2ZF.js +671 -0
  3. package/dist/chunk-6F7FN2ZF.js.map +1 -0
  4. package/dist/chunk-7Q4Z47HT.js +657 -0
  5. package/dist/chunk-7Q4Z47HT.js.map +1 -0
  6. package/dist/chunk-7SKDTIEK.js +49 -0
  7. package/dist/chunk-7SKDTIEK.js.map +1 -0
  8. package/dist/chunk-FEFH5O5K.js +49 -0
  9. package/dist/chunk-FEFH5O5K.js.map +1 -0
  10. package/dist/chunk-M2EKVXB6.js +127 -0
  11. package/dist/chunk-M2EKVXB6.js.map +1 -0
  12. package/dist/chunk-SBLIF6UU.js +1029 -0
  13. package/dist/chunk-SBLIF6UU.js.map +1 -0
  14. package/dist/chunk-VQ6T3HIX.js +9 -0
  15. package/dist/chunk-VQ6T3HIX.js.map +1 -0
  16. package/dist/chunk-YVZL4GET.js +328 -0
  17. package/dist/chunk-YVZL4GET.js.map +1 -0
  18. package/dist/chunk-ZRV4Y374.js +582 -0
  19. package/dist/chunk-ZRV4Y374.js.map +1 -0
  20. package/dist/craft/components.cjs +1838 -0
  21. package/dist/craft/components.cjs.map +1 -0
  22. package/dist/craft/components.d.cts +369 -0
  23. package/dist/craft/components.d.ts +369 -0
  24. package/dist/craft/components.js +78 -0
  25. package/dist/craft/components.js.map +1 -0
  26. package/dist/craft/forms.cjs +1376 -0
  27. package/dist/craft/forms.cjs.map +1 -0
  28. package/dist/craft/forms.d.cts +101 -0
  29. package/dist/craft/forms.d.ts +101 -0
  30. package/dist/craft/forms.js +14 -0
  31. package/dist/craft/forms.js.map +1 -0
  32. package/dist/craft/layout.cjs +410 -0
  33. package/dist/craft/layout.cjs.map +1 -0
  34. package/dist/craft/layout.d.cts +170 -0
  35. package/dist/craft/layout.d.ts +170 -0
  36. package/dist/craft/layout.js +27 -0
  37. package/dist/craft/layout.js.map +1 -0
  38. package/dist/craft/table.cjs +662 -0
  39. package/dist/craft/table.cjs.map +1 -0
  40. package/dist/craft/table.d.cts +99 -0
  41. package/dist/craft/table.d.ts +99 -0
  42. package/dist/craft/table.js +15 -0
  43. package/dist/craft/table.js.map +1 -0
  44. package/dist/craft/theme.cjs +166 -0
  45. package/dist/craft/theme.cjs.map +1 -0
  46. package/dist/craft/theme.d.cts +10 -0
  47. package/dist/craft/theme.d.ts +10 -0
  48. package/dist/craft/theme.js +12 -0
  49. package/dist/craft/theme.js.map +1 -0
  50. package/dist/index.cjs +2374 -317
  51. package/dist/index.cjs.map +1 -1
  52. package/dist/index.d.cts +10 -277
  53. package/dist/index.d.ts +10 -277
  54. package/dist/index.js +92 -1347
  55. package/dist/index.js.map +1 -1
  56. package/dist/styles.css +359 -4
  57. package/dist/theme-context-EVI9PfKv.d.cts +22 -0
  58. package/dist/theme-context-EVI9PfKv.d.ts +22 -0
  59. package/package.json +30 -1
package/dist/index.js CHANGED
@@ -1,1369 +1,113 @@
1
- // src/utils/cn.ts
2
- function cn(...values) {
3
- return values.filter(Boolean).join(" ");
4
- }
5
-
6
- // src/components/craft-button.tsx
7
- import { jsx } from "react/jsx-runtime";
8
- var sizeClasses = {
9
- sm: "h-9 px-4 text-xs",
10
- md: "h-11 px-6 text-sm",
11
- lg: "h-13 px-8 text-base"
12
- };
13
- var variantClasses = {
14
- solid: "bg-gradient-to-br from-[rgb(var(--nc-accent-1))] via-[rgb(var(--nc-accent-2))] to-[rgb(var(--nc-accent-3))] text-white shadow-[0_12px_30px_rgb(var(--nc-accent-1)/0.45)] hover:shadow-[0_16px_36px_rgb(var(--nc-accent-1)/0.6)] hover:scale-[1.02] active:scale-[0.98]",
15
- ghost: "bg-[color:rgb(var(--nc-surface)/0.12)] text-[rgb(var(--nc-fg))] hover:bg-[color:rgb(var(--nc-surface)/0.18)] backdrop-blur-sm border border-[rgb(var(--nc-border)/0.35)] hover:border-[color:rgb(var(--nc-border)/0.5)]",
16
- outline: "bg-transparent text-[color:rgb(var(--nc-accent-1))] border-2 border-[color:rgb(var(--nc-accent-1)/0.5)] hover:border-[color:rgb(var(--nc-accent-1))] hover:bg-[color:rgb(var(--nc-accent-1)/0.1)]",
17
- gradient: "bg-gradient-to-r from-[rgb(var(--nc-accent-1))] via-[rgb(var(--nc-accent-2))] to-[rgb(var(--nc-accent-3))] text-white shadow-[0_12px_30px_rgb(var(--nc-accent-2)/0.45)] hover:shadow-[0_16px_36px_rgb(var(--nc-accent-2)/0.6)] hover:scale-[1.02] active:scale-[0.98]"
18
- };
19
- function CraftButton({
20
- className,
21
- variant = "solid",
22
- size = "md",
23
- glow = true,
24
- tone,
25
- disabled,
26
- ...props
27
- }) {
28
- return /* @__PURE__ */ jsx(
29
- "button",
30
- {
31
- className: cn(
32
- "relative inline-flex items-center justify-center gap-2 rounded-xl font-semibold tracking-wide transition-all duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[rgb(var(--nc-accent-1)/0.6)] focus-visible:ring-offset-2 focus-visible:ring-offset-slate-900 disabled:opacity-50 disabled:cursor-not-allowed disabled:hover:scale-100",
33
- sizeClasses[size],
34
- variantClasses[variant],
35
- glow && (variant === "solid" || variant === "gradient") ? "before:absolute before:-inset-1 before:rounded-xl before:bg-linear-to-r before:from-[rgb(var(--nc-accent-1)/0.2)] before:via-[rgb(var(--nc-accent-2)/0.2)] before:to-[rgb(var(--nc-accent-3)/0.2)] before:blur-xl before:-z-10 before:opacity-0 hover:before:opacity-100 before:transition-opacity" : "",
36
- className
37
- ),
38
- "data-nc-theme": tone,
39
- disabled,
40
- ...props
41
- }
42
- );
43
- }
44
-
45
- // src/components/glass-card.tsx
46
- import { jsx as jsx2 } from "react/jsx-runtime";
47
- var intensityClasses = {
48
- subtle: "backdrop-blur-md bg-opacity-50",
49
- medium: "backdrop-blur-xl bg-opacity-70",
50
- strong: "backdrop-blur-2xl bg-opacity-90"
51
- };
52
- function GlassCard({
53
- className,
54
- tone,
55
- intensity = "medium",
56
- bordered = true,
57
- children,
58
- ...props
59
- }) {
60
- return /* @__PURE__ */ jsx2(
61
- "div",
62
- {
63
- className: cn(
64
- "relative overflow-hidden rounded-3xl p-6 text-[rgb(var(--nc-fg))]",
65
- "shadow-[0_8px_32px_rgba(0,0,0,0.3)]",
66
- "transition-all duration-300",
67
- "hover:shadow-[0_8px_40px_rgba(0,0,0,0.4)]",
68
- intensityClasses[intensity],
69
- "bg-linear-to-br from-[rgb(var(--nc-accent-1)/0.15)] via-[rgb(var(--nc-accent-2)/0.10)] to-[rgb(var(--nc-accent-3)/0.15)]",
70
- "border-[rgb(var(--nc-accent-1)/0.3)]",
71
- bordered ? "border-2" : "border-0",
72
- "before:absolute before:inset-0 before:bg-linear-to-br before:from-white/10 before:to-transparent before:opacity-0 hover:before:opacity-100 before:transition-opacity before:duration-300",
73
- className
74
- ),
75
- "data-nc-theme": tone,
76
- ...props,
77
- children: /* @__PURE__ */ jsx2("div", { className: "relative z-10", children })
78
- }
79
- );
80
- }
81
-
82
- // src/components/craft-input.tsx
83
- import * as React from "react";
84
- import { jsx as jsx3, jsxs } from "react/jsx-runtime";
85
- var inputSizeClasses = {
86
- sm: "h-10 px-4 text-sm",
87
- md: "h-12 px-5 text-base",
88
- lg: "h-14 px-6 text-lg"
89
- };
90
- var CraftInput = React.forwardRef(
91
- ({ className, tone, inputSize = "md", glow = true, icon, ...props }, ref) => {
92
- return /* @__PURE__ */ jsxs("div", { className: "relative w-full", "data-nc-theme": tone, children: [
93
- icon && /* @__PURE__ */ jsx3("div", { className: "absolute left-4 top-1/2 -translate-y-1/2 text-[rgb(var(--nc-fg-soft))]", children: icon }),
94
- /* @__PURE__ */ jsx3(
95
- "input",
96
- {
97
- ref,
98
- className: cn(
99
- "w-full rounded-2xl border-2 bg-[rgb(var(--nc-surface)/0.08)] text-[rgb(var(--nc-fg))] backdrop-blur-xl",
100
- "shadow-[inset_0_2px_8px_rgba(0,0,0,0.3)]",
101
- "focus:outline-none focus:ring-4",
102
- "transition-all duration-300",
103
- "disabled:opacity-50 disabled:cursor-not-allowed",
104
- inputSizeClasses[inputSize],
105
- "border-[rgb(var(--nc-border)/0.35)]",
106
- "focus:border-[rgb(var(--nc-accent-1)/0.8)] focus:ring-[rgb(var(--nc-accent-1)/0.3)]",
107
- "placeholder:text-[rgb(var(--nc-fg-soft))]",
108
- glow ? "focus:shadow-[0_0_30px_-5px_var(--glow-color)]" : "",
109
- icon ? "pl-12" : "",
110
- className
111
- ),
112
- style: {
113
- "--glow-color": "rgb(var(--nc-accent-1) / 0.5)"
114
- },
115
- ...props
116
- }
117
- )
118
- ] });
119
- }
120
- );
121
- CraftInput.displayName = "CraftInput";
122
-
123
- // src/components/craft-textarea.tsx
124
- import * as React2 from "react";
125
- import { jsx as jsx4 } from "react/jsx-runtime";
126
- var CraftTextarea = React2.forwardRef(
127
- ({ className, tone, rows = 4, ...props }, ref) => {
128
- return /* @__PURE__ */ jsx4("div", { className: "relative w-full", "data-nc-theme": tone, children: /* @__PURE__ */ jsx4(
129
- "textarea",
130
- {
131
- ref,
132
- rows,
133
- className: cn(
134
- "w-full rounded-2xl border-2 bg-[rgb(var(--nc-surface)/0.08)] text-[rgb(var(--nc-fg))] backdrop-blur-xl",
135
- "shadow-[inset_0_2px_8px_rgba(0,0,0,0.3)]",
136
- "focus:outline-none focus:ring-4",
137
- "transition-all duration-300",
138
- "disabled:opacity-50 disabled:cursor-not-allowed",
139
- "border-[rgb(var(--nc-border)/0.35)]",
140
- "focus:border-[rgb(var(--nc-accent-1)/0.8)] focus:ring-[rgb(var(--nc-accent-1)/0.3)]",
141
- "placeholder:text-[rgb(var(--nc-fg-soft))]",
142
- "px-5 py-3 text-base",
143
- className
144
- ),
145
- style: {
146
- "--glow-color": "rgb(var(--nc-accent-1) / 0.5)"
147
- },
148
- ...props
149
- }
150
- ) });
151
- }
152
- );
153
- CraftTextarea.displayName = "CraftTextarea";
154
-
155
- // src/components/craft-select.tsx
156
- import * as React3 from "react";
157
- import { jsx as jsx5, jsxs as jsxs2 } from "react/jsx-runtime";
158
- var CraftSelect = React3.forwardRef(
159
- ({ className, tone, children, ...props }, ref) => {
160
- return /* @__PURE__ */ jsxs2("div", { className: "relative w-full", "data-nc-theme": tone, children: [
161
- /* @__PURE__ */ jsx5(
162
- "select",
163
- {
164
- ref,
165
- className: cn(
166
- "w-full appearance-none rounded-2xl border-2 bg-[rgb(var(--nc-surface)/0.08)] text-[rgb(var(--nc-fg))] backdrop-blur-xl",
167
- "shadow-[inset_0_2px_8px_rgba(0,0,0,0.3)]",
168
- "focus:outline-none focus:ring-4",
169
- "transition-all duration-300",
170
- "disabled:opacity-50 disabled:cursor-not-allowed",
171
- "border-[rgb(var(--nc-border)/0.35)]",
172
- "focus:border-[rgb(var(--nc-accent-1)/0.8)] focus:ring-[rgb(var(--nc-accent-1)/0.3)]",
173
- "px-5 py-3 pr-10 text-base",
174
- className
175
- ),
176
- ...props,
177
- children
178
- }
179
- ),
180
- /* @__PURE__ */ jsx5(
181
- "svg",
182
- {
183
- className: "pointer-events-none absolute right-4 top-1/2 h-4 w-4 -translate-y-1/2 text-[rgb(var(--nc-fg-soft))]",
184
- viewBox: "0 0 20 20",
185
- fill: "currentColor",
186
- "aria-hidden": "true",
187
- children: /* @__PURE__ */ jsx5(
188
- "path",
189
- {
190
- fillRule: "evenodd",
191
- d: "M5.23 7.21a.75.75 0 011.06.02L10 10.94l3.71-3.7a.75.75 0 111.06 1.06l-4.24 4.24a.75.75 0 01-1.06 0L5.21 8.29a.75.75 0 01.02-1.08z",
192
- clipRule: "evenodd"
193
- }
194
- )
195
- }
196
- )
197
- ] });
198
- }
199
- );
200
- CraftSelect.displayName = "CraftSelect";
201
-
202
- // src/components/craft-checkbox.tsx
203
- import * as React4 from "react";
204
- import { jsx as jsx6, jsxs as jsxs3 } from "react/jsx-runtime";
205
- var CraftCheckbox = React4.forwardRef(
206
- ({ className, tone, label, description, ...props }, ref) => {
207
- return /* @__PURE__ */ jsxs3(
208
- "label",
209
- {
210
- className: cn(
211
- "flex items-start gap-3 text-sm text-[rgb(var(--nc-fg))]",
212
- props.disabled ? "opacity-60" : "cursor-pointer",
213
- className
214
- ),
215
- "data-nc-theme": tone,
216
- children: [
217
- /* @__PURE__ */ jsxs3("span", { className: "relative mt-0.5", children: [
218
- /* @__PURE__ */ jsx6(
219
- "input",
220
- {
221
- ref,
222
- type: "checkbox",
223
- className: "peer sr-only",
224
- ...props
225
- }
226
- ),
227
- /* @__PURE__ */ jsx6(
228
- "span",
229
- {
230
- className: cn(
231
- "flex h-5 w-5 items-center justify-center rounded-md border-2",
232
- "border-[rgb(var(--nc-border)/0.45)] bg-[rgb(var(--nc-surface)/0.08)]",
233
- "transition-all duration-200",
234
- "peer-checked:border-[rgb(var(--nc-accent-1))] peer-checked:bg-[rgb(var(--nc-accent-1)/0.25)]",
235
- "peer-focus-visible:ring-2 peer-focus-visible:ring-[rgb(var(--nc-accent-1)/0.5)]"
236
- ),
237
- children: /* @__PURE__ */ jsx6(
238
- "svg",
239
- {
240
- className: "h-3 w-3 text-[rgb(var(--nc-fg))] opacity-0 transition-opacity peer-checked:opacity-100",
241
- viewBox: "0 0 20 20",
242
- fill: "currentColor",
243
- "aria-hidden": "true",
244
- children: /* @__PURE__ */ jsx6(
245
- "path",
246
- {
247
- fillRule: "evenodd",
248
- d: "M16.704 5.29a1 1 0 010 1.415l-7.2 7.2a1 1 0 01-1.415 0l-3.2-3.2a1 1 0 111.415-1.415l2.492 2.493 6.493-6.493a1 1 0 011.415 0z",
249
- clipRule: "evenodd"
250
- }
251
- )
252
- }
253
- )
254
- }
255
- )
256
- ] }),
257
- /* @__PURE__ */ jsxs3("span", { className: "space-y-1", children: [
258
- label && /* @__PURE__ */ jsx6("span", { className: "block font-medium text-[rgb(var(--nc-fg))]", children: label }),
259
- description && /* @__PURE__ */ jsx6("span", { className: "block text-xs text-[rgb(var(--nc-fg-muted))]", children: description })
260
- ] })
261
- ]
262
- }
263
- );
264
- }
265
- );
266
- CraftCheckbox.displayName = "CraftCheckbox";
267
-
268
- // src/components/craft-switch.tsx
269
- import * as React5 from "react";
270
- import { jsx as jsx7, jsxs as jsxs4 } from "react/jsx-runtime";
271
- var CraftSwitch = React5.forwardRef(
272
- ({ className, tone, label, ...props }, ref) => {
273
- return /* @__PURE__ */ jsxs4(
274
- "label",
275
- {
276
- className: cn(
277
- "inline-flex items-center gap-3 text-sm text-[rgb(var(--nc-fg))]",
278
- props.disabled ? "opacity-60" : "cursor-pointer",
279
- className
280
- ),
281
- "data-nc-theme": tone,
282
- children: [
283
- /* @__PURE__ */ jsx7("input", { ref, type: "checkbox", className: "peer sr-only", ...props }),
284
- /* @__PURE__ */ jsx7(
285
- "span",
286
- {
287
- className: cn(
288
- "relative h-6 w-11 rounded-full border-2 border-[rgb(var(--nc-border)/0.35)] bg-[rgb(var(--nc-surface)/0.08)]",
289
- "transition-all duration-200",
290
- "peer-focus-visible:ring-2 peer-focus-visible:ring-[rgb(var(--nc-accent-1)/0.5)]",
291
- "peer-checked:border-[rgb(var(--nc-accent-1)/0.6)] peer-checked:bg-[rgb(var(--nc-accent-1)/0.25)]"
292
- ),
293
- children: /* @__PURE__ */ jsx7(
294
- "span",
295
- {
296
- className: cn(
297
- "absolute left-0.5 top-0.5 h-4 w-4 rounded-full bg-[rgb(var(--nc-surface-muted)/0.9)]",
298
- "transition-all duration-200",
299
- "peer-checked:translate-x-5 peer-checked:bg-[rgb(var(--nc-surface-muted))]"
300
- )
301
- }
302
- )
303
- }
304
- ),
305
- label && /* @__PURE__ */ jsx7("span", { children: label })
306
- ]
307
- }
308
- );
309
- }
310
- );
311
- CraftSwitch.displayName = "CraftSwitch";
312
-
313
- // src/components/craft-badge.tsx
314
- import { jsx as jsx8 } from "react/jsx-runtime";
315
- var variantClasses2 = {
316
- solid: "bg-[color:rgb(var(--nc-accent-1))] text-white shadow-[0_10px_20px_rgb(var(--nc-accent-1)/0.35)]",
317
- soft: "bg-[color:rgb(var(--nc-accent-1)/0.2)] text-[rgb(var(--nc-fg))]",
318
- outline: "border border-[color:rgb(var(--nc-accent-1)/0.6)] text-[rgb(var(--nc-fg))]"
319
- };
320
- function CraftBadge({
321
- className,
322
- variant = "soft",
323
- tone,
324
- ...props
325
- }) {
326
- return /* @__PURE__ */ jsx8(
327
- "span",
328
- {
329
- className: cn(
330
- "inline-flex items-center rounded-full px-3 py-1 text-xs font-semibold uppercase tracking-wide",
331
- variantClasses2[variant],
332
- className
333
- ),
334
- "data-nc-theme": tone,
335
- ...props
336
- }
337
- );
338
- }
339
-
340
- // src/components/craft-card.tsx
341
- import { jsx as jsx9 } from "react/jsx-runtime";
342
- function CraftCard({ className, tone, elevated = true, ...props }) {
343
- return /* @__PURE__ */ jsx9(
344
- "div",
345
- {
346
- className: cn(
347
- "rounded-3xl border border-[rgb(var(--nc-border)/0.3)] bg-[rgb(var(--nc-surface)/0.08)] p-6 text-[rgb(var(--nc-fg))] backdrop-blur-xl",
348
- elevated && "shadow-[0_18px_40px_rgba(0,0,0,0.35)]",
349
- "transition-all duration-300",
350
- className
351
- ),
352
- "data-nc-theme": tone,
353
- ...props
354
- }
355
- );
356
- }
357
-
358
- // src/components/craft-modal.tsx
359
- import * as React6 from "react";
360
- import { createPortal } from "react-dom";
361
- import { Fragment, jsx as jsx10, jsxs as jsxs5 } from "react/jsx-runtime";
362
- var FOCUSABLE_SELECTORS = [
363
- "a[href]",
364
- "button:not([disabled])",
365
- "textarea:not([disabled])",
366
- "input:not([disabled])",
367
- "select:not([disabled])",
368
- "[tabindex]:not([tabindex='-1'])"
369
- ].join(",");
370
- function useFocusTrap(active) {
371
- const ref = React6.useRef(null);
372
- React6.useEffect(() => {
373
- if (!active || !ref.current) return;
374
- const root = ref.current;
375
- const getFocusable = () => Array.from(root.querySelectorAll(FOCUSABLE_SELECTORS));
376
- const focusables = getFocusable();
377
- if (focusables.length) {
378
- focusables[0].focus();
379
- } else {
380
- root.focus();
381
- }
382
- const handleKeyDown = (event) => {
383
- if (event.key !== "Tab") return;
384
- const items = getFocusable();
385
- if (!items.length) return;
386
- const first = items[0];
387
- const last = items[items.length - 1];
388
- const activeEl = document.activeElement;
389
- if (event.shiftKey && activeEl === first) {
390
- event.preventDefault();
391
- last.focus();
392
- } else if (!event.shiftKey && activeEl === last) {
393
- event.preventDefault();
394
- first.focus();
395
- }
396
- };
397
- root.addEventListener("keydown", handleKeyDown);
398
- return () => root.removeEventListener("keydown", handleKeyDown);
399
- }, [active]);
400
- return ref;
401
- }
402
- function CraftModal({
403
- open,
404
- defaultOpen = false,
405
- onOpenChange,
406
- tone,
407
- title,
408
- description,
409
- children,
410
- trigger,
411
- footer,
412
- className
413
- }) {
414
- const [uncontrolledOpen, setUncontrolledOpen] = React6.useState(defaultOpen);
415
- const isControlled = typeof open === "boolean";
416
- const isOpen = isControlled ? open : uncontrolledOpen;
417
- const setOpen = React6.useCallback(
418
- (next) => {
419
- if (!isControlled) {
420
- setUncontrolledOpen(next);
421
- }
422
- onOpenChange == null ? void 0 : onOpenChange(next);
423
- },
424
- [isControlled, onOpenChange]
425
- );
426
- React6.useEffect(() => {
427
- if (!isOpen) return;
428
- const handleKey = (event) => {
429
- if (event.key === "Escape") setOpen(false);
430
- };
431
- document.addEventListener("keydown", handleKey);
432
- return () => document.removeEventListener("keydown", handleKey);
433
- }, [isOpen, setOpen]);
434
- const ref = useFocusTrap(isOpen);
435
- const content = isOpen ? /* @__PURE__ */ jsxs5("div", { className: "fixed inset-0 z-50 flex items-center justify-center px-4 py-8", children: [
436
- /* @__PURE__ */ jsx10(
437
- "div",
438
- {
439
- className: "absolute inset-0 backdrop-blur-sm",
440
- onClick: () => setOpen(false)
441
- }
442
- ),
443
- /* @__PURE__ */ jsxs5(
444
- "div",
445
- {
446
- ref,
447
- tabIndex: -1,
448
- className: cn(
449
- "relative z-10 w-full max-w-lg rounded-3xl border border-[rgb(var(--nc-border)/0.3)] bg-[rgb(var(--nc-surface)/0.12)] p-6 text-[rgb(var(--nc-fg))] shadow-[0_20px_60px_rgba(0,0,0,0.45)] backdrop-blur-2xl",
450
- className
451
- ),
452
- "data-nc-theme": tone,
453
- children: [
454
- /* @__PURE__ */ jsxs5("div", { className: "flex items-start justify-between gap-4", children: [
455
- /* @__PURE__ */ jsxs5("div", { className: "space-y-1", children: [
456
- title && /* @__PURE__ */ jsx10("h3", { className: "text-2xl font-semibold", children: title }),
457
- description && /* @__PURE__ */ jsx10("p", { className: "text-[rgb(var(--nc-fg-muted))]", children: description })
458
- ] }),
459
- /* @__PURE__ */ jsx10(
460
- "button",
461
- {
462
- className: "rounded-full border border-[rgb(var(--nc-border)/0.3)] bg-[rgb(var(--nc-surface)/0.12)] p-2 text-[rgb(var(--nc-fg-soft))] transition hover:text-[rgb(var(--nc-fg))]",
463
- onClick: () => setOpen(false),
464
- "aria-label": "Close",
465
- children: /* @__PURE__ */ jsx10("svg", { viewBox: "0 0 20 20", className: "h-4 w-4", fill: "currentColor", children: /* @__PURE__ */ jsx10("path", { d: "M6.28 5.22a.75.75 0 00-1.06 1.06L8.94 10l-3.72 3.72a.75.75 0 101.06 1.06L10 11.06l3.72 3.72a.75.75 0 101.06-1.06L11.06 10l3.72-3.72a.75.75 0 00-1.06-1.06L10 8.94 6.28 5.22z" }) })
466
- }
467
- )
468
- ] }),
469
- /* @__PURE__ */ jsx10("div", { className: "mt-5 space-y-4", children }),
470
- footer && /* @__PURE__ */ jsx10("div", { className: "mt-6", children: footer })
471
- ]
472
- }
473
- )
474
- ] }) : null;
475
- return /* @__PURE__ */ jsxs5(Fragment, { children: [
476
- trigger && /* @__PURE__ */ jsx10(
477
- "span",
478
- {
479
- onClick: () => setOpen(true),
480
- onKeyDown: (event) => {
481
- if (event.key === "Enter" || event.key === " ") setOpen(true);
482
- },
483
- role: "button",
484
- tabIndex: 0,
485
- className: "inline-flex",
486
- children: trigger
487
- }
488
- ),
489
- typeof document !== "undefined" && content ? createPortal(content, document.body) : content
490
- ] });
491
- }
492
-
493
- // src/components/craft-drawer.tsx
494
- import * as React7 from "react";
495
- import { createPortal as createPortal2 } from "react-dom";
496
- import { Fragment as Fragment2, jsx as jsx11, jsxs as jsxs6 } from "react/jsx-runtime";
497
- function CraftDrawer({
498
- open,
499
- defaultOpen = false,
500
- onOpenChange,
501
- tone,
502
- side = "left",
503
- title,
504
- children,
505
- trigger,
506
- footer,
507
- className
508
- }) {
509
- const [uncontrolledOpen, setUncontrolledOpen] = React7.useState(defaultOpen);
510
- const isControlled = typeof open === "boolean";
511
- const isOpen = isControlled ? open : uncontrolledOpen;
512
- const setOpen = React7.useCallback(
513
- (next) => {
514
- if (!isControlled) setUncontrolledOpen(next);
515
- onOpenChange == null ? void 0 : onOpenChange(next);
516
- },
517
- [isControlled, onOpenChange]
518
- );
519
- React7.useEffect(() => {
520
- if (!isOpen) return;
521
- const handleKey = (event) => {
522
- if (event.key === "Escape") setOpen(false);
523
- };
524
- document.addEventListener("keydown", handleKey);
525
- return () => document.removeEventListener("keydown", handleKey);
526
- }, [isOpen, setOpen]);
527
- const content = isOpen ? /* @__PURE__ */ jsxs6("div", { className: "fixed inset-0 z-50 overflow-hidden", children: [
528
- /* @__PURE__ */ jsx11(
529
- "div",
530
- {
531
- className: "absolute inset-0 backdrop-blur-sm",
532
- onClick: () => setOpen(false)
533
- }
534
- ),
535
- /* @__PURE__ */ jsxs6(
536
- "div",
537
- {
538
- className: cn(
539
- "absolute top-0 h-full w-full max-w-md border border-[rgb(var(--nc-border)/0.3)] bg-[rgb(var(--nc-surface)/0.12)] text-[rgb(var(--nc-fg))] shadow-[0_20px_60px_rgba(0,0,0,0.45)] backdrop-blur-2xl",
540
- side === "right" ? "right-0" : "left-0",
541
- className
542
- ),
543
- "data-nc-theme": tone,
544
- children: [
545
- /* @__PURE__ */ jsxs6("div", { className: "flex items-center justify-between border-b border-[rgb(var(--nc-border)/0.3)] p-6", children: [
546
- title && /* @__PURE__ */ jsx11("h3", { className: "text-xl font-semibold", children: title }),
547
- /* @__PURE__ */ jsx11(
548
- "button",
549
- {
550
- className: "rounded-full border border-[rgb(var(--nc-border)/0.3)] bg-[rgb(var(--nc-surface)/0.12)] p-2 text-[rgb(var(--nc-fg-soft))] transition hover:text-[rgb(var(--nc-fg))]",
551
- onClick: () => setOpen(false),
552
- "aria-label": "Close",
553
- children: /* @__PURE__ */ jsx11("svg", { viewBox: "0 0 20 20", className: "h-4 w-4", fill: "currentColor", children: /* @__PURE__ */ jsx11("path", { d: "M6.28 5.22a.75.75 0 00-1.06 1.06L8.94 10l-3.72 3.72a.75.75 0 101.06 1.06L10 11.06l3.72 3.72a.75.75 0 101.06-1.06L11.06 10l3.72-3.72a.75.75 0 00-1.06-1.06L10 8.94 6.28 5.22z" }) })
554
- }
555
- )
556
- ] }),
557
- /* @__PURE__ */ jsx11("div", { className: "p-6 space-y-4 overflow-y-auto h-[calc(100%-5.5rem)]", children }),
558
- footer && /* @__PURE__ */ jsx11("div", { className: "border-t border-[rgb(var(--nc-border)/0.3)] p-6", children: footer })
559
- ]
560
- }
561
- )
562
- ] }) : null;
563
- return /* @__PURE__ */ jsxs6(Fragment2, { children: [
564
- trigger && /* @__PURE__ */ jsx11(
565
- "span",
566
- {
567
- onClick: () => setOpen(true),
568
- onKeyDown: (event) => {
569
- if (event.key === "Enter" || event.key === " ") setOpen(true);
570
- },
571
- role: "button",
572
- tabIndex: 0,
573
- className: "inline-flex",
574
- children: trigger
575
- }
576
- ),
577
- typeof document !== "undefined" && content ? createPortal2(content, document.body) : content
578
- ] });
579
- }
580
-
581
- // src/components/craft-tabs.tsx
582
- import * as React8 from "react";
583
- import { jsx as jsx12, jsxs as jsxs7 } from "react/jsx-runtime";
584
- function CraftTabs({
585
- value,
586
- defaultValue,
587
- onValueChange,
588
- tone,
589
- tabs,
590
- panels,
591
- className
592
- }) {
593
- var _a, _b;
594
- const fallback = (_b = (_a = tabs[0]) == null ? void 0 : _a.value) != null ? _b : "";
595
- const [uncontrolledValue, setUncontrolledValue] = React8.useState(
596
- defaultValue != null ? defaultValue : fallback
597
- );
598
- const isControlled = value !== void 0;
599
- const activeValue = isControlled ? value : uncontrolledValue;
600
- const setValue = React8.useCallback(
601
- (next) => {
602
- if (!isControlled) setUncontrolledValue(next);
603
- onValueChange == null ? void 0 : onValueChange(next);
604
- },
605
- [isControlled, onValueChange]
606
- );
607
- const onKeyDown = (event) => {
608
- if (!tabs.length) return;
609
- const currentIndex = tabs.findIndex((tab) => tab.value === activeValue);
610
- if (event.key === "ArrowRight") {
611
- event.preventDefault();
612
- const next = tabs[(currentIndex + 1) % tabs.length];
613
- setValue(next.value);
614
- }
615
- if (event.key === "ArrowLeft") {
616
- event.preventDefault();
617
- const next = tabs[(currentIndex - 1 + tabs.length) % tabs.length];
618
- setValue(next.value);
619
- }
620
- };
621
- return /* @__PURE__ */ jsxs7("div", { className: cn("space-y-4", className), "data-nc-theme": tone, children: [
622
- /* @__PURE__ */ jsx12(
623
- "div",
624
- {
625
- className: "inline-flex flex-wrap items-center gap-2 rounded-full border border-[rgb(var(--nc-border)/0.3)] bg-[rgb(var(--nc-surface)/0.08)] p-2",
626
- role: "tablist",
627
- onKeyDown,
628
- children: tabs.map((tab) => /* @__PURE__ */ jsx12(
629
- "button",
630
- {
631
- role: "tab",
632
- "aria-selected": activeValue === tab.value,
633
- onClick: () => setValue(tab.value),
634
- className: cn(
635
- "rounded-full px-4 py-2 text-sm font-semibold transition-all",
636
- activeValue === tab.value ? "bg-[rgb(var(--nc-accent-1)/0.65)] text-white shadow-[0_7px_5px_rgb(var(--nc-accent-1)/0.35)]" : "text-[rgb(var(--nc-fg-muted))] hover:text-[rgb(var(--nc-fg))]"
637
- ),
638
- children: tab.label
639
- },
640
- tab.value
641
- ))
642
- }
643
- ),
644
- /* @__PURE__ */ jsx12("div", { className: "rounded-2xl border border-[rgb(var(--nc-border)/0.3)] bg-[rgb(var(--nc-surface)/0.08)] p-4 text-[rgb(var(--nc-fg))]", children: panels[activeValue] })
645
- ] });
646
- }
647
-
648
- // src/components/craft-tooltip.tsx
649
- import * as React9 from "react";
650
- import { jsx as jsx13, jsxs as jsxs8 } from "react/jsx-runtime";
651
- function CraftTooltip({ content, tone, children, side = "top" }) {
652
- const [open, setOpen] = React9.useState(false);
653
- return /* @__PURE__ */ jsxs8(
654
- "span",
655
- {
656
- className: "relative inline-flex",
657
- onMouseEnter: () => setOpen(true),
658
- onMouseLeave: () => setOpen(false),
659
- onFocus: () => setOpen(true),
660
- onBlur: () => setOpen(false),
661
- children: [
662
- children,
663
- /* @__PURE__ */ jsx13(
664
- "span",
665
- {
666
- className: cn(
667
- "pointer-events-none absolute z-20 whitespace-nowrap rounded-lg border border-white/10 bg-black/80 px-3 py-2 text-xs text-white shadow-lg transition-all",
668
- "backdrop-blur-xl",
669
- open ? "opacity-100 translate-y-0" : "opacity-0 translate-y-1",
670
- side === "top" && "bottom-full left-1/2 -translate-x-1/2 -translate-y-2",
671
- side === "bottom" && "top-full left-1/2 -translate-x-1/2 translate-y-2",
672
- side === "left" && "right-full top-1/2 -translate-y-1/2 -translate-x-2",
673
- side === "right" && "left-full top-1/2 -translate-y-1/2 translate-x-2"
674
- ),
675
- "data-nc-theme": tone,
676
- role: "tooltip",
677
- children: content
678
- }
679
- )
680
- ]
681
- }
682
- );
683
- }
684
-
685
- // src/components/craft-toast.tsx
686
- import * as React10 from "react";
687
- import { jsx as jsx14, jsxs as jsxs9 } from "react/jsx-runtime";
688
- var variantClasses3 = {
689
- info: "border-[color:rgb(var(--nc-accent-1)/0.4)]",
690
- success: "border-emerald-400/40",
691
- warning: "border-amber-400/40",
692
- error: "border-rose-400/40"
693
- };
694
- function useCraftToast() {
695
- const [toasts, setToasts] = React10.useState([]);
696
- const push = React10.useCallback((toast) => {
697
- const id = `${Date.now()}-${Math.random().toString(16).slice(2)}`;
698
- setToasts((prev) => [...prev, { ...toast, id }]);
699
- return id;
700
- }, []);
701
- const remove = React10.useCallback((id) => {
702
- setToasts((prev) => prev.filter((toast) => toast.id !== id));
703
- }, []);
704
- return { toasts, push, remove };
705
- }
706
- function CraftToastHost({ toasts, onDismiss, tone }) {
707
- return /* @__PURE__ */ jsx14(
708
- "div",
709
- {
710
- className: "fixed right-6 top-6 z-50 flex w-full max-w-sm flex-col gap-3",
711
- "data-nc-theme": tone,
712
- children: toasts.map((toast) => {
713
- var _a;
714
- return /* @__PURE__ */ jsx14(
715
- "div",
716
- {
717
- className: cn(
718
- "rounded-2xl border bg-[rgb(var(--nc-surface)/0.12)] p-4 text-[rgb(var(--nc-fg))] shadow-[0_15px_35px_rgba(0,0,0,0.35)] backdrop-blur-xl",
719
- variantClasses3[(_a = toast.variant) != null ? _a : "info"]
720
- ),
721
- children: /* @__PURE__ */ jsxs9("div", { className: "flex items-start justify-between gap-4", children: [
722
- /* @__PURE__ */ jsxs9("div", { children: [
723
- /* @__PURE__ */ jsx14("p", { className: "text-sm font-semibold", children: toast.title }),
724
- toast.description && /* @__PURE__ */ jsx14("p", { className: "text-xs text-[rgb(var(--nc-fg-muted))]", children: toast.description })
725
- ] }),
726
- /* @__PURE__ */ jsx14(
727
- "button",
728
- {
729
- className: "text-[rgb(var(--nc-fg-soft))] hover:text-[rgb(var(--nc-fg))]",
730
- onClick: () => onDismiss(toast.id),
731
- children: "\u2715"
732
- }
733
- )
734
- ] })
735
- },
736
- toast.id
737
- );
738
- })
739
- }
740
- );
741
- }
742
-
743
- // src/components/craft-skeleton.tsx
744
- import { jsx as jsx15 } from "react/jsx-runtime";
745
- function CraftSkeleton({ className, tone, ...props }) {
746
- return /* @__PURE__ */ jsx15(
747
- "div",
748
- {
749
- className: cn(
750
- "relative overflow-hidden rounded-2xl bg-[rgb(var(--nc-surface)/0.12)]",
751
- "after:absolute after:inset-0 after:-translate-x-full after:bg-linear-to-r after:from-transparent after:via-white/20 after:to-transparent",
752
- "after:animate-[shimmer_1.6s_infinite]",
753
- className
754
- ),
755
- "data-nc-theme": tone,
756
- ...props
757
- }
758
- );
759
- }
760
-
761
- // src/components/craft-empty-state.tsx
762
- import { jsx as jsx16, jsxs as jsxs10 } from "react/jsx-runtime";
763
- function CraftEmptyState({
764
- className,
765
- tone,
766
- title,
767
- description,
768
- icon,
769
- action,
770
- ...props
771
- }) {
772
- return /* @__PURE__ */ jsxs10(
773
- "div",
774
- {
775
- className: cn(
776
- "rounded-3xl border border-[rgb(var(--nc-border)/0.3)] bg-[rgb(var(--nc-surface)/0.08)] p-8 text-center text-[rgb(var(--nc-fg))] backdrop-blur-xl",
777
- "shadow-[0_18px_40px_rgba(0,0,0,0.25)]",
778
- className
779
- ),
780
- "data-nc-theme": tone,
781
- ...props,
782
- children: [
783
- icon && /* @__PURE__ */ jsx16("div", { className: "mx-auto mb-4 flex h-12 w-12 items-center justify-center rounded-2xl bg-[rgb(var(--nc-accent-1)/0.2)] text-[rgb(var(--nc-accent-1))]", children: icon }),
784
- /* @__PURE__ */ jsx16("h3", { className: "text-xl font-semibold", children: title }),
785
- description && /* @__PURE__ */ jsx16("p", { className: "mt-2 text-sm text-[rgb(var(--nc-fg-muted))]", children: description }),
786
- action && /* @__PURE__ */ jsx16("div", { className: "mt-6 flex justify-center", children: action })
787
- ]
788
- }
789
- );
790
- }
791
-
792
- // src/components/craft-date-picker.tsx
793
- import * as React11 from "react";
794
- import { jsx as jsx17, jsxs as jsxs11 } from "react/jsx-runtime";
795
- var WEEK_DAYS = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"];
796
- function formatDate(date) {
797
- const year = date.getFullYear();
798
- const month = `${date.getMonth() + 1}`.padStart(2, "0");
799
- const day = `${date.getDate()}`.padStart(2, "0");
800
- return `${year}-${month}-${day}`;
801
- }
802
- function parseDate(value) {
803
- if (!value) return null;
804
- const [year, month, day] = value.split("-").map(Number);
805
- if (!year || !month || !day) return null;
806
- return new Date(year, month - 1, day);
807
- }
808
- function isSameDay(a, b) {
809
- return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
810
- }
811
- function isOutsideRange(date, min, max) {
812
- const minDate = parseDate(min);
813
- const maxDate = parseDate(max);
814
- if (minDate && date < minDate) return true;
815
- if (maxDate && date > maxDate) return true;
816
- return false;
817
- }
818
- function CraftDatePicker({
819
- value,
820
- defaultValue,
821
- onChange,
822
- tone,
823
- min,
824
- max,
825
- placeholder = "Select date",
826
- className
827
- }) {
828
- const [open, setOpen] = React11.useState(false);
829
- const [uncontrolledValue, setUncontrolledValue] = React11.useState(defaultValue != null ? defaultValue : "");
830
- const isControlled = value !== void 0;
831
- const selectedValue = isControlled ? value != null ? value : "" : uncontrolledValue;
832
- const selectedDate = parseDate(selectedValue);
833
- const initialMonth = selectedDate != null ? selectedDate : /* @__PURE__ */ new Date();
834
- const [viewDate, setViewDate] = React11.useState(initialMonth);
835
- React11.useEffect(() => {
836
- if (selectedDate) setViewDate(selectedDate);
837
- }, [selectedDate]);
838
- const wrapperRef = React11.useRef(null);
839
- React11.useEffect(() => {
840
- if (!open) return;
841
- const handleClick = (event) => {
842
- var _a;
843
- if (!((_a = wrapperRef.current) == null ? void 0 : _a.contains(event.target))) {
844
- setOpen(false);
845
- }
846
- };
847
- const handleKey = (event) => {
848
- if (event.key === "Escape") setOpen(false);
849
- };
850
- document.addEventListener("mousedown", handleClick);
851
- document.addEventListener("keydown", handleKey);
852
- return () => {
853
- document.removeEventListener("mousedown", handleClick);
854
- document.removeEventListener("keydown", handleKey);
855
- };
856
- }, [open]);
857
- const setValue = React11.useCallback(
858
- (next) => {
859
- if (!isControlled) setUncontrolledValue(next);
860
- onChange == null ? void 0 : onChange(next);
861
- },
862
- [isControlled, onChange]
863
- );
864
- const monthStart = new Date(viewDate.getFullYear(), viewDate.getMonth(), 1);
865
- const monthEnd = new Date(viewDate.getFullYear(), viewDate.getMonth() + 1, 0);
866
- const startDay = monthStart.getDay();
867
- const daysInMonth = monthEnd.getDate();
868
- const cells = Array.from({ length: startDay + daysInMonth }, (_, i) => {
869
- const dayNumber = i - startDay + 1;
870
- if (dayNumber < 1) return null;
871
- return new Date(viewDate.getFullYear(), viewDate.getMonth(), dayNumber);
872
- });
873
- const handleDaySelect = (date) => {
874
- if (isOutsideRange(date, min, max)) return;
875
- const next = formatDate(date);
876
- setValue(next);
877
- setOpen(false);
878
- };
879
- const handleKeyDown = (event) => {
880
- if (!open) return;
881
- if (!selectedDate) return;
882
- const next = new Date(selectedDate);
883
- if (event.key === "ArrowRight") next.setDate(next.getDate() + 1);
884
- if (event.key === "ArrowLeft") next.setDate(next.getDate() - 1);
885
- if (event.key === "ArrowDown") next.setDate(next.getDate() + 7);
886
- if (event.key === "ArrowUp") next.setDate(next.getDate() - 7);
887
- if (event.key === "Enter") {
888
- event.preventDefault();
889
- handleDaySelect(selectedDate);
890
- return;
891
- }
892
- if (next.getTime() !== selectedDate.getTime()) {
893
- event.preventDefault();
894
- if (!isOutsideRange(next, min, max)) {
895
- setValue(formatDate(next));
896
- setViewDate(next);
897
- }
898
- }
899
- };
900
- return /* @__PURE__ */ jsxs11("div", { className: "relative w-full", "data-nc-theme": tone, ref: wrapperRef, children: [
901
- /* @__PURE__ */ jsxs11(
902
- "button",
903
- {
904
- type: "button",
905
- onClick: () => setOpen((prev) => !prev),
906
- className: cn(
907
- "flex w-full items-center justify-between rounded-2xl border-2 bg-[rgb(var(--nc-surface)/0.08)] px-5 py-3 text-left text-base text-[rgb(var(--nc-fg))] backdrop-blur-xl",
908
- "shadow-[inset_0_2px_8px_rgba(0,0,0,0.3)]",
909
- "transition-all duration-300",
910
- "border-[rgb(var(--nc-border)/0.35)]",
911
- "focus:outline-none focus:ring-4 focus:ring-[rgb(var(--nc-accent-1)/0.3)]",
912
- className
913
- ),
914
- children: [
915
- /* @__PURE__ */ jsx17("span", { className: selectedValue ? "text-[rgb(var(--nc-fg))]" : "text-[rgb(var(--nc-fg-soft))]", children: selectedValue || placeholder }),
916
- /* @__PURE__ */ jsx17("svg", { className: "h-4 w-4 text-[rgb(var(--nc-fg-soft))]", viewBox: "0 0 20 20", fill: "currentColor", children: /* @__PURE__ */ jsx17("path", { d: "M6 2a1 1 0 011 1v1h6V3a1 1 0 112 0v1h1a2 2 0 012 2v10a2 2 0 01-2 2H4a2 2 0 01-2-2V6a2 2 0 012-2h1V3a1 1 0 011-1zm10 6H4v8h12V8z" }) })
917
- ]
918
- }
919
- ),
920
- open && /* @__PURE__ */ jsxs11(
921
- "div",
922
- {
923
- className: cn(
924
- "absolute left-0 top-full z-20 mt-3 w-full rounded-3xl border border-[rgb(var(--nc-border)/0.3)] bg-[rgb(var(--nc-surface)/1.52)] p-4 text-[rgb(var(--nc-fg))] shadow-[0_20px_60px_rgba(0,0,0,0.55)] backdrop-blur-10xl"
925
- ),
926
- onKeyDown: handleKeyDown,
927
- tabIndex: -1,
928
- children: [
929
- /* @__PURE__ */ jsxs11("div", { className: "flex items-center justify-between", children: [
930
- /* @__PURE__ */ jsx17(
931
- "button",
932
- {
933
- type: "button",
934
- className: "rounded-xl border border-[rgb(var(--nc-border)/0.3)] bg-[rgb(var(--nc-surface)/0.12)] px-3 py-1 text-sm text-[rgb(var(--nc-fg))]",
935
- onClick: () => setViewDate(
936
- new Date(viewDate.getFullYear(), viewDate.getMonth() - 1, 1)
937
- ),
938
- children: "Prev"
939
- }
940
- ),
941
- /* @__PURE__ */ jsx17("div", { className: "text-sm font-semibold", children: viewDate.toLocaleString(void 0, { month: "long", year: "numeric" }) }),
942
- /* @__PURE__ */ jsx17(
943
- "button",
944
- {
945
- type: "button",
946
- className: "rounded-xl border border-[rgb(var(--nc-border)/0.3)] bg-[rgb(var(--nc-surface)/0.12)] px-3 py-1 text-sm text-[rgb(var(--nc-fg))]",
947
- onClick: () => setViewDate(
948
- new Date(viewDate.getFullYear(), viewDate.getMonth() + 1, 1)
949
- ),
950
- children: "Next"
951
- }
952
- )
953
- ] }),
954
- /* @__PURE__ */ jsx17("div", { className: "mt-4 grid grid-cols-7 gap-2 text-xs text-[rgb(var(--nc-fg-muted))]", children: WEEK_DAYS.map((day) => /* @__PURE__ */ jsx17("div", { className: "text-center", children: day }, day)) }),
955
- /* @__PURE__ */ jsx17("div", { className: "mt-2 grid grid-cols-7 gap-2", children: cells.map((date, index) => {
956
- if (!date) return /* @__PURE__ */ jsx17("div", {}, `empty-${index}`);
957
- const disabled = isOutsideRange(date, min, max);
958
- const selected = selectedDate && isSameDay(date, selectedDate);
959
- return /* @__PURE__ */ jsx17(
960
- "button",
961
- {
962
- type: "button",
963
- onClick: () => handleDaySelect(date),
964
- disabled,
965
- className: cn(
966
- "rounded-lg py-2 text-sm transition-all",
967
- selected ? "bg-[rgb(var(--nc-accent-1)/0.3)] text-[rgb(var(--nc-fg))]" : "text-[rgb(var(--nc-fg-muted))] hover:bg-[rgb(var(--nc-surface)/0.12)]",
968
- disabled && "opacity-40 hover:bg-transparent"
969
- ),
970
- children: date.getDate()
971
- },
972
- date.toISOString()
973
- );
974
- }) })
975
- ]
976
- }
977
- )
978
- ] });
979
- }
980
-
981
- // src/components/craft-number-input.tsx
982
- import * as React12 from "react";
983
- import { jsx as jsx18 } from "react/jsx-runtime";
984
- var CraftNumberInput = React12.forwardRef(({ className, tone, ...props }, ref) => {
985
- return /* @__PURE__ */ jsx18("div", { className: "relative w-full", "data-nc-theme": tone, children: /* @__PURE__ */ jsx18(
986
- "input",
987
- {
988
- ref,
989
- type: "number",
990
- className: cn(
991
- "w-full rounded-2xl border-2 bg-[rgb(var(--nc-surface)/0.08)] text-[rgb(var(--nc-fg))] backdrop-blur-xl",
992
- "shadow-[inset_0_2px_8px_rgba(0,0,0,0.3)]",
993
- "focus:outline-none focus:ring-4",
994
- "transition-all duration-300",
995
- "disabled:opacity-50 disabled:cursor-not-allowed",
996
- "border-[rgb(var(--nc-border)/0.35)]",
997
- "focus:border-[rgb(var(--nc-accent-1)/0.8)] focus:ring-[rgb(var(--nc-accent-1)/0.3)]",
998
- "px-5 py-3 text-base",
999
- className
1000
- ),
1001
- ...props
1002
- }
1003
- ) });
1004
- });
1005
- CraftNumberInput.displayName = "CraftNumberInput";
1006
-
1007
- // src/components/craft-currency-input.tsx
1008
- import * as React13 from "react";
1009
- import { jsx as jsx19, jsxs as jsxs12 } from "react/jsx-runtime";
1010
- var CraftCurrencyInput = React13.forwardRef(({ className, tone, currencySymbol = "$", ...props }, ref) => {
1011
- return /* @__PURE__ */ jsxs12("div", { className: "relative w-full", "data-nc-theme": tone, children: [
1012
- /* @__PURE__ */ jsx19("span", { className: "pointer-events-none absolute left-4 top-1/2 -translate-y-1/2 text-[rgb(var(--nc-fg-soft))]", children: currencySymbol }),
1013
- /* @__PURE__ */ jsx19(
1014
- "input",
1015
- {
1016
- ref,
1017
- type: "text",
1018
- inputMode: "decimal",
1019
- className: cn(
1020
- "w-full rounded-2xl border-2 bg-[rgb(var(--nc-surface)/0.08)] text-[rgb(var(--nc-fg))] backdrop-blur-xl",
1021
- "shadow-[inset_0_2px_8px_rgba(0,0,0,0.3)]",
1022
- "focus:outline-none focus:ring-4",
1023
- "transition-all duration-300",
1024
- "disabled:opacity-50 disabled:cursor-not-allowed",
1025
- "border-[rgb(var(--nc-border)/0.35)]",
1026
- "focus:border-[rgb(var(--nc-accent-1)/0.8)] focus:ring-[rgb(var(--nc-accent-1)/0.3)]",
1027
- "placeholder:text-[rgb(var(--nc-fg-soft))]",
1028
- "px-5 py-3 pl-9 text-base",
1029
- className
1030
- ),
1031
- ...props
1032
- }
1033
- )
1034
- ] });
1035
- });
1036
- CraftCurrencyInput.displayName = "CraftCurrencyInput";
1037
-
1038
- // src/components/layout/app-shell.tsx
1039
- import { jsx as jsx20, jsxs as jsxs13 } from "react/jsx-runtime";
1040
- function AppShell({ className, sidebar, topNav, children, ...props }) {
1041
- return /* @__PURE__ */ jsxs13(
1042
- "div",
1043
- {
1044
- className: cn(
1045
- "grid min-h-screen grid-cols-1 gap-6 bg-background p-6 lg:grid-cols-[260px_1fr]",
1046
- className
1047
- ),
1048
- ...props,
1049
- children: [
1050
- sidebar && /* @__PURE__ */ jsx20("div", { className: "h-full", children: sidebar }),
1051
- /* @__PURE__ */ jsxs13("div", { className: "flex flex-col gap-6", children: [
1052
- topNav,
1053
- /* @__PURE__ */ jsx20("main", { className: "flex-1", children })
1054
- ] })
1055
- ]
1056
- }
1057
- );
1058
- }
1059
-
1060
- // src/components/layout/sidebar.tsx
1061
- import { jsx as jsx21, jsxs as jsxs14 } from "react/jsx-runtime";
1062
- function Sidebar({ className, title, items, footer, ...props }) {
1063
- return /* @__PURE__ */ jsxs14(
1064
- "aside",
1065
- {
1066
- className: cn(
1067
- "flex h-full w-full flex-col gap-6 rounded-3xl border border-[rgb(var(--nc-border)/0.3)] bg-[rgb(var(--nc-surface)/0.08)] p-6 text-[rgb(var(--nc-fg))] backdrop-blur-xl",
1068
- className
1069
- ),
1070
- ...props,
1071
- children: [
1072
- title && /* @__PURE__ */ jsx21("div", { className: "text-lg font-semibold", children: title }),
1073
- /* @__PURE__ */ jsx21("nav", { className: "flex flex-col gap-2", children: items.map((item, index) => {
1074
- var _a;
1075
- return /* @__PURE__ */ jsxs14(
1076
- "a",
1077
- {
1078
- href: (_a = item.href) != null ? _a : "#",
1079
- className: cn(
1080
- "flex items-center gap-3 rounded-2xl px-3 py-2 text-sm transition",
1081
- item.active ? "bg-[rgb(var(--nc-accent-1)/0.25)] text-[rgb(var(--nc-fg))]" : "text-[rgb(var(--nc-fg-muted))] hover:bg-[rgb(var(--nc-surface)/0.12)] hover:text-[rgb(var(--nc-fg))]"
1082
- ),
1083
- children: [
1084
- item.icon,
1085
- /* @__PURE__ */ jsx21("span", { children: item.label })
1086
- ]
1087
- },
1088
- `${item.label}-${index}`
1089
- );
1090
- }) }),
1091
- footer && /* @__PURE__ */ jsx21("div", { className: "mt-auto pt-4", children: footer })
1092
- ]
1093
- }
1094
- );
1095
- }
1096
-
1097
- // src/components/layout/top-nav.tsx
1098
- import { jsx as jsx22, jsxs as jsxs15 } from "react/jsx-runtime";
1099
- function TopNav({ className, title, actions, breadcrumb, ...props }) {
1100
- return /* @__PURE__ */ jsxs15(
1101
- "header",
1102
- {
1103
- className: cn(
1104
- "flex flex-wrap items-center justify-between gap-4 rounded-3xl border border-[rgb(var(--nc-border)/0.3)] bg-[rgb(var(--nc-surface)/0.08)] px-6 py-4 text-[rgb(var(--nc-fg))] backdrop-blur-xl",
1105
- className
1106
- ),
1107
- ...props,
1108
- children: [
1109
- /* @__PURE__ */ jsxs15("div", { className: "space-y-1", children: [
1110
- breadcrumb,
1111
- title && /* @__PURE__ */ jsx22("div", { className: "text-xl font-semibold", children: title })
1112
- ] }),
1113
- actions && /* @__PURE__ */ jsx22("div", { className: "flex flex-wrap gap-3", children: actions })
1114
- ]
1115
- }
1116
- );
1117
- }
1118
-
1119
- // src/components/layout/page-header.tsx
1120
- import { jsx as jsx23, jsxs as jsxs16 } from "react/jsx-runtime";
1121
- function PageHeader({
1122
- className,
1123
- title,
1124
- description,
1125
- actions,
1126
- ...props
1127
- }) {
1128
- return /* @__PURE__ */ jsxs16(
1129
- "div",
1130
- {
1131
- className: cn("flex flex-wrap items-start justify-between gap-6", className),
1132
- ...props,
1133
- children: [
1134
- /* @__PURE__ */ jsxs16("div", { className: "space-y-2", children: [
1135
- /* @__PURE__ */ jsx23("h1", { className: "text-3xl font-bold text-[rgb(var(--nc-fg))]", children: title }),
1136
- description && /* @__PURE__ */ jsx23("p", { className: "text-[rgb(var(--nc-fg-muted))]", children: description })
1137
- ] }),
1138
- actions && /* @__PURE__ */ jsx23("div", { className: "flex flex-wrap gap-3", children: actions })
1139
- ]
1140
- }
1141
- );
1142
- }
1143
-
1144
- // src/components/layout/breadcrumbs.tsx
1145
- import { jsx as jsx24, jsxs as jsxs17 } from "react/jsx-runtime";
1146
- function Breadcrumbs({ className, items, ...props }) {
1147
- return /* @__PURE__ */ jsx24("nav", { className: cn("flex items-center text-sm text-[rgb(var(--nc-fg-muted))]", className), ...props, children: items.map((item, index) => {
1148
- const content = item.href ? /* @__PURE__ */ jsx24("a", { href: item.href, className: "transition hover:text-[rgb(var(--nc-fg))]", children: item.label }) : /* @__PURE__ */ jsx24("span", { className: "text-[rgb(var(--nc-fg))]", children: item.label });
1149
- return /* @__PURE__ */ jsxs17("span", { className: "flex items-center", children: [
1150
- content,
1151
- index < items.length - 1 && /* @__PURE__ */ jsx24("span", { className: "mx-2 text-[rgb(var(--nc-fg-soft))]", children: "/" })
1152
- ] }, `${item.label}-${index}`);
1153
- }) });
1154
- }
1155
-
1156
- // src/components/layout/auth-layout.tsx
1157
- import { jsx as jsx25, jsxs as jsxs18 } from "react/jsx-runtime";
1158
- function AuthLayout({
1159
- className,
1160
- title,
1161
- description,
1162
- footer,
1163
- graphic,
1164
- children,
1165
- ...props
1166
- }) {
1167
- return /* @__PURE__ */ jsxs18(
1168
- "div",
1169
- {
1170
- className: cn(
1171
- "grid min-h-screen grid-cols-1 bg-background",
1172
- "lg:grid-cols-[1.1fr_0.9fr]",
1173
- className
1174
- ),
1175
- ...props,
1176
- children: [
1177
- /* @__PURE__ */ jsx25("div", { className: "flex flex-col justify-center px-6 py-16 sm:px-12", children: /* @__PURE__ */ jsxs18("div", { className: "mx-auto w-full max-w-md space-y-6", children: [
1178
- (title || description) && /* @__PURE__ */ jsxs18("div", { className: "space-y-2", children: [
1179
- title && /* @__PURE__ */ jsx25("h1", { className: "text-3xl font-bold text-[rgb(var(--nc-fg))]", children: title }),
1180
- description && /* @__PURE__ */ jsx25("p", { className: "text-[rgb(var(--nc-fg-muted))]", children: description })
1181
- ] }),
1182
- children,
1183
- footer && /* @__PURE__ */ jsx25("div", { className: "text-sm text-[rgb(var(--nc-fg-muted))]", children: footer })
1184
- ] }) }),
1185
- /* @__PURE__ */ jsx25("div", { className: "hidden items-center justify-center border-l border-[rgb(var(--nc-border)/0.3)] bg-[rgb(var(--nc-surface)/0.08)] p-12 text-[rgb(var(--nc-fg))] lg:flex", children: graphic != null ? graphic : /* @__PURE__ */ jsxs18("div", { className: "max-w-sm space-y-4 text-center", children: [
1186
- /* @__PURE__ */ jsx25("h2", { className: "text-2xl font-semibold", children: "Crafted experiences" }),
1187
- /* @__PURE__ */ jsx25("p", { className: "text-[rgb(var(--nc-fg-muted))]", children: "Build authentication flows that feel premium and cohesive." })
1188
- ] }) })
1189
- ]
1190
- }
1191
- );
1192
- }
1193
-
1194
- // src/components/layout/container.tsx
1195
- import { jsx as jsx26 } from "react/jsx-runtime";
1196
- var sizeClasses2 = {
1197
- sm: "max-w-3xl",
1198
- md: "max-w-5xl",
1199
- lg: "max-w-6xl",
1200
- xl: "max-w-7xl"
1201
- };
1202
- function Container({ className, size = "lg", ...props }) {
1203
- return /* @__PURE__ */ jsx26(
1204
- "div",
1205
- {
1206
- className: cn("mx-auto w-full px-4 sm:px-6 lg:px-8", sizeClasses2[size], className),
1207
- ...props
1208
- }
1209
- );
1210
- }
1211
-
1212
- // src/components/layout/grid.tsx
1213
- import { jsx as jsx27 } from "react/jsx-runtime";
1214
- var colClasses = {
1215
- 1: "grid-cols-1",
1216
- 2: "grid-cols-1 md:grid-cols-2",
1217
- 3: "grid-cols-1 md:grid-cols-2 lg:grid-cols-3",
1218
- 4: "grid-cols-1 md:grid-cols-2 lg:grid-cols-4",
1219
- 5: "grid-cols-1 md:grid-cols-2 lg:grid-cols-5",
1220
- 6: "grid-cols-1 md:grid-cols-3 lg:grid-cols-6"
1221
- };
1222
- var gapClasses = {
1223
- sm: "gap-4",
1224
- md: "gap-6",
1225
- lg: "gap-8",
1226
- xl: "gap-10"
1227
- };
1228
- function Grid({ className, columns = 3, gap = "md", ...props }) {
1229
- return /* @__PURE__ */ jsx27("div", { className: cn("grid", colClasses[columns], gapClasses[gap], className), ...props });
1230
- }
1231
-
1232
- // src/theme/theme-context.tsx
1233
- import * as React14 from "react";
1234
- import { jsx as jsx28 } from "react/jsx-runtime";
1235
- var THEME_NAMES = [
1236
- "aurora",
1237
- "ember",
1238
- "ocean",
1239
- "midnight",
1240
- "cosmic"
1241
- ];
1242
- var ThemeContext = React14.createContext(null);
1243
- var DEFAULT_THEME_KEY = "nextcraft-theme";
1244
- var DEFAULT_MODE_KEY = "nextcraft-mode";
1245
- function ThemeProvider({
1246
- children,
1247
- defaultTheme = "ocean",
1248
- defaultMode = "system",
1249
- storageKeyTheme = DEFAULT_THEME_KEY,
1250
- storageKeyMode = DEFAULT_MODE_KEY
1251
- }) {
1252
- const [theme, setTheme] = React14.useState(defaultTheme);
1253
- const [mode, setMode] = React14.useState(defaultMode);
1254
- React14.useEffect(() => {
1255
- if (typeof window === "undefined") return;
1256
- try {
1257
- const storedTheme = window.localStorage.getItem(storageKeyTheme);
1258
- const storedMode = window.localStorage.getItem(storageKeyMode);
1259
- if (storedTheme) setTheme(storedTheme);
1260
- if (storedMode) setMode(storedMode);
1261
- } catch {
1262
- }
1263
- }, [storageKeyTheme, storageKeyMode]);
1264
- React14.useEffect(() => {
1265
- if (typeof window === "undefined") return;
1266
- try {
1267
- window.localStorage.setItem(storageKeyTheme, theme);
1268
- window.localStorage.setItem(storageKeyMode, mode);
1269
- } catch {
1270
- }
1271
- }, [theme, mode, storageKeyTheme, storageKeyMode]);
1272
- React14.useEffect(() => {
1273
- if (typeof document === "undefined") return;
1274
- const root = document.documentElement;
1275
- root.dataset.ncTheme = theme;
1276
- if (mode !== "system") {
1277
- root.dataset.ncMode = mode;
1278
- return;
1279
- }
1280
- const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
1281
- const applySystem = () => {
1282
- root.dataset.ncMode = mediaQuery.matches ? "dark" : "light";
1283
- };
1284
- applySystem();
1285
- if (typeof mediaQuery.addEventListener === "function") {
1286
- mediaQuery.addEventListener("change", applySystem);
1287
- return () => mediaQuery.removeEventListener("change", applySystem);
1288
- }
1289
- mediaQuery.addListener(applySystem);
1290
- return () => mediaQuery.removeListener(applySystem);
1291
- }, [theme, mode]);
1292
- const value = React14.useMemo(
1293
- () => ({ theme, mode, setTheme, setMode }),
1294
- [theme, mode]
1295
- );
1296
- return /* @__PURE__ */ jsx28(ThemeContext.Provider, { value, children });
1297
- }
1298
- function useTheme() {
1299
- const context = React14.useContext(ThemeContext);
1300
- if (!context) {
1301
- throw new Error("useTheme must be used within ThemeProvider");
1302
- }
1303
- return context;
1304
- }
1305
-
1306
- // src/components/theme-switcher.tsx
1307
- import { jsx as jsx29, jsxs as jsxs19 } from "react/jsx-runtime";
1308
- var MODE_OPTIONS = ["system", "light", "dark"];
1309
- function ThemeSwitcher({ className, showLabels = true, ...props }) {
1310
- const { theme, mode, setTheme, setMode } = useTheme();
1311
- return /* @__PURE__ */ jsxs19(
1312
- "div",
1313
- {
1314
- className: cn(
1315
- "flex flex-wrap items-center gap-3 rounded-2xl border border-[rgb(var(--nc-border)/0.3)] bg-[rgb(var(--nc-surface)/0.08)] px-4 py-3 text-sm text-[rgb(var(--nc-fg))] shadow-[inset_0_1px_0_rgba(255,255,255,0.06)]",
1316
- className
1317
- ),
1318
- ...props,
1319
- children: [
1320
- /* @__PURE__ */ jsxs19("label", { className: "flex items-center gap-2", children: [
1321
- showLabels && /* @__PURE__ */ jsx29("span", { className: "text-[rgb(var(--nc-fg-muted))]", children: "Theme" }),
1322
- /* @__PURE__ */ jsx29(
1323
- "select",
1324
- {
1325
- className: "rounded-lg border border-[rgb(var(--nc-border)/0.3)] bg-[rgb(var(--nc-surface)/0.12)] px-3 py-1 text-[rgb(var(--nc-fg))] outline-none focus:ring-2 focus:ring-[rgb(var(--nc-accent-1)/0.5)]",
1326
- value: theme,
1327
- onChange: (event) => setTheme(event.target.value),
1328
- children: THEME_NAMES.map((name) => /* @__PURE__ */ jsx29("option", { value: name, className: "text-slate-900", children: name }, name))
1329
- }
1330
- )
1331
- ] }),
1332
- /* @__PURE__ */ jsxs19("label", { className: "flex items-center gap-2", children: [
1333
- showLabels && /* @__PURE__ */ jsx29("span", { className: "text-[rgb(var(--nc-fg-muted))]", children: "Mode" }),
1334
- /* @__PURE__ */ jsx29(
1335
- "select",
1336
- {
1337
- className: "rounded-lg border border-[rgb(var(--nc-border)/0.3)] bg-[rgb(var(--nc-surface)/0.12)] px-3 py-1 text-[rgb(var(--nc-fg))] outline-none focus:ring-2 focus:ring-[rgb(var(--nc-accent-1)/0.5)]",
1338
- value: mode,
1339
- onChange: (event) => setMode(event.target.value),
1340
- children: MODE_OPTIONS.map((value) => /* @__PURE__ */ jsx29("option", { value, className: "text-slate-900", children: value }, value))
1341
- }
1342
- )
1343
- ] })
1344
- ]
1345
- }
1346
- );
1347
- }
1
+ import {
2
+ CraftAlert,
3
+ CraftBadge,
4
+ CraftCard,
5
+ CraftCommandPalette,
6
+ CraftConfirmDialog,
7
+ CraftCreateEditDrawer,
8
+ CraftDrawer,
9
+ CraftDropdownMenu,
10
+ CraftEmptyState,
11
+ CraftErrorState,
12
+ CraftLink,
13
+ CraftLoadingState,
14
+ CraftPopover,
15
+ CraftSkeleton,
16
+ CraftStatCard,
17
+ CraftTabs,
18
+ CraftToastHost,
19
+ CraftTooltip,
20
+ GlassCard,
21
+ useCraftToast
22
+ } from "./chunk-SBLIF6UU.js";
23
+ import {
24
+ CraftForm,
25
+ CraftFormBuilder,
26
+ CraftFormField
27
+ } from "./chunk-7Q4Z47HT.js";
28
+ import {
29
+ CraftButton,
30
+ CraftCheckbox,
31
+ CraftCurrencyInput,
32
+ CraftDatePicker,
33
+ CraftModal,
34
+ CraftNumberInput,
35
+ CraftSelect,
36
+ CraftSubmitButton,
37
+ CraftSwitch,
38
+ CraftTextarea
39
+ } from "./chunk-6F7FN2ZF.js";
40
+ import {
41
+ AppShell,
42
+ AppTemplate,
43
+ AuthLayout,
44
+ Breadcrumbs,
45
+ Container,
46
+ Grid,
47
+ PageHeader,
48
+ Sidebar,
49
+ TopNav,
50
+ layoutConfigSchema
51
+ } from "./chunk-YVZL4GET.js";
52
+ import {
53
+ CraftIcon,
54
+ CraftIconProvider
55
+ } from "./chunk-FEFH5O5K.js";
56
+ import {
57
+ CraftDataTable,
58
+ CraftFilterBar,
59
+ CraftPagination,
60
+ CraftTableToolbar
61
+ } from "./chunk-ZRV4Y374.js";
62
+ import {
63
+ CraftInput
64
+ } from "./chunk-7SKDTIEK.js";
65
+ import {
66
+ ThemeProvider,
67
+ ThemeSwitcher,
68
+ useTheme
69
+ } from "./chunk-M2EKVXB6.js";
70
+ import "./chunk-VQ6T3HIX.js";
1348
71
  export {
1349
72
  AppShell,
73
+ AppTemplate,
1350
74
  AuthLayout,
1351
75
  Breadcrumbs,
1352
76
  Container,
77
+ CraftAlert,
1353
78
  CraftBadge,
1354
79
  CraftButton,
1355
80
  CraftCard,
1356
81
  CraftCheckbox,
82
+ CraftCommandPalette,
83
+ CraftConfirmDialog,
84
+ CraftCreateEditDrawer,
1357
85
  CraftCurrencyInput,
86
+ CraftDataTable,
1358
87
  CraftDatePicker,
1359
88
  CraftDrawer,
89
+ CraftDropdownMenu,
1360
90
  CraftEmptyState,
91
+ CraftErrorState,
92
+ CraftFilterBar,
93
+ CraftForm,
94
+ CraftFormBuilder,
95
+ CraftFormField,
96
+ CraftIcon,
97
+ CraftIconProvider,
1361
98
  CraftInput,
99
+ CraftLink,
100
+ CraftLoadingState,
1362
101
  CraftModal,
1363
102
  CraftNumberInput,
103
+ CraftPagination,
104
+ CraftPopover,
1364
105
  CraftSelect,
1365
106
  CraftSkeleton,
107
+ CraftStatCard,
108
+ CraftSubmitButton,
1366
109
  CraftSwitch,
110
+ CraftTableToolbar,
1367
111
  CraftTabs,
1368
112
  CraftTextarea,
1369
113
  CraftToastHost,
@@ -1375,6 +119,7 @@ export {
1375
119
  ThemeProvider,
1376
120
  ThemeSwitcher,
1377
121
  TopNav,
122
+ layoutConfigSchema,
1378
123
  useCraftToast,
1379
124
  useTheme
1380
125
  };