najm-kit 2.10.0 → 2.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,650 @@
1
+ import { useResolvedFeedbackLabels, useNajmPreferencesContext } from './chunk-EEBLEDNI.mjs';
2
+ import { Button } from './chunk-XZL32HFR.mjs';
3
+ import { useNajmDesign, cn } from './chunk-KVZACF4G.mjs';
4
+ import { humanizeToken, DEFAULT_PLACEHOLDER, formatRelativeTime, formatTime, formatDateTime, formatDate, formatPercent, formatNumber, formatCurrency } from './chunk-JABLSOQN.mjs';
5
+ import * as React3 from 'react';
6
+ import { createContext, useContext, useMemo, useState, useCallback } from 'react';
7
+ import { jsx, jsxs } from 'react/jsx-runtime';
8
+ import { AlertTriangle, LoaderCircleIcon, LoaderPinwheelIcon, LoaderIcon, ShieldOff, Compass } from 'lucide-react';
9
+
10
+ function normalizeBranding(input) {
11
+ if (!input) return {};
12
+ const value = {};
13
+ const expanded = input.logoExpanded ?? input.sidebarLogoExpandedPath;
14
+ const collapsed = input.logoCollapsed ?? input.sidebarLogoCollapsedPath;
15
+ if (input.appName !== void 0) value.appName = input.appName;
16
+ if (input.logoFallback !== void 0) value.logoFallback = input.logoFallback;
17
+ if (input.logoHref !== void 0) value.logoHref = input.logoHref;
18
+ if (expanded !== void 0) value.logoExpanded = expanded;
19
+ if (collapsed !== void 0) value.logoCollapsed = collapsed;
20
+ return value;
21
+ }
22
+ var NBrandingContext = createContext(null);
23
+ function useNBranding() {
24
+ return useContext(NBrandingContext);
25
+ }
26
+ function NBrandingProvider({
27
+ children,
28
+ appName,
29
+ logoExpanded,
30
+ logoCollapsed,
31
+ logoFallback,
32
+ logoHref
33
+ }) {
34
+ const value = useMemo(
35
+ () => ({ appName, logoExpanded, logoCollapsed, logoFallback, logoHref }),
36
+ [appName, logoExpanded, logoCollapsed, logoFallback, logoHref]
37
+ );
38
+ return /* @__PURE__ */ jsx(NBrandingContext.Provider, { value, children });
39
+ }
40
+ var NBrandingEditorContext = createContext(null);
41
+ function useNBrandingEditor() {
42
+ return useContext(NBrandingEditorContext);
43
+ }
44
+ function NBrandingStateProvider({
45
+ children,
46
+ branding,
47
+ initialBranding
48
+ }) {
49
+ const [state, setState] = useState(
50
+ () => normalizeBranding(initialBranding ?? branding)
51
+ );
52
+ const setBranding = useCallback((patch) => {
53
+ const marks = normalizeBranding(patch);
54
+ setState((current) => ({ ...current, ...marks }));
55
+ }, []);
56
+ const controlled = useMemo(
57
+ () => branding ? normalizeBranding(branding) : void 0,
58
+ [branding]
59
+ );
60
+ const resolved = controlled ?? state;
61
+ const editor = useMemo(
62
+ () => ({ branding: resolved, setBranding: branding ? noop : setBranding }),
63
+ [resolved, branding, setBranding]
64
+ );
65
+ return /* @__PURE__ */ jsx(NBrandingEditorContext.Provider, { value: editor, children: /* @__PURE__ */ jsx(NBrandingProvider, { ...resolved, children }) });
66
+ }
67
+ function noop() {
68
+ }
69
+ var Default = ({ className, ...props }) => /* @__PURE__ */ jsx(LoaderIcon, { className: cn("animate-spin", className), ...props });
70
+ var Circle = ({ className, ...props }) => /* @__PURE__ */ jsx(LoaderCircleIcon, { className: cn("animate-spin", className), ...props });
71
+ var Pinwheel = ({ className, ...props }) => /* @__PURE__ */ jsx(LoaderPinwheelIcon, { className: cn("animate-spin", className), ...props });
72
+ var CircleFilled = ({ className, size = 24, ...props }) => /* @__PURE__ */ jsxs("div", { className: "relative", style: { width: size, height: size }, children: [
73
+ /* @__PURE__ */ jsx("div", { className: "absolute inset-0 rotate-180", children: /* @__PURE__ */ jsx(LoaderCircleIcon, { className: cn("animate-spin", className, "text-foreground opacity-20"), size, ...props }) }),
74
+ /* @__PURE__ */ jsx(LoaderCircleIcon, { className: cn("relative animate-spin", className), size, ...props })
75
+ ] });
76
+ var Ellipsis = ({ size = 24, ...props }) => /* @__PURE__ */ jsxs("svg", { height: size, viewBox: "0 0 24 24", width: size, xmlns: "http://www.w3.org/2000/svg", ...props, children: [
77
+ /* @__PURE__ */ jsx("title", { children: "Loading..." }),
78
+ /* @__PURE__ */ jsx("circle", { cx: "4", cy: "12", fill: "currentColor", r: "2", children: /* @__PURE__ */ jsx("animate", { attributeName: "cy", begin: "0;ellipsis3.end+0.25s", calcMode: "spline", dur: "0.6s", id: "ellipsis1", keySplines: ".33,.66,.66,1;.33,0,.66,.33", values: "12;6;12" }) }),
79
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", fill: "currentColor", r: "2", children: /* @__PURE__ */ jsx("animate", { attributeName: "cy", begin: "ellipsis1.begin+0.1s", calcMode: "spline", dur: "0.6s", keySplines: ".33,.66,.66,1;.33,0,.66,.33", values: "12;6;12" }) }),
80
+ /* @__PURE__ */ jsx("circle", { cx: "20", cy: "12", fill: "currentColor", r: "2", children: /* @__PURE__ */ jsx("animate", { attributeName: "cy", begin: "ellipsis1.begin+0.2s", calcMode: "spline", dur: "0.6s", id: "ellipsis3", keySplines: ".33,.66,.66,1;.33,0,.66,.33", values: "12;6;12" }) })
81
+ ] });
82
+ var Ring = ({ size = 24, ...props }) => /* @__PURE__ */ jsxs("svg", { height: size, stroke: "currentColor", viewBox: "0 0 44 44", width: size, xmlns: "http://www.w3.org/2000/svg", ...props, children: [
83
+ /* @__PURE__ */ jsx("title", { children: "Loading..." }),
84
+ /* @__PURE__ */ jsxs("g", { fill: "none", fillRule: "evenodd", strokeWidth: "2", children: [
85
+ /* @__PURE__ */ jsxs("circle", { cx: "22", cy: "22", r: "1", children: [
86
+ /* @__PURE__ */ jsx("animate", { attributeName: "r", begin: "0s", calcMode: "spline", dur: "1.8s", keySplines: "0.165, 0.84, 0.44, 1", keyTimes: "0; 1", repeatCount: "indefinite", values: "1; 20" }),
87
+ /* @__PURE__ */ jsx("animate", { attributeName: "stroke-opacity", begin: "0s", calcMode: "spline", dur: "1.8s", keySplines: "0.3, 0.61, 0.355, 1", keyTimes: "0; 1", repeatCount: "indefinite", values: "1; 0" })
88
+ ] }),
89
+ /* @__PURE__ */ jsxs("circle", { cx: "22", cy: "22", r: "1", children: [
90
+ /* @__PURE__ */ jsx("animate", { attributeName: "r", begin: "-0.9s", calcMode: "spline", dur: "1.8s", keySplines: "0.165, 0.84, 0.44, 1", keyTimes: "0; 1", repeatCount: "indefinite", values: "1; 20" }),
91
+ /* @__PURE__ */ jsx("animate", { attributeName: "stroke-opacity", begin: "-0.9s", calcMode: "spline", dur: "1.8s", keySplines: "0.3, 0.61, 0.355, 1", keyTimes: "0; 1", repeatCount: "indefinite", values: "1; 0" })
92
+ ] })
93
+ ] })
94
+ ] });
95
+ var Bars = ({ size = 24, ...props }) => /* @__PURE__ */ jsxs("svg", { height: size, viewBox: "0 0 24 24", width: size, xmlns: "http://www.w3.org/2000/svg", ...props, children: [
96
+ /* @__PURE__ */ jsx("title", { children: "Loading..." }),
97
+ /* @__PURE__ */ jsx("rect", { fill: "currentColor", height: "4", rx: "1", width: "4", x: "1", y: "10", children: /* @__PURE__ */ jsx("animate", { attributeName: "opacity", begin: "0s", dur: "0.6s", keyTimes: "0;0.5;1", repeatCount: "indefinite", values: "1;0.3;1" }) }),
98
+ /* @__PURE__ */ jsx("rect", { fill: "currentColor", height: "4", rx: "1", width: "4", x: "10", y: "10", children: /* @__PURE__ */ jsx("animate", { attributeName: "opacity", begin: "0.1s", dur: "0.6s", keyTimes: "0;0.5;1", repeatCount: "indefinite", values: "1;0.3;1" }) }),
99
+ /* @__PURE__ */ jsx("rect", { fill: "currentColor", height: "4", rx: "1", width: "4", x: "19", y: "10", children: /* @__PURE__ */ jsx("animate", { attributeName: "opacity", begin: "0.2s", dur: "0.6s", keyTimes: "0;0.5;1", repeatCount: "indefinite", values: "1;0.3;1" }) })
100
+ ] });
101
+ var Infinite = ({ size = 24, ...props }) => /* @__PURE__ */ jsxs(
102
+ "svg",
103
+ {
104
+ height: size,
105
+ preserveAspectRatio: "xMidYMid",
106
+ viewBox: "0 0 100 100",
107
+ width: size,
108
+ xmlns: "http://www.w3.org/2000/svg",
109
+ ...props,
110
+ children: [
111
+ /* @__PURE__ */ jsx("title", { children: "Loading..." }),
112
+ /* @__PURE__ */ jsx(
113
+ "path",
114
+ {
115
+ d: "M24.3 30C11.4 30 5 43.3 5 50s6.4 20 19.3 20c19.3 0 32.1-40 51.4-40 C88.6 30 95 43.3 95 50s-6.4 20-19.3 20C56.4 70 43.6 30 24.3 30z",
116
+ fill: "none",
117
+ stroke: "currentColor",
118
+ strokeDasharray: "205.271142578125 51.317785644531256",
119
+ strokeLinecap: "round",
120
+ strokeWidth: "10",
121
+ style: { transform: "scale(0.8)", transformOrigin: "50px 50px" },
122
+ children: /* @__PURE__ */ jsx(
123
+ "animate",
124
+ {
125
+ attributeName: "stroke-dashoffset",
126
+ dur: "2s",
127
+ keyTimes: "0;1",
128
+ repeatCount: "indefinite",
129
+ values: "0;256.58892822265625"
130
+ }
131
+ )
132
+ }
133
+ )
134
+ ]
135
+ }
136
+ );
137
+ var spinnerVariants = {
138
+ default: Default,
139
+ circle: Circle,
140
+ pinwheel: Pinwheel,
141
+ "circle-filled": CircleFilled,
142
+ ellipsis: Ellipsis,
143
+ ring: Ring,
144
+ bars: Bars,
145
+ infinite: Infinite
146
+ };
147
+ function NSpinner({ variant = "default", size = 24, className, ...props }) {
148
+ const Component = spinnerVariants[variant] || Default;
149
+ return /* @__PURE__ */ jsx(Component, { className, size, ...props });
150
+ }
151
+ function NPageLayout({
152
+ as: Comp = "main",
153
+ className,
154
+ style,
155
+ ...props
156
+ }) {
157
+ const { layout } = useNajmDesign();
158
+ const pageGutter = layout?.pageGutter ?? "var(--page-gutter, 24px)";
159
+ const sectionGap = layout?.sectionGap ?? "var(--section-gap, 20px)";
160
+ return /* @__PURE__ */ jsx(
161
+ Comp,
162
+ {
163
+ className: cn("flex min-w-0 flex-col", className),
164
+ style: {
165
+ /**
166
+ * Published so descendants can cancel the page padding exactly. A
167
+ * full-bleed child (a non-card NPageHeader) cannot guess these: the
168
+ * design config resolves them to literals, not to the `--page-gutter`
169
+ * / `--section-gap` fallbacks.
170
+ */
171
+ "--najm-page-gutter": pageGutter,
172
+ "--najm-section-gap": sectionGap,
173
+ gap: sectionGap,
174
+ paddingInline: pageGutter,
175
+ paddingBlock: sectionGap,
176
+ ...style
177
+ },
178
+ ...props
179
+ }
180
+ );
181
+ }
182
+ var INLINE_PADDING = {
183
+ loading: "py-8",
184
+ error: "py-8",
185
+ empty: "py-12"
186
+ };
187
+ var PANEL_BASE = "grid place-items-center min-h-64 w-full";
188
+ var PAGE_MIN = "min-h-[60vh]";
189
+ function NFeedbackStateFrame({
190
+ surface = "inline",
191
+ spacing = "empty",
192
+ className,
193
+ children,
194
+ ...rest
195
+ }) {
196
+ if (surface === "page") {
197
+ return /* @__PURE__ */ jsx(
198
+ NPageLayout,
199
+ {
200
+ as: "div",
201
+ className: cn(
202
+ "items-center justify-center text-center",
203
+ PAGE_MIN,
204
+ className
205
+ ),
206
+ ...rest,
207
+ children
208
+ }
209
+ );
210
+ }
211
+ if (surface === "panel") {
212
+ return /* @__PURE__ */ jsx("div", { className: cn(PANEL_BASE, className), ...rest, children });
213
+ }
214
+ return /* @__PURE__ */ jsx("div", { className: cn("flex flex-col items-center justify-center gap-3", INLINE_PADDING[spacing], className), ...rest, children });
215
+ }
216
+ function useLoadingLabel(explicit) {
217
+ const labels = useResolvedFeedbackLabels();
218
+ if (explicit !== void 0) return explicit;
219
+ return labels.loadingLabel;
220
+ }
221
+ function NLoadingState({
222
+ label,
223
+ className,
224
+ fullScreen = false,
225
+ spinnerVariant = "circle",
226
+ spinnerSize = 32,
227
+ surface = "inline"
228
+ }) {
229
+ const resolvedLabel = useLoadingLabel(label);
230
+ if (fullScreen) {
231
+ return /* @__PURE__ */ jsxs(
232
+ "div",
233
+ {
234
+ className: cn(
235
+ "fixed inset-0 z-50 bg-background/80 backdrop-blur-sm flex flex-col items-center justify-center gap-3 py-8",
236
+ className
237
+ ),
238
+ children: [
239
+ /* @__PURE__ */ jsx(NSpinner, { variant: spinnerVariant, size: spinnerSize }),
240
+ resolvedLabel && /* @__PURE__ */ jsx("p", { className: "text-muted-foreground text-sm", children: resolvedLabel })
241
+ ]
242
+ }
243
+ );
244
+ }
245
+ return /* @__PURE__ */ jsxs(
246
+ NFeedbackStateFrame,
247
+ {
248
+ surface,
249
+ spacing: "loading",
250
+ role: "status",
251
+ "aria-live": "polite",
252
+ "aria-busy": "true",
253
+ className,
254
+ children: [
255
+ /* @__PURE__ */ jsx(NSpinner, { variant: spinnerVariant, size: spinnerSize }),
256
+ resolvedLabel && /* @__PURE__ */ jsx("p", { className: "text-muted-foreground text-sm", children: resolvedLabel })
257
+ ]
258
+ }
259
+ );
260
+ }
261
+ var SIZE_CLASSES = {
262
+ sm: "h-8 w-8",
263
+ md: "h-10 w-10",
264
+ lg: "h-12 w-12",
265
+ xl: "h-16 w-16"
266
+ };
267
+ function renderFeedbackIcon(icon, options) {
268
+ if (!icon) return null;
269
+ const size = options?.size ?? "md";
270
+ const sizeClass = SIZE_CLASSES[size];
271
+ if (typeof icon === "function" || typeof icon === "object" && "render" in icon) {
272
+ const Component = icon;
273
+ return /* @__PURE__ */ jsx(
274
+ Component,
275
+ {
276
+ className: sizeClass,
277
+ "aria-hidden": options?.decorative ? true : void 0
278
+ }
279
+ );
280
+ }
281
+ if (React3.isValidElement(icon)) {
282
+ if (!options?.decorative) return icon;
283
+ return React3.cloneElement(icon, {
284
+ "aria-hidden": true
285
+ });
286
+ }
287
+ return null;
288
+ }
289
+ function NErrorState({
290
+ title,
291
+ message,
292
+ onRetry,
293
+ retryLabel,
294
+ className,
295
+ icon,
296
+ surface = "inline"
297
+ }) {
298
+ const labels = useResolvedFeedbackLabels();
299
+ const resolvedTitle = title ?? labels.errorTitle;
300
+ const resolvedMessage = message ?? labels.errorMessage;
301
+ const resolvedRetryLabel = retryLabel ?? labels.retryLabel;
302
+ const iconNode = renderFeedbackIcon(icon, { size: "md", decorative: true }) ?? /* @__PURE__ */ jsx(AlertTriangle, { className: "h-10 w-10", "aria-hidden": "true" });
303
+ return /* @__PURE__ */ jsxs(
304
+ NFeedbackStateFrame,
305
+ {
306
+ surface,
307
+ spacing: "error",
308
+ role: "alert",
309
+ className,
310
+ children: [
311
+ /* @__PURE__ */ jsx("div", { className: "text-destructive", children: iconNode }),
312
+ /* @__PURE__ */ jsxs("div", { className: "text-center", children: [
313
+ /* @__PURE__ */ jsx("h3", { className: "font-semibold text-foreground", children: resolvedTitle }),
314
+ resolvedMessage && /* @__PURE__ */ jsx("p", { className: "text-muted-foreground text-sm mt-1", children: resolvedMessage })
315
+ ] }),
316
+ onRetry && /* @__PURE__ */ jsx(Button, { variant: "outline", onClick: onRetry, className: cn("mt-1"), children: resolvedRetryLabel })
317
+ ]
318
+ }
319
+ );
320
+ }
321
+ function NEmptyState({
322
+ title,
323
+ description,
324
+ icon,
325
+ action,
326
+ className,
327
+ surface = "inline"
328
+ }) {
329
+ const labels = useResolvedFeedbackLabels();
330
+ const resolvedTitle = title ?? labels.emptyTitle;
331
+ const iconNode = icon ? renderFeedbackIcon(icon, { size: "md", decorative: true }) : null;
332
+ return /* @__PURE__ */ jsxs(
333
+ NFeedbackStateFrame,
334
+ {
335
+ surface,
336
+ spacing: "empty",
337
+ className,
338
+ children: [
339
+ iconNode && /* @__PURE__ */ jsx("div", { className: "text-muted-foreground/50", children: iconNode }),
340
+ /* @__PURE__ */ jsxs("div", { className: "text-center", children: [
341
+ resolvedTitle && /* @__PURE__ */ jsx("h3", { className: "font-semibold text-foreground", children: resolvedTitle }),
342
+ description && /* @__PURE__ */ jsx("p", { className: "text-muted-foreground text-sm mt-1", children: description })
343
+ ] }),
344
+ action && /* @__PURE__ */ jsx("div", { className: "mt-2", children: action })
345
+ ]
346
+ }
347
+ );
348
+ }
349
+ function NForbiddenState(props) {
350
+ const labels = useResolvedFeedbackLabels();
351
+ const { icon, ...rest } = props;
352
+ const resolvedTitle = props.title ?? labels.forbiddenTitle;
353
+ const resolvedDescription = props.description ?? labels.forbiddenDescription;
354
+ const size = props.surface === "page" ? "xl" : "md";
355
+ const resolvedIcon = renderFeedbackIcon(icon, { size, decorative: true }) ?? renderFeedbackIcon(ShieldOff, { size, decorative: true });
356
+ return /* @__PURE__ */ jsx(
357
+ NEmptyState,
358
+ {
359
+ ...rest,
360
+ title: resolvedTitle,
361
+ description: resolvedDescription,
362
+ icon: resolvedIcon ?? void 0
363
+ }
364
+ );
365
+ }
366
+ function NNotFoundState(props) {
367
+ const labels = useResolvedFeedbackLabels();
368
+ const { icon, ...rest } = props;
369
+ const resolvedTitle = props.title ?? labels.notFoundTitle;
370
+ const resolvedDescription = props.description ?? labels.notFoundDescription;
371
+ const size = props.surface === "page" ? "xl" : "md";
372
+ const resolvedIcon = renderFeedbackIcon(icon, { size, decorative: true }) ?? renderFeedbackIcon(Compass, { size, decorative: true });
373
+ return /* @__PURE__ */ jsx(
374
+ NEmptyState,
375
+ {
376
+ ...rest,
377
+ title: resolvedTitle,
378
+ description: resolvedDescription,
379
+ icon: resolvedIcon ?? void 0
380
+ }
381
+ );
382
+ }
383
+
384
+ // src/components/form/formFill.ts
385
+ var CITIES = ["Casablanca", "Rabat", "Marrakesh", "Tangier"];
386
+ var SCHOOL_LEVELS = ["Primary", "Middle school", "Secondary school"];
387
+ var CLOTHING_SIZES = ["6 years", "8 years", "10 years", "12 years"];
388
+ function pick(values) {
389
+ if (values.length === 0) return void 0;
390
+ return values[Math.floor(Math.random() * values.length)];
391
+ }
392
+ function randomDigits(length) {
393
+ return Array.from({ length }, () => Math.floor(Math.random() * 10)).join("");
394
+ }
395
+ function randomToken(length = 8) {
396
+ const alphabet = "abcdefghijklmnopqrstuvwxyz0123456789";
397
+ return Array.from(
398
+ { length },
399
+ () => alphabet[Math.floor(Math.random() * alphabet.length)]
400
+ ).join("");
401
+ }
402
+ function asZodLike(schema) {
403
+ return schema && typeof schema === "object" ? schema : void 0;
404
+ }
405
+ function definition(schema) {
406
+ const current = asZodLike(schema);
407
+ return current?._def ?? current?.def ?? {};
408
+ }
409
+ function schemaKind(schema) {
410
+ const currentDefinition = definition(schema);
411
+ const raw = currentDefinition.typeName ?? currentDefinition.type;
412
+ if (typeof raw !== "string") return "";
413
+ return raw.replace(/^Zod/, "").toLowerCase();
414
+ }
415
+ function unwrap(schema) {
416
+ const seen = /* @__PURE__ */ new Set();
417
+ let current = asZodLike(schema);
418
+ while (current && !seen.has(current)) {
419
+ seen.add(current);
420
+ const kind = schemaKind(current);
421
+ const currentDefinition = definition(current);
422
+ const inner = currentDefinition.innerType ?? currentDefinition.schema ?? (kind === "pipe" ? currentDefinition.out ?? currentDefinition.in : void 0);
423
+ if (!inner || typeof inner !== "object") break;
424
+ current = inner;
425
+ }
426
+ return current;
427
+ }
428
+ function objectShape(schema) {
429
+ const current = unwrap(schema);
430
+ if (schemaKind(current) !== "object") return null;
431
+ const shape = current?.shape ?? definition(current).shape;
432
+ return typeof shape === "function" ? shape() : shape ?? null;
433
+ }
434
+ function arrayElement(schema) {
435
+ const current = unwrap(schema);
436
+ if (schemaKind(current) !== "array") return null;
437
+ const currentDefinition = definition(current);
438
+ const element = current?.element ?? currentDefinition.element ?? currentDefinition.type;
439
+ return element && typeof element === "object" ? element : null;
440
+ }
441
+ function enumValues(schema) {
442
+ const current = unwrap(schema);
443
+ const currentDefinition = definition(current);
444
+ const kind = schemaKind(current);
445
+ if (kind === "literal") {
446
+ const values2 = currentDefinition.values;
447
+ if (Array.isArray(values2)) return values2;
448
+ return "value" in currentDefinition ? [currentDefinition.value] : [];
449
+ }
450
+ if (kind !== "enum" && kind !== "nativeenum") return [];
451
+ const entries = currentDefinition.entries;
452
+ if (entries && typeof entries === "object") return Object.values(entries);
453
+ const values = currentDefinition.values;
454
+ if (Array.isArray(values)) return values;
455
+ return Array.isArray(current?.options) ? [...current.options] : [];
456
+ }
457
+ function stringFormat(schema) {
458
+ const currentDefinition = definition(unwrap(schema));
459
+ if (typeof currentDefinition.format === "string") return currentDefinition.format;
460
+ const checks = Array.isArray(currentDefinition.checks) ? currentDefinition.checks : [];
461
+ for (const check of checks) {
462
+ if (!check || typeof check !== "object") continue;
463
+ const value = check;
464
+ const format = value.format ?? value.kind;
465
+ if (typeof format === "string") return format;
466
+ }
467
+ return "";
468
+ }
469
+ function resolveOverride(override, fieldName) {
470
+ if (typeof override === "function") return override(fieldName);
471
+ if (Array.isArray(override)) {
472
+ const value = pick(override);
473
+ if (value && typeof value === "object" && "value" in value) {
474
+ return value.value;
475
+ }
476
+ return value;
477
+ }
478
+ return override;
479
+ }
480
+ function localDateInput(date = /* @__PURE__ */ new Date()) {
481
+ return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, "0")}-${String(date.getDate()).padStart(2, "0")}`;
482
+ }
483
+ function birthDate(child) {
484
+ const date = /* @__PURE__ */ new Date();
485
+ date.setFullYear(date.getFullYear() - (child ? 10 : 35));
486
+ return localDateInput(date);
487
+ }
488
+ function fieldValue(fieldName, schema, siblingFields) {
489
+ const key = fieldName.toLowerCase();
490
+ const current = unwrap(schema);
491
+ const kind = schemaKind(current);
492
+ const format = stringFormat(current);
493
+ const values = enumValues(current);
494
+ if (values.length) return pick(values);
495
+ if (kind === "boolean") return true;
496
+ if (kind === "number" || kind === "bigint") {
497
+ if (key.includes("sortorder")) return 1;
498
+ if (key.includes("quantity")) return 5;
499
+ return 10;
500
+ }
501
+ if (format === "uuid" || key.endsWith("uuid")) {
502
+ return "9cc2c93f-f545-4e07-9f77-f79f08a71dd5";
503
+ }
504
+ if (format === "email" || key.includes("email")) {
505
+ return `test-${randomToken()}@example.com`;
506
+ }
507
+ if (format === "url" || key === "image" || key.includes("imageurl") || key.endsWith("url")) {
508
+ return `https://picsum.photos/seed/${randomToken()}/800/600`;
509
+ }
510
+ if (key === "month") return `${localDateInput().slice(0, 7)}-01`;
511
+ if (key === "registrationdate") return localDateInput();
512
+ if (format === "date" || key.includes("dateofbirth")) {
513
+ const child = siblingFields.has("schoolLevel") || siblingFields.has("clothingSize");
514
+ return birthDate(child);
515
+ }
516
+ if (key.endsWith("id") || key.endsWith("by")) return "";
517
+ if (key === "name") {
518
+ if (siblingFields.has("sku")) return `Test product ${randomToken(4)}`;
519
+ if (siblingFields.has("slug")) return `Test category ${randomToken(4)}`;
520
+ return "Test User";
521
+ }
522
+ if (key.includes("legalname")) return "Test User";
523
+ if (key.includes("phone")) return `+2126${randomDigits(8)}`;
524
+ if (key.endsWith("cin")) return `AB${randomDigits(6)}`;
525
+ if (key.includes("address")) return `10 Test Street, ${pick(CITIES)}`;
526
+ if (key.includes("schoollevel")) return pick(SCHOOL_LEVELS);
527
+ if (key.includes("clothingsize")) return pick(CLOTHING_SIZES);
528
+ if (key.includes("shoesize")) return "36";
529
+ if (key.includes("relationship")) return "Legal guardian";
530
+ if (key.includes("activationtargetmad")) return "7500";
531
+ if (key === "slug") return `test-${randomToken(6)}`;
532
+ if (key === "sku") return `TEST-${randomToken(8).toUpperCase()}`;
533
+ if (key.includes("amountmad") || key.includes("pricemad") || key.includes("limitmad") || key.includes("targetmad")) {
534
+ return "100.00";
535
+ }
536
+ if (key.includes("reason")) return "Generated for form testing.";
537
+ if (key.includes("notes")) return "Generated form testing note.";
538
+ if (key.includes("description")) return "Generated description for form testing.";
539
+ if (key.includes("code")) return randomToken(8).toUpperCase();
540
+ return `Test ${fieldName}`;
541
+ }
542
+ function buildFormFill(schema, overrides = {}) {
543
+ const shape = objectShape(schema) ?? {};
544
+ const siblingFields = new Set(Object.keys(shape));
545
+ const output = {};
546
+ for (const [fieldName, fieldSchema] of Object.entries(shape)) {
547
+ if (Object.prototype.hasOwnProperty.call(overrides, fieldName)) {
548
+ output[fieldName] = resolveOverride(overrides[fieldName], fieldName);
549
+ continue;
550
+ }
551
+ const nestedShape = objectShape(fieldSchema);
552
+ if (nestedShape) {
553
+ output[fieldName] = buildFormFill(fieldSchema);
554
+ continue;
555
+ }
556
+ const element = arrayElement(fieldSchema);
557
+ if (element) {
558
+ output[fieldName] = objectShape(element) ? [buildFormFill(element)] : [fieldValue(fieldName, element, siblingFields)];
559
+ continue;
560
+ }
561
+ output[fieldName] = fieldValue(fieldName, fieldSchema, siblingFields);
562
+ }
563
+ return output;
564
+ }
565
+ var DEFAULT_FORM_DEV_TOOLS = {
566
+ enabled: false,
567
+ shortcut: "F8"
568
+ };
569
+ var FormDevToolsContext = createContext(
570
+ DEFAULT_FORM_DEV_TOOLS
571
+ );
572
+ function normalizeFormDevTools(value) {
573
+ if (typeof value === "boolean") {
574
+ return { ...DEFAULT_FORM_DEV_TOOLS, enabled: value };
575
+ }
576
+ if (!value) return DEFAULT_FORM_DEV_TOOLS;
577
+ return {
578
+ enabled: value.enabled ?? true,
579
+ shortcut: value.shortcut ?? DEFAULT_FORM_DEV_TOOLS.shortcut
580
+ };
581
+ }
582
+ function FormDevToolsProvider({
583
+ children,
584
+ value
585
+ }) {
586
+ const resolved = useMemo(
587
+ () => normalizeFormDevTools(value),
588
+ [value]
589
+ );
590
+ return /* @__PURE__ */ jsx(FormDevToolsContext.Provider, { value: resolved, children });
591
+ }
592
+ function useResolvedFormDevTools(schema, local) {
593
+ const global = useContext(FormDevToolsContext);
594
+ const options = typeof local === "object" ? local : void 0;
595
+ const enabled = typeof local === "boolean" ? local : options?.enabled ?? global.enabled;
596
+ const shortcut = options?.shortcut ?? global.shortcut;
597
+ const fill = options?.fill ?? (schema ? () => buildFormFill(schema, options?.overrides) : void 0);
598
+ return { enabled, shortcut, fill };
599
+ }
600
+ var NajmFormatContext = React3.createContext(
601
+ null
602
+ );
603
+ function NajmFormatProvider({
604
+ children,
605
+ locale,
606
+ currency,
607
+ timeZone,
608
+ placeholder = DEFAULT_PLACEHOLDER
609
+ }) {
610
+ const preferences = useNajmPreferencesContext();
611
+ const resolvedTimeZone = timeZone ?? preferences?.timeZone ?? Intl.DateTimeFormat().resolvedOptions().timeZone;
612
+ const value = React3.useMemo(() => {
613
+ const config = {
614
+ locale,
615
+ timeZone: resolvedTimeZone,
616
+ currency,
617
+ placeholder
618
+ };
619
+ return {
620
+ locale,
621
+ timeZone: resolvedTimeZone,
622
+ currency,
623
+ placeholder,
624
+ config,
625
+ money: (minorUnits) => formatCurrency(minorUnits, config),
626
+ number: (value_, options) => formatNumber(value_, config, options),
627
+ percent: (value_, digits) => formatPercent(value_, config, digits),
628
+ date: (value_, options) => formatDate(value_, config, options),
629
+ dateTime: (value_) => formatDateTime(value_, config),
630
+ time: (value_) => formatTime(value_, config),
631
+ relativeTime: (value_) => formatRelativeTime(value_, config),
632
+ humanize: humanizeToken
633
+ };
634
+ }, [locale, resolvedTimeZone, currency, placeholder]);
635
+ return /* @__PURE__ */ jsx(NajmFormatContext.Provider, { value, children });
636
+ }
637
+ function useNajmFormatContext() {
638
+ return React3.useContext(NajmFormatContext);
639
+ }
640
+ function useNajmFormat() {
641
+ const value = React3.useContext(NajmFormatContext);
642
+ if (!value) {
643
+ throw new Error(
644
+ "useNajmFormat must be rendered under a NajmFormatProvider or NajmAppProvider."
645
+ );
646
+ }
647
+ return value;
648
+ }
649
+
650
+ export { FormDevToolsProvider, NBrandingProvider, NBrandingStateProvider, NEmptyState, NErrorState, NForbiddenState, NLoadingState, NNotFoundState, NPageLayout, NSpinner, NajmFormatProvider, buildFormFill, normalizeBranding, useNBranding, useNBrandingEditor, useNajmFormat, useNajmFormatContext, useResolvedFormDevTools };
@@ -1,4 +1,4 @@
1
- import { useImageChain, normalizeImageSources, NajmUIProvider } from './chunk-FDONJASN.mjs';
1
+ import { useImageChain, normalizeImageSources, NajmUIProvider } from './chunk-EEBLEDNI.mjs';
2
2
  import React from 'react';
3
3
  import { useRouter } from 'next/navigation';
4
4
  import NextImage from 'next/image';