najm-kit 2.11.11 → 2.11.13

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.
@@ -1,7 +1,8 @@
1
1
  import { NajmDesignProvider, cn } from './chunk-LK3SMYUP.mjs';
2
- import * as React2 from 'react';
3
- import React2__default from 'react';
2
+ import * as React3 from 'react';
3
+ import React3__default from 'react';
4
4
  import { jsx } from 'react/jsx-runtime';
5
+ import { DirectionProvider } from '@radix-ui/react-direction';
5
6
 
6
7
  // src/components/Badge/status.ts
7
8
  var NAJM_STATUS_COLORS = {
@@ -73,7 +74,7 @@ function statusTextClass(status, statusMap, fallback) {
73
74
  const color = findStatusColor(status, statusMap) ?? fallback;
74
75
  return color ? colorTextClass(color) : "";
75
76
  }
76
- var NTableDefaultsContext = React2__default.createContext({});
77
+ var NTableDefaultsContext = React3__default.createContext({});
77
78
  function NTableDefaultsProvider({
78
79
  children,
79
80
  value
@@ -81,17 +82,85 @@ function NTableDefaultsProvider({
81
82
  return /* @__PURE__ */ jsx(NTableDefaultsContext.Provider, { value, children });
82
83
  }
83
84
  function useNTableDefaults() {
84
- return React2__default.useContext(NTableDefaultsContext);
85
+ return React3__default.useContext(NTableDefaultsContext);
85
86
  }
86
87
  function useResolvedPaginationLabels(own) {
87
88
  const defaults = useNTableDefaults();
88
89
  const inherited = defaults.paginationLabels;
89
- return React2__default.useMemo(
90
+ return React3__default.useMemo(
90
91
  () => ({ ...inherited, ...own }),
91
92
  [inherited, own]
92
93
  );
93
94
  }
94
- var NajmPreferencesContext = React2.createContext(null);
95
+ function useResolvedToolbarLabels(own) {
96
+ const defaults = useNTableDefaults();
97
+ const inherited = defaults.toolbarLabels;
98
+ return React3__default.useMemo(
99
+ () => ({ ...inherited, ...own }),
100
+ [inherited, own]
101
+ );
102
+ }
103
+ var ENGLISH_FEEDBACK_LABELS = {
104
+ loadingLabel: "Loading...",
105
+ emptyTitle: "No data",
106
+ errorTitle: "Something went wrong",
107
+ retryLabel: "Try again",
108
+ forbiddenTitle: "Access denied",
109
+ forbiddenDescription: "You do not have permission to view this page.",
110
+ notFoundTitle: "Page not found",
111
+ notFoundDescription: "The requested page could not be found."
112
+ };
113
+ var NFeedbackDefaultsContext = React3.createContext(null);
114
+ function NFeedbackDefaultsProvider({
115
+ value,
116
+ children
117
+ }) {
118
+ return /* @__PURE__ */ jsx(NFeedbackDefaultsContext.Provider, { value, children });
119
+ }
120
+ function useNFeedbackDefaults() {
121
+ return React3.useContext(NFeedbackDefaultsContext);
122
+ }
123
+ var DEFAULT_FEEDBACK_KEY_PREFIX = "common.feedback";
124
+ function useResolvedFeedbackLabels() {
125
+ const ctx = useNFeedbackDefaults();
126
+ return React3.useMemo(() => resolveFeedbackLabels(ctx), [ctx]);
127
+ }
128
+ function resolveFeedbackLabels(ctx) {
129
+ const defaults = ctx?.defaults;
130
+ const t = ctx?.t;
131
+ const labels = defaults?.labels;
132
+ const labelKeys = defaults?.labelKeys;
133
+ const prefix = defaults?.prefix ?? DEFAULT_FEEDBACK_KEY_PREFIX;
134
+ const translated = (key) => {
135
+ if (!t) return void 0;
136
+ const value = t(key);
137
+ return value === key ? void 0 : value;
138
+ };
139
+ const pick = (field, hasFallback) => {
140
+ const literal = labels?.[field];
141
+ if (literal !== void 0) return literal;
142
+ const key = labelKeys?.[field];
143
+ const fromCatalog = translated(key ?? `${prefix}.${field}`);
144
+ if (fromCatalog !== void 0) return fromCatalog;
145
+ if (hasFallback) return ENGLISH_FEEDBACK_LABELS[field];
146
+ return void 0;
147
+ };
148
+ return {
149
+ loadingLabel: pick("loadingLabel", true) ?? ENGLISH_FEEDBACK_LABELS.loadingLabel,
150
+ emptyTitle: pick("emptyTitle", true) ?? ENGLISH_FEEDBACK_LABELS.emptyTitle,
151
+ errorTitle: pick("errorTitle", true) ?? ENGLISH_FEEDBACK_LABELS.errorTitle,
152
+ errorMessage: pick("errorMessage", false),
153
+ retryLabel: pick("retryLabel", true) ?? ENGLISH_FEEDBACK_LABELS.retryLabel,
154
+ forbiddenTitle: pick("forbiddenTitle", true) ?? ENGLISH_FEEDBACK_LABELS.forbiddenTitle,
155
+ forbiddenDescription: pick("forbiddenDescription", true) ?? ENGLISH_FEEDBACK_LABELS.forbiddenDescription,
156
+ notFoundTitle: pick("notFoundTitle", true) ?? ENGLISH_FEEDBACK_LABELS.notFoundTitle,
157
+ notFoundDescription: pick("notFoundDescription", true) ?? ENGLISH_FEEDBACK_LABELS.notFoundDescription
158
+ };
159
+ }
160
+ function resolveFeedbackDefaultsValue(defaults, t) {
161
+ return { defaults: defaults ?? {}, t };
162
+ }
163
+ var NajmPreferencesContext = React3.createContext(null);
95
164
  var DEFAULT_TIME_ZONE = "UTC";
96
165
  function isValidTimeZone(value) {
97
166
  try {
@@ -120,44 +189,44 @@ function NajmPreferencesProvider({
120
189
  onTimeZoneChange,
121
190
  normalizeTimeZone = defaultNormalizeTimeZone
122
191
  }) {
123
- const [theme, setThemeState] = React2.useState(initialTheme);
124
- const [timeZone, setTimeZoneState] = React2.useState(
192
+ const [theme, setThemeState] = React3.useState(initialTheme);
193
+ const [timeZone, setTimeZoneState] = React3.useState(
125
194
  () => normalizeTimeZone(initialTimeZone)
126
195
  );
127
- const onThemeChangeRef = React2.useRef(onThemeChange);
128
- const onTimeZoneChangeRef = React2.useRef(onTimeZoneChange);
129
- const normalizeRef = React2.useRef(normalizeTimeZone);
130
- React2.useEffect(() => {
196
+ const onThemeChangeRef = React3.useRef(onThemeChange);
197
+ const onTimeZoneChangeRef = React3.useRef(onTimeZoneChange);
198
+ const normalizeRef = React3.useRef(normalizeTimeZone);
199
+ React3.useEffect(() => {
131
200
  onThemeChangeRef.current = onThemeChange;
132
201
  onTimeZoneChangeRef.current = onTimeZoneChange;
133
202
  normalizeRef.current = normalizeTimeZone;
134
203
  });
135
- React2.useEffect(() => {
204
+ React3.useEffect(() => {
136
205
  applyTheme(theme);
137
206
  applyTimeZone(timeZone);
138
207
  }, []);
139
- const setTheme = React2.useCallback(async (next) => {
208
+ const setTheme = React3.useCallback(async (next) => {
140
209
  setThemeState(next);
141
210
  applyTheme(next);
142
211
  await onThemeChangeRef.current?.(next);
143
212
  }, []);
144
- const setTimeZone = React2.useCallback(async (next) => {
213
+ const setTimeZone = React3.useCallback(async (next) => {
145
214
  const normalized = normalizeRef.current(next);
146
215
  setTimeZoneState(normalized);
147
216
  applyTimeZone(normalized);
148
217
  await onTimeZoneChangeRef.current?.(normalized);
149
218
  }, []);
150
- const value = React2.useMemo(
219
+ const value = React3.useMemo(
151
220
  () => ({ theme, setTheme, timeZone, setTimeZone }),
152
221
  [theme, setTheme, timeZone, setTimeZone]
153
222
  );
154
223
  return /* @__PURE__ */ jsx(NajmPreferencesContext.Provider, { value, children });
155
224
  }
156
225
  function useNajmPreferencesContext() {
157
- return React2.useContext(NajmPreferencesContext);
226
+ return React3.useContext(NajmPreferencesContext);
158
227
  }
159
228
  function usePreferencesOrThrow(hook) {
160
- const value = React2.useContext(NajmPreferencesContext);
229
+ const value = React3.useContext(NajmPreferencesContext);
161
230
  if (!value) {
162
231
  throw new Error(
163
232
  `${hook} must be rendered under a NajmUIProvider or NajmPreferencesProvider.`
@@ -167,11 +236,11 @@ function usePreferencesOrThrow(hook) {
167
236
  }
168
237
  function useNajmTheme() {
169
238
  const { theme, setTheme } = usePreferencesOrThrow("useNajmTheme");
170
- return React2.useMemo(() => ({ theme, setTheme }), [theme, setTheme]);
239
+ return React3.useMemo(() => ({ theme, setTheme }), [theme, setTheme]);
171
240
  }
172
241
  function useNajmTimeZone() {
173
242
  const { timeZone, setTimeZone } = usePreferencesOrThrow("useNajmTimeZone");
174
- return React2.useMemo(
243
+ return React3.useMemo(
175
244
  () => ({ timeZone, setTimeZone }),
176
245
  [timeZone, setTimeZone]
177
246
  );
@@ -195,14 +264,52 @@ function buildPaginationLabels(t, prefix = DEFAULT_PAGINATION_KEY_PREFIX) {
195
264
  rowsSelected: (selected, total) => t(key("rowsSelected"), { selected, total })
196
265
  };
197
266
  }
267
+
268
+ // src/providers/toolbarLabels.ts
269
+ var DEFAULT_TOOLBAR_KEY_PREFIX = "common.table";
270
+ function buildToolbarLabels(t, prefix) {
271
+ const scope = prefix ?? DEFAULT_TOOLBAR_KEY_PREFIX;
272
+ return {
273
+ settings: t(`${scope}.settings`),
274
+ view: t(`${scope}.view`),
275
+ columns: t(`${scope}.columns`),
276
+ modeTable: t(`${scope}.modeTable`),
277
+ modeCards: t(`${scope}.modeCards`),
278
+ modeJson: t(`${scope}.modeJson`),
279
+ modeFiles: t(`${scope}.modeFiles`),
280
+ modeOption: (mode) => t(`${scope}.modeOption`, { mode }),
281
+ filters: t(`${scope}.filters`),
282
+ filterRegion: t(`${scope}.filterRegion`),
283
+ allOption: t(`${scope}.allOption`),
284
+ create: t(`${scope}.create`)
285
+ };
286
+ }
287
+ function useDocumentDirection(override) {
288
+ const [direction, setDirection] = React3.useState(
289
+ override ?? "ltr"
290
+ );
291
+ React3.useEffect(() => {
292
+ if (override) {
293
+ setDirection(override);
294
+ return;
295
+ }
296
+ const root = document.documentElement;
297
+ const read = () => setDirection(root.getAttribute("dir") === "rtl" ? "rtl" : "ltr");
298
+ read();
299
+ const observer = new MutationObserver(read);
300
+ observer.observe(root, { attributes: true, attributeFilter: ["dir"] });
301
+ return () => observer.disconnect();
302
+ }, [override]);
303
+ return direction;
304
+ }
198
305
  var EMPTY_DESIGN = Object.freeze({
199
306
  version: 1,
200
307
  theme: {},
201
308
  components: {}
202
309
  });
203
- var NajmDesignEditorContext = React2.createContext(null);
310
+ var NajmDesignEditorContext = React3.createContext(null);
204
311
  function useNajmDesignEditor() {
205
- return React2.useContext(NajmDesignEditorContext);
312
+ return React3.useContext(NajmDesignEditorContext);
206
313
  }
207
314
  function cloneDesign(design) {
208
315
  return structuredClone(design);
@@ -212,29 +319,29 @@ function NajmDesignEditorProvider({
212
319
  design,
213
320
  initialDesign
214
321
  }) {
215
- const [state, setState] = React2.useState(() => ({
322
+ const [state, setState] = React3.useState(() => ({
216
323
  committed: initialDesign ?? design ?? EMPTY_DESIGN,
217
324
  draft: null
218
325
  }));
219
- const beginDraft = React2.useCallback(() => {
326
+ const beginDraft = React3.useCallback(() => {
220
327
  setState(
221
328
  (current) => current.draft ? current : { ...current, draft: cloneDesign(current.committed) }
222
329
  );
223
330
  }, []);
224
- const setDraft = React2.useCallback((next) => {
331
+ const setDraft = React3.useCallback((next) => {
225
332
  setState((current) => ({ ...current, draft: cloneDesign(next) }));
226
333
  }, []);
227
- const cancelDraft = React2.useCallback(() => {
334
+ const cancelDraft = React3.useCallback(() => {
228
335
  setState(
229
336
  (current) => current.draft === null ? current : { ...current, draft: null }
230
337
  );
231
338
  }, []);
232
- const setCommitted = React2.useCallback((next) => {
339
+ const setCommitted = React3.useCallback((next) => {
233
340
  setState(
234
341
  (current) => current.committed === next && current.draft === null ? current : { committed: next, draft: null }
235
342
  );
236
343
  }, []);
237
- const value = React2.useMemo(() => {
344
+ const value = React3.useMemo(() => {
238
345
  if (design) {
239
346
  return {
240
347
  design,
@@ -262,20 +369,20 @@ function NajmDesignEditorProvider({
262
369
  }
263
370
  function noop() {
264
371
  }
265
- var NBadgeDefaultsContext = React2.createContext(null);
372
+ var NBadgeDefaultsContext = React3.createContext(null);
266
373
  function NBadgeDefaultsProvider({
267
374
  defaults,
268
375
  t,
269
376
  children
270
377
  }) {
271
- const value = React2.useMemo(
378
+ const value = React3.useMemo(
272
379
  () => ({ defaults, t }),
273
380
  [defaults, t]
274
381
  );
275
382
  return /* @__PURE__ */ jsx(NBadgeDefaultsContext.Provider, { value, children });
276
383
  }
277
384
  function useNBadgeDefaults() {
278
- return React2.useContext(NBadgeDefaultsContext);
385
+ return React3.useContext(NBadgeDefaultsContext);
279
386
  }
280
387
  function resolveBadgeStatusLabel(status, defaults, t) {
281
388
  if (!defaults) return void 0;
@@ -290,78 +397,30 @@ function mergeBadgeMaps(base, overrides) {
290
397
  if (!overrides) return base;
291
398
  return { ...base, ...overrides };
292
399
  }
293
- var ENGLISH_FEEDBACK_LABELS = {
294
- loadingLabel: "Loading...",
295
- emptyTitle: "No data",
296
- errorTitle: "Something went wrong",
297
- retryLabel: "Try again",
298
- forbiddenTitle: "Access denied",
299
- forbiddenDescription: "You do not have permission to view this page.",
300
- notFoundTitle: "Page not found",
301
- notFoundDescription: "The requested page could not be found."
302
- };
303
- var NFeedbackDefaultsContext = React2.createContext(null);
304
- function NFeedbackDefaultsProvider({
305
- value,
306
- children
307
- }) {
308
- return /* @__PURE__ */ jsx(NFeedbackDefaultsContext.Provider, { value, children });
309
- }
310
- function useNFeedbackDefaults() {
311
- return React2.useContext(NFeedbackDefaultsContext);
312
- }
313
- var DEFAULT_FEEDBACK_KEY_PREFIX = "common.feedback";
314
- function useResolvedFeedbackLabels() {
315
- const ctx = useNFeedbackDefaults();
316
- return React2.useMemo(() => resolveFeedbackLabels(ctx), [ctx]);
317
- }
318
- function resolveFeedbackLabels(ctx) {
319
- const defaults = ctx?.defaults;
320
- const t = ctx?.t;
321
- const labels = defaults?.labels;
322
- const labelKeys = defaults?.labelKeys;
323
- defaults?.prefix ?? DEFAULT_FEEDBACK_KEY_PREFIX;
324
- const pick = (field, hasFallback) => {
325
- const literal = labels?.[field];
326
- if (literal !== void 0) return literal;
327
- const key = labelKeys?.[field];
328
- if (key && t) return t(key);
329
- if (hasFallback) return ENGLISH_FEEDBACK_LABELS[field];
330
- return void 0;
331
- };
332
- return {
333
- loadingLabel: pick("loadingLabel", true) ?? ENGLISH_FEEDBACK_LABELS.loadingLabel,
334
- emptyTitle: pick("emptyTitle", true) ?? ENGLISH_FEEDBACK_LABELS.emptyTitle,
335
- errorTitle: pick("errorTitle", true) ?? ENGLISH_FEEDBACK_LABELS.errorTitle,
336
- errorMessage: pick("errorMessage", false),
337
- retryLabel: pick("retryLabel", true) ?? ENGLISH_FEEDBACK_LABELS.retryLabel,
338
- forbiddenTitle: pick("forbiddenTitle", true) ?? ENGLISH_FEEDBACK_LABELS.forbiddenTitle,
339
- forbiddenDescription: pick("forbiddenDescription", true) ?? ENGLISH_FEEDBACK_LABELS.forbiddenDescription,
340
- notFoundTitle: pick("notFoundTitle", true) ?? ENGLISH_FEEDBACK_LABELS.notFoundTitle,
341
- notFoundDescription: pick("notFoundDescription", true) ?? ENGLISH_FEEDBACK_LABELS.notFoundDescription
342
- };
343
- }
344
- function resolveFeedbackDefaultsValue(defaults, t) {
345
- return { defaults: defaults ?? {}, t };
346
- }
347
400
  function NajmUICore({
348
401
  children,
349
402
  className,
350
403
  t,
351
404
  paginationKeyPrefix = DEFAULT_PAGINATION_KEY_PREFIX,
405
+ toolbarKeyPrefix = DEFAULT_TOOLBAR_KEY_PREFIX,
406
+ dir,
352
407
  tableDefaults,
353
408
  badgeDefaults,
354
409
  feedbackDefaults
355
410
  }) {
356
411
  const { theme } = useNajmTheme();
412
+ const direction = useDocumentDirection(dir);
357
413
  const design = useNajmDesignEditor()?.design ?? EMPTY_DESIGN;
358
- const defaults = React2.useMemo(() => {
414
+ const defaults = React3.useMemo(() => {
359
415
  const translated = t ? buildPaginationLabels(t, paginationKeyPrefix) : void 0;
360
416
  const overrides = tableDefaults?.paginationLabels;
361
417
  const paginationLabels = translated || overrides ? { ...translated, ...overrides } : void 0;
362
- return { ...tableDefaults, paginationLabels };
363
- }, [t, paginationKeyPrefix, tableDefaults]);
364
- const feedbackValue = React2.useMemo(
418
+ const translatedToolbar = t ? buildToolbarLabels(t, toolbarKeyPrefix) : void 0;
419
+ const toolbarOverrides = tableDefaults?.toolbarLabels;
420
+ const toolbarLabels = translatedToolbar || toolbarOverrides ? { ...translatedToolbar, ...toolbarOverrides } : void 0;
421
+ return { ...tableDefaults, paginationLabels, toolbarLabels };
422
+ }, [t, paginationKeyPrefix, toolbarKeyPrefix, tableDefaults]);
423
+ const feedbackValue = React3.useMemo(
365
424
  () => resolveFeedbackDefaultsValue(feedbackDefaults, t),
366
425
  [feedbackDefaults, t]
367
426
  );
@@ -371,7 +430,7 @@ function NajmUICore({
371
430
  config: design,
372
431
  mode: theme,
373
432
  className: cn("min-h-full", className),
374
- children: /* @__PURE__ */ jsx(NTableDefaultsProvider, { value: defaults, children: /* @__PURE__ */ jsx(NBadgeDefaultsProvider, { defaults: badgeDefaults, t, children: /* @__PURE__ */ jsx(NFeedbackDefaultsProvider, { value: feedbackValue, children }) }) })
433
+ children: /* @__PURE__ */ jsx(DirectionProvider, { dir: direction, children: /* @__PURE__ */ jsx(NTableDefaultsProvider, { value: defaults, children: /* @__PURE__ */ jsx(NBadgeDefaultsProvider, { defaults: badgeDefaults, t, children: /* @__PURE__ */ jsx(NFeedbackDefaultsProvider, { value: feedbackValue, children }) }) }) })
375
434
  }
376
435
  );
377
436
  }
@@ -382,6 +441,8 @@ function NajmUIProvider({
382
441
  className,
383
442
  t,
384
443
  paginationKeyPrefix,
444
+ toolbarKeyPrefix,
445
+ dir,
385
446
  tableDefaults,
386
447
  badgeDefaults,
387
448
  feedbackDefaults,
@@ -398,6 +459,8 @@ function NajmUIProvider({
398
459
  className,
399
460
  t,
400
461
  paginationKeyPrefix,
462
+ toolbarKeyPrefix,
463
+ dir,
401
464
  tableDefaults,
402
465
  badgeDefaults,
403
466
  feedbackDefaults,
@@ -442,7 +505,7 @@ function selectImageSource(sources, failed) {
442
505
  var NO_FAILURES = [];
443
506
  function useImageChain(sources) {
444
507
  const key = JSON.stringify(sources);
445
- const [state, setState] = React2.useState(() => ({
508
+ const [state, setState] = React3.useState(() => ({
446
509
  key,
447
510
  failed: NO_FAILURES,
448
511
  loaded: null
@@ -451,13 +514,13 @@ function useImageChain(sources) {
451
514
  const current = state.key === key ? state : fresh;
452
515
  if (state.key !== key) setState(fresh);
453
516
  const active = selectImageSource(sources, current.failed);
454
- const markLoaded = React2.useCallback(() => {
517
+ const markLoaded = React3.useCallback(() => {
455
518
  if (active === void 0) return;
456
519
  setState(
457
520
  (prev) => prev.key !== key || prev.loaded === active ? prev : { ...prev, loaded: active }
458
521
  );
459
522
  }, [key, active]);
460
- const markFailed = React2.useCallback(() => {
523
+ const markFailed = React3.useCallback(() => {
461
524
  if (active === void 0) return;
462
525
  setState((prev) => {
463
526
  if (prev.key !== key || prev.failed.includes(active)) return prev;
@@ -477,4 +540,4 @@ function useImageChain(sources) {
477
540
  };
478
541
  }
479
542
 
480
- export { DEFAULT_PAGINATION_KEY_PREFIX, DEFAULT_TIME_ZONE, EMPTY_DESIGN, NAJM_COLOR_TEXT_CLASSES, NAJM_STATUS_COLORS, NTableDefaultsProvider, NajmDesignEditorProvider, NajmPreferencesProvider, NajmUIProvider, buildPaginationLabels, colorTextClass, findStatusColor, mergeBadgeMaps, normalizeImageSources, normalizeStatusToken, resolveBadgeStatusLabel, resolveStatusColor, statusTextClass, useImageChain, useNBadgeDefaults, useNTableDefaults, useNajmDesignEditor, useNajmPreferencesContext, useNajmTheme, useNajmTimeZone, useResolvedFeedbackLabels, useResolvedPaginationLabels };
543
+ export { DEFAULT_FEEDBACK_KEY_PREFIX, DEFAULT_PAGINATION_KEY_PREFIX, DEFAULT_TIME_ZONE, DEFAULT_TOOLBAR_KEY_PREFIX, EMPTY_DESIGN, NAJM_COLOR_TEXT_CLASSES, NAJM_STATUS_COLORS, NTableDefaultsProvider, NajmDesignEditorProvider, NajmPreferencesProvider, NajmUIProvider, buildPaginationLabels, buildToolbarLabels, colorTextClass, findStatusColor, mergeBadgeMaps, normalizeImageSources, normalizeStatusToken, resolveBadgeStatusLabel, resolveStatusColor, statusTextClass, useDocumentDirection, useImageChain, useNBadgeDefaults, useNTableDefaults, useNajmDesignEditor, useNajmPreferencesContext, useNajmTheme, useNajmTimeZone, useResolvedFeedbackLabels, useResolvedPaginationLabels, useResolvedToolbarLabels };
@@ -1,4 +1,4 @@
1
- import { useImageChain, normalizeImageSources, NajmUIProvider } from './chunk-6UDJNTJ6.mjs';
1
+ import { useImageChain, normalizeImageSources, NajmUIProvider } from './chunk-BDQK6ECA.mjs';
2
2
  import React from 'react';
3
3
  import { useRouter } from 'next/navigation';
4
4
  import NextImage from 'next/image';