@jameskabz/nextcraft-ui 0.6.2 → 0.6.4

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 (44) hide show
  1. package/dist/craft/components.cjs +64 -1779
  2. package/dist/craft/components.cjs.map +1 -1
  3. package/dist/craft/components.js +31 -42
  4. package/dist/craft/components.js.map +1 -1
  5. package/dist/craft/forms.cjs +6 -1347
  6. package/dist/craft/forms.cjs.map +1 -1
  7. package/dist/craft/forms.js +3 -8
  8. package/dist/craft/forms.js.map +1 -1
  9. package/dist/craft/layout.cjs +20 -374
  10. package/dist/craft/layout.cjs.map +1 -1
  11. package/dist/craft/layout.js +10 -14
  12. package/dist/craft/layout.js.map +1 -1
  13. package/dist/craft/table.cjs +8 -632
  14. package/dist/craft/table.cjs.map +1 -1
  15. package/dist/craft/table.js +4 -8
  16. package/dist/craft/table.js.map +1 -1
  17. package/dist/craft/theme.cjs +5 -137
  18. package/dist/craft/theme.cjs.map +1 -1
  19. package/dist/craft/theme.js +2 -6
  20. package/dist/craft/theme.js.map +1 -1
  21. package/dist/index.cjs +103 -3426
  22. package/dist/index.cjs.map +1 -1
  23. package/dist/index.js +50 -70
  24. package/dist/index.js.map +1 -1
  25. package/dist/styles.css +0 -31
  26. package/package.json +8 -4
  27. package/dist/chunk-6F7FN2ZF.js +0 -671
  28. package/dist/chunk-6F7FN2ZF.js.map +0 -1
  29. package/dist/chunk-7Q4Z47HT.js +0 -657
  30. package/dist/chunk-7Q4Z47HT.js.map +0 -1
  31. package/dist/chunk-7SKDTIEK.js +0 -49
  32. package/dist/chunk-7SKDTIEK.js.map +0 -1
  33. package/dist/chunk-FEFH5O5K.js +0 -49
  34. package/dist/chunk-FEFH5O5K.js.map +0 -1
  35. package/dist/chunk-M2EKVXB6.js +0 -127
  36. package/dist/chunk-M2EKVXB6.js.map +0 -1
  37. package/dist/chunk-SBLIF6UU.js +0 -1029
  38. package/dist/chunk-SBLIF6UU.js.map +0 -1
  39. package/dist/chunk-VQ6T3HIX.js +0 -9
  40. package/dist/chunk-VQ6T3HIX.js.map +0 -1
  41. package/dist/chunk-YVZL4GET.js +0 -328
  42. package/dist/chunk-YVZL4GET.js.map +0 -1
  43. package/dist/chunk-ZRV4Y374.js +0 -582
  44. package/dist/chunk-ZRV4Y374.js.map +0 -1
package/dist/index.cjs CHANGED
@@ -1,9 +1,7 @@
1
1
  "use strict";
2
- var __create = Object.create;
3
2
  var __defProp = Object.defineProperty;
4
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
5
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
6
  var __export = (target, all) => {
9
7
  for (var name in all)
@@ -17,3435 +15,114 @@ var __copyProps = (to, from, except, desc) => {
17
15
  }
18
16
  return to;
19
17
  };
20
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
- // If the importer is in node compatibility mode or this is not an ESM
22
- // file that has been converted to a CommonJS file using a Babel-
23
- // compatible transform (i.e. "__esModule" has not been set), then set
24
- // "default" to the CommonJS "module.exports" for node compatibility.
25
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
- mod
27
- ));
28
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
-
30
- // src/index.ts
31
19
  var index_exports = {};
32
20
  __export(index_exports, {
33
- AppShell: () => AppShell,
34
- AppTemplate: () => AppTemplate,
35
- AuthLayout: () => AuthLayout,
36
- Breadcrumbs: () => Breadcrumbs,
37
- Container: () => Container,
38
- CraftAlert: () => CraftAlert,
39
- CraftBadge: () => CraftBadge,
40
- CraftButton: () => CraftButton,
41
- CraftCard: () => CraftCard,
42
- CraftCheckbox: () => CraftCheckbox,
43
- CraftCommandPalette: () => CraftCommandPalette,
44
- CraftConfirmDialog: () => CraftConfirmDialog,
45
- CraftCreateEditDrawer: () => CraftCreateEditDrawer,
46
- CraftCurrencyInput: () => CraftCurrencyInput,
47
- CraftDataTable: () => CraftDataTable,
48
- CraftDatePicker: () => CraftDatePicker,
49
- CraftDrawer: () => CraftDrawer,
50
- CraftDropdownMenu: () => CraftDropdownMenu,
51
- CraftEmptyState: () => CraftEmptyState,
52
- CraftErrorState: () => CraftErrorState,
53
- CraftFilterBar: () => CraftFilterBar,
54
- CraftForm: () => CraftForm,
55
- CraftFormBuilder: () => CraftFormBuilder,
56
- CraftFormField: () => CraftFormField,
57
- CraftIcon: () => CraftIcon,
58
- CraftIconProvider: () => CraftIconProvider,
59
- CraftInput: () => CraftInput,
60
- CraftLink: () => CraftLink,
61
- CraftLoadingState: () => CraftLoadingState,
62
- CraftModal: () => CraftModal,
63
- CraftNumberInput: () => CraftNumberInput,
64
- CraftPagination: () => CraftPagination,
65
- CraftPopover: () => CraftPopover,
66
- CraftSelect: () => CraftSelect,
67
- CraftSkeleton: () => CraftSkeleton,
68
- CraftStatCard: () => CraftStatCard,
69
- CraftSubmitButton: () => CraftSubmitButton,
70
- CraftSwitch: () => CraftSwitch,
71
- CraftTableToolbar: () => CraftTableToolbar,
72
- CraftTabs: () => CraftTabs,
73
- CraftTextarea: () => CraftTextarea,
74
- CraftToastHost: () => CraftToastHost,
75
- CraftTooltip: () => CraftTooltip,
76
- GlassCard: () => GlassCard,
77
- Grid: () => Grid,
78
- PageHeader: () => PageHeader,
79
- Sidebar: () => Sidebar,
80
- ThemeProvider: () => ThemeProvider,
81
- ThemeSwitcher: () => ThemeSwitcher,
82
- TopNav: () => TopNav,
83
- layoutConfigSchema: () => layoutConfigSchema,
84
- useCraftToast: () => useCraftToast,
85
- useTheme: () => useTheme
21
+ AppShell: () => import_app_shell.AppShell,
22
+ AppTemplate: () => import_app_template.AppTemplate,
23
+ AuthLayout: () => import_auth_layout.AuthLayout,
24
+ Breadcrumbs: () => import_breadcrumbs.Breadcrumbs,
25
+ Container: () => import_container.Container,
26
+ CraftAlert: () => import_craft_alert.CraftAlert,
27
+ CraftBadge: () => import_craft_badge.CraftBadge,
28
+ CraftButton: () => import_craft_button.CraftButton,
29
+ CraftCard: () => import_craft_card.CraftCard,
30
+ CraftCheckbox: () => import_craft_checkbox.CraftCheckbox,
31
+ CraftCommandPalette: () => import_craft_command_palette.CraftCommandPalette,
32
+ CraftConfirmDialog: () => import_craft_confirm_dialog.CraftConfirmDialog,
33
+ CraftCreateEditDrawer: () => import_craft_create_edit_drawer.CraftCreateEditDrawer,
34
+ CraftCurrencyInput: () => import_craft_currency_input.CraftCurrencyInput,
35
+ CraftDataTable: () => import_craft_data_table.CraftDataTable,
36
+ CraftDatePicker: () => import_craft_date_picker.CraftDatePicker,
37
+ CraftDrawer: () => import_craft_drawer.CraftDrawer,
38
+ CraftDropdownMenu: () => import_craft_dropdown_menu.CraftDropdownMenu,
39
+ CraftEmptyState: () => import_craft_empty_state.CraftEmptyState,
40
+ CraftErrorState: () => import_craft_error_state.CraftErrorState,
41
+ CraftFilterBar: () => import_craft_filter_bar.CraftFilterBar,
42
+ CraftForm: () => import_craft_form.CraftForm,
43
+ CraftFormBuilder: () => import_craft_form_builder.CraftFormBuilder,
44
+ CraftFormField: () => import_craft_form_field.CraftFormField,
45
+ CraftIcon: () => import_craft_icon.CraftIcon,
46
+ CraftIconProvider: () => import_craft_icon.CraftIconProvider,
47
+ CraftInput: () => import_craft_input.CraftInput,
48
+ CraftLink: () => import_craft_link.CraftLink,
49
+ CraftLoadingState: () => import_craft_loading_state.CraftLoadingState,
50
+ CraftModal: () => import_craft_modal.CraftModal,
51
+ CraftNumberInput: () => import_craft_number_input.CraftNumberInput,
52
+ CraftPagination: () => import_craft_pagination.CraftPagination,
53
+ CraftPopover: () => import_craft_popover.CraftPopover,
54
+ CraftSelect: () => import_craft_select.CraftSelect,
55
+ CraftSkeleton: () => import_craft_skeleton.CraftSkeleton,
56
+ CraftStatCard: () => import_craft_stat_card.CraftStatCard,
57
+ CraftSubmitButton: () => import_craft_submit_button.CraftSubmitButton,
58
+ CraftSwitch: () => import_craft_switch.CraftSwitch,
59
+ CraftTableToolbar: () => import_craft_table_toolbar.CraftTableToolbar,
60
+ CraftTabs: () => import_craft_tabs.CraftTabs,
61
+ CraftTextarea: () => import_craft_textarea.CraftTextarea,
62
+ CraftToastHost: () => import_craft_toast.CraftToastHost,
63
+ CraftTooltip: () => import_craft_tooltip.CraftTooltip,
64
+ GlassCard: () => import_glass_card.GlassCard,
65
+ Grid: () => import_grid.Grid,
66
+ PageHeader: () => import_page_header.PageHeader,
67
+ Sidebar: () => import_sidebar.Sidebar,
68
+ ThemeProvider: () => import_theme_context.ThemeProvider,
69
+ ThemeSwitcher: () => import_theme_switcher.ThemeSwitcher,
70
+ TopNav: () => import_top_nav.TopNav,
71
+ layoutConfigSchema: () => import_layout_config.layoutConfigSchema,
72
+ useCraftToast: () => import_craft_toast.useCraftToast,
73
+ useTheme: () => import_theme_context.useTheme
86
74
  });
87
75
  module.exports = __toCommonJS(index_exports);
