najm-kit 2.6.2 → 2.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.
- package/dist/NajmUIProvider-x4chK0io.d.ts +425 -0
- package/dist/adapters/next.d.ts +32 -1
- package/dist/adapters/next.mjs +51 -2
- package/dist/chunk-4DLRXB2W.mjs +832 -0
- package/dist/chunk-JZJCQBOH.mjs +173 -0
- package/dist/chunk-YBM5CTE6.mjs +366 -0
- package/dist/index.d.ts +74 -316
- package/dist/index.mjs +247 -1391
- package/dist/json.mjs +7 -462
- package/package.json +5 -1
|
@@ -0,0 +1,425 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import * as React$1 from 'react';
|
|
3
|
+
import React__default, { ReactNode } from 'react';
|
|
4
|
+
|
|
5
|
+
type NajmMode = 'light' | 'dark';
|
|
6
|
+
type NajmAccent = 'neutral' | 'emerald' | 'green' | 'slate' | 'blue' | 'violet';
|
|
7
|
+
type NajmPreset = 'light' | 'dark' | 'dark-emerald' | 'dark-green' | 'dark-slate' | 'dark-blue' | 'dark-violet';
|
|
8
|
+
interface NajmAppearance {
|
|
9
|
+
/** Global border thickness, e.g. `'0'`, `'1px'`, `'2px'`. `'0'` hides borders. */
|
|
10
|
+
borderWidth?: string;
|
|
11
|
+
}
|
|
12
|
+
interface NajmThemeTokens {
|
|
13
|
+
background?: string;
|
|
14
|
+
foreground?: string;
|
|
15
|
+
card?: string;
|
|
16
|
+
'card-foreground'?: string;
|
|
17
|
+
popover?: string;
|
|
18
|
+
'popover-foreground'?: string;
|
|
19
|
+
primary?: string;
|
|
20
|
+
'primary-foreground'?: string;
|
|
21
|
+
secondary?: string;
|
|
22
|
+
'secondary-foreground'?: string;
|
|
23
|
+
tertiary?: string;
|
|
24
|
+
'tertiary-foreground'?: string;
|
|
25
|
+
muted?: string;
|
|
26
|
+
'muted-foreground'?: string;
|
|
27
|
+
accent?: string;
|
|
28
|
+
'accent-foreground'?: string;
|
|
29
|
+
destructive?: string;
|
|
30
|
+
'destructive-foreground'?: string;
|
|
31
|
+
border?: string;
|
|
32
|
+
input?: string;
|
|
33
|
+
ring?: string;
|
|
34
|
+
sidebar?: string;
|
|
35
|
+
'sidebar-foreground'?: string;
|
|
36
|
+
'sidebar-primary'?: string;
|
|
37
|
+
'sidebar-primary-foreground'?: string;
|
|
38
|
+
'sidebar-accent'?: string;
|
|
39
|
+
'sidebar-accent-foreground'?: string;
|
|
40
|
+
'sidebar-border'?: string;
|
|
41
|
+
'sidebar-ring'?: string;
|
|
42
|
+
'chart-1'?: string;
|
|
43
|
+
'chart-2'?: string;
|
|
44
|
+
'chart-3'?: string;
|
|
45
|
+
'chart-4'?: string;
|
|
46
|
+
'chart-5'?: string;
|
|
47
|
+
radius?: string;
|
|
48
|
+
}
|
|
49
|
+
/** Serializable theme settings suitable for JSON files, APIs, or local storage. */
|
|
50
|
+
interface NajmThemeConfig {
|
|
51
|
+
preset?: NajmPreset;
|
|
52
|
+
mode?: NajmMode;
|
|
53
|
+
accent?: NajmAccent;
|
|
54
|
+
tokens?: NajmThemeTokens;
|
|
55
|
+
/**
|
|
56
|
+
* Per-mode token overrides authored on top of the composed preset. Keeps
|
|
57
|
+
* light and dark customizations independent: editing a token in one mode
|
|
58
|
+
* records it here so it survives switching to the other mode and back.
|
|
59
|
+
* Providers resolve this field on top of the composed mode/accent preset.
|
|
60
|
+
*/
|
|
61
|
+
overrides?: Partial<Record<NajmMode, NajmThemeTokens>>;
|
|
62
|
+
accentOnly?: boolean;
|
|
63
|
+
appearance?: NajmAppearance;
|
|
64
|
+
radius?: string;
|
|
65
|
+
}
|
|
66
|
+
interface NajmThemeProviderProps {
|
|
67
|
+
/** Serializable theme settings. Explicit provider props override this config. */
|
|
68
|
+
config?: NajmThemeConfig;
|
|
69
|
+
preset?: NajmPreset;
|
|
70
|
+
mode?: NajmMode;
|
|
71
|
+
accent?: NajmAccent;
|
|
72
|
+
tokens?: NajmThemeTokens;
|
|
73
|
+
/** When true, only inject accent tokens (primary, ring, accent and their foregrounds).
|
|
74
|
+
* Everything else (bg, card, fg…) is inherited from the parent cascade. */
|
|
75
|
+
accentOnly?: boolean;
|
|
76
|
+
/** App-wide UI preferences (currently global border width). */
|
|
77
|
+
appearance?: NajmAppearance;
|
|
78
|
+
/** Global base radius, for example `0`, `0.5rem`, or `0.75rem`. */
|
|
79
|
+
radius?: string;
|
|
80
|
+
className?: string;
|
|
81
|
+
asChild?: boolean;
|
|
82
|
+
children: React.ReactNode;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
type NajmDensity = "compact" | "default" | "comfortable";
|
|
86
|
+
/** Tailwind's mobile-first viewport breakpoints, plus the default value. */
|
|
87
|
+
type NajmResponsiveBreakpoint = "base" | "sm" | "md" | "lg" | "xl" | "2xl";
|
|
88
|
+
/**
|
|
89
|
+
* A scalar value for every viewport, or mobile-first breakpoint overrides.
|
|
90
|
+
* For example: `{ base: 164, lg: 200, xl: 240 }`.
|
|
91
|
+
*/
|
|
92
|
+
type NajmResponsiveValue<T> = T | Partial<Record<NajmResponsiveBreakpoint, T>>;
|
|
93
|
+
type NajmComponentRadius = "inherit" | "none" | "xs" | "sm" | "md" | "lg" | "xl" | "full" | string;
|
|
94
|
+
interface NajmSlotStyle {
|
|
95
|
+
className?: string;
|
|
96
|
+
radius?: NajmComponentRadius;
|
|
97
|
+
borderWidth?: string;
|
|
98
|
+
padding?: string;
|
|
99
|
+
paddingTop?: string;
|
|
100
|
+
}
|
|
101
|
+
interface NajmVariantStyle {
|
|
102
|
+
/** Reuse another variant's recipe. Example: primary badge uses secondary. */
|
|
103
|
+
use?: string;
|
|
104
|
+
className?: string;
|
|
105
|
+
tokens?: Record<string, string>;
|
|
106
|
+
}
|
|
107
|
+
interface NajmComponentStyleConfig {
|
|
108
|
+
/** Render components that support it as a card-like surface. */
|
|
109
|
+
card?: boolean;
|
|
110
|
+
/** Sidebar-only: render section titles above grouped nav items. */
|
|
111
|
+
showSectionLabels?: boolean;
|
|
112
|
+
/** Sidebar-only: render separator lines between nav item sections. */
|
|
113
|
+
showSectionSeparators?: boolean;
|
|
114
|
+
/** Sidebar-only: expanded width in px (default 240). Supports responsive overrides. */
|
|
115
|
+
expandedWidth?: NajmResponsiveValue<number>;
|
|
116
|
+
/** Sidebar-only: collapsed width in px (default 64). Supports responsive overrides. */
|
|
117
|
+
collapsedWidth?: NajmResponsiveValue<number>;
|
|
118
|
+
/** Sidebar-only: mobile drawer width in px. Defaults to the expanded width. */
|
|
119
|
+
mobileWidth?: NajmResponsiveValue<number>;
|
|
120
|
+
defaultVariant?: string;
|
|
121
|
+
defaultSize?: string;
|
|
122
|
+
density?: NajmDensity;
|
|
123
|
+
/** NTable-only: CSS color used for the table header and add button. */
|
|
124
|
+
headerColor?: string;
|
|
125
|
+
/** NTable-only: CSS color used for table header text and add button text. */
|
|
126
|
+
headerTextColor?: string;
|
|
127
|
+
/** NTable-only: CSS color used for table container and row borders. */
|
|
128
|
+
borderColor?: string;
|
|
129
|
+
radius?: NajmComponentRadius;
|
|
130
|
+
borderWidth?: string;
|
|
131
|
+
slots?: Record<string, NajmSlotStyle>;
|
|
132
|
+
variants?: Record<string, NajmVariantStyle>;
|
|
133
|
+
}
|
|
134
|
+
type NajmComponentName = "button" | "badge" | "card" | "table" | "tabs" | "dialog" | "alert" | "sidebar" | "pageHeader" | "input" | "select" | "dropdown" | "sheet" | "popover" | "tooltip" | "progress" | "avatar";
|
|
135
|
+
type NajmComponentThemeConfig = Partial<Record<NajmComponentName, NajmComponentStyleConfig>>;
|
|
136
|
+
interface NajmTypographyConfig {
|
|
137
|
+
fontSans?: string;
|
|
138
|
+
fontHeading?: string;
|
|
139
|
+
fontMono?: string;
|
|
140
|
+
baseSize?: string;
|
|
141
|
+
scale?: "compact" | "default" | "comfortable";
|
|
142
|
+
lineHeight?: string;
|
|
143
|
+
letterSpacing?: string;
|
|
144
|
+
}
|
|
145
|
+
interface NajmLayoutConfig {
|
|
146
|
+
/** Page inline padding, usually used by NPageLayout. */
|
|
147
|
+
pageGutter?: string;
|
|
148
|
+
/** Vertical page padding and stacked section gap, usually used by NPageLayout. */
|
|
149
|
+
sectionGap?: string;
|
|
150
|
+
}
|
|
151
|
+
interface NajmDesignConfig {
|
|
152
|
+
version: 1;
|
|
153
|
+
theme: NajmThemeConfig;
|
|
154
|
+
typography?: NajmTypographyConfig;
|
|
155
|
+
components?: NajmComponentThemeConfig;
|
|
156
|
+
layout?: NajmLayoutConfig;
|
|
157
|
+
}
|
|
158
|
+
declare const NAJM_COMPONENT_NAMES: readonly NajmComponentName[];
|
|
159
|
+
/** Maps a NajmComponentRadius keyword to a CSS value (or var). */
|
|
160
|
+
declare const RADIUS_VALUE_MAP: Record<string, string>;
|
|
161
|
+
declare function resolveRadiusValue(radius: NajmComponentRadius | undefined): string | undefined;
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* How the page controls present position within the result.
|
|
165
|
+
*
|
|
166
|
+
* `numbered` renders a windowed list of page buttons. `compact` renders the
|
|
167
|
+
* `Page X of Y` text with first/previous/next/last controls.
|
|
168
|
+
*
|
|
169
|
+
* `numbered` needs a trustworthy page count. Under `manualPagination` that
|
|
170
|
+
* means the application must pass a `pageCount` derived from a real result
|
|
171
|
+
* total, or — when its endpoint reports no total — pass `hasNextPage` and no
|
|
172
|
+
* `pageCount` at all, which renders the unbounded bar described on the NTable
|
|
173
|
+
* prop. With neither, the bar falls back to `compact` on its own rather than
|
|
174
|
+
* inviting clicks on pages that may not exist.
|
|
175
|
+
*
|
|
176
|
+
* What it must never be handed is a `pageCount` that is really a lower bound,
|
|
177
|
+
* such as `pageIndex + 2`. That reads as a two-page result on page one and a
|
|
178
|
+
* three-page result on page two, so the bar grows a number per click with
|
|
179
|
+
* nothing to say why. NTable warns in development when it catches a count
|
|
180
|
+
* moving in lockstep with the page index.
|
|
181
|
+
*/
|
|
182
|
+
type NTablePaginationVariant = "numbered" | "compact";
|
|
183
|
+
/**
|
|
184
|
+
* Accessible names and visible copy for the page controls.
|
|
185
|
+
*
|
|
186
|
+
* Every field is optional and falls back to English. Supply them to localize —
|
|
187
|
+
* the numbered variant is mostly digits, but its controls still need names.
|
|
188
|
+
*/
|
|
189
|
+
interface NTablePaginationLabels {
|
|
190
|
+
/** Labels the rows-per-page select. Defaults to `"Rows/page"`. */
|
|
191
|
+
rowsPerPage?: string;
|
|
192
|
+
/** Accessible name of the whole page control group. Defaults to `"Pagination"`. */
|
|
193
|
+
pagination?: string;
|
|
194
|
+
/** Accessible name for one page button, given a 1-based page. */
|
|
195
|
+
goToPage?: (page: number) => string;
|
|
196
|
+
/** Accessible name of the current page button, given a 1-based page. */
|
|
197
|
+
currentPage?: (page: number) => string;
|
|
198
|
+
firstPage?: string;
|
|
199
|
+
previousPage?: string;
|
|
200
|
+
nextPage?: string;
|
|
201
|
+
lastPage?: string;
|
|
202
|
+
/** The `compact` variant's position text, given 1-based values. */
|
|
203
|
+
pageOf?: (page: number, pageCount: number) => string;
|
|
204
|
+
/**
|
|
205
|
+
* The position text when the result has no known total, given the 1-based
|
|
206
|
+
* page. Defaults to `"Page X"` — there is no `of Y` to state, and repeating
|
|
207
|
+
* the moving lower bound there would be the same lie the numbered bar avoids.
|
|
208
|
+
*/
|
|
209
|
+
pageOfUnknown?: (page: number) => string;
|
|
210
|
+
/** The selection summary, given selected and total row counts. */
|
|
211
|
+
rowsSelected?: (selected: number, total: number) => string;
|
|
212
|
+
}
|
|
213
|
+
interface NTableLoadMorePagination {
|
|
214
|
+
/** Render the supplied rows as one card list with an explicit continuation control. */
|
|
215
|
+
mode: "load-more";
|
|
216
|
+
/** Whether the owning application has another server page available. */
|
|
217
|
+
hasNextPage: boolean;
|
|
218
|
+
/** True while the owning application is appending the next page. */
|
|
219
|
+
loadingMore?: boolean;
|
|
220
|
+
/** A controlled append error. Existing rows remain rendered and the control becomes Retry. */
|
|
221
|
+
loadMoreError?: ReactNode;
|
|
222
|
+
/** Fetch exactly one additional page. Najm Kit never constructs or owns the request. */
|
|
223
|
+
onLoadMore: () => unknown | Promise<unknown>;
|
|
224
|
+
loadMoreLabel?: string;
|
|
225
|
+
loadingMoreLabel?: string;
|
|
226
|
+
retryLabel?: string;
|
|
227
|
+
endLabel?: string;
|
|
228
|
+
loadMoreErrorLabel?: string;
|
|
229
|
+
/** Localize the polite announcement made after appended rows arrive. */
|
|
230
|
+
itemsLoadedLabel?: (count: number) => string;
|
|
231
|
+
}
|
|
232
|
+
interface NTableInfinitePagination {
|
|
233
|
+
/**
|
|
234
|
+
* Render the supplied rows as one card list that continues automatically when
|
|
235
|
+
* the end of the list scrolls into view. No control and no end-of-list
|
|
236
|
+
* element are rendered while the list is healthy; the continuation button
|
|
237
|
+
* appears only after an append failure, as the retry target.
|
|
238
|
+
*/
|
|
239
|
+
mode: "infinite";
|
|
240
|
+
/** Whether the owning application has another server page available. */
|
|
241
|
+
hasNextPage: boolean;
|
|
242
|
+
/** True while the owning application is appending the next page. */
|
|
243
|
+
loadingMore?: boolean;
|
|
244
|
+
/** A controlled append error. Existing rows remain rendered and Retry appears. */
|
|
245
|
+
loadMoreError?: ReactNode;
|
|
246
|
+
/** Fetch exactly one additional page. Najm Kit never constructs or owns the request. */
|
|
247
|
+
onLoadMore: () => unknown | Promise<unknown>;
|
|
248
|
+
/**
|
|
249
|
+
* Distance ahead of the list end at which the next page is requested.
|
|
250
|
+
* Defaults to `"80px"`.
|
|
251
|
+
*/
|
|
252
|
+
rootMargin?: string;
|
|
253
|
+
loadingMoreLabel?: string;
|
|
254
|
+
retryLabel?: string;
|
|
255
|
+
loadMoreErrorLabel?: string;
|
|
256
|
+
/** Localize the polite announcement made after appended rows arrive. */
|
|
257
|
+
itemsLoadedLabel?: (count: number) => string;
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* Presentation policy used while NTable is actually rendering cards.
|
|
261
|
+
*
|
|
262
|
+
* `paged` preserves the existing page controls. `all` renders every supplied
|
|
263
|
+
* row without a footer, in card and table modes alike. `load-more` renders
|
|
264
|
+
* every supplied row and adds a guarded, accessible continuation control.
|
|
265
|
+
* `infinite` renders every supplied row and continues on scroll instead.
|
|
266
|
+
*
|
|
267
|
+
* Applications remain responsible for fetching, accumulating, filtering,
|
|
268
|
+
* sorting, authorization, and privacy. `all` renders exactly the rows it is
|
|
269
|
+
* given and never fetches, so a caller that has not loaded the whole set must
|
|
270
|
+
* not select it.
|
|
271
|
+
*/
|
|
272
|
+
type NTableCardPagination = {
|
|
273
|
+
mode?: "paged";
|
|
274
|
+
} | {
|
|
275
|
+
mode: "all";
|
|
276
|
+
} | NTableLoadMorePagination | NTableInfinitePagination;
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* Defaults every `NTable` beneath the provider inherits.
|
|
280
|
+
*
|
|
281
|
+
* Localized copy is the motivating case: an application with more than a couple
|
|
282
|
+
* of tables should not repeat the same label bundle at every render site, and
|
|
283
|
+
* an application with more than one locale should not have to remember to.
|
|
284
|
+
*/
|
|
285
|
+
interface NTableDefaults {
|
|
286
|
+
paginationLabels?: NTablePaginationLabels;
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* Supply table defaults to everything below.
|
|
290
|
+
*
|
|
291
|
+
* `value` is passed straight through, so memoize it in the caller — an inline
|
|
292
|
+
* object literal rebuilds on every render of the shell and re-renders every
|
|
293
|
+
* table beneath it. Most label fields are functions, so `useMemo` on the
|
|
294
|
+
* translator is usually the whole job.
|
|
295
|
+
*/
|
|
296
|
+
declare function NTableDefaultsProvider({ children, value, }: {
|
|
297
|
+
children: React__default.ReactNode;
|
|
298
|
+
value: NTableDefaults;
|
|
299
|
+
}): react_jsx_runtime.JSX.Element;
|
|
300
|
+
declare function useNTableDefaults(): NTableDefaults;
|
|
301
|
+
|
|
302
|
+
/**
|
|
303
|
+
* Theme and time zone, the two preferences that outlive a render.
|
|
304
|
+
*
|
|
305
|
+
* Both are *uncontrolled*: the `initial*` props seed state the provider owns
|
|
306
|
+
* from then on, and later changes to those props are ignored. That is the
|
|
307
|
+
* shape the server hand-off wants — the page is rendered once against a cookie,
|
|
308
|
+
* and every change after that originates here.
|
|
309
|
+
*
|
|
310
|
+
* Persistence is not this provider's business. It applies the change to the
|
|
311
|
+
* document, then hands the new value to a callback the application supplies.
|
|
312
|
+
* See `NajmNextUIProvider` in `najm-kit/next` for the cookie-endpoint wiring.
|
|
313
|
+
*/
|
|
314
|
+
interface NajmPreferencesContextValue {
|
|
315
|
+
theme: NajmMode;
|
|
316
|
+
setTheme: (theme: NajmMode) => Promise<void>;
|
|
317
|
+
timeZone: string;
|
|
318
|
+
setTimeZone: (timeZone: string) => Promise<void>;
|
|
319
|
+
}
|
|
320
|
+
declare const DEFAULT_TIME_ZONE = "UTC";
|
|
321
|
+
interface NajmPreferencesProviderProps {
|
|
322
|
+
children: React$1.ReactNode;
|
|
323
|
+
/** Seeds theme state; ignored after mount. Defaults to `"light"`. */
|
|
324
|
+
initialTheme?: NajmMode;
|
|
325
|
+
/** Seeds time zone state; ignored after mount. Defaults to `"UTC"`. */
|
|
326
|
+
initialTimeZone?: string;
|
|
327
|
+
/** Persist the new theme. Rejections propagate to the `setTheme` caller. */
|
|
328
|
+
onThemeChange?: (theme: NajmMode) => void | Promise<void>;
|
|
329
|
+
/** Persist the new time zone. Rejections propagate to `setTimeZone`. */
|
|
330
|
+
onTimeZoneChange?: (timeZone: string) => void | Promise<void>;
|
|
331
|
+
/** Sanitize a time zone before it is stored. Defaults to identity. */
|
|
332
|
+
normalizeTimeZone?: (value: string) => string;
|
|
333
|
+
}
|
|
334
|
+
/**
|
|
335
|
+
* Standalone preferences, without the design and table layers.
|
|
336
|
+
*
|
|
337
|
+
* `NajmUIProvider` renders this internally, so most applications never name it.
|
|
338
|
+
* It is exported for the case where something *above* the design layer needs to
|
|
339
|
+
* read the theme — a runtime theme editor, typically, which owns the design
|
|
340
|
+
* config and therefore has to sit above the provider consuming it. Hoisting
|
|
341
|
+
* preferences out is then a reorder rather than a fork.
|
|
342
|
+
*/
|
|
343
|
+
declare function NajmPreferencesProvider({ children, initialTheme, initialTimeZone, onThemeChange, onTimeZoneChange, normalizeTimeZone, }: NajmPreferencesProviderProps): react_jsx_runtime.JSX.Element;
|
|
344
|
+
/**
|
|
345
|
+
* Returns the context when one is mounted, or `null`.
|
|
346
|
+
*
|
|
347
|
+
* `NajmUIProvider` uses this to defer to an outer `NajmPreferencesProvider`
|
|
348
|
+
* instead of shadowing it, so nesting the two is well-defined rather than
|
|
349
|
+
* quietly producing two disagreeing themes.
|
|
350
|
+
*/
|
|
351
|
+
declare function useNajmPreferencesContext(): NajmPreferencesContextValue | null;
|
|
352
|
+
/** The live theme and a setter that persists through `onThemeChange`. */
|
|
353
|
+
declare function useNajmTheme(): Pick<NajmPreferencesContextValue, "theme" | "setTheme">;
|
|
354
|
+
/** The live time zone and a setter that persists through `onTimeZoneChange`. */
|
|
355
|
+
declare function useNajmTimeZone(): Pick<NajmPreferencesContextValue, "timeZone" | "setTimeZone">;
|
|
356
|
+
|
|
357
|
+
/**
|
|
358
|
+
* The translator shape `NajmUIProvider` accepts.
|
|
359
|
+
*
|
|
360
|
+
* Deliberately structural rather than an import from `najm-i18n`: the kit
|
|
361
|
+
* depends on no `najm-*` package, and this signature is satisfied by every
|
|
362
|
+
* mainstream i18n library. The application keeps its catalog and its own
|
|
363
|
+
* language provider.
|
|
364
|
+
*/
|
|
365
|
+
type NajmTranslate = (key: string, params?: Record<string, string | number>) => string;
|
|
366
|
+
declare const DEFAULT_PAGINATION_KEY_PREFIX = "common.pagination";
|
|
367
|
+
/**
|
|
368
|
+
* Projects a translator onto the ten pagination labels.
|
|
369
|
+
*
|
|
370
|
+
* Keys are `<prefix>.<field>`, matching the `NTablePaginationLabels` field
|
|
371
|
+
* names one-for-one, so a catalog is readable next to the type. Interpolation
|
|
372
|
+
* params are named for what they are: `page`, `pageCount`, `selected`, `total`.
|
|
373
|
+
*
|
|
374
|
+
* No result is inspected or second-guessed. A translator that echoes missing
|
|
375
|
+
* keys will render those keys — that is the translator's contract to define,
|
|
376
|
+
* and quietly swapping in English would hide the missing entry rather than
|
|
377
|
+
* surface it. Applications that want the packaged English for a given label
|
|
378
|
+
* should omit the key from the prefix and override it via `tableDefaults`.
|
|
379
|
+
*/
|
|
380
|
+
declare function buildPaginationLabels(t: NajmTranslate, prefix?: string): NTablePaginationLabels;
|
|
381
|
+
|
|
382
|
+
interface NajmUIProviderProps extends Omit<NajmPreferencesProviderProps, "children"> {
|
|
383
|
+
children: React$1.ReactNode;
|
|
384
|
+
/** The design config handed to `NajmDesignProvider`. */
|
|
385
|
+
design: NajmDesignConfig;
|
|
386
|
+
/** Forwarded to `NajmDesignProvider`. */
|
|
387
|
+
className?: string;
|
|
388
|
+
/**
|
|
389
|
+
* Translator for the pagination labels. Omit it and the packaged English
|
|
390
|
+
* applies — the provider is still worth mounting for design and preferences.
|
|
391
|
+
*
|
|
392
|
+
* Memoize it. The labels are rebuilt whenever its identity changes, and
|
|
393
|
+
* rebuilding them re-renders every table beneath.
|
|
394
|
+
*/
|
|
395
|
+
t?: NajmTranslate;
|
|
396
|
+
/** Catalog prefix for the labels. Defaults to `"common.pagination"`. */
|
|
397
|
+
paginationKeyPrefix?: string;
|
|
398
|
+
/**
|
|
399
|
+
* Per-key overrides layered over the translated labels. Memoize it, for the
|
|
400
|
+
* same reason as `t`.
|
|
401
|
+
*/
|
|
402
|
+
tableDefaults?: NTableDefaults;
|
|
403
|
+
}
|
|
404
|
+
/**
|
|
405
|
+
* The one provider a Najm application mounts for UI concerns.
|
|
406
|
+
*
|
|
407
|
+
* Composes three things that otherwise get copied between projects: theme and
|
|
408
|
+
* time zone state with async persistence, a `NajmDesignProvider` fed the live
|
|
409
|
+
* theme, and `NTable` pagination labels derived from the application's
|
|
410
|
+
* translator.
|
|
411
|
+
*
|
|
412
|
+
* What it deliberately does not own: auth, react-query, and the translation
|
|
413
|
+
* catalog. Those stay in the application — folding them in would make a UI
|
|
414
|
+
* package depend on `najm-auth` and `@tanstack/react-query` and turn it into a
|
|
415
|
+
* framework. Persistence is injected as callbacks so this entry imports
|
|
416
|
+
* nothing from `next`; see `NajmNextUIProvider` in `najm-kit/next`.
|
|
417
|
+
*
|
|
418
|
+
* Rendering this under an existing `NajmPreferencesProvider` is supported: the
|
|
419
|
+
* outer one wins and the preference props here are ignored. That is what lets
|
|
420
|
+
* an application with a runtime theme editor hoist preferences above its
|
|
421
|
+
* design context without forking this component.
|
|
422
|
+
*/
|
|
423
|
+
declare function NajmUIProvider({ children, design, className, t, paginationKeyPrefix, tableDefaults, initialTheme, initialTimeZone, onThemeChange, onTimeZoneChange, normalizeTimeZone, }: NajmUIProviderProps): react_jsx_runtime.JSX.Element;
|
|
424
|
+
|
|
425
|
+
export { type NajmDensity as A, type NajmPreferencesContextValue as B, NajmPreferencesProvider as C, DEFAULT_PAGINATION_KEY_PREFIX as D, type NajmPreferencesProviderProps as E, type NajmSlotStyle as F, type NajmTranslate as G, NajmUIProvider as H, buildPaginationLabels as I, resolveRadiusValue as J, useNTableDefaults as K, useNajmPreferencesContext as L, useNajmTheme as M, type NajmUIProviderProps as N, useNajmTimeZone as O, RADIUS_VALUE_MAP as R, type NajmThemeProviderProps as a, type NajmAppearance as b, type NajmMode as c, type NajmDesignConfig as d, type NajmThemeConfig as e, type NajmAccent as f, type NajmThemeTokens as g, type NajmPreset as h, type NajmComponentName as i, type NajmComponentStyleConfig as j, type NajmComponentThemeConfig as k, type NajmTypographyConfig as l, type NajmLayoutConfig as m, type NajmVariantStyle as n, type NTablePaginationVariant as o, type NTablePaginationLabels as p, type NTableCardPagination as q, type NajmResponsiveBreakpoint as r, type NajmResponsiveValue as s, DEFAULT_TIME_ZONE as t, NAJM_COMPONENT_NAMES as u, type NTableDefaults as v, NTableDefaultsProvider as w, type NTableInfinitePagination as x, type NTableLoadMorePagination as y, type NajmComponentRadius as z };
|
package/dist/adapters/next.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
1
2
|
import React__default from 'react';
|
|
3
|
+
import { N as NajmUIProviderProps } from '../NajmUIProvider-x4chK0io.js';
|
|
2
4
|
|
|
3
5
|
interface NextLinkAdapterProps extends Record<string, any> {
|
|
4
6
|
href: string;
|
|
@@ -16,5 +18,34 @@ declare function useNextNavigationAdapter(): {
|
|
|
16
18
|
push: (path: string) => void;
|
|
17
19
|
replace: (path: string) => void;
|
|
18
20
|
};
|
|
21
|
+
/** Where `NajmNextUIProvider` POSTs each preference. */
|
|
22
|
+
interface NajmNextUIEndpoints {
|
|
23
|
+
/** Defaults to `/api/ui-theme`. Receives `{ theme }`. */
|
|
24
|
+
theme?: string;
|
|
25
|
+
/** Defaults to `/api/ui-timezone`. Receives `{ timeZone }`. */
|
|
26
|
+
timeZone?: string;
|
|
27
|
+
}
|
|
28
|
+
interface NajmNextUIProviderProps extends Omit<NajmUIProviderProps, 'onThemeChange' | 'onTimeZoneChange'> {
|
|
29
|
+
endpoints?: NajmNextUIEndpoints;
|
|
30
|
+
/**
|
|
31
|
+
* Call `router.refresh()` after a preference is persisted, so server
|
|
32
|
+
* components re-render against the new cookie. Defaults to `true`.
|
|
33
|
+
*/
|
|
34
|
+
refreshOnChange?: boolean;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* `NajmUIProvider` with the Next wiring supplied: preferences are POSTed to
|
|
38
|
+
* cookie route handlers and the router is refreshed so server components see
|
|
39
|
+
* the change.
|
|
40
|
+
*
|
|
41
|
+
* The route handlers are the application's — this package calls them, it does
|
|
42
|
+
* not ship them. Each takes a JSON body (`{ theme }` / `{ timeZone }`), sets
|
|
43
|
+
* its cookie, and returns any 2xx.
|
|
44
|
+
*
|
|
45
|
+
* This is the only module in the package that imports `next`, which is why
|
|
46
|
+
* `next` is an *optional* peer dependency: consumers of the root entry never
|
|
47
|
+
* reach this file.
|
|
48
|
+
*/
|
|
49
|
+
declare function NajmNextUIProvider({ endpoints, refreshOnChange, ...props }: NajmNextUIProviderProps): react_jsx_runtime.JSX.Element;
|
|
19
50
|
|
|
20
|
-
export { NextLinkAdapter, type NextLinkAdapterProps, useNextNavigationAdapter };
|
|
51
|
+
export { type NajmNextUIEndpoints, NajmNextUIProvider, type NajmNextUIProviderProps, NextLinkAdapter, type NextLinkAdapterProps, useNextNavigationAdapter };
|
package/dist/adapters/next.mjs
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
|
+
import { NajmUIProvider } from '../chunk-JZJCQBOH.mjs';
|
|
2
|
+
import '../chunk-YBM5CTE6.mjs';
|
|
1
3
|
import React from 'react';
|
|
4
|
+
import { useRouter } from 'next/navigation';
|
|
5
|
+
import { jsx } from 'react/jsx-runtime';
|
|
2
6
|
|
|
3
|
-
// src/adapters/next.tsx
|
|
4
7
|
function NextLinkAdapter({ children, ...props }) {
|
|
5
8
|
return React.createElement("a", props, children);
|
|
6
9
|
}
|
|
@@ -19,5 +22,51 @@ function useNextNavigationAdapter() {
|
|
|
19
22
|
}
|
|
20
23
|
};
|
|
21
24
|
}
|
|
25
|
+
var DEFAULT_THEME_ENDPOINT = "/api/ui-theme";
|
|
26
|
+
var DEFAULT_TIME_ZONE_ENDPOINT = "/api/ui-timezone";
|
|
27
|
+
async function postPreference(endpoint, body) {
|
|
28
|
+
const response = await fetch(endpoint, {
|
|
29
|
+
method: "POST",
|
|
30
|
+
headers: { "Content-Type": "application/json" },
|
|
31
|
+
credentials: "same-origin",
|
|
32
|
+
body: JSON.stringify(body)
|
|
33
|
+
});
|
|
34
|
+
if (!response.ok) {
|
|
35
|
+
throw new Error(
|
|
36
|
+
`Failed to persist preference to ${endpoint}: ${response.status}`
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
function NajmNextUIProvider({
|
|
41
|
+
endpoints,
|
|
42
|
+
refreshOnChange = true,
|
|
43
|
+
...props
|
|
44
|
+
}) {
|
|
45
|
+
const router = useRouter();
|
|
46
|
+
const themeEndpoint = endpoints?.theme ?? DEFAULT_THEME_ENDPOINT;
|
|
47
|
+
const timeZoneEndpoint = endpoints?.timeZone ?? DEFAULT_TIME_ZONE_ENDPOINT;
|
|
48
|
+
const onThemeChange = React.useCallback(
|
|
49
|
+
async (theme) => {
|
|
50
|
+
await postPreference(themeEndpoint, { theme });
|
|
51
|
+
if (refreshOnChange) router.refresh();
|
|
52
|
+
},
|
|
53
|
+
[themeEndpoint, refreshOnChange, router]
|
|
54
|
+
);
|
|
55
|
+
const onTimeZoneChange = React.useCallback(
|
|
56
|
+
async (timeZone) => {
|
|
57
|
+
await postPreference(timeZoneEndpoint, { timeZone });
|
|
58
|
+
if (refreshOnChange) router.refresh();
|
|
59
|
+
},
|
|
60
|
+
[timeZoneEndpoint, refreshOnChange, router]
|
|
61
|
+
);
|
|
62
|
+
return /* @__PURE__ */ jsx(
|
|
63
|
+
NajmUIProvider,
|
|
64
|
+
{
|
|
65
|
+
...props,
|
|
66
|
+
onThemeChange,
|
|
67
|
+
onTimeZoneChange
|
|
68
|
+
}
|
|
69
|
+
);
|
|
70
|
+
}
|
|
22
71
|
|
|
23
|
-
export { NextLinkAdapter, useNextNavigationAdapter };
|
|
72
|
+
export { NajmNextUIProvider, NextLinkAdapter, useNextNavigationAdapter };
|