najm-kit 2.9.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.
package/dist/json.mjs CHANGED
@@ -1,5 +1,5 @@
1
- import { Button } from './chunk-JUYT2ISO.mjs';
2
- export { NTableJson } from './chunk-JUYT2ISO.mjs';
1
+ export { NTableJson } from './chunk-K7T7X6PX.mjs';
2
+ import { Button } from './chunk-XZL32HFR.mjs';
3
3
  import { cn } from './chunk-KVZACF4G.mjs';
4
4
  import './chunk-TFHWLE7N.mjs';
5
5
  import { useMemo, useRef, useCallback } from 'react';
package/dist/theme.css CHANGED
@@ -307,10 +307,10 @@ input:autofill {
307
307
  overflow-x: auto;
308
308
  scrollbar-width: none;
309
309
  }
310
- .najm-overlay-scroll-x::-webkit-scrollbar {
311
- display: none;
312
- }
313
-
310
+ .najm-overlay-scroll-x::-webkit-scrollbar {
311
+ display: none;
312
+ }
313
+
314
314
  /* Responsive table actions stay discoverable on touch and tablet layouts.
315
315
  Fine-pointer desktops may keep the quieter hover/focus reveal treatment. */
316
316
  .ntable-card-action {
@@ -367,7 +367,7 @@ input:autofill {
367
367
  .nimage-input-compact-overlay:focus-visible {
368
368
  opacity: 1;
369
369
  }
370
- }
370
+ }
371
371
 