88
-
89
- // src/utils/cn.ts
90
- function cn(...values) {
91
- return values.filter(Boolean).join(" ");
92
- }
93
-
94
- // src/components/craft-button.tsx
95
- var import_jsx_runtime = require("react/jsx-runtime");
96
- var sizeClasses = {
97
- sm: "h-9 px-4 text-xs",
98
- md: "h-11 px-6 text-sm",
99
- lg: "h-13 px-8 text-base"
100
- };
101
- var variantClasses = {
102
- 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]",
103
- 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)]",
104
- 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)]",
105
- 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]"
106
- };
107
- function CraftButton({
108
- className,
109
- variant = "solid",
110
- size = "md",
111
- glow = true,
112
- tone,
113
- disabled,
114
- ...props
115
- }) {
116
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
117
- "button",
118
- {
119
- className: cn(
120
- "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",
121
- sizeClasses[size],
122
- variantClasses[variant],
123
- 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" : "",
124
- className
125
- ),
126
- "data-nc-theme": tone,
127
- disabled,
128
- ...props
129
- }
130
- );
131
- }
132
-
133
- // src/components/glass-card.tsx
134
- var import_jsx_runtime2 = require("react/jsx-runtime");
135
- var intensityClasses = {
136
- subtle: "backdrop-blur-md bg-opacity-50",
137
- medium: "backdrop-blur-xl bg-opacity-70",
138
- strong: "backdrop-blur-2xl bg-opacity-90"
139
- };
140
- function GlassCard({
141
- className,
142
- tone,
143
- intensity = "medium",
144
- bordered = true,
145
- children,
146
- ...props
147
- }) {
148
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
149
- "div",
150
- {
151
- className: cn(
152
- "relative overflow-hidden rounded-3xl p-6 text-[rgb(var(--nc-fg))]",
153
- "shadow-[0_8px_32px_rgba(0,0,0,0.3)]",
154
- "transition-all duration-300",
155
- "hover:shadow-[0_8px_40px_rgba(0,0,0,0.4)]",
156
- intensityClasses[intensity],
157
- "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)]",
158
- "border-[rgb(var(--nc-accent-1)/0.3)]",
159
- bordered ? "border-2" : "border-0",
160
- "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",
161
- className
162
- ),
163
- "data-nc-theme": tone,
164
- ...props,
165
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "relative z-10", children })
166
- }
167
- );
168
- }
169
-
170
- // src/components/craft-input.tsx
171
- var React = __toESM(require("react"), 1);
172
- var import_jsx_runtime3 = require("react/jsx-runtime");
173
- var inputSizeClasses = {
174
- sm: "h-10 px-4 text-sm",
175
- md: "h-12 px-5 text-base",
176
- lg: "h-14 px-6 text-lg"
177
- };
178
- var CraftInput = React.forwardRef(
179
- ({ className, tone, inputSize = "md", glow = true, icon, ...props }, ref) => {
180
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "relative w-full", "data-nc-theme": tone, children: [
181
- icon && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "absolute left-4 top-1/2 -translate-y-1/2 text-[rgb(var(--nc-fg-soft))]", children: icon }),
182
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
183
- "input",
184
- {
185
- ref,
186
- className: cn(
187
- "w-full rounded-2xl border-2 bg-[rgb(var(--nc-surface)/0.08)] text-[rgb(var(--nc-fg))] backdrop-blur-xl",
188
- "shadow-[inset_0_2px_8px_rgba(0,0,0,0.3)]",
189
- "focus:outline-none focus:ring-4",
190
- "transition-all duration-300",
191
- "disabled:opacity-50 disabled:cursor-not-allowed",
192
- inputSizeClasses[inputSize],
193
- "border-[rgb(var(--nc-border)/0.35)]",
194
- "focus:border-[rgb(var(--nc-accent-1)/0.8)] focus:ring-[rgb(var(--nc-accent-1)/0.3)]",
195
- "placeholder:text-[rgb(var(--nc-fg-soft))]",
196
- glow ? "focus:shadow-[0_0_30px_-5px_var(--glow-color)]" : "",
197
- icon ? "pl-12" : "",
198
- className
199
- ),
200
- style: {
201
- "--glow-color": "rgb(var(--nc-accent-1) / 0.5)"
202
- },
203
- ...props
204
- }
205
- )
206
- ] });
207
- }
208
- );
209
- CraftInput.displayName = "CraftInput";
210
-
211
- // src/components/craft-textarea.tsx
212
- var React2 = __toESM(require("react"), 1);
213
- var import_jsx_runtime4 = require("react/jsx-runtime");
214
- var CraftTextarea = React2.forwardRef(
215
- ({ className, tone, rows = 4, ...props }, ref) => {
216
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "relative w-full", "data-nc-theme": tone, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
217
- "textarea",
218
- {
219
- ref,
220
- rows,
221
- className: cn(
222
- "w-full rounded-2xl border-2 bg-[rgb(var(--nc-surface)/0.08)] text-[rgb(var(--nc-fg))] backdrop-blur-xl",
223
- "shadow-[inset_0_2px_8px_rgba(0,0,0,0.3)]",
224
- "focus:outline-none focus:ring-4",
225
- "transition-all duration-300",
226
- "disabled:opacity-50 disabled:cursor-not-allowed",
227
- "border-[rgb(var(--nc-border)/0.35)]",
228
- "focus:border-[rgb(var(--nc-accent-1)/0.8)] focus:ring-[rgb(var(--nc-accent-1)/0.3)]",
229
- "placeholder:text-[rgb(var(--nc-fg-soft))]",
230
- "px-5 py-3 text-base",
231
- className
232
- ),
233
- style: {
234
- "--glow-color": "rgb(var(--nc-accent-1) / 0.5)"
235
- },
236
- ...props
237
- }
238
- ) });
239
- }
240
- );
241
- CraftTextarea.displayName = "CraftTextarea";
242
-
243
- // src/components/craft-select.tsx
244
- var React3 = __toESM(require("react"), 1);
245
- var import_jsx_runtime5 = require("react/jsx-runtime");
246
- var CraftSelect = React3.forwardRef(
247
- ({ className, tone, children, ...props }, ref) => {
248
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "relative w-full", "data-nc-theme": tone, children: [
249
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
250
- "select",
251
- {
252
- ref,
253
- className: cn(
254
- "w-full appearance-none rounded-2xl border-2 bg-[rgb(var(--nc-surface)/0.08)] text-[rgb(var(--nc-fg))] backdrop-blur-xl",
255
- "shadow-[inset_0_2px_8px_rgba(0,0,0,0.3)]",
256
- "focus:outline-none focus:ring-4",
257
- "transition-all duration-300",
258
- "disabled:opacity-50 disabled:cursor-not-allowed",
259
- "border-[rgb(var(--nc-border)/0.35)]",
260
- "focus:border-[rgb(var(--nc-accent-1)/0.8)] focus:ring-[rgb(var(--nc-accent-1)/0.3)]",
261
- "px-5 py-3 pr-10 text-base",
262
- className
263
- ),
264
- ...props,
265
- children
266
- }
267
- ),
268
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
269
- "svg",
270
- {
271
- className: "pointer-events-none absolute right-4 top-1/2 h-4 w-4 -translate-y-1/2 text-[rgb(var(--nc-fg-soft))]",
272
- viewBox: "0 0 20 20",
273
- fill: "currentColor",
274
- "aria-hidden": "true",
275
- children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
276
- "path",
277
- {
278
- fillRule: "evenodd",
279
- 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",
280
- clipRule: "evenodd"
281
- }
282
- )
283
- }
284
- )
285
- ] });
286
- }
287
- );
288
- CraftSelect.displayName = "CraftSelect";
289
-
290
- // src/components/craft-checkbox.tsx
291
- var React4 = __toESM(require("react"), 1);
292
- var import_jsx_runtime6 = require("react/jsx-runtime");
293
- var CraftCheckbox = React4.forwardRef(
294
- ({ className, tone, label, description, ...props }, ref) => {
295
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
296
- "label",
297
- {
298
- className: cn(
299
- "flex items-start gap-3 text-sm text-[rgb(var(--nc-fg))]",
300
- props.disabled ? "opacity-60" : "cursor-pointer",
301
- className
302
- ),
303
- "data-nc-theme": tone,
304
- children: [
305
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "relative mt-0.5", children: [
306
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
307
- "input",
308
- {
309
- ref,
310
- type: "checkbox",
311
- className: "peer sr-only",
312
- ...props
313
- }
314
- ),
315
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
316
- "span",
317
- {
318
- className: cn(
319
- "flex h-5 w-5 items-center justify-center rounded-md border-2",
320
- "border-[rgb(var(--nc-border)/0.45)] bg-[rgb(var(--nc-surface)/0.08)]",
321
- "transition-all duration-200",
322
- "peer-checked:border-[rgb(var(--nc-accent-1))] peer-checked:bg-[rgb(var(--nc-accent-1)/0.25)]",
323
- "peer-focus-visible:ring-2 peer-focus-visible:ring-[rgb(var(--nc-accent-1)/0.5)]"
324
- ),
325
- children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
326
- "svg",
327
- {
328
- className: "h-3 w-3 text-[rgb(var(--nc-fg))] opacity-0 transition-opacity peer-checked:opacity-100",
329
- viewBox: "0 0 20 20",
330
- fill: "currentColor",
331
- "aria-hidden": "true",
332
- children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
333
- "path",
334
- {
335
- fillRule: "evenodd",
336
- 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",
337
- clipRule: "evenodd"
338
- }
339
- )
340
- }
341
- )
342
- }
343
- )
344
- ] }),
345
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "space-y-1", children: [
346
- label && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "block font-medium text-[rgb(var(--nc-fg))]", children: label }),
347
- description && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "block text-xs text-[rgb(var(--nc-fg-muted))]", children: description })
348
- ] })
349
- ]
350
- }
351
- );
352
- }
353
- );
354
- CraftCheckbox.displayName = "CraftCheckbox";
355
-
356
- // src/components/craft-switch.tsx
357
- var React5 = __toESM(require("react"), 1);
358
- var import_jsx_runtime7 = require("react/jsx-runtime");
359
- var CraftSwitch = React5.forwardRef(
360
- ({ className, tone, label, ...props }, ref) => {
361
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
362
- "label",
363
- {
364
- className: cn(
365
- "inline-flex items-center gap-3 text-sm text-[rgb(var(--nc-fg))]",
366
- props.disabled ? "opacity-60" : "cursor-pointer",
367
- className
368
- ),
369
- "data-nc-theme": tone,
370
- children: [
371
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("input", { ref, type: "checkbox", className: "peer sr-only", ...props }),
372
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
373
- "span",
374
- {
375
- className: cn(
376
- "relative h-6 w-11 rounded-full border-2 border-[rgb(var(--nc-border)/0.35)] bg-[rgb(var(--nc-surface)/0.08)]",
377
- "transition-all duration-200",
378
- "peer-focus-visible:ring-2 peer-focus-visible:ring-[rgb(var(--nc-accent-1)/0.5)]",
379
- "peer-checked:border-[rgb(var(--nc-accent-1)/0.6)] peer-checked:bg-[rgb(var(--nc-accent-1)/0.25)]"
380
- ),
381
- children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
382
- "span",
383
- {
384
- className: cn(
385
- "absolute left-0.5 top-0.5 h-4 w-4 rounded-full bg-[rgb(var(--nc-surface-muted)/0.9)]",
386
- "transition-all duration-200",
387
- "peer-checked:translate-x-5 peer-checked:bg-[rgb(var(--nc-surface-muted))]"
388
- )
389
- }
390
- )
391
- }
392
- ),
393
- label && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: label })
394
- ]
395
- }
396
- );
397
- }
398
- );
399
- CraftSwitch.displayName = "CraftSwitch";
400
-
401
- // src/components/craft-badge.tsx
402
- var import_jsx_runtime8 = require("react/jsx-runtime");
403
- var variantClasses2 = {
404
- solid: "bg-[color:rgb(var(--nc-accent-1))] text-white shadow-[0_10px_20px_rgb(var(--nc-accent-1)/0.35)]",
405
- soft: "bg-[color:rgb(var(--nc-accent-1)/0.2)] text-[rgb(var(--nc-fg))]",
406
- outline: "border border-[color:rgb(var(--nc-accent-1)/0.6)] text-[rgb(var(--nc-fg))]"
407
- };
408
- function CraftBadge({
409
- className,
410
- variant = "soft",
411
- tone,
412
- ...props
413
- }) {
414
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
415
- "span",
416
- {
417
- className: cn(
418
- "inline-flex items-center rounded-full px-3 py-1 text-xs font-semibold uppercase tracking-wide",
419
- variantClasses2[variant],
420
- className
421
- ),
422
- "data-nc-theme": tone,
423
- ...props
424
- }
425
- );
426
- }
427
-
428
- // src/components/craft-alert.tsx
429
- var import_jsx_runtime9 = require("react/jsx-runtime");
430
- var variantClasses3 = {
431
- info: "border-[rgb(var(--nc-accent-1)/0.45)] bg-[rgb(var(--nc-accent-1)/0.12)]",
432
- success: "border-[rgb(var(--nc-accent-2)/0.45)] bg-[rgb(var(--nc-accent-2)/0.12)]",
433
- warning: "border-[rgb(var(--nc-accent-3)/0.45)] bg-[rgb(var(--nc-accent-3)/0.12)]",
434
- error: "border-[rgb(var(--nc-accent-3)/0.65)] bg-[rgb(var(--nc-accent-3)/0.18)]"
435
- };
436
- function CraftAlert({
437
- title,
438
- description,
439
- variant = "info",
440
- icon,
441
- actions,
442
- tone,
443
- className,
444
- ...props
445
- }) {
446
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
447
- "div",
448
- {
449
- className: cn(
450
- "rounded-2xl border p-4 text-[rgb(var(--nc-fg))] backdrop-blur-xl",
451
- variantClasses3[variant],
452
- className
453
- ),
454
- "data-nc-theme": tone,
455
- ...props,
456
- children: [
457
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex items-start gap-3", children: [
458
- icon && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "mt-1 text-[rgb(var(--nc-fg))]", children: icon }),
459
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "space-y-1", children: [
460
- title && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { className: "text-sm font-semibold", children: title }),
461
- description && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { className: "text-sm text-[rgb(var(--nc-fg-muted))]", children: description })
462
- ] })
463
- ] }),
464
- actions && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "mt-3 flex flex-wrap gap-2", children: actions })
465
- ]
466
- }
467
- );
468
- }
469
-
470
- // src/components/craft-error-state.tsx
471
- var import_jsx_runtime10 = require("react/jsx-runtime");
472
- function CraftErrorState({
473
- title = "Something went wrong",
474
- description = "Try again or check your connection.",
475
- actionLabel = "Retry",
476
- onAction,
477
- action,
478
- tone,
479
- className,
480
- ...props
481
- }) {
482
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
483
- "div",
484
- {
485
- className: cn(
486
- "rounded-3xl border border-[rgb(var(--nc-border)/0.35)] bg-[rgb(var(--nc-surface)/0.12)] p-6 text-[rgb(var(--nc-fg))] shadow-[0_12px_30px_rgba(0,0,0,0.25)] backdrop-blur-xl",
487
- className
488
- ),
489
- "data-nc-theme": tone,
490
- ...props,
491
- children: [
492
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "space-y-2", children: [
493
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("h3", { className: "text-lg font-semibold", children: title }),
494
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "text-sm text-[rgb(var(--nc-fg-muted))]", children: description })
495
- ] }),
496
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "mt-4", children: action != null ? action : onAction && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(CraftButton, { size: "sm", onClick: onAction, children: actionLabel }) })
497
- ]
498
- }
499
- );
500
- }
501
-
502
- // src/components/craft-loading-state.tsx
503
- var import_jsx_runtime11 = require("react/jsx-runtime");
504
- var sizeClasses2 = {
505
- sm: "h-4 w-4 border-2",
506
- md: "h-6 w-6 border-2",
507
- lg: "h-8 w-8 border-[3px]"
508
- };
509
- function CraftLoadingState({
510
- label = "Loading...",
511
- size = "md",
512
- tone,
513
- className,
514
- ...props
515
- }) {
516
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
517
- "div",
518
- {
519
- className: cn("flex items-center gap-3 text-[rgb(var(--nc-fg))]", className),
520
- "data-nc-theme": tone,
521
- ...props,
522
- children: [
523
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
524
- "span",
525
- {
526
- className: cn(
527
- "inline-block animate-spin rounded-full border-[rgb(var(--nc-accent-1)/0.25)] border-t-[rgb(var(--nc-accent-1))]",
528
- sizeClasses2[size]
529
- ),
530
- "aria-hidden": "true"
531
- }
532
- ),
533
- label && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "text-sm text-[rgb(var(--nc-fg-muted))]", children: label })
534
- ]
535
- }
536
- );
537
- }
538
-
539
- // src/components/craft-card.tsx
540
- var import_jsx_runtime12 = require("react/jsx-runtime");
541
- var intensityClasses2 = {
542
- subtle: "backdrop-blur-md bg-opacity-50",
543
- medium: "backdrop-blur-xl bg-opacity-70",
544
- strong: "backdrop-blur-2xl bg-opacity-90"
545
- };
546
- function CraftCard({
547
- className,
548
- tone,
549
- elevated = true,
550
- intensity = "medium",
551
- bordered = true,
552
- children,
553
- ...props
554
- }) {
555
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
556
- "div",
557
- {
558
- className: cn(
559
- "relative overflow-hidden rounded-3xl p-6 text-[rgb(var(--nc-fg))]",
560
- intensityClasses2[intensity],
561
- "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)]",
562
- bordered ? "border-2 border-[rgb(var(--nc-accent-1)/0.3)]" : "border-0",
563
- elevated ? "shadow-[0_8px_32px_rgba(0,0,0,0.3)] hover:shadow-[0_8px_40px_rgba(0,0,0,0.4)]" : "shadow-none",
564
- "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",
565
- "transition-all duration-300",
566
- className
567
- ),
568
- "data-nc-theme": tone,
569
- ...props,
570
- children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "relative z-10", children })
571
- }
572
- );
573
- }
574
-
575
- // src/components/craft-modal.tsx
576
- var React6 = __toESM(require("react"), 1);
577
- var import_react_dom = require("react-dom");
578
- var import_jsx_runtime13 = require("react/jsx-runtime");
579
- var FOCUSABLE_SELECTORS = [
580
- "a[href]",
581
- "button:not([disabled])",
582
- "textarea:not([disabled])",
583
- "input:not([disabled])",
584
- "select:not([disabled])",
585
- "[tabindex]:not([tabindex='-1'])"
586
- ].join(",");
587
- function useFocusTrap(active) {
588
- const ref = React6.useRef(null);
589
- React6.useEffect(() => {
590
- if (!active || !ref.current) return;
591
- const root = ref.current;
592
- const getFocusable = () => Array.from(root.querySelectorAll(FOCUSABLE_SELECTORS));
593
- const focusables = getFocusable();
594
- if (focusables.length) {
595
- focusables[0].focus();
596
- } else {
597
- root.focus();
598
- }
599
- const handleKeyDown = (event) => {
600
- if (event.key !== "Tab") return;
601
- const items = getFocusable();
602
- if (!items.length) return;
603
- const first = items[0];
604
- const last = items[items.length - 1];
605
- const activeEl = document.activeElement;
606
- if (event.shiftKey && activeEl === first) {
607
- event.preventDefault();
608
- last.focus();
609
- } else if (!event.shiftKey && activeEl === last) {
610
- event.preventDefault();
611
- first.focus();
612
- }
613
- };
614
- root.addEventListener("keydown", handleKeyDown);
615
- return () => root.removeEventListener("keydown", handleKeyDown);
616
- }, [active]);
617
- return ref;
618
- }
619
- function CraftModal({
620
- open,
621
- defaultOpen = false,
622
- onOpenChange,
623
- tone,
624
- title,
625
- description,
626
- children,
627
- trigger,
628
- footer,
629
- className
630
- }) {
631
- const [uncontrolledOpen, setUncontrolledOpen] = React6.useState(defaultOpen);
632
- const isControlled = typeof open === "boolean";
633
- const isOpen = isControlled ? open : uncontrolledOpen;
634
- const setOpen = React6.useCallback(
635
- (next) => {
636
- if (!isControlled) {
637
- setUncontrolledOpen(next);
638
- }
639
- onOpenChange == null ? void 0 : onOpenChange(next);
640
- },
641
- [isControlled, onOpenChange]
642
- );
643
- React6.useEffect(() => {
644
- if (!isOpen) return;
645
- const handleKey = (event) => {
646
- if (event.key === "Escape") setOpen(false);
647
- };
648
- document.addEventListener("keydown", handleKey);
649
- return () => document.removeEventListener("keydown", handleKey);
650
- }, [isOpen, setOpen]);
651
- const ref = useFocusTrap(isOpen);
652
- const content = isOpen ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "fixed inset-0 z-50 flex items-center justify-center px-4 py-8", children: [
653
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
654
- "div",
655
- {
656
- className: "absolute inset-0 backdrop-blur-sm",
657
- onClick: () => setOpen(false)
658
- }
659
- ),
660
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
661
- "div",
662
- {
663
- ref,
664
- tabIndex: -1,
665
- className: cn(
666
- "relative z-10 w-full max-w-7xl rounded-3xl border border-[rgb(var(--nc-border)/0.45)] p-6 text-[rgb(var(--nc-fg))] shadow-[0_20px_60px_rgba(0,0,0,0.45)] backdrop-blur-2xl",
667
- "max-h-[calc(100vh-1rem)] overflow-y-auto",
668
- className
669
- ),
670
- "data-nc-theme": tone,
671
- children: [
672
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex items-start justify-between gap-4", children: [
673
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "space-y-1", children: [
674
- title && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("h3", { className: "text-2xl font-semibold", children: title }),
675
- description && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: "text-[rgb(var(--nc-fg-muted))]", children: description })
676
- ] }),
677
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
678
- "button",
679
- {
680
- 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))]",
681
- onClick: () => setOpen(false),
682
- "aria-label": "Close",
683
- children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("svg", { viewBox: "0 0 20 20", className: "h-4 w-4", fill: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("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" }) })
684
- }
685
- )
686
- ] }),
687
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "mt-5 space-y-4", children }),
688
- footer && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "mt-6", children: footer })
689
- ]
690
- }
691
- )
692
- ] }) : null;
693
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
694
- trigger && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
695
- "span",
696
- {
697
- onClick: () => setOpen(true),
698
- onKeyDown: (event) => {
699
- if (event.key === "Enter" || event.key === " ") setOpen(true);
700
- },
701
- role: "button",
702
- tabIndex: 0,
703
- className: "inline-flex",
704
- children: trigger
705
- }
706
- ),
707
- typeof document !== "undefined" && content ? (0, import_react_dom.createPortal)(content, document.body) : content
708
- ] });
709
- }
710
-
711
- // src/components/craft-drawer.tsx
712
- var React7 = __toESM(require("react"), 1);
713
- var import_react_dom2 = require("react-dom");
714
- var import_jsx_runtime14 = require("react/jsx-runtime");
715
- function CraftDrawer({
716
- open,
717
- defaultOpen = false,
718
- onOpenChange,
719
- tone,
720
- side = "left",
721
- title,
722
- children,
723
- trigger,
724
- footer,
725
- className
726
- }) {
727
- const [uncontrolledOpen, setUncontrolledOpen] = React7.useState(defaultOpen);
728
- const isControlled = typeof open === "boolean";
729
- const isOpen = isControlled ? open : uncontrolledOpen;
730
- const setOpen = React7.useCallback(
731
- (next) => {
732
- if (!isControlled) setUncontrolledOpen(next);
733
- onOpenChange == null ? void 0 : onOpenChange(next);
734
- },
735
- [isControlled, onOpenChange]
736
- );
737
- React7.useEffect(() => {
738
- if (!isOpen) return;
739
- const handleKey = (event) => {
740
- if (event.key === "Escape") setOpen(false);
741
- };
742
- document.addEventListener("keydown", handleKey);
743
- return () => document.removeEventListener("keydown", handleKey);
744
- }, [isOpen, setOpen]);
745
- const content = isOpen ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "fixed inset-0 z-50 overflow-hidden", children: [
746
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
747
- "div",
748
- {
749
- className: "absolute inset-0 backdrop-blur-sm",
750
- onClick: () => setOpen(false)
751
- }
752
- ),
753
- /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
754
- "div",
755
- {
756
- className: cn(
757
- "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",
758
- side === "right" ? "right-0" : "left-0",
759
- className
760
- ),
761
- "data-nc-theme": tone,
762
- children: [
763
- /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex items-center justify-between border-b border-[rgb(var(--nc-border)/0.3)] p-6", children: [
764
- title && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("h3", { className: "text-xl font-semibold", children: title }),
765
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
766
- "button",
767
- {
768
- 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))]",
769
- onClick: () => setOpen(false),
770
- "aria-label": "Close",
771
- children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("svg", { viewBox: "0 0 20 20", className: "h-4 w-4", fill: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("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" }) })
772
- }
773
- )
774
- ] }),
775
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "p-6 space-y-4 overflow-y-auto h-[calc(100%-5.5rem)]", children }),
776
- footer && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "border-t border-[rgb(var(--nc-border)/0.3)] p-6", children: footer })
777
- ]
778
- }
779
- )
780
- ] }) : null;
781
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
782
- trigger && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
783
- "span",
784
- {
785
- onClick: () => setOpen(true),
786
- onKeyDown: (event) => {
787
- if (event.key === "Enter" || event.key === " ") setOpen(true);
788
- },
789
- role: "button",
790
- tabIndex: 0,
791
- className: "inline-flex",
792
- children: trigger
793
- }
794
- ),
795
- typeof document !== "undefined" && content ? (0, import_react_dom2.createPortal)(content, document.body) : content
796
- ] });
797
- }
798
-
799
- // src/components/craft-tabs.tsx
800
- var React8 = __toESM(require("react"), 1);
801
- var import_jsx_runtime15 = require("react/jsx-runtime");
802
- function CraftTabs({
803
- value,
804
- defaultValue,
805
- onValueChange,
806
- tone,
807
- tabs,
808
- panels,
809
- className
810
- }) {
811
- var _a, _b;
812
- const fallback = (_b = (_a = tabs[0]) == null ? void 0 : _a.value) != null ? _b : "";
813
- const [uncontrolledValue, setUncontrolledValue] = React8.useState(
814
- defaultValue != null ? defaultValue : fallback
815
- );
816
- const isControlled = value !== void 0;
817
- const activeValue = isControlled ? value : uncontrolledValue;
818
- const setValue = React8.useCallback(
819
- (next) => {
820
- if (!isControlled) setUncontrolledValue(next);
821
- onValueChange == null ? void 0 : onValueChange(next);
822
- },
823
- [isControlled, onValueChange]
824
- );
825
- const onKeyDown = (event) => {
826
- if (!tabs.length) return;
827
- const currentIndex = tabs.findIndex((tab) => tab.value === activeValue);
828
- if (event.key === "ArrowRight") {
829
- event.preventDefault();
830
- const next = tabs[(currentIndex + 1) % tabs.length];
831
- setValue(next.value);
832
- }
833
- if (event.key === "ArrowLeft") {
834
- event.preventDefault();
835
- const next = tabs[(currentIndex - 1 + tabs.length) % tabs.length];
836
- setValue(next.value);
837
- }
838
- };
839
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: cn("space-y-4", className), "data-nc-theme": tone, children: [
840
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
841
- "div",
842
- {
843
- 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",
844
- role: "tablist",
845
- onKeyDown,
846
- children: tabs.map((tab) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
847
- "button",
848
- {
849
- role: "tab",
850
- "aria-selected": activeValue === tab.value,
851
- onClick: () => setValue(tab.value),
852
- className: cn(
853
- "rounded-full px-4 py-2 text-sm font-semibold transition-all",
854
- 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))]"
855
- ),
856
- children: tab.label
857
- },
858
- tab.value
859
- ))
860
- }
861
- ),
862
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("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] })
863
- ] });
864
- }
865
-
866
- // src/components/craft-tooltip.tsx
867
- var React9 = __toESM(require("react"), 1);
868
- var import_jsx_runtime16 = require("react/jsx-runtime");
869
- function CraftTooltip({ content, tone, children, side = "top" }) {
870
- const [open, setOpen] = React9.useState(false);
871
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
872
- "span",
873
- {
874
- className: "relative inline-flex",
875
- onMouseEnter: () => setOpen(true),
876
- onMouseLeave: () => setOpen(false),
877
- onFocus: () => setOpen(true),
878
- onBlur: () => setOpen(false),
879
- children: [
880
- children,
881
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
882
- "span",
883
- {
884
- className: cn(
885
- "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",
886
- "backdrop-blur-xl",
887
- open ? "opacity-100 translate-y-0" : "opacity-0 translate-y-1",
888
- side === "top" && "bottom-full left-1/2 -translate-x-1/2 -translate-y-2",
889
- side === "bottom" && "top-full left-1/2 -translate-x-1/2 translate-y-2",
890
- side === "left" && "right-full top-1/2 -translate-y-1/2 -translate-x-2",
891
- side === "right" && "left-full top-1/2 -translate-y-1/2 translate-x-2"
892
- ),
893
- "data-nc-theme": tone,
894
- role: "tooltip",
895
- children: content
896
- }
897
- )
898
- ]
899
- }
900
- );
901
- }
902
-
903
- // src/components/craft-toast.tsx
904
- var React10 = __toESM(require("react"), 1);
905
- var import_jsx_runtime17 = require("react/jsx-runtime");
906
- var variantClasses4 = {
907
- info: "border-[color:rgb(var(--nc-accent-1)/0.4)]",
908
- success: "border-emerald-400/40",
909
- warning: "border-amber-400/40",
910
- error: "border-rose-400/40"
911
- };
912
- function useCraftToast() {
913
- const [toasts, setToasts] = React10.useState([]);
914
- const push = React10.useCallback((toast) => {
915
- const id = `${Date.now()}-${Math.random().toString(16).slice(2)}`;
916
- setToasts((prev) => [...prev, { ...toast, id }]);
917
- return id;
918
- }, []);
919
- const remove = React10.useCallback((id) => {
920
- setToasts((prev) => prev.filter((toast) => toast.id !== id));
921
- }, []);
922
- return { toasts, push, remove };
923
- }
924
- function CraftToastHost({ toasts, onDismiss, tone }) {
925
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
926
- "div",
927
- {
928
- className: "fixed right-6 top-6 z-50 flex w-full max-w-sm flex-col gap-3",
929
- "data-nc-theme": tone,
930
- children: toasts.map((toast) => {
931
- var _a;
932
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
933
- "div",
934
- {
935
- className: cn(
936
- "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",
937
- variantClasses4[(_a = toast.variant) != null ? _a : "info"]
938
- ),
939
- children: /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "flex items-start justify-between gap-4", children: [
940
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { children: [
941
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { className: "text-sm font-semibold", children: toast.title }),
942
- toast.description && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { className: "text-xs text-[rgb(var(--nc-fg-muted))]", children: toast.description })
943
- ] }),
944
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
945
- "button",
946
- {
947
- className: "text-[rgb(var(--nc-fg-soft))] hover:text-[rgb(var(--nc-fg))]",
948
- onClick: () => onDismiss(toast.id),
949
- children: "\u2715"
950
- }
951
- )
952
- ] })
953
- },
954
- toast.id
955
- );
956
- })
957
- }
958
- );
959
- }
960
-
961
- // src/components/craft-skeleton.tsx
962
- var import_jsx_runtime18 = require("react/jsx-runtime");
963
- function CraftSkeleton({ className, tone, ...props }) {
964
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
965
- "div",
966
- {
967
- className: cn(
968
- "relative overflow-hidden rounded-2xl bg-[rgb(var(--nc-surface)/0.12)]",
969
- "after:absolute after:inset-0 after:-translate-x-full after:bg-linear-to-r after:from-transparent after:via-white/20 after:to-transparent",
970
- "after:animate-[shimmer_1.6s_infinite]",
971
- className
972
- ),
973
- "data-nc-theme": tone,
974
- ...props
975
- }
976
- );
977
- }
978
-
979
- // src/components/craft-empty-state.tsx
980
- var import_jsx_runtime19 = require("react/jsx-runtime");
981
- function CraftEmptyState({
982
- className,
983
- tone,
984
- title,
985
- description,
986
- icon,
987
- action,
988
- ...props
989
- }) {
990
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
991
- "div",
992
- {
993
- className: cn(
994
- "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",
995
- "shadow-[0_18px_40px_rgba(0,0,0,0.25)]",
996
- className
997
- ),
998
- "data-nc-theme": tone,
999
- ...props,
1000
- children: [
1001
- icon && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("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 }),
1002
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("h3", { className: "text-xl font-semibold", children: title }),
1003
- description && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { className: "mt-2 text-sm text-[rgb(var(--nc-fg-muted))]", children: description }),
1004
- action && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "mt-6 flex justify-center", children: action })
1005
- ]
1006
- }
1007
- );
1008
- }
1009
-
1010
- // src/components/craft-popover.tsx
1011
- var React11 = __toESM(require("react"), 1);
1012
- var import_jsx_runtime20 = require("react/jsx-runtime");
1013
- var alignClasses = {
1014
- start: "left-0",
1015
- center: "left-1/2 -translate-x-1/2",
1016
- end: "right-0"
1017
- };
1018
- function CraftPopover({
1019
- open,
1020
- defaultOpen = false,
1021
- onOpenChange,
1022
- trigger,
1023
- content,
1024
- align = "start",
1025
- sideOffset = 10,
1026
- tone,
1027
- className,
1028
- contentClassName
1029
- }) {
1030
- const [uncontrolledOpen, setUncontrolledOpen] = React11.useState(defaultOpen);
1031
- const isControlled = typeof open === "boolean";
1032
- const isOpen = isControlled ? open : uncontrolledOpen;
1033
- const rootRef = React11.useRef(null);
1034
- const setOpen = React11.useCallback(
1035
- (next) => {
1036
- if (!isControlled) setUncontrolledOpen(next);
1037
- onOpenChange == null ? void 0 : onOpenChange(next);
1038
- },
1039
- [isControlled, onOpenChange]
1040
- );
1041
- React11.useEffect(() => {
1042
- if (!isOpen) return;
1043
- const handleClick = (event) => {
1044
- if (!rootRef.current) return;
1045
- if (!rootRef.current.contains(event.target)) setOpen(false);
1046
- };
1047
- const handleKey = (event) => {
1048
- if (event.key === "Escape") setOpen(false);
1049
- };
1050
- document.addEventListener("mousedown", handleClick);
1051
- document.addEventListener("keydown", handleKey);
1052
- return () => {
1053
- document.removeEventListener("mousedown", handleClick);
1054
- document.removeEventListener("keydown", handleKey);
1055
- };
1056
- }, [isOpen, setOpen]);
1057
- const triggerNode = React11.isValidElement(trigger) ? React11.cloneElement(trigger, {
1058
- onClick: (event) => {
1059
- const handler = trigger.props.onClick;
1060
- handler == null ? void 0 : handler(event);
1061
- if (!event.defaultPrevented) setOpen(!isOpen);
1062
- },
1063
- "aria-expanded": isOpen,
1064
- "aria-haspopup": "dialog"
1065
- }) : /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
1066
- "button",
1067
- {
1068
- type: "button",
1069
- onClick: () => setOpen(!isOpen),
1070
- className: "inline-flex",
1071
- "aria-expanded": isOpen,
1072
- "aria-haspopup": "dialog",
1073
- children: trigger
1074
- }
1075
- );
1076
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: cn("relative inline-flex", className), ref: rootRef, children: [
1077
- triggerNode,
1078
- isOpen && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
1079
- "div",
1080
- {
1081
- className: cn(
1082
- "absolute z-40 w-max min-w-48 rounded-2xl border border-[rgb(var(--nc-border)/0.35)] bg-[rgb(var(--nc-surface)/0.08)] p-3 text-[rgb(var(--nc-fg))] shadow-[0_18px_40px_rgba(0,0,0,0.35)] backdrop-blur-2xl",
1083
- alignClasses[align],
1084
- contentClassName
1085
- ),
1086
- style: { marginTop: sideOffset },
1087
- role: "dialog",
1088
- "data-nc-theme": tone,
1089
- children: content
1090
- }
1091
- )
1092
- ] });
1093
- }
1094
-
1095
- // src/components/craft-dropdown-menu.tsx
1096
- var React12 = __toESM(require("react"), 1);
1097
- var import_jsx_runtime21 = require("react/jsx-runtime");
1098
- function CraftDropdownMenu({
1099
- trigger,
1100
- items = [],
1101
- content,
1102
- open,
1103
- defaultOpen = false,
1104
- onOpenChange,
1105
- align = "end",
1106
- tone,
1107
- className,
1108
- menuClassName
1109
- }) {
1110
- const [uncontrolledOpen, setUncontrolledOpen] = React12.useState(defaultOpen);
1111
- const isControlled = typeof open === "boolean";
1112
- const isOpen = isControlled ? open : uncontrolledOpen;
1113
- const setOpen = React12.useCallback(
1114
- (next) => {
1115
- if (!isControlled) setUncontrolledOpen(next);
1116
- onOpenChange == null ? void 0 : onOpenChange(next);
1117
- },
1118
- [isControlled, onOpenChange]
1119
- );
1120
- const menuContent = content != null ? content : items.length ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: cn("space-y-1", menuClassName), role: "menu", children: items.map((item, index) => {
1121
- var _a;
1122
- const key = (_a = item.id) != null ? _a : `${index}-${String(item.label)}`;
1123
- const itemClasses = cn(
1124
- "flex w-full items-start gap-3 rounded-xl px-3 py-2 text-left text-sm transition",
1125
- item.disabled ? "cursor-not-allowed text-[rgb(var(--nc-fg-soft))] opacity-60" : "text-[rgb(var(--nc-fg))] hover:bg-[rgb(var(--nc-surface)/0.12)]"
1126
- );
1127
- const contentNode = /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
1128
- item.icon && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "mt-0.5", children: item.icon }),
1129
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("span", { className: "flex-1", children: [
1130
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "block font-medium", children: item.label }),
1131
- item.description && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "block text-xs text-[rgb(var(--nc-fg-muted))]", children: item.description })
1132
- ] })
1133
- ] });
1134
- if (item.href) {
1135
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
1136
- "a",
1137
- {
1138
- href: item.href,
1139
- className: itemClasses,
1140
- role: "menuitem",
1141
- onClick: () => {
1142
- var _a2;
1143
- if (item.disabled) return;
1144
- (_a2 = item.onSelect) == null ? void 0 : _a2.call(item);
1145
- setOpen(false);
1146
- },
1147
- children: contentNode
1148
- },
1149
- key
1150
- );
1151
- }
1152
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
1153
- "button",
1154
- {
1155
- type: "button",
1156
- className: itemClasses,
1157
- role: "menuitem",
1158
- onClick: () => {
1159
- var _a2;
1160
- if (item.disabled) return;
1161
- (_a2 = item.onSelect) == null ? void 0 : _a2.call(item);
1162
- setOpen(false);
1163
- },
1164
- children: contentNode
1165
- },
1166
- key
1167
- );
1168
- }) }) : null;
1169
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
1170
- CraftPopover,
1171
- {
1172
- trigger,
1173
- content: menuContent,
1174
- open: isOpen,
1175
- onOpenChange: setOpen,
1176
- align,
1177
- tone,
1178
- className
1179
- }
1180
- );
1181
- }
1182
-
1183
- // src/components/craft-command-palette.tsx
1184
- var React13 = __toESM(require("react"), 1);
1185
- var import_jsx_runtime22 = require("react/jsx-runtime");
1186
- function CraftCommandPalette({
1187
- items,
1188
- open,
1189
- defaultOpen = false,
1190
- onOpenChange,
1191
- trigger,
1192
- title = "Command Palette",
1193
- placeholder = "Search commands...",
1194
- emptyText = "No results found.",
1195
- tone,
1196
- className
1197
- }) {
1198
- const [uncontrolledOpen, setUncontrolledOpen] = React13.useState(defaultOpen);
1199
- const isControlled = typeof open === "boolean";
1200
- const isOpen = isControlled ? open : uncontrolledOpen;
1201
- const [query, setQuery] = React13.useState("");
1202
- const setOpen = React13.useCallback(
1203
- (next) => {
1204
- if (!isControlled) setUncontrolledOpen(next);
1205
- onOpenChange == null ? void 0 : onOpenChange(next);
1206
- },
1207
- [isControlled, onOpenChange]
1208
- );
1209
- const filtered = React13.useMemo(() => {
1210
- const q = query.trim().toLowerCase();
1211
- if (!q) return items;
1212
- return items.filter((item) => {
1213
- var _a, _b;
1214
- const haystack = [
1215
- item.label,
1216
- (_a = item.description) != null ? _a : "",
1217
- ...(_b = item.keywords) != null ? _b : []
1218
- ].join(" ").toLowerCase();
1219
- return haystack.includes(q);
1220
- });
1221
- }, [items, query]);
1222
- React13.useEffect(() => {
1223
- if (!isOpen) setQuery("");
1224
- }, [isOpen]);
1225
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
1226
- CraftModal,
1227
- {
1228
- open: isOpen,
1229
- onOpenChange: setOpen,
1230
- trigger,
1231
- title,
1232
- tone,
1233
- className: cn("max-w-xl", className),
1234
- children: /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "space-y-4", children: [
1235
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
1236
- CraftInput,
1237
- {
1238
- type: "search",
1239
- placeholder,
1240
- value: query,
1241
- onChange: (event) => setQuery(event.target.value)
1242
- }
1243
- ),
1244
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "space-y-2", children: [
1245
- filtered.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "rounded-2xl border border-[rgb(var(--nc-border)/0.35)] bg-[rgb(var(--nc-surface)/0.12)] p-4 text-sm text-[rgb(var(--nc-fg-muted))]", children: emptyText }),
1246
- filtered.map((item) => /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
1247
- "button",
1248
- {
1249
- type: "button",
1250
- disabled: item.disabled,
1251
- onClick: () => {
1252
- var _a;
1253
- if (item.disabled) return;
1254
- (_a = item.onSelect) == null ? void 0 : _a.call(item);
1255
- setOpen(false);
1256
- },
1257
- className: cn(
1258
- "flex w-full items-start gap-3 rounded-2xl border border-[rgb(var(--nc-border)/0.35)] bg-[rgb(var(--nc-surface)/0.08)] px-4 py-3 text-left transition",
1259
- item.disabled ? "cursor-not-allowed opacity-60" : "hover:bg-[rgb(var(--nc-surface)/0.16)]"
1260
- ),
1261
- children: [
1262
- item.icon && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "mt-1", children: item.icon }),
1263
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("span", { children: [
1264
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "block text-sm font-semibold", children: item.label }),
1265
- item.description && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "block text-xs text-[rgb(var(--nc-fg-muted))]", children: item.description })
1266
- ] })
1267
- ]
1268
- },
1269
- item.id
1270
- ))
1271
- ] })
1272
- ] })
1273
- }
1274
- );
1275
- }
1276
-
1277
- // src/components/craft-link.tsx
1278
- var import_link = __toESM(require("next/link"), 1);
1279
- var import_jsx_runtime23 = require("react/jsx-runtime");
1280
- var variantClasses5 = {
1281
- default: "text-[rgb(var(--nc-accent-1))] hover:text-[rgb(var(--nc-accent-1))]",
1282
- muted: "text-[rgb(var(--nc-fg-muted))] hover:text-[rgb(var(--nc-fg))]",
1283
- button: "inline-flex items-center rounded-xl border border-[rgb(var(--nc-border)/0.35)] bg-[rgb(var(--nc-surface)/0.12)] px-4 py-2 text-sm font-semibold text-[rgb(var(--nc-fg))] transition hover:bg-[rgb(var(--nc-surface)/0.2)]",
1284
- ghost: "inline-flex items-center rounded-xl px-4 py-2 text-sm font-semibold text-[rgb(var(--nc-fg))] transition hover:bg-[rgb(var(--nc-surface)/0.18)]"
1285
- };
1286
- function CraftLink({
1287
- variant = "default",
1288
- underline = false,
1289
- tone,
1290
- className,
1291
- children,
1292
- ...props
1293
- }) {
1294
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
1295
- import_link.default,
1296
- {
1297
- className: cn(
1298
- "transition-colors",
1299
- variantClasses5[variant],
1300
- underline && "underline underline-offset-4",
1301
- className
1302
- ),
1303
- "data-nc-theme": tone,
1304
- ...props,
1305
- children
1306
- }
1307
- );
1308
- }
1309
-
1310
- // src/components/craft-stat-card.tsx
1311
- var import_jsx_runtime24 = require("react/jsx-runtime");
1312
- var trendClasses = {
1313
- up: "text-emerald-300",
1314
- down: "text-rose-300",
1315
- neutral: "text-[rgb(var(--nc-fg-muted))]"
1316
- };
1317
- function CraftStatCard({
1318
- label,
1319
- value,
1320
- delta,
1321
- trend = "neutral",
1322
- icon,
1323
- footer,
1324
- tone,
1325
- className,
1326
- ...props
1327
- }) {
1328
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
1329
- CraftCard,
1330
- {
1331
- className: cn("space-y-3", className),
1332
- tone,
1333
- ...props,
1334
- children: [
1335
- /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex items-center justify-between", children: [
1336
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { className: "text-sm text-[rgb(var(--nc-fg-muted))]", children: label }),
1337
- icon && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { className: "text-[rgb(var(--nc-fg-soft))]", children: icon })
1338
- ] }),
1339
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("p", { className: "text-3xl font-semibold", children: value }),
1340
- /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex items-center justify-between text-xs", children: [
1341
- delta && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: trendClasses[trend], children: delta }),
1342
- footer && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "text-[rgb(var(--nc-fg-muted))]", children: footer })
1343
- ] })
1344
- ]
1345
- }
1346
- );
1347
- }
1348
-
1349
- // src/components/craft-date-picker.tsx
1350
- var React14 = __toESM(require("react"), 1);
1351
- var import_jsx_runtime25 = require("react/jsx-runtime");
1352
- var WEEK_DAYS = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"];
1353
- function formatDate(date) {
1354
- const year = date.getFullYear();
1355
- const month = `${date.getMonth() + 1}`.padStart(2, "0");
1356
- const day = `${date.getDate()}`.padStart(2, "0");
1357
- return `${year}-${month}-${day}`;
1358
- }
1359
- function parseDate(value) {
1360
- if (!value) return null;
1361
- const [year, month, day] = value.split("-").map(Number);
1362
- if (!year || !month || !day) return null;
1363
- return new Date(year, month - 1, day);
1364
- }
1365
- function isSameDay(a, b) {
1366
- return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
1367
- }
1368
- function isOutsideRange(date, min, max) {
1369
- const minDate = parseDate(min);
1370
- const maxDate = parseDate(max);
1371
- if (minDate && date < minDate) return true;
1372
- if (maxDate && date > maxDate) return true;
1373
- return false;
1374
- }
1375
- function CraftDatePicker({
1376
- value,
1377
- defaultValue,
1378
- onChange,
1379
- tone,
1380
- min,
1381
- max,
1382
- placeholder = "Select date",
1383
- className
1384
- }) {
1385
- const [open, setOpen] = React14.useState(false);
1386
- const [uncontrolledValue, setUncontrolledValue] = React14.useState(defaultValue != null ? defaultValue : "");
1387
- const isControlled = value !== void 0;
1388
- const selectedValue = isControlled ? value != null ? value : "" : uncontrolledValue;
1389
- const selectedDate = parseDate(selectedValue);
1390
- const initialMonth = selectedDate != null ? selectedDate : /* @__PURE__ */ new Date();
1391
- const [viewDate, setViewDate] = React14.useState(initialMonth);
1392
- React14.useEffect(() => {
1393
- if (selectedDate) setViewDate(selectedDate);
1394
- }, [selectedDate]);
1395
- const wrapperRef = React14.useRef(null);
1396
- React14.useEffect(() => {
1397
- if (!open) return;
1398
- const handleClick = (event) => {
1399
- var _a;
1400
- if (!((_a = wrapperRef.current) == null ? void 0 : _a.contains(event.target))) {
1401
- setOpen(false);
1402
- }
1403
- };
1404
- const handleKey = (event) => {
1405
- if (event.key === "Escape") setOpen(false);
1406
- };
1407
- document.addEventListener("mousedown", handleClick);
1408
- document.addEventListener("keydown", handleKey);
1409
- return () => {
1410
- document.removeEventListener("mousedown", handleClick);
1411
- document.removeEventListener("keydown", handleKey);
1412
- };
1413
- }, [open]);
1414
- const setValue = React14.useCallback(
1415
- (next) => {
1416
- if (!isControlled) setUncontrolledValue(next);
1417
- onChange == null ? void 0 : onChange(next);
1418
- },
1419
- [isControlled, onChange]
1420
- );
1421
- const monthStart = new Date(viewDate.getFullYear(), viewDate.getMonth(), 1);
1422
- const monthEnd = new Date(viewDate.getFullYear(), viewDate.getMonth() + 1, 0);
1423
- const startDay = monthStart.getDay();
1424
- const daysInMonth = monthEnd.getDate();
1425
- const cells = Array.from({ length: startDay + daysInMonth }, (_, i) => {
1426
- const dayNumber = i - startDay + 1;
1427
- if (dayNumber < 1) return null;
1428
- return new Date(viewDate.getFullYear(), viewDate.getMonth(), dayNumber);
1429
- });
1430
- const handleDaySelect = (date) => {
1431
- if (isOutsideRange(date, min, max)) return;
1432
- const next = formatDate(date);
1433
- setValue(next);
1434
- setOpen(false);
1435
- };
1436
- const handleKeyDown = (event) => {
1437
- if (!open) return;
1438
- if (!selectedDate) return;
1439
- const next = new Date(selectedDate);
1440
- if (event.key === "ArrowRight") next.setDate(next.getDate() + 1);
1441
- if (event.key === "ArrowLeft") next.setDate(next.getDate() - 1);
1442
- if (event.key === "ArrowDown") next.setDate(next.getDate() + 7);
1443
- if (event.key === "ArrowUp") next.setDate(next.getDate() - 7);
1444
- if (event.key === "Enter") {
1445
- event.preventDefault();
1446
- handleDaySelect(selectedDate);
1447
- return;
1448
- }
1449
- if (next.getTime() !== selectedDate.getTime()) {
1450
- event.preventDefault();
1451
- if (!isOutsideRange(next, min, max)) {
1452
- setValue(formatDate(next));
1453
- setViewDate(next);
1454
- }
1455
- }
1456
- };
1457
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "relative w-full", "data-nc-theme": tone, ref: wrapperRef, children: [
1458
- /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
1459
- "button",
1460
- {
1461
- type: "button",
1462
- onClick: () => setOpen((prev) => !prev),
1463
- className: cn(
1464
- "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",
1465
- "shadow-[inset_0_2px_8px_rgba(0,0,0,0.3)]",
1466
- "transition-all duration-300",
1467
- "border-[rgb(var(--nc-border)/0.35)]",
1468
- "focus:outline-none focus:ring-4 focus:ring-[rgb(var(--nc-accent-1)/0.3)]",
1469
- className
1470
- ),
1471
- children: [
1472
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: selectedValue ? "text-[rgb(var(--nc-fg))]" : "text-[rgb(var(--nc-fg-soft))]", children: selectedValue || placeholder }),
1473
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("svg", { className: "h-4 w-4 text-[rgb(var(--nc-fg-soft))]", viewBox: "0 0 20 20", fill: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("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" }) })
1474
- ]
1475
- }
1476
- ),
1477
- open && /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
1478
- "div",
1479
- {
1480
- className: cn(
1481
- "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"
1482
- ),
1483
- onKeyDown: handleKeyDown,
1484
- tabIndex: -1,
1485
- children: [
1486
- /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex items-center justify-between", children: [
1487
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
1488
- "button",
1489
- {
1490
- type: "button",
1491
- 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))]",
1492
- onClick: () => setViewDate(
1493
- new Date(viewDate.getFullYear(), viewDate.getMonth() - 1, 1)
1494
- ),
1495
- children: "Prev"
1496
- }
1497
- ),
1498
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "text-sm font-semibold", children: viewDate.toLocaleString(void 0, { month: "long", year: "numeric" }) }),
1499
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
1500
- "button",
1501
- {
1502
- type: "button",
1503
- 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))]",
1504
- onClick: () => setViewDate(
1505
- new Date(viewDate.getFullYear(), viewDate.getMonth() + 1, 1)
1506
- ),
1507
- children: "Next"
1508
- }
1509
- )
1510
- ] }),
1511
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "mt-4 grid grid-cols-7 gap-2 text-xs text-[rgb(var(--nc-fg-muted))]", children: WEEK_DAYS.map((day) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "text-center", children: day }, day)) }),
1512
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "mt-2 grid grid-cols-7 gap-2", children: cells.map((date, index) => {
1513
- if (!date) return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", {}, `empty-${index}`);
1514
- const disabled = isOutsideRange(date, min, max);
1515
- const selected = selectedDate && isSameDay(date, selectedDate);
1516
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
1517
- "button",
1518
- {
1519
- type: "button",
1520
- onClick: () => handleDaySelect(date),
1521
- disabled,
1522
- className: cn(
1523
- "rounded-lg py-2 text-sm transition-all",
1524
- 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)]",
1525
- disabled && "opacity-40 hover:bg-transparent"
1526
- ),
1527
- children: date.getDate()
1528
- },
1529
- date.toISOString()
1530
- );
1531
- }) })
1532
- ]
1533
- }
1534
- )
1535
- ] });
1536
- }
1537
-
1538
- // src/components/craft-icon.tsx
1539
- var React15 = __toESM(require("react"), 1);
1540
- var import_dynamic = require("lucide-react/dynamic");
1541
- var import_jsx_runtime26 = require("react/jsx-runtime");
1542
- var CraftIconContext = React15.createContext(null);
1543
- function CraftIconProvider({ icons, children }) {
1544
- return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(CraftIconContext.Provider, { value: icons, children });
1545
- }
1546
- function CraftIcon({
1547
- name,
1548
- className,
1549
- "aria-label": ariaLabel,
1550
- icons,
1551
- useLucide = true
1552
- }) {
1553
- const contextRegistry = React15.useContext(CraftIconContext);
1554
- const registry = icons != null ? icons : contextRegistry;
1555
- const icon = registry == null ? void 0 : registry[name];
1556
- if (!icon) {
1557
- if (!useLucide) return null;
1558
- return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
1559
- import_dynamic.DynamicIcon,
1560
- {
1561
- name,
1562
- className,
1563
- "aria-hidden": ariaLabel ? void 0 : true,
1564
- "aria-label": ariaLabel
1565
- }
1566
- );
1567
- }
1568
- if (React15.isValidElement(icon)) {
1569
- return React15.cloneElement(icon, {
1570
- className: cn(icon.props.className, className),
1571
- "aria-hidden": ariaLabel ? void 0 : true,
1572
- "aria-label": ariaLabel
1573
- });
1574
- }
1575
- return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className, "aria-label": ariaLabel, children: icon });
1576
- }
1577
-
1578
- // src/components/craft-number-input.tsx
1579
- var React16 = __toESM(require("react"), 1);
1580
- var import_jsx_runtime27 = require("react/jsx-runtime");
1581
- var CraftNumberInput = React16.forwardRef(({ className, tone, ...props }, ref) => {
1582
- return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: "relative w-full", "data-nc-theme": tone, children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
1583
- "input",
1584
- {
1585
- ref,
1586
- type: "number",
1587
- className: cn(
1588
- "w-full rounded-2xl border-2 bg-[rgb(var(--nc-surface)/0.08)] text-[rgb(var(--nc-fg))] backdrop-blur-xl",
1589
- "shadow-[inset_0_2px_8px_rgba(0,0,0,0.3)]",
1590
- "focus:outline-none focus:ring-4",
1591
- "transition-all duration-300",
1592
- "disabled:opacity-50 disabled:cursor-not-allowed",
1593
- "border-[rgb(var(--nc-border)/0.35)]",
1594
- "focus:border-[rgb(var(--nc-accent-1)/0.8)] focus:ring-[rgb(var(--nc-accent-1)/0.3)]",
1595
- "px-5 py-3 text-base",
1596
- className
1597
- ),
1598
- ...props
1599
- }
1600
- ) });
1601
- });
1602
- CraftNumberInput.displayName = "CraftNumberInput";
1603
-
1604
- // src/components/craft-currency-input.tsx
1605
- var React17 = __toESM(require("react"), 1);
1606
- var import_jsx_runtime28 = require("react/jsx-runtime");
1607
- var CraftCurrencyInput = React17.forwardRef(({ className, tone, currencySymbol = "$", ...props }, ref) => {
1608
- return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "relative w-full", "data-nc-theme": tone, children: [
1609
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "pointer-events-none absolute left-4 top-1/2 -translate-y-1/2 text-[rgb(var(--nc-fg-soft))]", children: currencySymbol }),
1610
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
1611
- "input",
1612
- {
1613
- ref,
1614
- type: "text",
1615
- inputMode: "decimal",
1616
- className: cn(
1617
- "w-full rounded-2xl border-2 bg-[rgb(var(--nc-surface)/0.08)] text-[rgb(var(--nc-fg))] backdrop-blur-xl",
1618
- "shadow-[inset_0_2px_8px_rgba(0,0,0,0.3)]",
1619
- "focus:outline-none focus:ring-4",
1620
- "transition-all duration-300",
1621
- "disabled:opacity-50 disabled:cursor-not-allowed",
1622
- "border-[rgb(var(--nc-border)/0.35)]",
1623
- "focus:border-[rgb(var(--nc-accent-1)/0.8)] focus:ring-[rgb(var(--nc-accent-1)/0.3)]",
1624
- "placeholder:text-[rgb(var(--nc-fg-soft))]",
1625
- "px-5 py-3 pl-9 text-base",
1626
- className
1627
- ),
1628
- ...props
1629
- }
1630
- )
1631
- ] });
1632
- });
1633
- CraftCurrencyInput.displayName = "CraftCurrencyInput";
1634
-
1635
- // src/components/craft-form.tsx
1636
- var React18 = __toESM(require("react"), 1);
1637
- var import_react_hook_form2 = require("react-hook-form");
1638
-
1639
- // src/components/craft-submit-button.tsx
1640
- var import_react_hook_form = require("react-hook-form");
1641
- var import_jsx_runtime29 = require("react/jsx-runtime");
1642
- function CraftSubmitButton({
1643
- className,
1644
- tone,
1645
- loading,
1646
- loadingLabel = "Submitting...",
1647
- disableWhenInvalid = true,
1648
- disabled,
1649
- children,
1650
- ...props
1651
- }) {
1652
- var _a, _b, _c, _d;
1653
- const form = (0, import_react_hook_form.useFormContext)();
1654
- const isSubmitting = (_b = loading != null ? loading : (_a = form == null ? void 0 : form.formState) == null ? void 0 : _a.isSubmitting) != null ? _b : false;
1655
- const isValid = (_d = (_c = form == null ? void 0 : form.formState) == null ? void 0 : _c.isValid) != null ? _d : true;
1656
- const isDisabled = disabled || isSubmitting || disableWhenInvalid && !isValid;
1657
- return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
1658
- "button",
1659
- {
1660
- type: "submit",
1661
- className: cn(
1662
- "relative inline-flex items-center justify-center gap-2 rounded-xl px-6 py-2 text-sm font-semibold",
1663
- "bg-linear-to-br from-[rgb(var(--nc-accent-1))] via-[rgb(var(--nc-accent-2))] to-[rgb(var(--nc-accent-3))]",
1664
- "text-white shadow-[0_12px_30px_rgb(var(--nc-accent-1)/0.35)]",
1665
- "transition-all duration-200",
1666
- "hover:shadow-[0_16px_36px_rgb(var(--nc-accent-1)/0.5)] hover:scale-[1.02] active:scale-[0.98]",
1667
- "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[rgb(var(--nc-accent-1)/0.6)]",
1668
- "disabled:opacity-60 disabled:cursor-not-allowed disabled:hover:scale-100",
1669
- className
1670
- ),
1671
- "data-nc-theme": tone,
1672
- disabled: isDisabled,
1673
- ...props,
1674
- children: [
1675
- isSubmitting && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "inline-flex h-4 w-4 animate-spin rounded-full border-2 border-white/60 border-t-white" }),
1676
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { children: isSubmitting ? loadingLabel : children })
1677
- ]
1678
- }
1679
- );
1680
- }
1681
-
1682
- // src/components/craft-form.tsx
1683
- var import_jsx_runtime30 = require("react/jsx-runtime");
1684
- function CraftForm({
1685
- form,
1686
- onSubmit,
1687
- open,
1688
- defaultOpen = false,
1689
- onOpenChange,
1690
- trigger,
1691
- title,
1692
- description,
1693
- submitLabel = "Save",
1694
- cancelLabel = "Cancel",
1695
- tone,
1696
- className,
1697
- children,
1698
- footer,
1699
- disableSubmitWhenInvalid = true,
1700
- closeOnSubmit = true,
1701
- formClassName
1702
- }) {
1703
- const [uncontrolledOpen, setUncontrolledOpen] = React18.useState(defaultOpen);
1704
- const isControlled = typeof open === "boolean";
1705
- const isOpen = isControlled ? open : uncontrolledOpen;
1706
- const setOpen = React18.useCallback(
1707
- (next) => {
1708
- if (!isControlled) setUncontrolledOpen(next);
1709
- onOpenChange == null ? void 0 : onOpenChange(next);
1710
- },
1711
- [isControlled, onOpenChange]
1712
- );
1713
- const formId = React18.useId();
1714
- const handleSubmit = form.handleSubmit(async (values) => {
1715
- await onSubmit(values);
1716
- if (closeOnSubmit) setOpen(false);
1717
- });
1718
- const footerContent = footer != null ? footer : /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex flex-wrap items-center justify-end gap-3", children: [
1719
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(CraftButton, { type: "button", variant: "ghost", onClick: () => setOpen(false), children: cancelLabel }),
1720
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
1721
- CraftSubmitButton,
1722
- {
1723
- form: formId,
1724
- disableWhenInvalid: disableSubmitWhenInvalid,
1725
- children: submitLabel
1726
- }
1727
- )
1728
- ] });
1729
- return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_react_hook_form2.FormProvider, { ...form, children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
1730
- CraftModal,
1731
- {
1732
- open: isOpen,
1733
- onOpenChange: setOpen,
1734
- trigger,
1735
- title,
1736
- description,
1737
- tone,
1738
- className,
1739
- footer: footerContent,
1740
- children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
1741
- "form",
1742
- {
1743
- id: formId,
1744
- onSubmit: handleSubmit,
1745
- className: cn("space-y-5", formClassName),
1746
- children
1747
- }
1748
- )
1749
- }
1750
- ) });
1751
- }
1752
-
1753
- // src/components/craft-form-builder.tsx
1754
- var React19 = __toESM(require("react"), 1);
1755
- var import_react_hook_form4 = require("react-hook-form");
1756
-
1757
- // src/components/craft-form-field.tsx
1758
- var import_react_hook_form3 = require("react-hook-form");
1759
- var import_jsx_runtime31 = require("react/jsx-runtime");
1760
- function getFieldError(errors, name) {
1761
- if (!errors || typeof errors !== "object") return void 0;
1762
- const segments = name.split(".");
1763
- let current = errors;
1764
- for (const segment of segments) {
1765
- if (!current || typeof current !== "object") return void 0;
1766
- current = current[segment];
1767
- }
1768
- return current;
1769
- }
1770
- var baseInputClass = "w-full rounded-2xl border-2 bg-[rgb(var(--nc-surface)/0.08)] text-[rgb(var(--nc-fg))] backdrop-blur-xl shadow-[inset_0_2px_8px_rgba(0,0,0,0.3)] focus:outline-none focus:ring-4 transition-all duration-300 disabled:opacity-50 disabled:cursor-not-allowed border-[rgb(var(--nc-border)/0.35)] focus:border-[rgb(var(--nc-accent-1)/0.8)] focus:ring-[rgb(var(--nc-accent-1)/0.3)] px-5 py-3 text-base placeholder:text-[rgb(var(--nc-fg-soft))]";
1771
- function CraftFormField({
1772
- name,
1773
- label,
1774
- description,
1775
- type = "text",
1776
- options = [],
1777
- placeholder,
1778
- tone,
1779
- className,
1780
- inputClassName,
1781
- labelClassName,
1782
- descriptionClassName,
1783
- rules,
1784
- disabled,
1785
- fieldProps
1786
- }) {
1787
- const { register, control, formState } = (0, import_react_hook_form3.useFormContext)();
1788
- const error = getFieldError(formState.errors, name);
1789
- const errorMessage = typeof (error == null ? void 0 : error.message) === "string" ? error.message : void 0;
1790
- if (type === "hidden") {
1791
- return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("input", { type: "hidden", ...register(name, rules) });
1792
- }
1793
- const labelNode = label ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
1794
- "label",
1795
- {
1796
- htmlFor: name,
1797
- className: cn(
1798
- "text-sm font-semibold text-[rgb(var(--nc-fg))]",
1799
- labelClassName
1800
- ),
1801
- children: label
1802
- }
1803
- ) : null;
1804
- const descriptionNode = description ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
1805
- "p",
1806
- {
1807
- className: cn(
1808
- "text-xs text-[rgb(var(--nc-fg-muted))]",
1809
- descriptionClassName
1810
- ),
1811
- children: description
1812
- }
1813
- ) : null;
1814
- const errorNode = errorMessage ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("p", { className: "text-xs text-[rgb(var(--nc-accent-3))]", children: errorMessage }) : null;
1815
- const renderInput = () => {
1816
- if (type === "textarea") {
1817
- return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
1818
- CraftTextarea,
1819
- {
1820
- id: name,
1821
- placeholder,
1822
- tone,
1823
- className: inputClassName,
1824
- disabled,
1825
- ...fieldProps,
1826
- ...register(name, rules)
1827
- }
1828
- );
1829
- }
1830
- if (type === "select" || type === "multiselect") {
1831
- return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(
1832
- CraftSelect,
1833
- {
1834
- id: name,
1835
- tone,
1836
- className: inputClassName,
1837
- multiple: type === "multiselect",
1838
- disabled,
1839
- ...fieldProps,
1840
- ...register(name, rules),
1841
- children: [
1842
- placeholder && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("option", { value: "", disabled: true, children: placeholder }),
1843
- options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
1844
- "option",
1845
- {
1846
- value: option.value,
1847
- disabled: option.disabled,
1848
- children: option.label
1849
- },
1850
- option.value
1851
- ))
1852
- ]
1853
- }
1854
- );
1855
- }
1856
- if (type === "checkbox") {
1857
- return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
1858
- CraftCheckbox,
1859
- {
1860
- tone,
1861
- label,
1862
- description,
1863
- disabled,
1864
- ...fieldProps,
1865
- ...register(name, rules)
1866
- }
1867
- );
1868
- }
1869
- if (type === "switch") {
1870
- return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
1871
- CraftSwitch,
1872
- {
1873
- tone,
1874
- label,
1875
- disabled,
1876
- ...fieldProps,
1877
- ...register(name, rules)
1878
- }
1879
- );
1880
- }
1881
- if (type === "date") {
1882
- return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
1883
- import_react_hook_form3.Controller,
1884
- {
1885
- control,
1886
- name,
1887
- rules,
1888
- render: ({ field }) => {
1889
- var _a;
1890
- return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
1891
- CraftDatePicker,
1892
- {
1893
- value: (_a = field.value) != null ? _a : "",
1894
- onChange: field.onChange,
1895
- tone,
1896
- placeholder,
1897
- ...fieldProps
1898
- }
1899
- );
1900
- }
1901
- }
1902
- );
1903
- }
1904
- if (type === "number") {
1905
- return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
1906
- CraftNumberInput,
1907
- {
1908
- id: name,
1909
- tone,
1910
- placeholder,
1911
- className: inputClassName,
1912
- disabled,
1913
- ...fieldProps,
1914
- ...register(name, rules)
1915
- }
1916
- );
1917
- }
1918
- if (type === "currency") {
1919
- return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
1920
- CraftCurrencyInput,
1921
- {
1922
- id: name,
1923
- tone,
1924
- placeholder,
1925
- className: inputClassName,
1926
- disabled,
1927
- ...fieldProps,
1928
- ...register(name, rules)
1929
- }
1930
- );
1931
- }
1932
- if (type === "radio") {
1933
- return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "grid gap-3", children: options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(
1934
- "label",
1935
- {
1936
- className: cn(
1937
- "flex items-center gap-3 rounded-2xl border border-[rgb(var(--nc-border)/0.35)] bg-[rgb(var(--nc-surface)/0.08)] px-4 py-3 text-sm text-[rgb(var(--nc-fg))]",
1938
- "transition-all duration-200",
1939
- "focus-within:ring-2 focus-within:ring-[rgb(var(--nc-accent-1)/0.5)]",
1940
- option.disabled ? "opacity-60" : "cursor-pointer"
1941
- ),
1942
- "data-nc-theme": tone,
1943
- children: [
1944
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
1945
- "input",
1946
- {
1947
- type: "radio",
1948
- value: option.value,
1949
- disabled: option.disabled || disabled,
1950
- className: "h-4 w-4 accent-[rgb(var(--nc-accent-1))]",
1951
- ...fieldProps,
1952
- ...register(name, rules)
1953
- }
1954
- ),
1955
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { children: option.label })
1956
- ]
1957
- },
1958
- option.value
1959
- )) });
1960
- }
1961
- if (type === "range" || type === "slider") {
1962
- return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
1963
- "input",
1964
- {
1965
- id: name,
1966
- type: "range",
1967
- className: cn(
1968
- "w-full accent-[rgb(var(--nc-accent-1))]",
1969
- inputClassName
1970
- ),
1971
- disabled,
1972
- ...fieldProps,
1973
- ...register(name, rules)
1974
- }
1975
- );
1976
- }
1977
- if (type === "file" || type === "multifile") {
1978
- return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
1979
- "input",
1980
- {
1981
- id: name,
1982
- type: "file",
1983
- multiple: type === "multifile",
1984
- className: cn(
1985
- baseInputClass,
1986
- "file:mr-4 file:rounded-xl file:border-0 file:bg-[rgb(var(--nc-surface)/0.35)] file:px-4 file:py-2 file:text-sm file:font-semibold file:text-[rgb(var(--nc-fg))]",
1987
- inputClassName
1988
- ),
1989
- disabled,
1990
- ...fieldProps,
1991
- ...register(name, rules)
1992
- }
1993
- );
1994
- }
1995
- const inputType = type === "search" || type === "password" || type === "email" || type === "tel" || type === "url" || type === "time" || type === "datetime-local" || type === "month" || type === "week" || type === "color" ? type : "text";
1996
- return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
1997
- CraftInput,
1998
- {
1999
- id: name,
2000
- type: inputType,
2001
- placeholder,
2002
- tone,
2003
- className: inputClassName,
2004
- disabled,
2005
- ...fieldProps,
2006
- ...register(name, rules)
2007
- }
2008
- );
2009
- };
2010
- const showLabel = type !== "checkbox" && type !== "switch";
2011
- const showDescriptionAbove = type !== "checkbox" && type !== "switch";
2012
- const showDescriptionBelow = type === "switch";
2013
- return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: cn("space-y-2", className), "data-nc-theme": tone, children: [
2014
- showLabel ? labelNode : null,
2015
- showDescriptionAbove ? descriptionNode : null,
2016
- renderInput(),
2017
- showDescriptionBelow ? descriptionNode : null,
2018
- errorNode
2019
- ] });
2020
- }
2021
-
2022
- // src/components/craft-form-builder.tsx
2023
- var import_jsx_runtime32 = require("react/jsx-runtime");
2024
- function defaultValueForField(field) {
2025
- var _a, _b, _c, _d;
2026
- if (field.defaultValue !== void 0) return field.defaultValue;
2027
- switch (field.type) {
2028
- case "checkbox":
2029
- case "switch":
2030
- return false;
2031
- case "number":
2032
- case "slider":
2033
- case "range":
2034
- return (_a = field.min) != null ? _a : 0;
2035
- case "multifile":
2036
- return [];
2037
- case "file":
2038
- return null;
2039
- case "multiselect":
2040
- return [];
2041
- case "radio":
2042
- return (_d = (_c = (_b = field.options) == null ? void 0 : _b[0]) == null ? void 0 : _c.value) != null ? _d : "";
2043
- default:
2044
- return "";
2045
- }
2046
- }
2047
- function buildDefaultValues(fields, initialData) {
2048
- const values = {};
2049
- fields.forEach((field) => {
2050
- const initialValue = initialData == null ? void 0 : initialData[field.name];
2051
- if (initialValue !== void 0 && initialValue !== null) {
2052
- values[field.name] = initialValue;
2053
- } else {
2054
- values[field.name] = defaultValueForField(field);
2055
- }
2056
- });
2057
- return values;
2058
- }
2059
- function buildRules(field, getValues) {
2060
- var _a;
2061
- const rules = { ...field.rules };
2062
- const mergeValidate = (current, next) => {
2063
- if (!current) return next;
2064
- if (typeof current === "function") {
2065
- return (value) => {
2066
- const result = current(
2067
- value,
2068
- getValues()
2069
- );
2070
- if (result !== true) return result;
2071
- return next(value);
2072
- };
2073
- }
2074
- if (typeof current === "object") {
2075
- return (value) => {
2076
- const entries = Object.entries(current);
2077
- for (const [, validator] of entries) {
2078
- const result = validator(
2079
- value,
2080
- getValues()
2081
- );
2082
- if (result !== true) return result;
2083
- }
2084
- return next(value);
2085
- };
2086
- }
2087
- return next;
2088
- };
2089
- if (field.required && field.type !== "hidden") {
2090
- if (field.type === "checkbox" || field.type === "switch") {
2091
- rules.validate = mergeValidate(
2092
- rules.validate,
2093
- (value) => {
2094
- var _a2;
2095
- return value ? true : `${String((_a2 = field.label) != null ? _a2 : field.name)} is required`;
2096
- }
2097
- );
2098
- } else if (field.type === "multiselect") {
2099
- rules.validate = mergeValidate(
2100
- rules.validate,
2101
- (value) => {
2102
- var _a2;
2103
- return Array.isArray(value) && value.length > 0 ? true : `${String((_a2 = field.label) != null ? _a2 : field.name)} is required`;
2104
- }
2105
- );
2106
- } else if (field.type === "file") {
2107
- rules.validate = mergeValidate(
2108
- rules.validate,
2109
- (value) => {
2110
- var _a2;
2111
- return value instanceof FileList && value.length > 0 ? true : `${String((_a2 = field.label) != null ? _a2 : field.name)} is required`;
2112
- }
2113
- );
2114
- } else if (field.type === "multifile") {
2115
- rules.validate = mergeValidate(
2116
- rules.validate,
2117
- (value) => {
2118
- var _a2;
2119
- return Array.isArray(value) && value.length > 0 ? true : `${String((_a2 = field.label) != null ? _a2 : field.name)} is required`;
2120
- }
2121
- );
2122
- } else {
2123
- rules.required = `${String((_a = field.label) != null ? _a : field.name)} is required`;
2124
- }
2125
- }
2126
- if (field.min !== void 0) {
2127
- rules.min = { value: field.min, message: `Min ${field.min}` };
2128
- }
2129
- if (field.max !== void 0) {
2130
- rules.max = { value: field.max, message: `Max ${field.max}` };
2131
- }
2132
- if (field.type === "email") {
2133
- rules.pattern = {
2134
- value: /^[^\s@]+@[^\s@]+\.[^\s@]+$/,
2135
- message: "Please enter a valid email address"
2136
- };
2137
- }
2138
- if (field.type === "url") {
2139
- rules.pattern = {
2140
- value: /^https?:\/\/.+/,
2141
- message: "Please enter a valid URL"
2142
- };
2143
- }
2144
- if (field.validate) {
2145
- rules.validate = mergeValidate(
2146
- rules.validate,
2147
- (value) => {
2148
- var _a2;
2149
- return (_a2 = field.validate) == null ? void 0 : _a2.call(field, value, getValues());
2150
- }
2151
- );
2152
- }
2153
- return rules;
2154
- }
2155
- function CraftFormBuilder({
2156
- title = "Form",
2157
- description,
2158
- fields,
2159
- initialData = null,
2160
- open,
2161
- defaultOpen = false,
2162
- onOpenChange,
2163
- trigger,
2164
- submitLabel = "Submit",
2165
- cancelLabel = "Cancel",
2166
- resetLabel = "Reset",
2167
- showReset = true,
2168
- showCancel = true,
2169
- tone,
2170
- className,
2171
- formClassName,
2172
- loading = false,
2173
- disableSubmitWhenInvalid = true,
2174
- closeOnSubmit = true,
2175
- closeOnCancel = true,
2176
- onSubmit,
2177
- onReset,
2178
- onCancel,
2179
- customValidation
2180
- }) {
2181
- const [uncontrolledOpen, setUncontrolledOpen] = React19.useState(defaultOpen);
2182
- const isControlled = typeof open === "boolean";
2183
- const isOpen = isControlled ? open : uncontrolledOpen;
2184
- const setOpen = React19.useCallback(
2185
- (next) => {
2186
- if (!isControlled) setUncontrolledOpen(next);
2187
- onOpenChange == null ? void 0 : onOpenChange(next);
2188
- },
2189
- [isControlled, onOpenChange]
2190
- );
2191
- const defaultValues = React19.useMemo(
2192
- () => buildDefaultValues(fields, initialData),
2193
- [fields, initialData]
2194
- );
2195
- const form = (0, import_react_hook_form4.useForm)({
2196
- mode: "onChange",
2197
- defaultValues
2198
- });
2199
- const formId = React19.useId();
2200
- React19.useEffect(() => {
2201
- form.reset(defaultValues);
2202
- }, [defaultValues, form]);
2203
- const handleSubmit = form.handleSubmit(async (values) => {
2204
- if (customValidation) {
2205
- const customErrors = customValidation(values);
2206
- if (customErrors && Object.keys(customErrors).length > 0) {
2207
- Object.entries(customErrors).forEach(([key, message]) => {
2208
- if (message) {
2209
- form.setError(key, {
2210
- type: "custom",
2211
- message: String(message)
2212
- });
2213
- }
2214
- });
2215
- return;
2216
- }
2217
- }
2218
- await onSubmit(values);
2219
- if (closeOnSubmit) setOpen(false);
2220
- });
2221
- const handleReset = () => {
2222
- form.reset(defaultValues);
2223
- onReset == null ? void 0 : onReset();
2224
- };
2225
- const handleCancel = () => {
2226
- onCancel == null ? void 0 : onCancel();
2227
- if (closeOnCancel) setOpen(false);
2228
- };
2229
- return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_react_hook_form4.FormProvider, { ...form, children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
2230
- CraftModal,
2231
- {
2232
- open: isOpen,
2233
- onOpenChange: setOpen,
2234
- trigger,
2235
- title,
2236
- description,
2237
- tone,
2238
- className,
2239
- footer: /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "flex flex-wrap items-center justify-end gap-3", children: [
2240
- showReset && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
2241
- CraftButton,
2242
- {
2243
- type: "button",
2244
- variant: "outline",
2245
- onClick: handleReset,
2246
- disabled: loading,
2247
- children: resetLabel
2248
- }
2249
- ),
2250
- showCancel && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
2251
- CraftButton,
2252
- {
2253
- type: "button",
2254
- variant: "ghost",
2255
- onClick: handleCancel,
2256
- disabled: loading,
2257
- children: cancelLabel
2258
- }
2259
- ),
2260
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
2261
- CraftSubmitButton,
2262
- {
2263
- loading,
2264
- disableWhenInvalid: disableSubmitWhenInvalid,
2265
- form: formId,
2266
- children: submitLabel
2267
- }
2268
- )
2269
- ] }),
2270
- children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
2271
- "form",
2272
- {
2273
- id: formId,
2274
- onSubmit: handleSubmit,
2275
- className: cn("space-y-5", formClassName),
2276
- children: fields.map((field) => /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "space-y-2", children: [
2277
- field.helpText && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("p", { className: "text-xs text-[rgb(var(--nc-fg-muted))]", children: field.helpText }),
2278
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
2279
- CraftFormField,
2280
- {
2281
- name: field.name,
2282
- label: field.label,
2283
- description: field.description,
2284
- type: field.type,
2285
- placeholder: field.placeholder,
2286
- options: field.options,
2287
- tone,
2288
- disabled: field.disabled || loading,
2289
- rules: buildRules(field, form.getValues),
2290
- fieldProps: {
2291
- min: field.min,
2292
- max: field.max,
2293
- step: field.step,
2294
- rows: field.rows,
2295
- accept: field.accept,
2296
- multiple: field.type === "multifile",
2297
- ...field.fieldProps
2298
- }
2299
- }
2300
- )
2301
- ] }, field.name))
2302
- }
2303
- )
2304
- }
2305
- ) });
2306
- }
2307
-
2308
- // src/components/craft-confirm-dialog.tsx
2309
- var React20 = __toESM(require("react"), 1);
2310
- var import_jsx_runtime33 = require("react/jsx-runtime");
2311
- function CraftConfirmDialog({
2312
- open,
2313
- defaultOpen = false,
2314
- onOpenChange,
2315
- tone,
2316
- title = "Confirm action",
2317
- description,
2318
- confirmLabel = "Confirm",
2319
- cancelLabel = "Cancel",
2320
- onConfirm,
2321
- trigger,
2322
- className,
2323
- confirmVariant = "solid"
2324
- }) {
2325
- const [uncontrolledOpen, setUncontrolledOpen] = React20.useState(defaultOpen);
2326
- const isControlled = typeof open === "boolean";
2327
- const isOpen = isControlled ? open : uncontrolledOpen;
2328
- const setOpen = React20.useCallback(
2329
- (next) => {
2330
- if (!isControlled) setUncontrolledOpen(next);
2331
- onOpenChange == null ? void 0 : onOpenChange(next);
2332
- },
2333
- [isControlled, onOpenChange]
2334
- );
2335
- const [isLoading, setIsLoading] = React20.useState(false);
2336
- const handleConfirm = async () => {
2337
- if (!onConfirm) {
2338
- setOpen(false);
2339
- return;
2340
- }
2341
- setIsLoading(true);
2342
- await onConfirm();
2343
- setIsLoading(false);
2344
- setOpen(false);
2345
- };
2346
- return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
2347
- CraftModal,
2348
- {
2349
- open: isOpen,
2350
- onOpenChange: setOpen,
2351
- trigger,
2352
- title,
2353
- description,
2354
- tone,
2355
- className: cn("max-w-md", className),
2356
- footer: /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "flex flex-wrap items-center justify-end gap-3", children: [
2357
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
2358
- CraftButton,
2359
- {
2360
- type: "button",
2361
- variant: "ghost",
2362
- onClick: () => setOpen(false),
2363
- children: cancelLabel
2364
- }
2365
- ),
2366
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
2367
- CraftButton,
2368
- {
2369
- type: "button",
2370
- variant: confirmVariant,
2371
- disabled: isLoading,
2372
- onClick: handleConfirm,
2373
- children: isLoading ? "Working..." : confirmLabel
2374
- }
2375
- )
2376
- ] }),
2377
- children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "text-sm text-[rgb(var(--nc-fg-muted))]", children: description })
2378
- }
2379
- );
2380
- }
2381
-
2382
- // src/components/craft-create-edit-drawer.tsx
2383
- var React21 = __toESM(require("react"), 1);
2384
- var import_react_hook_form5 = require("react-hook-form");
2385
- var import_jsx_runtime34 = require("react/jsx-runtime");
2386
- function CraftCreateEditDrawer({
2387
- mode = "create",
2388
- form,
2389
- onSubmit,
2390
- open,
2391
- defaultOpen = false,
2392
- onOpenChange,
2393
- trigger,
2394
- title,
2395
- description,
2396
- submitLabel,
2397
- cancelLabel = "Cancel",
2398
- tone,
2399
- className,
2400
- children,
2401
- footer,
2402
- disableSubmitWhenInvalid = true,
2403
- closeOnSubmit = true,
2404
- side = "right"
2405
- }) {
2406
- const [uncontrolledOpen, setUncontrolledOpen] = React21.useState(defaultOpen);
2407
- const isControlled = typeof open === "boolean";
2408
- const isOpen = isControlled ? open : uncontrolledOpen;
2409
- const setOpen = React21.useCallback(
2410
- (next) => {
2411
- if (!isControlled) setUncontrolledOpen(next);
2412
- onOpenChange == null ? void 0 : onOpenChange(next);
2413
- },
2414
- [isControlled, onOpenChange]
2415
- );
2416
- const formId = React21.useId();
2417
- const handleSubmit = form.handleSubmit(async (values) => {
2418
- await onSubmit(values);
2419
- if (closeOnSubmit) setOpen(false);
2420
- });
2421
- const resolvedTitle = title != null ? title : mode === "create" ? "Create item" : "Edit item";
2422
- const resolvedSubmitLabel = submitLabel != null ? submitLabel : mode === "create" ? "Create" : "Save changes";
2423
- const footerContent = footer != null ? footer : /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "flex flex-wrap items-center justify-end gap-3", children: [
2424
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(CraftButton, { type: "button", variant: "ghost", onClick: () => setOpen(false), children: cancelLabel }),
2425
- /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
2426
- CraftSubmitButton,
2427
- {
2428
- form: formId,
2429
- disableWhenInvalid: disableSubmitWhenInvalid,
2430
- children: resolvedSubmitLabel
2431
- }
2432
- )
2433
- ] });
2434
- return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_react_hook_form5.FormProvider, { ...form, children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
2435
- CraftDrawer,
2436
- {
2437
- open: isOpen,
2438
- onOpenChange: setOpen,
2439
- trigger,
2440
- title: resolvedTitle,
2441
- tone,
2442
- side,
2443
- className: cn("flex flex-col", className),
2444
- footer: footerContent,
2445
- children: /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("form", { id: formId, onSubmit: handleSubmit, className: "space-y-5", children: [
2446
- description && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("p", { className: "text-sm text-[rgb(var(--nc-fg-muted))]", children: description }),
2447
- children
2448
- ] })
2449
- }
2450
- ) });
2451
- }
2452
-
2453
- // src/components/craft-filter-bar.tsx
2454
- var import_jsx_runtime35 = require("react/jsx-runtime");
2455
- function CraftFilterBar({
2456
- title,
2457
- description,
2458
- searchValue,
2459
- onSearchChange,
2460
- searchPlaceholder = "Search...",
2461
- actions,
2462
- filters,
2463
- tone,
2464
- className
2465
- }) {
2466
- return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(
2467
- "div",
2468
- {
2469
- className: cn(
2470
- "rounded-3xl border border-[rgb(var(--nc-border)/0.3)] bg-[rgb(var(--nc-surface)/0.12)] p-4 text-[rgb(var(--nc-fg))] shadow-[0_12px_36px_rgba(0,0,0,0.2)] backdrop-blur-2xl",
2471
- className
2472
- ),
2473
- "data-nc-theme": tone,
2474
- children: [
2475
- /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: "flex flex-wrap items-center justify-between gap-4", children: [
2476
- /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { children: [
2477
- title && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("h3", { className: "text-lg font-semibold", children: title }),
2478
- description && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("p", { className: "text-sm text-[rgb(var(--nc-fg-muted))]", children: description })
2479
- ] }),
2480
- actions && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: "flex items-center gap-3", children: actions })
2481
- ] }),
2482
- /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: "mt-4 grid gap-4 md:grid-cols-[minmax(0,1fr)_auto]", children: [
2483
- /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
2484
- CraftInput,
2485
- {
2486
- type: "search",
2487
- placeholder: searchPlaceholder,
2488
- value: searchValue != null ? searchValue : "",
2489
- onChange: (event) => onSearchChange == null ? void 0 : onSearchChange(event.target.value),
2490
- tone
2491
- }
2492
- ),
2493
- filters && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: "flex flex-wrap items-center gap-3", children: filters })
2494
- ] })
2495
- ]
2496
- }
2497
- );
2498
- }
2499
-
2500
- // src/components/craft-table-toolbar.tsx
2501
- var import_jsx_runtime36 = require("react/jsx-runtime");
2502
- function CraftTableToolbar({
2503
- title,
2504
- description,
2505
- searchValue,
2506
- onSearchChange,
2507
- searchPlaceholder = "Search table...",
2508
- actions,
2509
- filters,
2510
- bulkActions,
2511
- tone,
2512
- className
2513
- }) {
2514
- return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
2515
- "div",
2516
- {
2517
- className: cn(
2518
- "rounded-3xl border border-[rgb(var(--nc-border)/0.3)] bg-[rgb(var(--nc-surface)/0.12)] p-4 text-[rgb(var(--nc-fg))] shadow-[0_12px_36px_rgba(0,0,0,0.2)] backdrop-blur-2xl",
2519
- className
2520
- ),
2521
- "data-nc-theme": tone,
2522
- children: [
2523
- /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "flex flex-wrap items-center justify-between gap-4", children: [
2524
- /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { children: [
2525
- title && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("h3", { className: "text-lg font-semibold", children: title }),
2526
- description && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("p", { className: "text-sm text-[rgb(var(--nc-fg-muted))]", children: description })
2527
- ] }),
2528
- actions && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { className: "flex items-center gap-3", children: actions })
2529
- ] }),
2530
- /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "mt-4 grid gap-4 lg:grid-cols-[minmax(0,1fr)_auto]", children: [
2531
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
2532
- CraftInput,
2533
- {
2534
- type: "search",
2535
- placeholder: searchPlaceholder,
2536
- value: searchValue != null ? searchValue : "",
2537
- onChange: (event) => onSearchChange == null ? void 0 : onSearchChange(event.target.value),
2538
- tone
2539
- }
2540
- ),
2541
- /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "flex flex-wrap items-center gap-3", children: [
2542
- filters,
2543
- bulkActions
2544
- ] })
2545
- ] })
2546
- ]
2547
- }
2548
- );
2549
- }
2550
-
2551
- // src/components/craft-data-table.tsx
2552
- var React22 = __toESM(require("react"), 1);
2553
-
2554
- // src/components/craft-pagination.tsx
2555
- var import_jsx_runtime37 = require("react/jsx-runtime");
2556
- function getPageNumbers(pageIndex, pageCount, maxButtons = 5) {
2557
- if (pageCount <= maxButtons) {
2558
- return Array.from({ length: pageCount }, (_, i) => i);
2559
- }
2560
- const pages = [];
2561
- const start = Math.max(0, pageIndex - 1);
2562
- const end = Math.min(pageCount - 1, pageIndex + 1);
2563
- pages.push(0);
2564
- if (start > 1) pages.push("ellipsis");
2565
- for (let i = start; i <= end; i += 1) {
2566
- if (i !== 0 && i !== pageCount - 1) pages.push(i);
2567
- }
2568
- if (end < pageCount - 2) pages.push("ellipsis");
2569
- pages.push(pageCount - 1);
2570
- return pages;
2571
- }
2572
- function CraftPagination({
2573
- pageIndex,
2574
- pageCount,
2575
- onPageChange,
2576
- canPrevious = pageIndex > 0,
2577
- canNext = pageIndex < pageCount - 1,
2578
- pageSize,
2579
- pageSizeOptions = [10, 20, 50],
2580
- onPageSizeChange,
2581
- tone,
2582
- className
2583
- }) {
2584
- const pages = getPageNumbers(pageIndex, pageCount);
2585
- return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(
2586
- "div",
2587
- {
2588
- className: cn(
2589
- "flex flex-wrap items-center justify-between gap-4",
2590
- className
2591
- ),
2592
- "data-nc-theme": tone,
2593
- children: [
2594
- /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "flex items-center gap-2", children: [
2595
- /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
2596
- "button",
2597
- {
2598
- type: "button",
2599
- className: cn(
2600
- "rounded-xl border border-[rgb(var(--nc-border)/0.3)] bg-[rgb(var(--nc-surface)/0.12)] px-3 py-2 text-xs text-[rgb(var(--nc-fg))] transition",
2601
- "hover:bg-[rgb(var(--nc-surface)/0.2)]",
2602
- !canPrevious && "opacity-50 cursor-not-allowed"
2603
- ),
2604
- onClick: () => onPageChange(Math.max(pageIndex - 1, 0)),
2605
- disabled: !canPrevious,
2606
- children: "Prev"
2607
- }
2608
- ),
2609
- pages.map(
2610
- (page, index) => page === "ellipsis" ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { className: "px-2 text-[rgb(var(--nc-fg-muted))]", children: "..." }, `ellipsis-${index}`) : /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
2611
- "button",
2612
- {
2613
- type: "button",
2614
- className: cn(
2615
- "rounded-xl border px-3 py-2 text-xs transition",
2616
- page === pageIndex ? "border-[rgb(var(--nc-accent-1)/0.6)] bg-[rgb(var(--nc-accent-1)/0.2)] text-[rgb(var(--nc-fg))]" : "border-[rgb(var(--nc-border)/0.3)] bg-[rgb(var(--nc-surface)/0.12)] text-[rgb(var(--nc-fg-muted))] hover:text-[rgb(var(--nc-fg))] hover:bg-[rgb(var(--nc-surface)/0.2)]"
2617
- ),
2618
- onClick: () => onPageChange(page),
2619
- children: page + 1
2620
- },
2621
- page
2622
- )
2623
- ),
2624
- /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
2625
- "button",
2626
- {
2627
- type: "button",
2628
- className: cn(
2629
- "rounded-xl border border-[rgb(var(--nc-border)/0.3)] bg-[rgb(var(--nc-surface)/0.12)] px-3 py-2 text-xs text-[rgb(var(--nc-fg))] transition",
2630
- "hover:bg-[rgb(var(--nc-surface)/0.2)]",
2631
- !canNext && "opacity-50 cursor-not-allowed"
2632
- ),
2633
- onClick: () => onPageChange(Math.min(pageIndex + 1, pageCount - 1)),
2634
- disabled: !canNext,
2635
- children: "Next"
2636
- }
2637
- )
2638
- ] }),
2639
- onPageSizeChange && /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "flex items-center gap-2 text-xs text-[rgb(var(--nc-fg-muted))]", children: [
2640
- /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { children: "Rows" }),
2641
- /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
2642
- "select",
2643
- {
2644
- className: "rounded-xl border border-[rgb(var(--nc-border)/0.3)] bg-[rgb(var(--nc-surface)/0.12)] px-2 py-1 text-xs text-[rgb(var(--nc-fg))]",
2645
- value: pageSize,
2646
- onChange: (event) => onPageSizeChange(Number(event.target.value)),
2647
- children: pageSizeOptions.map((size) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("option", { value: size, children: size }, size))
2648
- }
2649
- )
2650
- ] })
2651
- ]
2652
- }
2653
- );
2654
- }
2655
-
2656
- // src/components/craft-data-table.tsx
2657
- var import_jsx_runtime38 = require("react/jsx-runtime");
2658
- function getColumnValue(column, row) {
2659
- if (typeof column.accessor === "function") return column.accessor(row);
2660
- const record = row;
2661
- if (typeof column.accessor === "string") return record[column.accessor];
2662
- return record[column.id];
2663
- }
2664
- function normalizeValue(value) {
2665
- if (value === null || value === void 0) return "";
2666
- if (typeof value === "number") return value;
2667
- if (typeof value === "string") return value.toLowerCase();
2668
- if (value instanceof Date) return value.getTime();
2669
- return String(value).toLowerCase();
2670
- }
2671
- function CraftDataTable({
2672
- data,
2673
- columns,
2674
- tone,
2675
- className,
2676
- loading = false,
2677
- emptyState,
2678
- toolbar,
2679
- enableSorting = true,
2680
- enableFiltering = true,
2681
- enableColumnVisibility = true,
2682
- enableRowSelection = true,
2683
- enablePagination = true,
2684
- showGlobalFilter,
2685
- manualSorting = false,
2686
- manualFiltering = false,
2687
- manualPagination = false,
2688
- sortBy,
2689
- onSortChange,
2690
- filters,
2691
- onFiltersChange,
2692
- globalFilter,
2693
- onGlobalFilterChange,
2694
- columnVisibility,
2695
- onColumnVisibilityChange,
2696
- selectedRowIds,
2697
- onRowSelectionChange,
2698
- getRowId,
2699
- pageIndex,
2700
- pageSize = 10,
2701
- pageCount,
2702
- onPageChange,
2703
- onPageSizeChange
2704
- }) {
2705
- const [internalSort, setInternalSort] = React22.useState(null);
2706
- const [internalFilters, setInternalFilters] = React22.useState({});
2707
- const [internalGlobalFilter, setInternalGlobalFilter] = React22.useState("");
2708
- const [internalVisibility, setInternalVisibility] = React22.useState(
2709
- () => columns.reduce((acc, column) => {
2710
- acc[column.id] = !column.hidden;
2711
- return acc;
2712
- }, {})
2713
- );
2714
- const [internalSelection, setInternalSelection] = React22.useState({});
2715
- const [internalPageIndex, setInternalPageIndex] = React22.useState(0);
2716
- const [showColumns, setShowColumns] = React22.useState(false);
2717
- const resolvedSort = sortBy != null ? sortBy : internalSort;
2718
- const resolvedFilters = filters != null ? filters : internalFilters;
2719
- const resolvedGlobalFilter = globalFilter != null ? globalFilter : internalGlobalFilter;
2720
- const resolvedVisibility = columnVisibility != null ? columnVisibility : internalVisibility;
2721
- const resolvedSelection = selectedRowIds != null ? selectedRowIds : internalSelection;
2722
- const resolvedPageIndex = pageIndex != null ? pageIndex : internalPageIndex;
2723
- const setSort = (next) => {
2724
- if (sortBy === void 0) setInternalSort(next);
2725
- onSortChange == null ? void 0 : onSortChange(next);
2726
- };
2727
- const setFilters = (next) => {
2728
- if (filters === void 0) setInternalFilters(next);
2729
- onFiltersChange == null ? void 0 : onFiltersChange(next);
2730
- };
2731
- const setVisibility = (next) => {
2732
- if (columnVisibility === void 0) setInternalVisibility(next);
2733
- onColumnVisibilityChange == null ? void 0 : onColumnVisibilityChange(next);
2734
- };
2735
- const setSelection = (next) => {
2736
- if (selectedRowIds === void 0) setInternalSelection(next);
2737
- onRowSelectionChange == null ? void 0 : onRowSelectionChange(next);
2738
- };
2739
- const setPageIndex = React22.useCallback(
2740
- (next) => {
2741
- if (pageIndex === void 0) setInternalPageIndex(next);
2742
- onPageChange == null ? void 0 : onPageChange(next);
2743
- },
2744
- [pageIndex, onPageChange]
2745
- );
2746
- const visibleColumns = columns.filter(
2747
- (column) => resolvedVisibility[column.id] !== false
2748
- );
2749
- const filteredData = React22.useMemo(() => {
2750
- if (manualFiltering) return data;
2751
- const globalValue = resolvedGlobalFilter.trim();
2752
- return data.filter((row) => {
2753
- if (globalValue) {
2754
- const matchesGlobal = columns.some((column) => {
2755
- const value = normalizeValue(getColumnValue(column, row));
2756
- return String(value).includes(globalValue.toLowerCase());
2757
- });
2758
- if (!matchesGlobal) return false;
2759
- }
2760
- return Object.entries(resolvedFilters).every(([columnId, value]) => {
2761
- if (!value) return true;
2762
- const column = columns.find((col) => col.id === columnId);
2763
- if (!column) return true;
2764
- const cellValue = normalizeValue(getColumnValue(column, row));
2765
- return String(cellValue).includes(value.toLowerCase());
2766
- });
2767
- });
2768
- }, [columns, data, manualFiltering, resolvedFilters, resolvedGlobalFilter]);
2769
- const sortedData = React22.useMemo(() => {
2770
- if (manualSorting || !resolvedSort) return filteredData;
2771
- const column = columns.find((col) => col.id === resolvedSort.id);
2772
- if (!column) return filteredData;
2773
- const sorted = [...filteredData].sort((a, b) => {
2774
- const valueA = normalizeValue(getColumnValue(column, a));
2775
- const valueB = normalizeValue(getColumnValue(column, b));
2776
- if (typeof valueA === "number" && typeof valueB === "number") {
2777
- return valueA - valueB;
2778
- }
2779
- return String(valueA).localeCompare(String(valueB));
2780
- });
2781
- return resolvedSort.desc ? sorted.reverse() : sorted;
2782
- }, [columns, filteredData, manualSorting, resolvedSort]);
2783
- const resolvedPageCount = manualPagination ? Math.max(pageCount != null ? pageCount : 1, 1) : Math.max(Math.ceil(sortedData.length / pageSize), 1);
2784
- React22.useEffect(() => {
2785
- if (resolvedPageIndex > resolvedPageCount - 1) {
2786
- setPageIndex(Math.max(resolvedPageCount - 1, 0));
2787
- }
2788
- }, [resolvedPageCount, resolvedPageIndex, setPageIndex]);
2789
- const pagedData = React22.useMemo(() => {
2790
- if (!enablePagination || manualPagination) return sortedData;
2791
- const start = resolvedPageIndex * pageSize;
2792
- return sortedData.slice(start, start + pageSize);
2793
- }, [enablePagination, manualPagination, pageSize, resolvedPageIndex, sortedData]);
2794
- const rowIdFor = React22.useCallback(
2795
- (row, index) => {
2796
- var _a;
2797
- return (_a = getRowId == null ? void 0 : getRowId(row, index)) != null ? _a : String(index);
2798
- },
2799
- [getRowId]
2800
- );
2801
- const pageStartIndex = enablePagination && !manualPagination ? resolvedPageIndex * pageSize : 0;
2802
- const pageRowIds = pagedData.map(
2803
- (row, index) => rowIdFor(row, pageStartIndex + index)
2804
- );
2805
- const allSelected = pageRowIds.length > 0 && pageRowIds.every((id) => resolvedSelection[id]);
2806
- const someSelected = pageRowIds.some((id) => resolvedSelection[id]);
2807
- const headerCheckboxRef = React22.useRef(null);
2808
- React22.useEffect(() => {
2809
- if (headerCheckboxRef.current) {
2810
- headerCheckboxRef.current.indeterminate = someSelected && !allSelected;
2811
- }
2812
- }, [someSelected, allSelected]);
2813
- const toggleSort = (column) => {
2814
- if (!enableSorting || column.sortable === false) return;
2815
- const current = resolvedSort;
2816
- if (!current || current.id !== column.id) {
2817
- setSort({ id: column.id, desc: false });
2818
- return;
2819
- }
2820
- if (!current.desc) {
2821
- setSort({ id: column.id, desc: true });
2822
- return;
2823
- }
2824
- setSort(null);
2825
- };
2826
- const emptyContent = emptyState != null ? emptyState : /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: "text-center text-sm text-[rgb(var(--nc-fg-muted))]", children: "No results found." });
2827
- const resolvedShowGlobalFilter = showGlobalFilter != null ? showGlobalFilter : enableFiltering && !toolbar;
2828
- const setGlobalFilter = (next) => {
2829
- if (globalFilter === void 0) setInternalGlobalFilter(next);
2830
- onGlobalFilterChange == null ? void 0 : onGlobalFilterChange(next);
2831
- };
2832
- return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className: cn("space-y-4", className), "data-nc-theme": tone, children: [
2833
- toolbar,
2834
- resolvedShowGlobalFilter && /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className: "flex items-center justify-between gap-3 rounded-2xl border border-[rgb(var(--nc-border)/0.3)] bg-[rgb(var(--nc-surface)/0.12)] px-3 py-2 text-sm text-[rgb(var(--nc-fg))]", children: [
2835
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { className: "text-xs text-[rgb(var(--nc-fg-muted))]", children: "Global filter" }),
2836
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
2837
- "input",
2838
- {
2839
- type: "search",
2840
- value: resolvedGlobalFilter,
2841
- onChange: (event) => setGlobalFilter(event.target.value),
2842
- placeholder: "Search all columns...",
2843
- className: "w-full max-w-xs rounded-xl border border-[rgb(var(--nc-border)/0.3)] bg-[rgb(var(--nc-surface)/0.18)] px-3 py-2 text-xs text-[rgb(var(--nc-fg))]"
2844
- }
2845
- )
2846
- ] }),
2847
- enableColumnVisibility && /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className: "relative flex justify-end", children: [
2848
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
2849
- "button",
2850
- {
2851
- type: "button",
2852
- className: "rounded-xl border border-[rgb(var(--nc-border)/0.3)] bg-[rgb(var(--nc-surface)/0.12)] px-3 py-2 text-xs text-[rgb(var(--nc-fg))] transition hover:bg-[rgb(var(--nc-surface)/0.2)]",
2853
- onClick: () => setShowColumns((prev) => !prev),
2854
- children: "Columns"
2855
- }
2856
- ),
2857
- showColumns && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: "absolute right-0 top-10 z-20 w-48 rounded-2xl border border-[rgb(var(--nc-border)/0.3)] bg-[rgb(var(--nc-surface)/0.2)] p-3 shadow-[0_12px_30px_rgba(0,0,0,0.35)] backdrop-blur-2xl", children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: "grid gap-2", children: columns.map((column) => /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
2858
- "label",
2859
- {
2860
- className: "flex items-center gap-2 text-xs text-[rgb(var(--nc-fg))]",
2861
- children: [
2862
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
2863
- "input",
2864
- {
2865
- type: "checkbox",
2866
- className: "h-4 w-4 accent-[rgb(var(--nc-accent-1))]",
2867
- checked: resolvedVisibility[column.id] !== false,
2868
- onChange: (event) => setVisibility({
2869
- ...resolvedVisibility,
2870
- [column.id]: event.target.checked
2871
- })
2872
- }
2873
- ),
2874
- column.header
2875
- ]
2876
- },
2877
- column.id
2878
- )) }) })
2879
- ] }),
2880
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: "overflow-hidden rounded-3xl border border-[rgb(var(--nc-border)/0.3)] bg-[rgb(var(--nc-surface)/0.08)] shadow-[0_18px_50px_rgba(0,0,0,0.35)] backdrop-blur-2xl", children: /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("table", { className: "w-full border-collapse text-left text-sm", children: [
2881
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("thead", { className: "bg-[rgb(var(--nc-surface)/0.12)] text-[rgb(var(--nc-fg-muted))]", children: /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("tr", { children: [
2882
- enableRowSelection && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("th", { className: "w-12 px-4 py-3", children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
2883
- "input",
2884
- {
2885
- ref: headerCheckboxRef,
2886
- type: "checkbox",
2887
- className: "h-4 w-4 accent-[rgb(var(--nc-accent-1))]",
2888
- checked: allSelected,
2889
- onChange: (event) => {
2890
- const next = { ...resolvedSelection };
2891
- pageRowIds.forEach((id) => {
2892
- next[id] = event.target.checked;
2893
- });
2894
- setSelection(next);
2895
- }
2896
- }
2897
- ) }),
2898
- visibleColumns.map((column) => {
2899
- var _a;
2900
- return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
2901
- "th",
2902
- {
2903
- className: cn(
2904
- "px-4 py-3 text-xs font-semibold uppercase tracking-[0.2em]",
2905
- column.headerClassName
2906
- ),
2907
- style: { width: column.width },
2908
- children: [
2909
- /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
2910
- "button",
2911
- {
2912
- type: "button",
2913
- className: cn(
2914
- "flex items-center gap-2",
2915
- enableSorting && column.sortable !== false ? "cursor-pointer" : "cursor-default"
2916
- ),
2917
- onClick: () => toggleSort(column),
2918
- children: [
2919
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { children: column.header }),
2920
- (resolvedSort == null ? void 0 : resolvedSort.id) === column.id && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { className: "text-[rgb(var(--nc-accent-1))]", children: resolvedSort.desc ? "\u2193" : "\u2191" })
2921
- ]
2922
- }
2923
- ),
2924
- enableFiltering && column.filterable !== false && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
2925
- "input",
2926
- {
2927
- type: "text",
2928
- value: (_a = resolvedFilters[column.id]) != null ? _a : "",
2929
- onChange: (event) => setFilters({
2930
- ...resolvedFilters,
2931
- [column.id]: event.target.value
2932
- }),
2933
- placeholder: "Filter",
2934
- className: "mt-2 w-full rounded-xl border border-[rgb(var(--nc-border)/0.3)] bg-[rgb(var(--nc-surface)/0.18)] px-2 py-1 text-xs text-[rgb(var(--nc-fg))]"
2935
- }
2936
- )
2937
- ]
2938
- },
2939
- column.id
2940
- );
2941
- })
2942
- ] }) }),
2943
- /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("tbody", { className: "text-[rgb(var(--nc-fg))]", children: [
2944
- loading && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
2945
- "td",
2946
- {
2947
- colSpan: visibleColumns.length + (enableRowSelection ? 1 : 0),
2948
- className: "px-4 py-10 text-center text-sm text-[rgb(var(--nc-fg-muted))]",
2949
- children: /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("span", { className: "inline-flex items-center gap-2", children: [
2950
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { className: "h-4 w-4 animate-spin rounded-full border-2 border-[rgb(var(--nc-fg-muted))] border-t-transparent" }),
2951
- "Loading data..."
2952
- ] })
2953
- }
2954
- ) }),
2955
- !loading && pagedData.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
2956
- "td",
2957
- {
2958
- colSpan: visibleColumns.length + (enableRowSelection ? 1 : 0),
2959
- className: "px-4 py-10",
2960
- children: emptyContent
2961
- }
2962
- ) }),
2963
- !loading && pagedData.map((row, rowIndex) => {
2964
- const rowId = rowIdFor(row, pageStartIndex + rowIndex);
2965
- const isSelected = resolvedSelection[rowId];
2966
- return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
2967
- "tr",
2968
- {
2969
- className: cn(
2970
- "border-t border-[rgb(var(--nc-border)/0.15)]",
2971
- isSelected && "bg-[rgb(var(--nc-accent-1)/0.08)]"
2972
- ),
2973
- children: [
2974
- enableRowSelection && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("td", { className: "px-4 py-4", children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
2975
- "input",
2976
- {
2977
- type: "checkbox",
2978
- className: "h-4 w-4 accent-[rgb(var(--nc-accent-1))]",
2979
- checked: isSelected,
2980
- onChange: (event) => setSelection({
2981
- ...resolvedSelection,
2982
- [rowId]: event.target.checked
2983
- })
2984
- }
2985
- ) }),
2986
- visibleColumns.map((column) => {
2987
- var _a;
2988
- return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
2989
- "td",
2990
- {
2991
- className: cn(
2992
- "px-4 py-4",
2993
- column.align === "center" && "text-center",
2994
- column.align === "right" && "text-right",
2995
- column.cellClassName
2996
- ),
2997
- children: column.cell ? column.cell(row) : String((_a = getColumnValue(column, row)) != null ? _a : "")
2998
- },
2999
- column.id
3000
- );
3001
- })
3002
- ]
3003
- },
3004
- rowId
3005
- );
3006
- })
3007
- ] })
3008
- ] }) }),
3009
- enablePagination && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
3010
- CraftPagination,
3011
- {
3012
- pageIndex: resolvedPageIndex,
3013
- pageCount: resolvedPageCount,
3014
- onPageChange: setPageIndex,
3015
- pageSize,
3016
- onPageSizeChange,
3017
- tone
3018
- }
3019
- )
3020
- ] });
3021
- }
3022
-
3023
- // src/components/layout/app-shell.tsx
3024
- var import_jsx_runtime39 = require("react/jsx-runtime");
3025
- function AppShell({ className, sidebar, topNav, children, ...props }) {
3026
- return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(
3027
- "div",
3028
- {
3029
- className: cn(
3030
- "grid min-h-screen grid-cols-1 gap-6 bg-background p-6 lg:grid-cols-[260px_1fr]",
3031
- className
3032
- ),
3033
- ...props,
3034
- children: [
3035
- sidebar && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: "h-full lg:sticky lg:top-6 lg:self-start lg:max-h-[calc(100vh-3rem)] lg:overflow-y-auto", children: sidebar }),
3036
- /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: "flex flex-col gap-6", children: [
3037
- topNav && /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: "lg:sticky lg:top-6 lg:z-20", children: topNav }),
3038
- /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("main", { className: "flex-1", children })
3039
- ] })
3040
- ]
3041
- }
3042
- );
3043
- }
3044
-
3045
- // src/components/layout/app-template.tsx
3046
- var React23 = __toESM(require("react"), 1);
3047
-
3048
- // src/components/layout/breadcrumbs.tsx
3049
- var import_jsx_runtime40 = require("react/jsx-runtime");
3050
- function Breadcrumbs({ className, items, ...props }) {
3051
- return /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("nav", { className: cn("flex items-center text-sm text-[rgb(var(--nc-fg-muted))]", className), ...props, children: items.map((item, index) => {
3052
- const content = item.href ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("a", { href: item.href, className: "transition hover:text-[rgb(var(--nc-fg))]", children: item.label }) : /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { className: "text-[rgb(var(--nc-fg))]", children: item.label });
3053
- return /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("span", { className: "flex items-center", children: [
3054
- content,
3055
- index < items.length - 1 && /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("span", { className: "mx-2 text-[rgb(var(--nc-fg-soft))]", children: "/" })
3056
- ] }, `${item.label}-${index}`);
3057
- }) });
3058
- }
3059
-
3060
- // src/components/layout/sidebar.tsx
3061
- var import_jsx_runtime41 = require("react/jsx-runtime");
3062
- function Sidebar({ className, title, items, footer, ...props }) {
3063
- return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(
3064
- "aside",
3065
- {
3066
- className: cn(
3067
- "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",
3068
- className
3069
- ),
3070
- ...props,
3071
- children: [
3072
- title && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "text-lg font-semibold", children: title }),
3073
- /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("nav", { className: "flex flex-col gap-2", children: items.map((item, index) => {
3074
- var _a;
3075
- return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(
3076
- "a",
3077
- {
3078
- href: (_a = item.href) != null ? _a : "#",
3079
- className: cn(
3080
- "flex items-center gap-3 rounded-2xl px-3 py-2 text-sm transition",
3081
- 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))]"
3082
- ),
3083
- children: [
3084
- item.icon,
3085
- /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("span", { children: item.label })
3086
- ]
3087
- },
3088
- `${item.label}-${index}`
3089
- );
3090
- }) }),
3091
- footer && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "mt-auto pt-4", children: footer })
3092
- ]
3093
- }
3094
- );
3095
- }
3096
-
3097
- // src/components/layout/top-nav.tsx
3098
- var import_jsx_runtime42 = require("react/jsx-runtime");
3099
- function TopNav({ className, title, actions, breadcrumb, ...props }) {
3100
- return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
3101
- "header",
3102
- {
3103
- className: cn(
3104
- "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",
3105
- className
3106
- ),
3107
- ...props,
3108
- children: [
3109
- /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "space-y-1", children: [
3110
- breadcrumb,
3111
- title && /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { className: "text-xl font-semibold", children: title })
3112
- ] }),
3113
- actions && /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { className: "flex flex-wrap gap-3", children: actions })
3114
- ]
3115
- }
3116
- );
3117
- }
3118
-
3119
- // src/components/layout/app-template.tsx
3120
- var import_jsx_runtime43 = require("react/jsx-runtime");
3121
- function AppTemplate({
3122
- config,
3123
- headerActions,
3124
- headerBreadcrumb,
3125
- sidebarFooter,
3126
- resolveIcon,
3127
- icons,
3128
- activePath,
3129
- getActivePath,
3130
- lucideFallback = true,
3131
- children
3132
- }) {
3133
- const sidebarConfig = config.sidebar;
3134
- const headerConfig = config.header;
3135
- const resolvedActivePath = activePath != null ? activePath : getActivePath == null ? void 0 : getActivePath();
3136
- const buildIcon = React23.useCallback(
3137
- (name) => {
3138
- if (!name) return void 0;
3139
- if (resolveIcon) return resolveIcon(name);
3140
- if (icons == null ? void 0 : icons[name]) return icons[name];
3141
- return /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(CraftIcon, { name, useLucide: lucideFallback });
3142
- },
3143
- [icons, lucideFallback, resolveIcon]
3144
- );
3145
- const sidebarItems = sidebarConfig ? sidebarConfig.items.map((item) => {
3146
- var _a;
3147
- return {
3148
- label: item.label,
3149
- href: item.href,
3150
- active: (_a = item.active) != null ? _a : resolvedActivePath && item.href ? item.href === resolvedActivePath : false,
3151
- icon: buildIcon(item.icon)
3152
- };
3153
- }) : null;
3154
- const breadcrumbNode = headerBreadcrumb != null ? headerBreadcrumb : (headerConfig == null ? void 0 : headerConfig.breadcrumb) ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Breadcrumbs, { items: headerConfig.breadcrumb }) : null;
3155
- const sidebarFooterNode = sidebarFooter != null ? sidebarFooter : (sidebarConfig == null ? void 0 : sidebarConfig.footerText) ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", { className: "text-xs text-[rgb(var(--nc-fg-muted))]", children: sidebarConfig.footerText }) : null;
3156
- return /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
3157
- AppShell,
3158
- {
3159
- sidebar: sidebarConfig && sidebarItems ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
3160
- Sidebar,
3161
- {
3162
- title: sidebarConfig.title,
3163
- items: sidebarItems,
3164
- footer: sidebarFooterNode
3165
- }
3166
- ) : void 0,
3167
- topNav: headerConfig ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
3168
- TopNav,
3169
- {
3170
- title: headerConfig.title,
3171
- breadcrumb: breadcrumbNode,
3172
- actions: headerActions
3173
- }
3174
- ) : void 0,
3175
- children
3176
- }
3177
- );
3178
- }
3179
-
3180
- // src/components/layout/layout-config.ts
3181
- var layoutConfigSchema = {
3182
- $schema: "https://json-schema.org/draft/2020-12/schema",
3183
- title: "Nextcraft UI Layout Config",
3184
- type: "object",
3185
- additionalProperties: false,
3186
- properties: {
3187
- sidebar: {
3188
- type: "object",
3189
- additionalProperties: false,
3190
- properties: {
3191
- title: { type: "string" },
3192
- footerText: { type: "string" },
3193
- items: {
3194
- type: "array",
3195
- items: {
3196
- type: "object",
3197
- additionalProperties: false,
3198
- properties: {
3199
- label: { type: "string" },
3200
- href: { type: "string" },
3201
- icon: { type: "string" },
3202
- active: { type: "boolean" }
3203
- },
3204
- required: ["label"]
3205
- }
3206
- }
3207
- },
3208
- required: ["items"]
3209
- },
3210
- header: {
3211
- type: "object",
3212
- additionalProperties: false,
3213
- properties: {
3214
- title: { type: "string" },
3215
- breadcrumb: {
3216
- type: "array",
3217
- items: {
3218
- type: "object",
3219
- additionalProperties: false,
3220
- properties: {
3221
- label: { type: "string" },
3222
- href: { type: "string" }
3223
- },
3224
- required: ["label"]
3225
- }
3226
- }
3227
- }
3228
- }
3229
- }
3230
- };
3231
-
3232
- // src/components/layout/page-header.tsx
3233
- var import_jsx_runtime44 = require("react/jsx-runtime");
3234
- function PageHeader({
3235
- className,
3236
- title,
3237
- description,
3238
- actions,
3239
- ...props
3240
- }) {
3241
- return /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(
3242
- "div",
3243
- {
3244
- className: cn("flex flex-wrap items-start justify-between gap-6", className),
3245
- ...props,
3246
- children: [
3247
- /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "space-y-2", children: [
3248
- /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("h1", { className: "text-3xl font-bold text-[rgb(var(--nc-fg))]", children: title }),
3249
- description && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("p", { className: "text-[rgb(var(--nc-fg-muted))]", children: description })
3250
- ] }),
3251
- actions && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { className: "flex flex-wrap gap-3", children: actions })
3252
- ]
3253
- }
3254
- );
3255
- }
3256
-
3257
- // src/components/layout/auth-layout.tsx
3258
- var import_jsx_runtime45 = require("react/jsx-runtime");
3259
- function AuthLayout({
3260
- className,
3261
- title,
3262
- description,
3263
- footer,
3264
- graphic,
3265
- children,
3266
- ...props
3267
- }) {
3268
- return /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(
3269
- "div",
3270
- {
3271
- className: cn(
3272
- "grid min-h-screen grid-cols-1 bg-background",
3273
- "lg:grid-cols-[1.1fr_0.9fr]",
3274
- className
3275
- ),
3276
- ...props,
3277
- children: [
3278
- /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: "flex flex-col justify-center px-6 py-16 sm:px-12", children: /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "mx-auto w-full max-w-md space-y-6", children: [
3279
- (title || description) && /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "space-y-2", children: [
3280
- title && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("h1", { className: "text-3xl font-bold text-[rgb(var(--nc-fg))]", children: title }),
3281
- description && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("p", { className: "text-[rgb(var(--nc-fg-muted))]", children: description })
3282
- ] }),
3283
- children,
3284
- footer && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: "text-sm text-[rgb(var(--nc-fg-muted))]", children: footer })
3285
- ] }) }),
3286
- /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("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__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "max-w-sm space-y-4 text-center", children: [
3287
- /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("h2", { className: "text-2xl font-semibold", children: "Crafted experiences" }),
3288
- /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("p", { className: "text-[rgb(var(--nc-fg-muted))]", children: "Build authentication flows that feel premium and cohesive." })
3289
- ] }) })
3290
- ]
3291
- }
3292
- );
3293
- }
3294
-
3295
- // src/components/layout/container.tsx
3296
- var import_jsx_runtime46 = require("react/jsx-runtime");
3297
- var sizeClasses3 = {
3298
- sm: "max-w-3xl",
3299
- md: "max-w-5xl",
3300
- lg: "max-w-6xl",
3301
- xl: "max-w-7xl"
3302
- };
3303
- function Container({ className, size = "lg", ...props }) {
3304
- return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
3305
- "div",
3306
- {
3307
- className: cn("mx-auto w-full px-4 sm:px-6 lg:px-8", sizeClasses3[size], className),
3308
- ...props
3309
- }
3310
- );
3311
- }
3312
-
3313
- // src/components/layout/grid.tsx
3314
- var import_jsx_runtime47 = require("react/jsx-runtime");
3315
- var colClasses = {
3316
- 1: "grid-cols-1",
3317
- 2: "grid-cols-1 md:grid-cols-2",
3318
- 3: "grid-cols-1 md:grid-cols-2 lg:grid-cols-3",
3319
- 4: "grid-cols-1 md:grid-cols-2 lg:grid-cols-4",
3320
- 5: "grid-cols-1 md:grid-cols-2 lg:grid-cols-5",
3321
- 6: "grid-cols-1 md:grid-cols-3 lg:grid-cols-6"
3322
- };
3323
- var gapClasses = {
3324
- sm: "gap-4",
3325
- md: "gap-6",
3326
- lg: "gap-8",
3327
- xl: "gap-10"
3328
- };
3329
- function Grid({ className, columns = 3, gap = "md", ...props }) {
3330
- return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: cn("grid", colClasses[columns], gapClasses[gap], className), ...props });
3331
- }
3332
-
3333
- // src/theme/theme-context.tsx
3334
- var React24 = __toESM(require("react"), 1);
3335
- var import_jsx_runtime48 = require("react/jsx-runtime");
3336
- var THEME_NAMES = [
3337
- "aurora",
3338
- "ember",
3339
- "ocean",
3340
- "midnight",
3341
- "cosmic"
3342
- ];
3343
- var ThemeContext = React24.createContext(null);
3344
- var DEFAULT_THEME_KEY = "nextcraft-theme";
3345
- var DEFAULT_MODE_KEY = "nextcraft-mode";
3346
- function ThemeProvider({
3347
- children,
3348
- defaultTheme = "ocean",
3349
- defaultMode = "system",
3350
- storageKeyTheme = DEFAULT_THEME_KEY,
3351
- storageKeyMode = DEFAULT_MODE_KEY
3352
- }) {
3353
- const [theme, setTheme] = React24.useState(defaultTheme);
3354
- const [mode, setMode] = React24.useState(defaultMode);
3355
- React24.useEffect(() => {
3356
- if (typeof window === "undefined") return;
3357
- try {
3358
- const storedTheme = window.localStorage.getItem(storageKeyTheme);
3359
- const storedMode = window.localStorage.getItem(storageKeyMode);
3360
- if (storedTheme) setTheme(storedTheme);
3361
- if (storedMode) setMode(storedMode);
3362
- } catch {
3363
- }
3364
- }, [storageKeyTheme, storageKeyMode]);
3365
- React24.useEffect(() => {
3366
- if (typeof window === "undefined") return;
3367
- try {
3368
- window.localStorage.setItem(storageKeyTheme, theme);
3369
- window.localStorage.setItem(storageKeyMode, mode);
3370
- } catch {
3371
- }
3372
- }, [theme, mode, storageKeyTheme, storageKeyMode]);
3373
- React24.useEffect(() => {
3374
- if (typeof document === "undefined") return;
3375
- const root = document.documentElement;
3376
- root.dataset.ncTheme = theme;
3377
- if (mode !== "system") {
3378
- root.dataset.ncMode = mode;
3379
- return;
3380
- }
3381
- const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
3382
- const applySystem = () => {
3383
- root.dataset.ncMode = mediaQuery.matches ? "dark" : "light";
3384
- };
3385
- applySystem();
3386
- if (typeof mediaQuery.addEventListener === "function") {
3387
- mediaQuery.addEventListener("change", applySystem);
3388
- return () => mediaQuery.removeEventListener("change", applySystem);
3389
- }
3390
- mediaQuery.addListener(applySystem);
3391
- return () => mediaQuery.removeListener(applySystem);
3392
- }, [theme, mode]);
3393
- const value = React24.useMemo(
3394
- () => ({ theme, mode, setTheme, setMode }),
3395
- [theme, mode]
3396
- );
3397
- return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(ThemeContext.Provider, { value, children });
3398
- }
3399
- function useTheme() {
3400
- const context = React24.useContext(ThemeContext);
3401
- if (!context) {
3402
- throw new Error("useTheme must be used within ThemeProvider");
3403
- }
3404
- return context;
3405
- }
3406
-
3407
- // src/components/theme-switcher.tsx
3408
- var import_jsx_runtime49 = require("react/jsx-runtime");
3409
- var MODE_OPTIONS = ["system", "light", "dark"];
3410
- function ThemeSwitcher({ className, showLabels = true, ...props }) {
3411
- const { theme, mode, setTheme, setMode } = useTheme();
3412
- return /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(
3413
- "div",
3414
- {
3415
- className: cn(
3416
- "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)]",
3417
- className
3418
- ),
3419
- ...props,
3420
- children: [
3421
- /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("label", { className: "flex items-center gap-2", children: [
3422
- showLabels && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "text-[rgb(var(--nc-fg-muted))]", children: "Theme" }),
3423
- /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
3424
- "select",
3425
- {
3426
- 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)]",
3427
- value: theme,
3428
- onChange: (event) => setTheme(event.target.value),
3429
- children: THEME_NAMES.map((name) => /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("option", { value: name, className: "text-slate-900", children: name }, name))
3430
- }
3431
- )
3432
- ] }),
3433
- /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("label", { className: "flex items-center gap-2", children: [
3434
- showLabels && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "text-[rgb(var(--nc-fg-muted))]", children: "Mode" }),
3435
- /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
3436
- "select",
3437
- {
3438
- 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)]",
3439
- value: mode,
3440
- onChange: (event) => setMode(event.target.value),
3441
- children: MODE_OPTIONS.map((value) => /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("option", { value, className: "text-slate-900", children: value }, value))
3442
- }
3443
- )
3444
- ] })
3445
- ]
3446
- }
3447
- );
3448
- }
76
+ var import_craft_button = require("./components/craft-button");
77
+ var import_glass_card = require("./components/glass-card");
78
+ var import_craft_input = require("./components/craft-input");
79
+ var import_craft_textarea = require("./components/craft-textarea");
80
+ var import_craft_select = require("./components/craft-select");
81
+ var import_craft_checkbox = require("./components/craft-checkbox");
82
+ var import_craft_switch = require("./components/craft-switch");
83
+ var import_craft_badge = require("./components/craft-badge");
84
+ var import_craft_alert = require("./components/craft-alert");
85
+ var import_craft_error_state = require("./components/craft-error-state");
86
+ var import_craft_loading_state = require("./components/craft-loading-state");
87
+ var import_craft_card = require("./components/craft-card");
88
+ var import_craft_modal = require("./components/craft-modal");
89
+ var import_craft_drawer = require("./components/craft-drawer");
90
+ var import_craft_tabs = require("./components/craft-tabs");
91
+ var import_craft_tooltip = require("./components/craft-tooltip");
92
+ var import_craft_toast = require("./components/craft-toast");
93
+ var import_craft_skeleton = require("./components/craft-skeleton");
94
+ var import_craft_empty_state = require("./components/craft-empty-state");
95
+ var import_craft_popover = require("./components/craft-popover");
96
+ var import_craft_dropdown_menu = require("./components/craft-dropdown-menu");
97
+ var import_craft_command_palette = require("./components/craft-command-palette");
98
+ var import_craft_link = require("./components/craft-link");
99
+ var import_craft_stat_card = require("./components/craft-stat-card");
100
+ var import_craft_date_picker = require("./components/craft-date-picker");
101
+ var import_craft_icon = require("./components/craft-icon");
102
+ var import_craft_number_input = require("./components/craft-number-input");
103
+ var import_craft_currency_input = require("./components/craft-currency-input");
104
+ var import_craft_form = require("./components/craft-form");
105
+ var import_craft_form_builder = require("./components/craft-form-builder");
106
+ var import_craft_form_field = require("./components/craft-form-field");
107
+ var import_craft_submit_button = require("./components/craft-submit-button");
108
+ var import_craft_confirm_dialog = require("./components/craft-confirm-dialog");
109
+ var import_craft_create_edit_drawer = require("./components/craft-create-edit-drawer");
110
+ var import_craft_filter_bar = require("./components/craft-filter-bar");
111
+ var import_craft_table_toolbar = require("./components/craft-table-toolbar");
112
+ var import_craft_data_table = require("./components/craft-data-table");
113
+ var import_craft_pagination = require("./components/craft-pagination");
114
+ var import_app_shell = require("./components/layout/app-shell");
115
+ var import_app_template = require("./components/layout/app-template");
116
+ var import_layout_config = require("./components/layout/layout-config");
117
+ var import_sidebar = require("./components/layout/sidebar");
118
+ var import_top_nav = require("./components/layout/top-nav");
119
+ var import_page_header = require("./components/layout/page-header");
120
+ var import_breadcrumbs = require("./components/layout/breadcrumbs");
121
+ var import_auth_layout = require("./components/layout/auth-layout");
122
+ var import_container = require("./components/layout/container");
123
+ var import_grid = require("./components/layout/grid");
124
+ var import_theme_switcher = require("./components/theme-switcher");
125
+ var import_theme_context = require("./theme/theme-context");
3449
126
  // Annotate the CommonJS export names for ESM import in node:
3450
127
  0 && (module.exports = {
3451
128
  AppShell,