372
372
  /* OverlayScrollbars theme used by the <NajmScroll> component — a thin,
373
373
  translucent slate bar that floats over content with no reserved space.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "najm-kit",
3
- "version": "2.9.0",
3
+ "version": "2.11.0",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "description": "Reusable React UI component package for Najm framework",
@@ -84,6 +84,8 @@
84
84
  "test": "bun test && bun run test:rsc",
85
85
  "test:rsc": "cd test/rsc && bun test --conditions react-server",
86
86
  "test:next16": "bun run build && bun integration/next16-ui-bootstrap/run.ts",
87
+ "test:acceptance": "playwright test",
88
+ "typecheck:acceptance": "tsc --noEmit -p acceptance/tsconfig.json",
87
89
  "clean": "rimraf dist tsconfig.tsbuildinfo"
88
90
  },
89
91
  "peerDependencies": {
@@ -1,161 +0,0 @@
1
- import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import * as React from 'react';
3
- import React__default from 'react';
4
- import { e as NajmMode, a as NajmDesignConfig } from './design-types-Rkpt8Pg1.js';
5
- import { b as NTablePaginationLabels, N as NajmTranslate } from './paginationLabels-dZLSNxfo.js';
6
-
7
- /**
8
- * Defaults every `NTable` beneath the provider inherits.
9
- *
10
- * Localized copy is the motivating case: an application with more than a couple
11
- * of tables should not repeat the same label bundle at every render site, and
12
- * an application with more than one locale should not have to remember to.
13
- */
14
- interface NTableDefaults {
15
- paginationLabels?: NTablePaginationLabels;
16
- }
17
- /**
18
- * Supply table defaults to everything below.
19
- *
20
- * `value` is passed straight through, so memoize it in the caller — an inline
21
- * object literal rebuilds on every render of the shell and re-renders every
22
- * table beneath it. Most label fields are functions, so `useMemo` on the
23
- * translator is usually the whole job.
24
- */
25
- declare function NTableDefaultsProvider({ children, value, }: {
26
- children: React__default.ReactNode;
27
- value: NTableDefaults;
28
- }): react_jsx_runtime.JSX.Element;
29
- declare function useNTableDefaults(): NTableDefaults;
30
-
31
- /**
32
- * Theme and time zone, the two preferences that outlive a render.
33
- *
34
- * Both are *uncontrolled*: the `initial*` props seed state the provider owns
35
- * from then on, and later changes to those props are ignored. That is the
36
- * shape the server hand-off wants — the page is rendered once against a cookie,
37
- * and every change after that originates here.
38
- *
39
- * Persistence is not this provider's business. It applies the change to the
40
- * document, then hands the new value to a callback the application supplies.
41
- * See `NajmNextUIProvider` in `najm-kit/next` for the cookie-endpoint wiring.
42
- */
43
- interface NajmPreferencesContextValue {
44
- theme: NajmMode;
45
- setTheme: (theme: NajmMode) => Promise<void>;
46
- timeZone: string;
47
- setTimeZone: (timeZone: string) => Promise<void>;
48
- }
49
- declare const DEFAULT_TIME_ZONE = "UTC";
50
- interface NajmPreferencesProviderProps {
51
- children: React.ReactNode;
52
- /** Seeds theme state; ignored after mount. Defaults to `"light"`. */
53
- initialTheme?: NajmMode;
54
- /** Seeds time zone state; ignored after mount. Defaults to `"UTC"`. */
55
- initialTimeZone?: string;
56
- /** Persist the new theme. Rejections propagate to the `setTheme` caller. */
57
- onThemeChange?: (theme: NajmMode) => void | Promise<void>;
58
- /** Persist the new time zone. Rejections propagate to `setTimeZone`. */
59
- onTimeZoneChange?: (timeZone: string) => void | Promise<void>;
60
- /**
61
- * Sanitize a time zone before it is stored.
62
- *
63
- * Defaults to an IANA check that falls back to `DEFAULT_TIME_ZONE`, which is
64
- * what every application wanted from the callback it used to have to supply.
65
- * Pass one to narrow further — a fixed set backing a picker, say.
66
- */
67
- normalizeTimeZone?: (value: string) => string;
68
- }
69
- /**
70
- * Standalone preferences, without the design and table layers.
71
- *
72
- * `NajmUIProvider` renders this internally, so most applications never name it.
73
- * It is exported for the case where something *above* the design layer needs to
74
- * read the theme — a runtime theme editor, typically, which owns the design
75
- * config and therefore has to sit above the provider consuming it. Hoisting
76
- * preferences out is then a reorder rather than a fork.
77
- */
78
- declare function NajmPreferencesProvider({ children, initialTheme, initialTimeZone, onThemeChange, onTimeZoneChange, normalizeTimeZone, }: NajmPreferencesProviderProps): react_jsx_runtime.JSX.Element;
79
- /**
80
- * Returns the context when one is mounted, or `null`.
81
- *
82
- * `NajmUIProvider` uses this to defer to an outer `NajmPreferencesProvider`
83
- * instead of shadowing it, so nesting the two is well-defined rather than
84
- * quietly producing two disagreeing themes.
85
- */
86
- declare function useNajmPreferencesContext(): NajmPreferencesContextValue | null;
87
- /** The live theme and a setter that persists through `onThemeChange`. */
88
- declare function useNajmTheme(): Pick<NajmPreferencesContextValue, "theme" | "setTheme">;
89
- /** The live time zone and a setter that persists through `onTimeZoneChange`. */
90
- declare function useNajmTimeZone(): Pick<NajmPreferencesContextValue, "timeZone" | "setTimeZone">;
91
-
92
- interface NajmUIProviderProps extends Omit<NajmPreferencesProviderProps, "children"> {
93
- children: React.ReactNode;
94
- /**
95
- * The design config handed to `NajmDesignProvider`, owned by the application.
96
- *
97
- * Optional, and deliberately so: an application with no runtime theme editor
98
- * has nothing to put here, and requiring it was the only reason such an
99
- * application still had to author a provider file just to hold a constant.
100
- *
101
- * Prefer `initialDesign` for a theme editor. Passing `design` means the
102
- * application holds the draft state itself, which is the file this provider
103
- * exists to delete.
104
- */
105
- design?: NajmDesignConfig;
106
- /**
107
- * Seeds design state this provider owns from then on; ignored after mount.
108
- * A theme editor drives it through `useNajmDesignEditor`.
109
- */
110
- initialDesign?: NajmDesignConfig;
111
- /**
112
- * Forwarded to `NajmDesignProvider`, merged over a `min-h-full` default.
113
- *
114
- * The default is not decoration. `NajmThemeProvider` renders a real `div`
115
- * between the document body and the application, and a block box of
116
- * automatic height severs any `h-full` chain below it — every application
117
- * mounting this at the root was passing the same class back to repair that.
118
- * It is inert where it is not needed: a percentage `min-height` against an
119
- * auto-height parent imposes no constraint.
120
- *
121
- * Merged with `cn`, so a conflicting utility here still wins.
122
- */
123
- className?: string;
124
- /**
125
- * Translator for the pagination labels. Omit it and the packaged English
126
- * applies — the provider is still worth mounting for design and preferences.
127
- *
128
- * Memoize it. The labels are rebuilt whenever its identity changes, and
129
- * rebuilding them re-renders every table beneath.
130
- */
131
- t?: NajmTranslate;
132
- /** Catalog prefix for the labels. Defaults to `"common.pagination"`. */
133
- paginationKeyPrefix?: string;
134
- /**
135
- * Per-key overrides layered over the translated labels. Memoize it, for the
136
- * same reason as `t`.
137
- */
138
- tableDefaults?: NTableDefaults;
139
- }
140
- /**
141
- * The one provider a Najm application mounts for UI concerns.
142
- *
143
- * Composes three things that otherwise get copied between projects: theme and
144
- * time zone state with async persistence, a `NajmDesignProvider` fed the live
145
- * theme, and `NTable` pagination labels derived from the application's
146
- * translator.
147
- *
148
- * What it deliberately does not own: auth, react-query, and the translation
149
- * catalog. Those stay in the application — folding them in would make a UI
150
- * package depend on `najm-auth` and `@tanstack/react-query` and turn it into a
151
- * framework. Persistence is injected as callbacks so this entry imports
152
- * nothing from `next`; see `NajmNextUIProvider` in `najm-kit/next`.
153
- *
154
- * Rendering this under an existing `NajmPreferencesProvider` is supported: the
155
- * outer one wins and the preference props here are ignored. That is what lets
156
- * an application with a runtime theme editor hoist preferences above its
157
- * design context without forking this component.
158
- */
159
- declare function NajmUIProvider({ children, design, initialDesign, className, t, paginationKeyPrefix, tableDefaults, initialTheme, initialTimeZone, onThemeChange, onTimeZoneChange, normalizeTimeZone, }: NajmUIProviderProps): react_jsx_runtime.JSX.Element;
160
-
161
- export { DEFAULT_TIME_ZONE as D, type NajmUIProviderProps as N, type NTableDefaults as a, NTableDefaultsProvider as b, type NajmPreferencesContextValue as c, NajmPreferencesProvider as d, type NajmPreferencesProviderProps as e, NajmUIProvider as f, useNajmPreferencesContext as g, useNajmTheme as h, useNajmTimeZone as i, useNTableDefaults as u };
@@ -1,333 +0,0 @@
1
- import { useNajmPreferencesContext } from './chunk-USZUOJMK.mjs';
2
- import { humanizeToken, DEFAULT_PLACEHOLDER, formatRelativeTime, formatTime, formatDateTime, formatDate, formatPercent, formatNumber, formatCurrency } from './chunk-JABLSOQN.mjs';
3
- import * as React2 from 'react';
4
- import { createContext, useContext, useMemo, useState, useCallback } from 'react';
5
- import { jsx } from 'react/jsx-runtime';
6
-
7
- function normalizeBranding(input) {
8
- if (!input) return {};
9
- const value = {};
10
- const expanded = input.logoExpanded ?? input.sidebarLogoExpandedPath;
11
- const collapsed = input.logoCollapsed ?? input.sidebarLogoCollapsedPath;
12
- if (input.appName !== void 0) value.appName = input.appName;
13
- if (input.logoFallback !== void 0) value.logoFallback = input.logoFallback;
14
- if (input.logoHref !== void 0) value.logoHref = input.logoHref;
15
- if (expanded !== void 0) value.logoExpanded = expanded;
16
- if (collapsed !== void 0) value.logoCollapsed = collapsed;
17
- return value;
18
- }
19
- var NBrandingContext = createContext(null);
20
- function useNBranding() {
21
- return useContext(NBrandingContext);
22
- }
23
- function NBrandingProvider({
24
- children,
25
- appName,
26
- logoExpanded,
27
- logoCollapsed,
28
- logoFallback,
29
- logoHref
30
- }) {
31
- const value = useMemo(
32
- () => ({ appName, logoExpanded, logoCollapsed, logoFallback, logoHref }),
33
- [appName, logoExpanded, logoCollapsed, logoFallback, logoHref]
34
- );
35
- return /* @__PURE__ */ jsx(NBrandingContext.Provider, { value, children });
36
- }
37
- var NBrandingEditorContext = createContext(null);
38
- function useNBrandingEditor() {
39
- return useContext(NBrandingEditorContext);
40
- }
41
- function NBrandingStateProvider({
42
- children,
43
- branding,
44
- initialBranding
45
- }) {
46
- const [state, setState] = useState(
47
- () => normalizeBranding(initialBranding ?? branding)
48
- );
49
- const setBranding = useCallback((patch) => {
50
- const marks = normalizeBranding(patch);
51
- setState((current) => ({ ...current, ...marks }));
52
- }, []);
53
- const controlled = useMemo(
54
- () => branding ? normalizeBranding(branding) : void 0,
55
- [branding]
56
- );
57
- const resolved = controlled ?? state;
58
- const editor = useMemo(
59
- () => ({ branding: resolved, setBranding: branding ? noop : setBranding }),
60
- [resolved, branding, setBranding]
61
- );
62
- return /* @__PURE__ */ jsx(NBrandingEditorContext.Provider, { value: editor, children: /* @__PURE__ */ jsx(NBrandingProvider, { ...resolved, children }) });
63
- }
64
- function noop() {
65
- }
66
-
67
- // src/components/form/formFill.ts
68
- var CITIES = ["Casablanca", "Rabat", "Marrakesh", "Tangier"];
69
- var SCHOOL_LEVELS = ["Primary", "Middle school", "Secondary school"];
70
- var CLOTHING_SIZES = ["6 years", "8 years", "10 years", "12 years"];
71
- function pick(values) {
72
- if (values.length === 0) return void 0;
73
- return values[Math.floor(Math.random() * values.length)];
74
- }
75
- function randomDigits(length) {
76
- return Array.from({ length }, () => Math.floor(Math.random() * 10)).join("");
77
- }
78
- function randomToken(length = 8) {
79
- const alphabet = "abcdefghijklmnopqrstuvwxyz0123456789";
80
- return Array.from(
81
- { length },
82
- () => alphabet[Math.floor(Math.random() * alphabet.length)]
83
- ).join("");
84
- }
85
- function asZodLike(schema) {
86
- return schema && typeof schema === "object" ? schema : void 0;
87
- }
88
- function definition(schema) {
89
- const current = asZodLike(schema);
90
- return current?._def ?? current?.def ?? {};
91
- }
92
- function schemaKind(schema) {
93
- const currentDefinition = definition(schema);
94
- const raw = currentDefinition.typeName ?? currentDefinition.type;
95
- if (typeof raw !== "string") return "";
96
- return raw.replace(/^Zod/, "").toLowerCase();
97
- }
98
- function unwrap(schema) {
99
- const seen = /* @__PURE__ */ new Set();
100
- let current = asZodLike(schema);
101
- while (current && !seen.has(current)) {
102
- seen.add(current);
103
- const kind = schemaKind(current);
104
- const currentDefinition = definition(current);
105
- const inner = currentDefinition.innerType ?? currentDefinition.schema ?? (kind === "pipe" ? currentDefinition.out ?? currentDefinition.in : void 0);
106
- if (!inner || typeof inner !== "object") break;
107
- current = inner;
108
- }
109
- return current;
110
- }
111
- function objectShape(schema) {
112
- const current = unwrap(schema);
113
- if (schemaKind(current) !== "object") return null;
114
- const shape = current?.shape ?? definition(current).shape;
115
- return typeof shape === "function" ? shape() : shape ?? null;
116
- }
117
- function arrayElement(schema) {
118
- const current = unwrap(schema);
119
- if (schemaKind(current) !== "array") return null;
120
- const currentDefinition = definition(current);
121
- const element = current?.element ?? currentDefinition.element ?? currentDefinition.type;
122
- return element && typeof element === "object" ? element : null;
123
- }
124
- function enumValues(schema) {
125
- const current = unwrap(schema);
126
- const currentDefinition = definition(current);
127
- const kind = schemaKind(current);
128
- if (kind === "literal") {
129
- const values2 = currentDefinition.values;
130
- if (Array.isArray(values2)) return values2;
131
- return "value" in currentDefinition ? [currentDefinition.value] : [];
132
- }
133
- if (kind !== "enum" && kind !== "nativeenum") return [];
134
- const entries = currentDefinition.entries;
135
- if (entries && typeof entries === "object") return Object.values(entries);
136
- const values = currentDefinition.values;
137
- if (Array.isArray(values)) return values;
138
- return Array.isArray(current?.options) ? [...current.options] : [];
139
- }
140
- function stringFormat(schema) {
141
- const currentDefinition = definition(unwrap(schema));
142
- if (typeof currentDefinition.format === "string") return currentDefinition.format;
143
- const checks = Array.isArray(currentDefinition.checks) ? currentDefinition.checks : [];
144
- for (const check of checks) {
145
- if (!check || typeof check !== "object") continue;
146
- const value = check;
147
- const format = value.format ?? value.kind;
148
- if (typeof format === "string") return format;
149
- }
150
- return "";
151
- }
152
- function resolveOverride(override, fieldName) {
153
- if (typeof override === "function") return override(fieldName);
154
- if (Array.isArray(override)) {
155
- const value = pick(override);
156
- if (value && typeof value === "object" && "value" in value) {
157
- return value.value;
158
- }
159
- return value;
160
- }
161
- return override;
162
- }
163
- function localDateInput(date = /* @__PURE__ */ new Date()) {
164
- return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, "0")}-${String(date.getDate()).padStart(2, "0")}`;
165
- }
166
- function birthDate(child) {
167
- const date = /* @__PURE__ */ new Date();
168
- date.setFullYear(date.getFullYear() - (child ? 10 : 35));
169
- return localDateInput(date);
170
- }
171
- function fieldValue(fieldName, schema, siblingFields) {
172
- const key = fieldName.toLowerCase();
173
- const current = unwrap(schema);
174
- const kind = schemaKind(current);
175
- const format = stringFormat(current);
176
- const values = enumValues(current);
177
- if (values.length) return pick(values);
178
- if (kind === "boolean") return true;
179
- if (kind === "number" || kind === "bigint") {
180
- if (key.includes("sortorder")) return 1;
181
- if (key.includes("quantity")) return 5;
182
- return 10;
183
- }
184
- if (format === "uuid" || key.endsWith("uuid")) {
185
- return "9cc2c93f-f545-4e07-9f77-f79f08a71dd5";
186
- }
187
- if (format === "email" || key.includes("email")) {
188
- return `test-${randomToken()}@example.com`;
189
- }
190
- if (format === "url" || key === "image" || key.includes("imageurl") || key.endsWith("url")) {
191
- return `https://picsum.photos/seed/${randomToken()}/800/600`;
192
- }
193
- if (key === "month") return `${localDateInput().slice(0, 7)}-01`;
194
- if (key === "registrationdate") return localDateInput();
195
- if (format === "date" || key.includes("dateofbirth")) {
196
- const child = siblingFields.has("schoolLevel") || siblingFields.has("clothingSize");
197
- return birthDate(child);
198
- }
199
- if (key.endsWith("id") || key.endsWith("by")) return "";
200
- if (key === "name") {
201
- if (siblingFields.has("sku")) return `Test product ${randomToken(4)}`;
202
- if (siblingFields.has("slug")) return `Test category ${randomToken(4)}`;
203
- return "Test User";
204
- }
205
- if (key.includes("legalname")) return "Test User";
206
- if (key.includes("phone")) return `+2126${randomDigits(8)}`;
207
- if (key.endsWith("cin")) return `AB${randomDigits(6)}`;
208
- if (key.includes("address")) return `10 Test Street, ${pick(CITIES)}`;
209
- if (key.includes("schoollevel")) return pick(SCHOOL_LEVELS);
210
- if (key.includes("clothingsize")) return pick(CLOTHING_SIZES);
211
- if (key.includes("shoesize")) return "36";
212
- if (key.includes("relationship")) return "Legal guardian";
213
- if (key.includes("activationtargetmad")) return "7500";
214
- if (key === "slug") return `test-${randomToken(6)}`;
215
- if (key === "sku") return `TEST-${randomToken(8).toUpperCase()}`;
216
- if (key.includes("amountmad") || key.includes("pricemad") || key.includes("limitmad") || key.includes("targetmad")) {
217
- return "100.00";
218
- }
219
- if (key.includes("reason")) return "Generated for form testing.";
220
- if (key.includes("notes")) return "Generated form testing note.";
221
- if (key.includes("description")) return "Generated description for form testing.";
222
- if (key.includes("code")) return randomToken(8).toUpperCase();
223
- return `Test ${fieldName}`;
224
- }
225
- function buildFormFill(schema, overrides = {}) {
226
- const shape = objectShape(schema) ?? {};
227
- const siblingFields = new Set(Object.keys(shape));
228
- const output = {};
229
- for (const [fieldName, fieldSchema] of Object.entries(shape)) {
230
- if (Object.prototype.hasOwnProperty.call(overrides, fieldName)) {
231
- output[fieldName] = resolveOverride(overrides[fieldName], fieldName);
232
- continue;
233
- }
234
- const nestedShape = objectShape(fieldSchema);
235
- if (nestedShape) {
236
- output[fieldName] = buildFormFill(fieldSchema);
237
- continue;
238
- }
239
- const element = arrayElement(fieldSchema);
240
- if (element) {
241
- output[fieldName] = objectShape(element) ? [buildFormFill(element)] : [fieldValue(fieldName, element, siblingFields)];
242
- continue;
243
- }
244
- output[fieldName] = fieldValue(fieldName, fieldSchema, siblingFields);
245
- }
246
- return output;
247
- }
248
- var DEFAULT_FORM_DEV_TOOLS = {
249
- enabled: false,
250
- shortcut: "F8"
251
- };
252
- var FormDevToolsContext = createContext(
253
- DEFAULT_FORM_DEV_TOOLS
254
- );
255
- function normalizeFormDevTools(value) {
256
- if (typeof value === "boolean") {
257
- return { ...DEFAULT_FORM_DEV_TOOLS, enabled: value };
258
- }
259
- if (!value) return DEFAULT_FORM_DEV_TOOLS;
260
- return {
261
- enabled: value.enabled ?? true,
262
- shortcut: value.shortcut ?? DEFAULT_FORM_DEV_TOOLS.shortcut
263
- };
264
- }
265
- function FormDevToolsProvider({
266
- children,
267
- value
268
- }) {
269
- const resolved = useMemo(
270
- () => normalizeFormDevTools(value),
271
- [value]
272
- );
273
- return /* @__PURE__ */ jsx(FormDevToolsContext.Provider, { value: resolved, children });
274
- }
275
- function useResolvedFormDevTools(schema, local) {
276
- const global = useContext(FormDevToolsContext);
277
- const options = typeof local === "object" ? local : void 0;
278
- const enabled = typeof local === "boolean" ? local : options?.enabled ?? global.enabled;
279
- const shortcut = options?.shortcut ?? global.shortcut;
280
- const fill = options?.fill ?? (schema ? () => buildFormFill(schema, options?.overrides) : void 0);
281
- return { enabled, shortcut, fill };
282
- }
283
- var NajmFormatContext = React2.createContext(
284
- null
285
- );
286
- function NajmFormatProvider({
287
- children,
288
- locale,
289
- currency,
290
- timeZone,
291
- placeholder = DEFAULT_PLACEHOLDER
292
- }) {
293
- const preferences = useNajmPreferencesContext();
294
- const resolvedTimeZone = timeZone ?? preferences?.timeZone ?? Intl.DateTimeFormat().resolvedOptions().timeZone;
295
- const value = React2.useMemo(() => {
296
- const config = {
297
- locale,
298
- timeZone: resolvedTimeZone,
299
- currency,
300
- placeholder
301
- };
302
- return {
303
- locale,
304
- timeZone: resolvedTimeZone,
305
- currency,
306
- placeholder,
307
- config,
308
- money: (minorUnits) => formatCurrency(minorUnits, config),
309
- number: (value_, options) => formatNumber(value_, config, options),
310
- percent: (value_, digits) => formatPercent(value_, config, digits),
311
- date: (value_, options) => formatDate(value_, config, options),
312
- dateTime: (value_) => formatDateTime(value_, config),
313
- time: (value_) => formatTime(value_, config),
314
- relativeTime: (value_) => formatRelativeTime(value_, config),
315
- humanize: humanizeToken
316
- };
317
- }, [locale, resolvedTimeZone, currency, placeholder]);
318
- return /* @__PURE__ */ jsx(NajmFormatContext.Provider, { value, children });
319
- }
320
- function useNajmFormatContext() {
321
- return React2.useContext(NajmFormatContext);
322
- }
323
- function useNajmFormat() {
324
- const value = React2.useContext(NajmFormatContext);
325
- if (!value) {
326
- throw new Error(
327
- "useNajmFormat must be rendered under a NajmFormatProvider or NajmAppProvider."
328
- );
329
- }
330
- return value;
331
- }
332
-
333
- export { FormDevToolsProvider, NBrandingProvider, NBrandingStateProvider, NajmFormatProvider, buildFormFill, normalizeBranding, useNBranding, useNBrandingEditor, useNajmFormat, useNajmFormatContext, useResolvedFormDevTools };