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,832 @@
|
|
|
1
|
+
import { useNajmComponentStyle } from './chunk-YBM5CTE6.mjs';
|
|
2
|
+
import { clsx } from 'clsx';
|
|
3
|
+
import { twMerge } from 'tailwind-merge';
|
|
4
|
+
import * as React2 from 'react';
|
|
5
|
+
import React2__default, { createContext, useContext } from 'react';
|
|
6
|
+
import * as LucideIcons from 'lucide-react';
|
|
7
|
+
import { LoaderCircleIcon } from 'lucide-react';
|
|
8
|
+
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
9
|
+
import { Slot } from '@radix-ui/react-slot';
|
|
10
|
+
import { cva } from 'class-variance-authority';
|
|
11
|
+
import { OverlayScrollbars } from 'overlayscrollbars';
|
|
12
|
+
import { OverlayScrollbarsComponent } from 'overlayscrollbars-react';
|
|
13
|
+
|
|
14
|
+
function cn(...inputs) {
|
|
15
|
+
return twMerge(clsx(inputs));
|
|
16
|
+
}
|
|
17
|
+
function toPascalCase(value) {
|
|
18
|
+
return value.replace(/([a-z0-9])([A-Z])/g, "$1 $2").split(/[\s_-]+/).filter(Boolean).map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join("");
|
|
19
|
+
}
|
|
20
|
+
function isImageSource(value) {
|
|
21
|
+
return value.startsWith("/") || value.startsWith("./") || value.startsWith("../") || value.startsWith("http://") || value.startsWith("https://") || value.startsWith("data:image/") || /\.(avif|gif|jpe?g|png|svg|webp)(\?.*)?$/i.test(value);
|
|
22
|
+
}
|
|
23
|
+
function isComponentSource(value) {
|
|
24
|
+
return typeof value === "function" || Boolean(value && typeof value === "object" && "$$typeof" in value);
|
|
25
|
+
}
|
|
26
|
+
var NIcon = ({
|
|
27
|
+
icon = "circle",
|
|
28
|
+
size = 24,
|
|
29
|
+
alt = "",
|
|
30
|
+
className,
|
|
31
|
+
style,
|
|
32
|
+
onClick,
|
|
33
|
+
...rest
|
|
34
|
+
}) => {
|
|
35
|
+
const dimensionStyle = {
|
|
36
|
+
width: size,
|
|
37
|
+
height: size,
|
|
38
|
+
...style
|
|
39
|
+
};
|
|
40
|
+
if (React2__default.isValidElement(icon)) {
|
|
41
|
+
return React2__default.cloneElement(icon, {
|
|
42
|
+
className: cn(className, icon.props.className),
|
|
43
|
+
onClick,
|
|
44
|
+
...rest
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
if (icon && typeof icon === "object" && "src" in icon) {
|
|
48
|
+
return /* @__PURE__ */ jsx(
|
|
49
|
+
"img",
|
|
50
|
+
{
|
|
51
|
+
alt: icon.alt ?? alt,
|
|
52
|
+
className: cn("inline-block shrink-0 object-contain", className),
|
|
53
|
+
src: icon.src,
|
|
54
|
+
style: dimensionStyle,
|
|
55
|
+
onClick,
|
|
56
|
+
...rest
|
|
57
|
+
}
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
if (isComponentSource(icon)) {
|
|
61
|
+
const IconComponent = icon;
|
|
62
|
+
return /* @__PURE__ */ jsx(IconComponent, { size, className, onClick, style, ...rest });
|
|
63
|
+
}
|
|
64
|
+
if (typeof icon === "string") {
|
|
65
|
+
if (isImageSource(icon)) {
|
|
66
|
+
return /* @__PURE__ */ jsx(
|
|
67
|
+
"img",
|
|
68
|
+
{
|
|
69
|
+
alt,
|
|
70
|
+
className: cn("inline-block shrink-0 object-contain", className),
|
|
71
|
+
src: icon,
|
|
72
|
+
style: dimensionStyle,
|
|
73
|
+
onClick,
|
|
74
|
+
...rest
|
|
75
|
+
}
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
const pascalCaseIcon = toPascalCase(icon);
|
|
79
|
+
if (LucideIcons[pascalCaseIcon]) {
|
|
80
|
+
const LucideIcon = LucideIcons[pascalCaseIcon];
|
|
81
|
+
return /* @__PURE__ */ jsx(LucideIcon, { size, className, onClick, style, ...rest });
|
|
82
|
+
}
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
return null;
|
|
86
|
+
};
|
|
87
|
+
NIcon.displayName = "NIcon";
|
|
88
|
+
|
|
89
|
+
// src/theme/borders.ts
|
|
90
|
+
var SURFACE_BORDER_CLASSES = {
|
|
91
|
+
all: "najm-border border-border",
|
|
92
|
+
top: "najm-border-t border-border",
|
|
93
|
+
right: "najm-border-r border-border",
|
|
94
|
+
bottom: "najm-border-b border-border",
|
|
95
|
+
left: "najm-border-l border-border"
|
|
96
|
+
};
|
|
97
|
+
var SIDEBAR_BORDER_CLASSES = {
|
|
98
|
+
all: "najm-border border-sidebar-border",
|
|
99
|
+
top: "najm-border-t border-sidebar-border",
|
|
100
|
+
right: "najm-border-r border-sidebar-border",
|
|
101
|
+
bottom: "najm-border-b border-sidebar-border",
|
|
102
|
+
left: "najm-border-l border-sidebar-border"
|
|
103
|
+
};
|
|
104
|
+
var BORDER_RESET_CLASSES = {
|
|
105
|
+
all: "border-0",
|
|
106
|
+
top: "border-t-0",
|
|
107
|
+
right: "border-r-0",
|
|
108
|
+
bottom: "border-b-0",
|
|
109
|
+
left: "border-l-0"
|
|
110
|
+
};
|
|
111
|
+
function surfaceBorderClasses(bordered = true, side = "all") {
|
|
112
|
+
return bordered === false ? BORDER_RESET_CLASSES[side] : SURFACE_BORDER_CLASSES[side];
|
|
113
|
+
}
|
|
114
|
+
function sidebarBorderClasses(bordered = true, side = "all") {
|
|
115
|
+
return bordered === false ? BORDER_RESET_CLASSES[side] : SIDEBAR_BORDER_CLASSES[side];
|
|
116
|
+
}
|
|
117
|
+
function inputBorderClasses(bordered = true) {
|
|
118
|
+
return bordered === false ? "border-0" : "najm-border border-input";
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// src/theme/design-types.ts
|
|
122
|
+
var NAJM_COMPONENT_NAMES = [
|
|
123
|
+
"button",
|
|
124
|
+
"badge",
|
|
125
|
+
"card",
|
|
126
|
+
"table",
|
|
127
|
+
"tabs",
|
|
128
|
+
"dialog",
|
|
129
|
+
"alert",
|
|
130
|
+
"sidebar",
|
|
131
|
+
"pageHeader",
|
|
132
|
+
"input",
|
|
133
|
+
"select",
|
|
134
|
+
"dropdown",
|
|
135
|
+
"sheet",
|
|
136
|
+
"popover",
|
|
137
|
+
"tooltip",
|
|
138
|
+
"progress",
|
|
139
|
+
"avatar"
|
|
140
|
+
];
|
|
141
|
+
var RADIUS_VALUE_MAP = {
|
|
142
|
+
none: "0",
|
|
143
|
+
xs: "var(--radius-xs)",
|
|
144
|
+
sm: "var(--radius-sm)",
|
|
145
|
+
md: "var(--radius-md)",
|
|
146
|
+
lg: "var(--radius-lg)",
|
|
147
|
+
xl: "var(--radius-xl)",
|
|
148
|
+
full: "9999px"
|
|
149
|
+
};
|
|
150
|
+
function resolveRadiusValue(radius) {
|
|
151
|
+
if (!radius || radius === "inherit") return void 0;
|
|
152
|
+
return RADIUS_VALUE_MAP[radius] ?? radius;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// src/theme/config.ts
|
|
156
|
+
var MODES = ["light", "dark"];
|
|
157
|
+
var ACCENTS = ["neutral", "emerald", "green", "slate", "blue", "violet"];
|
|
158
|
+
var PRESETS = ["light", "dark", "dark-emerald", "dark-green", "dark-slate", "dark-blue", "dark-violet"];
|
|
159
|
+
var TOKEN_KEYS = [
|
|
160
|
+
"background",
|
|
161
|
+
"foreground",
|
|
162
|
+
"card",
|
|
163
|
+
"card-foreground",
|
|
164
|
+
"popover",
|
|
165
|
+
"popover-foreground",
|
|
166
|
+
"primary",
|
|
167
|
+
"primary-foreground",
|
|
168
|
+
"secondary",
|
|
169
|
+
"secondary-foreground",
|
|
170
|
+
"tertiary",
|
|
171
|
+
"tertiary-foreground",
|
|
172
|
+
"muted",
|
|
173
|
+
"muted-foreground",
|
|
174
|
+
"accent",
|
|
175
|
+
"accent-foreground",
|
|
176
|
+
"destructive",
|
|
177
|
+
"destructive-foreground",
|
|
178
|
+
"border",
|
|
179
|
+
"input",
|
|
180
|
+
"ring",
|
|
181
|
+
"sidebar",
|
|
182
|
+
"sidebar-foreground",
|
|
183
|
+
"sidebar-primary",
|
|
184
|
+
"sidebar-primary-foreground",
|
|
185
|
+
"sidebar-accent",
|
|
186
|
+
"sidebar-accent-foreground",
|
|
187
|
+
"sidebar-border",
|
|
188
|
+
"sidebar-ring",
|
|
189
|
+
"chart-1",
|
|
190
|
+
"chart-2",
|
|
191
|
+
"chart-3",
|
|
192
|
+
"chart-4",
|
|
193
|
+
"chart-5",
|
|
194
|
+
"radius"
|
|
195
|
+
];
|
|
196
|
+
var ROOT_KEYS = /* @__PURE__ */ new Set([
|
|
197
|
+
"preset",
|
|
198
|
+
"mode",
|
|
199
|
+
"accent",
|
|
200
|
+
"tokens",
|
|
201
|
+
"overrides",
|
|
202
|
+
"accentOnly",
|
|
203
|
+
"appearance",
|
|
204
|
+
"radius"
|
|
205
|
+
]);
|
|
206
|
+
var TOKEN_KEY_SET = new Set(TOKEN_KEYS);
|
|
207
|
+
var MODE_KEY_SET = new Set(MODES);
|
|
208
|
+
function isRecord(value) {
|
|
209
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
210
|
+
}
|
|
211
|
+
function assertKnownKeys(value, keys, path) {
|
|
212
|
+
const unknown = Object.keys(value).find((key) => !keys.has(key));
|
|
213
|
+
if (unknown) throw new TypeError(`Unknown ${path} property: ${unknown}`);
|
|
214
|
+
}
|
|
215
|
+
function optionalEnum(value, values, path) {
|
|
216
|
+
if (value === void 0) return void 0;
|
|
217
|
+
if (typeof value !== "string" || !values.includes(value)) {
|
|
218
|
+
throw new TypeError(`${path} must be one of: ${values.join(", ")}`);
|
|
219
|
+
}
|
|
220
|
+
return value;
|
|
221
|
+
}
|
|
222
|
+
function optionalString(value, path) {
|
|
223
|
+
if (value === void 0) return void 0;
|
|
224
|
+
if (typeof value !== "string" || value.trim() === "") {
|
|
225
|
+
throw new TypeError(`${path} must be a non-empty string`);
|
|
226
|
+
}
|
|
227
|
+
return value;
|
|
228
|
+
}
|
|
229
|
+
function parseTokens(value) {
|
|
230
|
+
if (value === void 0) return void 0;
|
|
231
|
+
if (!isRecord(value)) throw new TypeError("theme.tokens must be an object");
|
|
232
|
+
assertKnownKeys(value, TOKEN_KEY_SET, "theme.tokens");
|
|
233
|
+
const tokens = {};
|
|
234
|
+
for (const key of TOKEN_KEYS) {
|
|
235
|
+
const token = optionalString(value[key], `theme.tokens.${key}`);
|
|
236
|
+
if (token !== void 0) tokens[key] = token;
|
|
237
|
+
}
|
|
238
|
+
return tokens;
|
|
239
|
+
}
|
|
240
|
+
function parseOverrides(value) {
|
|
241
|
+
if (value === void 0) return void 0;
|
|
242
|
+
if (!isRecord(value)) throw new TypeError("theme.overrides must be an object");
|
|
243
|
+
assertKnownKeys(value, MODE_KEY_SET, "theme.overrides");
|
|
244
|
+
const overrides = {};
|
|
245
|
+
for (const mode of MODES) {
|
|
246
|
+
const entry = value[mode];
|
|
247
|
+
if (entry === void 0) continue;
|
|
248
|
+
overrides[mode] = parseTokens(entry) ?? {};
|
|
249
|
+
}
|
|
250
|
+
return overrides;
|
|
251
|
+
}
|
|
252
|
+
function defineNajmThemeConfig(config) {
|
|
253
|
+
return config;
|
|
254
|
+
}
|
|
255
|
+
function parseNajmThemeConfig(input) {
|
|
256
|
+
let value = input;
|
|
257
|
+
if (typeof input === "string") {
|
|
258
|
+
try {
|
|
259
|
+
value = JSON.parse(input);
|
|
260
|
+
} catch (error) {
|
|
261
|
+
throw new TypeError(`Invalid theme JSON: ${error.message}`);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
if (!isRecord(value)) throw new TypeError("Theme config must be an object");
|
|
265
|
+
assertKnownKeys(value, ROOT_KEYS, "theme");
|
|
266
|
+
let appearance;
|
|
267
|
+
if (value.appearance !== void 0) {
|
|
268
|
+
if (!isRecord(value.appearance)) throw new TypeError("theme.appearance must be an object");
|
|
269
|
+
assertKnownKeys(value.appearance, /* @__PURE__ */ new Set(["borderWidth"]), "theme.appearance");
|
|
270
|
+
appearance = {
|
|
271
|
+
borderWidth: optionalString(
|
|
272
|
+
value.appearance.borderWidth,
|
|
273
|
+
"theme.appearance.borderWidth"
|
|
274
|
+
)
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
const accentOnly = value.accentOnly;
|
|
278
|
+
if (accentOnly !== void 0 && typeof accentOnly !== "boolean") {
|
|
279
|
+
throw new TypeError("theme.accentOnly must be a boolean");
|
|
280
|
+
}
|
|
281
|
+
const parsedAccentOnly = typeof accentOnly === "boolean" ? accentOnly : void 0;
|
|
282
|
+
const config = {};
|
|
283
|
+
const preset = optionalEnum(value.preset, PRESETS, "theme.preset");
|
|
284
|
+
const mode = optionalEnum(value.mode, MODES, "theme.mode");
|
|
285
|
+
const accent = optionalEnum(value.accent, ACCENTS, "theme.accent");
|
|
286
|
+
const tokens = parseTokens(value.tokens);
|
|
287
|
+
const overrides = parseOverrides(value.overrides);
|
|
288
|
+
const radius = optionalString(value.radius, "theme.radius");
|
|
289
|
+
if (preset !== void 0) config.preset = preset;
|
|
290
|
+
if (mode !== void 0) config.mode = mode;
|
|
291
|
+
if (accent !== void 0) config.accent = accent;
|
|
292
|
+
if (tokens !== void 0) config.tokens = tokens;
|
|
293
|
+
if (overrides !== void 0) config.overrides = overrides;
|
|
294
|
+
if (parsedAccentOnly !== void 0) config.accentOnly = parsedAccentOnly;
|
|
295
|
+
if (appearance !== void 0) config.appearance = appearance;
|
|
296
|
+
if (radius !== void 0) config.radius = radius;
|
|
297
|
+
return config;
|
|
298
|
+
}
|
|
299
|
+
function stringifyNajmThemeConfig(config, space = 2) {
|
|
300
|
+
return JSON.stringify(config, null, space);
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
// src/theme/design-config.ts
|
|
304
|
+
var ROOT_KEYS2 = /* @__PURE__ */ new Set(["version", "theme", "typography", "components", "layout"]);
|
|
305
|
+
var TYPOGRAPHY_KEYS = /* @__PURE__ */ new Set([
|
|
306
|
+
"fontSans",
|
|
307
|
+
"fontHeading",
|
|
308
|
+
"fontMono",
|
|
309
|
+
"baseSize",
|
|
310
|
+
"scale",
|
|
311
|
+
"lineHeight",
|
|
312
|
+
"letterSpacing"
|
|
313
|
+
]);
|
|
314
|
+
var LAYOUT_KEYS = /* @__PURE__ */ new Set(["pageGutter", "sectionGap"]);
|
|
315
|
+
var COMPONENT_KEYS = /* @__PURE__ */ new Set([
|
|
316
|
+
"card",
|
|
317
|
+
"showSectionLabels",
|
|
318
|
+
"showSectionSeparators",
|
|
319
|
+
"expandedWidth",
|
|
320
|
+
"collapsedWidth",
|
|
321
|
+
"mobileWidth",
|
|
322
|
+
"defaultVariant",
|
|
323
|
+
"defaultSize",
|
|
324
|
+
"density",
|
|
325
|
+
"headerColor",
|
|
326
|
+
"headerTextColor",
|
|
327
|
+
"borderColor",
|
|
328
|
+
"radius",
|
|
329
|
+
"borderWidth",
|
|
330
|
+
"slots",
|
|
331
|
+
"variants"
|
|
332
|
+
]);
|
|
333
|
+
var SLOT_KEYS = /* @__PURE__ */ new Set(["className", "radius", "borderWidth", "padding", "paddingTop"]);
|
|
334
|
+
var VARIANT_KEYS = /* @__PURE__ */ new Set(["use", "className", "tokens"]);
|
|
335
|
+
var COMPONENT_NAME_SET = new Set(NAJM_COMPONENT_NAMES);
|
|
336
|
+
var DENSITIES = /* @__PURE__ */ new Set(["compact", "default", "comfortable"]);
|
|
337
|
+
var SCALES = /* @__PURE__ */ new Set(["compact", "default", "comfortable"]);
|
|
338
|
+
var RESPONSIVE_BREAKPOINTS = /* @__PURE__ */ new Set(["base", "sm", "md", "lg", "xl", "2xl"]);
|
|
339
|
+
function isRecord2(value) {
|
|
340
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
341
|
+
}
|
|
342
|
+
function assertKnownKeys2(value, keys, path) {
|
|
343
|
+
const unknown = Object.keys(value).find((key) => !keys.has(key));
|
|
344
|
+
if (unknown) throw new TypeError(`Unknown ${path} property: ${unknown}`);
|
|
345
|
+
}
|
|
346
|
+
function optionalString2(value, path) {
|
|
347
|
+
if (value === void 0) return void 0;
|
|
348
|
+
if (typeof value !== "string") {
|
|
349
|
+
throw new TypeError(`${path} must be a string`);
|
|
350
|
+
}
|
|
351
|
+
return value;
|
|
352
|
+
}
|
|
353
|
+
function optionalBoolean(value, path) {
|
|
354
|
+
if (value === void 0) return void 0;
|
|
355
|
+
if (typeof value !== "boolean") {
|
|
356
|
+
throw new TypeError(`${path} must be a boolean`);
|
|
357
|
+
}
|
|
358
|
+
return value;
|
|
359
|
+
}
|
|
360
|
+
function optionalResponsiveNumber(value, path) {
|
|
361
|
+
if (value === void 0) return void 0;
|
|
362
|
+
if (typeof value === "number") return value;
|
|
363
|
+
if (!isRecord2(value)) throw new TypeError(`${path} must be a number or breakpoint object`);
|
|
364
|
+
const unknown = Object.keys(value).find((key) => !RESPONSIVE_BREAKPOINTS.has(key));
|
|
365
|
+
if (unknown) throw new TypeError(`Unknown ${path} breakpoint: ${unknown}`);
|
|
366
|
+
const parsed = {};
|
|
367
|
+
for (const [breakpoint, width] of Object.entries(value)) {
|
|
368
|
+
if (typeof width !== "number") {
|
|
369
|
+
throw new TypeError(`${path}.${breakpoint} must be a number`);
|
|
370
|
+
}
|
|
371
|
+
parsed[breakpoint] = width;
|
|
372
|
+
}
|
|
373
|
+
return parsed;
|
|
374
|
+
}
|
|
375
|
+
function optionalEnum2(value, values, path) {
|
|
376
|
+
if (value === void 0) return void 0;
|
|
377
|
+
if (typeof value !== "string" || !values.has(value)) {
|
|
378
|
+
throw new TypeError(`${path} must be one of: ${[...values].join(", ")}`);
|
|
379
|
+
}
|
|
380
|
+
return value;
|
|
381
|
+
}
|
|
382
|
+
function parseTypography(value) {
|
|
383
|
+
if (value === void 0) return void 0;
|
|
384
|
+
if (!isRecord2(value)) throw new TypeError("typography must be an object");
|
|
385
|
+
assertKnownKeys2(value, TYPOGRAPHY_KEYS, "typography");
|
|
386
|
+
const cfg = {};
|
|
387
|
+
const fontSans = optionalString2(value.fontSans, "typography.fontSans");
|
|
388
|
+
const fontHeading = optionalString2(value.fontHeading, "typography.fontHeading");
|
|
389
|
+
const fontMono = optionalString2(value.fontMono, "typography.fontMono");
|
|
390
|
+
const baseSize = optionalString2(value.baseSize, "typography.baseSize");
|
|
391
|
+
const scale = optionalEnum2(value.scale, SCALES, "typography.scale");
|
|
392
|
+
const lineHeight = optionalString2(value.lineHeight, "typography.lineHeight");
|
|
393
|
+
const letterSpacing = optionalString2(value.letterSpacing, "typography.letterSpacing");
|
|
394
|
+
if (fontSans !== void 0) cfg.fontSans = fontSans;
|
|
395
|
+
if (fontHeading !== void 0) cfg.fontHeading = fontHeading;
|
|
396
|
+
if (fontMono !== void 0) cfg.fontMono = fontMono;
|
|
397
|
+
if (baseSize !== void 0) cfg.baseSize = baseSize;
|
|
398
|
+
if (scale !== void 0) cfg.scale = scale;
|
|
399
|
+
if (lineHeight !== void 0) cfg.lineHeight = lineHeight;
|
|
400
|
+
if (letterSpacing !== void 0) cfg.letterSpacing = letterSpacing;
|
|
401
|
+
return cfg;
|
|
402
|
+
}
|
|
403
|
+
function parseLayout(value) {
|
|
404
|
+
if (value === void 0) return void 0;
|
|
405
|
+
if (!isRecord2(value)) throw new TypeError("layout must be an object");
|
|
406
|
+
assertKnownKeys2(value, LAYOUT_KEYS, "layout");
|
|
407
|
+
const cfg = {};
|
|
408
|
+
const pageGutter = optionalString2(value.pageGutter, "layout.pageGutter");
|
|
409
|
+
const sectionGap = optionalString2(value.sectionGap, "layout.sectionGap");
|
|
410
|
+
if (pageGutter !== void 0) cfg.pageGutter = pageGutter;
|
|
411
|
+
if (sectionGap !== void 0) cfg.sectionGap = sectionGap;
|
|
412
|
+
return cfg;
|
|
413
|
+
}
|
|
414
|
+
function parseVariant(value, path) {
|
|
415
|
+
if (!isRecord2(value)) throw new TypeError(`${path} must be an object`);
|
|
416
|
+
assertKnownKeys2(value, VARIANT_KEYS, path);
|
|
417
|
+
const variant = {};
|
|
418
|
+
const use = optionalString2(value.use, `${path}.use`);
|
|
419
|
+
const className = optionalString2(value.className, `${path}.className`);
|
|
420
|
+
if (use !== void 0) variant.use = use;
|
|
421
|
+
if (className !== void 0) variant.className = className;
|
|
422
|
+
if (value.tokens !== void 0) {
|
|
423
|
+
if (!isRecord2(value.tokens)) throw new TypeError(`${path}.tokens must be an object`);
|
|
424
|
+
variant.tokens = value.tokens;
|
|
425
|
+
}
|
|
426
|
+
return variant;
|
|
427
|
+
}
|
|
428
|
+
function parseComponentStyle(value, path) {
|
|
429
|
+
if (!isRecord2(value)) throw new TypeError(`${path} must be an object`);
|
|
430
|
+
assertKnownKeys2(value, COMPONENT_KEYS, path);
|
|
431
|
+
const cfg = {};
|
|
432
|
+
const card = optionalBoolean(value.card, `${path}.card`);
|
|
433
|
+
const showSectionLabels = optionalBoolean(value.showSectionLabels, `${path}.showSectionLabels`);
|
|
434
|
+
const showSectionSeparators = optionalBoolean(value.showSectionSeparators, `${path}.showSectionSeparators`);
|
|
435
|
+
const expandedWidth = optionalResponsiveNumber(value.expandedWidth, `${path}.expandedWidth`);
|
|
436
|
+
const collapsedWidth = optionalResponsiveNumber(value.collapsedWidth, `${path}.collapsedWidth`);
|
|
437
|
+
const mobileWidth = optionalResponsiveNumber(value.mobileWidth, `${path}.mobileWidth`);
|
|
438
|
+
const defaultVariant = optionalString2(value.defaultVariant, `${path}.defaultVariant`);
|
|
439
|
+
const defaultSize = optionalString2(value.defaultSize, `${path}.defaultSize`);
|
|
440
|
+
const density = optionalEnum2(value.density, DENSITIES, `${path}.density`);
|
|
441
|
+
const headerColor = optionalString2(value.headerColor, `${path}.headerColor`);
|
|
442
|
+
const headerTextColor = optionalString2(value.headerTextColor, `${path}.headerTextColor`);
|
|
443
|
+
const borderColor = optionalString2(value.borderColor, `${path}.borderColor`);
|
|
444
|
+
const radius = optionalString2(value.radius, `${path}.radius`);
|
|
445
|
+
const borderWidth = optionalString2(value.borderWidth, `${path}.borderWidth`);
|
|
446
|
+
if (card !== void 0) cfg.card = card;
|
|
447
|
+
if (showSectionLabels !== void 0) cfg.showSectionLabels = showSectionLabels;
|
|
448
|
+
if (showSectionSeparators !== void 0) cfg.showSectionSeparators = showSectionSeparators;
|
|
449
|
+
if (expandedWidth !== void 0) cfg.expandedWidth = expandedWidth;
|
|
450
|
+
if (collapsedWidth !== void 0) cfg.collapsedWidth = collapsedWidth;
|
|
451
|
+
if (mobileWidth !== void 0) cfg.mobileWidth = mobileWidth;
|
|
452
|
+
if (defaultVariant !== void 0) cfg.defaultVariant = defaultVariant;
|
|
453
|
+
if (defaultSize !== void 0) cfg.defaultSize = defaultSize;
|
|
454
|
+
if (density !== void 0) cfg.density = density;
|
|
455
|
+
if (headerColor !== void 0) cfg.headerColor = headerColor;
|
|
456
|
+
if (headerTextColor !== void 0) cfg.headerTextColor = headerTextColor;
|
|
457
|
+
if (borderColor !== void 0) cfg.borderColor = borderColor;
|
|
458
|
+
if (radius !== void 0) cfg.radius = radius;
|
|
459
|
+
if (borderWidth !== void 0) cfg.borderWidth = borderWidth;
|
|
460
|
+
if (value.slots !== void 0) {
|
|
461
|
+
if (!isRecord2(value.slots)) throw new TypeError(`${path}.slots must be an object`);
|
|
462
|
+
const slots = {};
|
|
463
|
+
for (const [slotName, slotValue] of Object.entries(value.slots)) {
|
|
464
|
+
if (!isRecord2(slotValue)) throw new TypeError(`${path}.slots.${slotName} must be an object`);
|
|
465
|
+
assertKnownKeys2(slotValue, SLOT_KEYS, `${path}.slots.${slotName}`);
|
|
466
|
+
slots[slotName] = slotValue;
|
|
467
|
+
}
|
|
468
|
+
cfg.slots = slots;
|
|
469
|
+
}
|
|
470
|
+
if (value.variants !== void 0) {
|
|
471
|
+
if (!isRecord2(value.variants)) throw new TypeError(`${path}.variants must be an object`);
|
|
472
|
+
const variants = {};
|
|
473
|
+
for (const [variantName, variantValue] of Object.entries(value.variants)) {
|
|
474
|
+
variants[variantName] = parseVariant(variantValue, `${path}.variants.${variantName}`);
|
|
475
|
+
}
|
|
476
|
+
cfg.variants = variants;
|
|
477
|
+
}
|
|
478
|
+
return cfg;
|
|
479
|
+
}
|
|
480
|
+
function parseComponents(value) {
|
|
481
|
+
if (value === void 0) return void 0;
|
|
482
|
+
if (!isRecord2(value)) throw new TypeError("components must be an object");
|
|
483
|
+
const unknown = Object.keys(value).find((key) => !COMPONENT_NAME_SET.has(key));
|
|
484
|
+
if (unknown) throw new TypeError(`Unknown component name: ${unknown}`);
|
|
485
|
+
const components = {};
|
|
486
|
+
for (const [name, cfg] of Object.entries(value)) {
|
|
487
|
+
components[name] = parseComponentStyle(cfg, `components.${name}`);
|
|
488
|
+
}
|
|
489
|
+
return components;
|
|
490
|
+
}
|
|
491
|
+
function defineNajmDesignConfig(config) {
|
|
492
|
+
return config;
|
|
493
|
+
}
|
|
494
|
+
function parseNajmDesignConfig(input) {
|
|
495
|
+
let value = input;
|
|
496
|
+
if (typeof input === "string") {
|
|
497
|
+
try {
|
|
498
|
+
value = JSON.parse(input);
|
|
499
|
+
} catch (error) {
|
|
500
|
+
throw new TypeError(`Invalid design JSON: ${error.message}`);
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
if (!isRecord2(value)) throw new TypeError("Design config must be an object");
|
|
504
|
+
if (!("version" in value) && !("theme" in value)) {
|
|
505
|
+
return {
|
|
506
|
+
version: 1,
|
|
507
|
+
theme: parseNajmThemeConfig(value)
|
|
508
|
+
};
|
|
509
|
+
}
|
|
510
|
+
assertKnownKeys2(value, ROOT_KEYS2, "design");
|
|
511
|
+
if (value.version !== void 0 && value.version !== 1) {
|
|
512
|
+
throw new TypeError("design.version must be 1");
|
|
513
|
+
}
|
|
514
|
+
if (value.theme === void 0) throw new TypeError("design.theme is required");
|
|
515
|
+
const config = {
|
|
516
|
+
version: 1,
|
|
517
|
+
theme: parseNajmThemeConfig(value.theme)
|
|
518
|
+
};
|
|
519
|
+
const typography = parseTypography(value.typography);
|
|
520
|
+
if (typography !== void 0) config.typography = typography;
|
|
521
|
+
const components = parseComponents(value.components);
|
|
522
|
+
if (components !== void 0) config.components = components;
|
|
523
|
+
const layout = parseLayout(value.layout);
|
|
524
|
+
if (layout !== void 0) config.layout = layout;
|
|
525
|
+
return config;
|
|
526
|
+
}
|
|
527
|
+
function stringifyNajmDesignConfig(config, space = 2) {
|
|
528
|
+
return JSON.stringify(config, null, space);
|
|
529
|
+
}
|
|
530
|
+
function resolveVariantAlias(variants, variant) {
|
|
531
|
+
if (!variants) return { variant };
|
|
532
|
+
const seen = /* @__PURE__ */ new Set();
|
|
533
|
+
let current = variant;
|
|
534
|
+
let style = variants[current];
|
|
535
|
+
while (style?.use && !seen.has(current)) {
|
|
536
|
+
seen.add(current);
|
|
537
|
+
const next = style.use;
|
|
538
|
+
if (seen.has(next)) break;
|
|
539
|
+
current = next;
|
|
540
|
+
style = variants[current];
|
|
541
|
+
}
|
|
542
|
+
return { variant: current, style };
|
|
543
|
+
}
|
|
544
|
+
var buttonVariants = cva(
|
|
545
|
+
[
|
|
546
|
+
"relative inline-flex shrink-0 cursor-pointer items-center justify-center gap-2 whitespace-nowrap text-sm font-medium outline-none transition-all",
|
|
547
|
+
"disabled:pointer-events-none disabled:opacity-50 data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50",
|
|
548
|
+
"focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
|
|
549
|
+
"aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40",
|
|
550
|
+
"[&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4"
|
|
551
|
+
].join(" "),
|
|
552
|
+
{
|
|
553
|
+
variants: {
|
|
554
|
+
variant: {
|
|
555
|
+
default: "bg-primary text-primary-foreground shadow-xs hover:bg-primary/90",
|
|
556
|
+
destructive: "bg-destructive text-white shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:bg-destructive/60 dark:focus-visible:ring-destructive/40",
|
|
557
|
+
outline: "border border-input bg-transparent text-foreground shadow-xs hover:bg-accent hover:text-accent-foreground",
|
|
558
|
+
secondary: "bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80",
|
|
559
|
+
tertiary: "bg-tertiary text-tertiary-foreground shadow-xs hover:bg-tertiary/80",
|
|
560
|
+
ghost: "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
|
|
561
|
+
link: "h-auto p-0 text-primary underline-offset-4 hover:underline",
|
|
562
|
+
success: "bg-emerald-600 text-white shadow-xs hover:bg-emerald-700",
|
|
563
|
+
warning: "bg-amber-400 text-slate-950 shadow-xs hover:bg-amber-500",
|
|
564
|
+
info: "bg-sky-600 text-white shadow-xs hover:bg-sky-700",
|
|
565
|
+
soft: "bg-primary/10 text-primary shadow-none hover:bg-primary/15",
|
|
566
|
+
subtle: "bg-muted text-foreground shadow-none hover:bg-muted/80",
|
|
567
|
+
plain: "bg-transparent shadow-none hover:bg-transparent"
|
|
568
|
+
},
|
|
569
|
+
size: {
|
|
570
|
+
"2xs": "h-5 gap-1 px-1.5 text-[11px] [&_svg:not([class*='size-'])]:size-3",
|
|
571
|
+
xs: "h-6 gap-1 px-2 text-xs [&_svg:not([class*='size-'])]:size-3",
|
|
572
|
+
sm: "h-8 gap-1.5 px-3 has-[>svg]:px-2.5",
|
|
573
|
+
default: "h-9 px-4 py-2 has-[>svg]:px-3",
|
|
574
|
+
md: "h-9 px-4 py-2 has-[>svg]:px-3",
|
|
575
|
+
lg: "h-10 px-6 has-[>svg]:px-4",
|
|
576
|
+
xl: "h-12 px-8 text-base [&_svg:not([class*='size-'])]:size-5",
|
|
577
|
+
"2xl": "h-14 px-10 text-base [&_svg:not([class*='size-'])]:size-5",
|
|
578
|
+
icon: "size-9",
|
|
579
|
+
"icon-xs": "size-6 [&_svg:not([class*='size-'])]:size-3",
|
|
580
|
+
"icon-sm": "size-8",
|
|
581
|
+
"icon-lg": "size-10 [&_svg:not([class*='size-'])]:size-5",
|
|
582
|
+
"icon-xl": "size-12 [&_svg:not([class*='size-'])]:size-5"
|
|
583
|
+
},
|
|
584
|
+
rounded: {
|
|
585
|
+
none: "rounded-none",
|
|
586
|
+
sm: "rounded-sm",
|
|
587
|
+
default: "rounded-md",
|
|
588
|
+
md: "rounded-md",
|
|
589
|
+
lg: "rounded-lg",
|
|
590
|
+
xl: "rounded-xl",
|
|
591
|
+
"2xl": "rounded-2xl",
|
|
592
|
+
full: "rounded-full"
|
|
593
|
+
},
|
|
594
|
+
fullWidth: {
|
|
595
|
+
true: "w-full",
|
|
596
|
+
false: ""
|
|
597
|
+
}
|
|
598
|
+
},
|
|
599
|
+
defaultVariants: {
|
|
600
|
+
variant: "default",
|
|
601
|
+
size: "default",
|
|
602
|
+
rounded: "default",
|
|
603
|
+
fullWidth: false
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
);
|
|
607
|
+
function isPromiseLike(value) {
|
|
608
|
+
return Boolean(value && typeof value.then === "function");
|
|
609
|
+
}
|
|
610
|
+
var defaultLoader = /* @__PURE__ */ jsx(LoaderCircleIcon, { "aria-hidden": "true", className: "animate-spin" });
|
|
611
|
+
function renderIcon(icon) {
|
|
612
|
+
if (!icon) return null;
|
|
613
|
+
return /* @__PURE__ */ jsx(NIcon, { "aria-hidden": "true", icon, className: "shrink-0" });
|
|
614
|
+
}
|
|
615
|
+
var Button = React2.forwardRef(
|
|
616
|
+
({
|
|
617
|
+
className,
|
|
618
|
+
variant,
|
|
619
|
+
size,
|
|
620
|
+
rounded,
|
|
621
|
+
fullWidth,
|
|
622
|
+
asChild = false,
|
|
623
|
+
loading = false,
|
|
624
|
+
autoLoading = true,
|
|
625
|
+
disabledWhileLoading = true,
|
|
626
|
+
loadingText,
|
|
627
|
+
loader = defaultLoader,
|
|
628
|
+
loaderPosition = "left",
|
|
629
|
+
leftIcon,
|
|
630
|
+
rightIcon,
|
|
631
|
+
bordered,
|
|
632
|
+
disabled,
|
|
633
|
+
children,
|
|
634
|
+
onClick,
|
|
635
|
+
style,
|
|
636
|
+
...props
|
|
637
|
+
}, ref) => {
|
|
638
|
+
const recipe = useNajmComponentStyle("button");
|
|
639
|
+
const aliased = resolveVariantAlias(
|
|
640
|
+
recipe?.variants,
|
|
641
|
+
variant ?? recipe?.defaultVariant ?? "default"
|
|
642
|
+
);
|
|
643
|
+
const effVariant = variant ?? aliased.variant ?? recipe?.defaultVariant;
|
|
644
|
+
const effSize = size ?? recipe?.defaultSize;
|
|
645
|
+
const recipeRadius = rounded === void 0 ? resolveRadiusValue(recipe?.radius) : void 0;
|
|
646
|
+
const recipeStyle = recipeRadius ? { borderRadius: recipeRadius } : void 0;
|
|
647
|
+
const [pending, setPending] = React2.useState(false);
|
|
648
|
+
const isLoading = loading || pending;
|
|
649
|
+
const isDisabled = disabled || disabledWhileLoading && isLoading;
|
|
650
|
+
const Comp = asChild ? Slot : "button";
|
|
651
|
+
const handleClick = React2.useCallback(
|
|
652
|
+
(event) => {
|
|
653
|
+
if (isDisabled) {
|
|
654
|
+
event.preventDefault();
|
|
655
|
+
return;
|
|
656
|
+
}
|
|
657
|
+
const result = onClick?.(event);
|
|
658
|
+
if (autoLoading && isPromiseLike(result)) {
|
|
659
|
+
setPending(true);
|
|
660
|
+
void result.then(
|
|
661
|
+
() => setPending(false),
|
|
662
|
+
() => setPending(false)
|
|
663
|
+
);
|
|
664
|
+
}
|
|
665
|
+
},
|
|
666
|
+
[autoLoading, isDisabled, onClick]
|
|
667
|
+
);
|
|
668
|
+
const child = asChild ? React2.Children.only(children) : null;
|
|
669
|
+
const childContent = asChild && React2.isValidElement(child) ? child.props.children : children;
|
|
670
|
+
const content = loadingText && isLoading ? loadingText : childContent;
|
|
671
|
+
const loaderNode = isLoading ? loader : null;
|
|
672
|
+
const leftIconNode = renderIcon(leftIcon);
|
|
673
|
+
const rightIconNode = renderIcon(rightIcon);
|
|
674
|
+
const showCenteredLoader = Boolean(loaderNode && loaderPosition === "center");
|
|
675
|
+
const renderedContent = showCenteredLoader ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
676
|
+
/* @__PURE__ */ jsxs("span", { className: "invisible inline-flex items-center gap-2", children: [
|
|
677
|
+
leftIconNode,
|
|
678
|
+
content,
|
|
679
|
+
rightIconNode
|
|
680
|
+
] }),
|
|
681
|
+
/* @__PURE__ */ jsx("span", { className: "absolute inset-0 inline-flex items-center justify-center", children: loaderNode })
|
|
682
|
+
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
683
|
+
loaderNode && loaderPosition === "left" ? loaderNode : leftIconNode,
|
|
684
|
+
content,
|
|
685
|
+
loaderNode && loaderPosition === "right" ? loaderNode : rightIconNode
|
|
686
|
+
] });
|
|
687
|
+
const renderedChild = asChild && React2.isValidElement(child) ? React2.cloneElement(child, void 0, renderedContent) : renderedContent;
|
|
688
|
+
return /* @__PURE__ */ jsx(
|
|
689
|
+
Comp,
|
|
690
|
+
{
|
|
691
|
+
ref,
|
|
692
|
+
"data-slot": "button",
|
|
693
|
+
"data-loading": isLoading || void 0,
|
|
694
|
+
"data-disabled": isDisabled || void 0,
|
|
695
|
+
"data-bordered": effVariant === "outline" ? "true" : bordered === false ? "false" : bordered ? "true" : void 0,
|
|
696
|
+
"aria-busy": isLoading || void 0,
|
|
697
|
+
"aria-disabled": asChild && isDisabled ? true : void 0,
|
|
698
|
+
disabled: !asChild ? isDisabled : void 0,
|
|
699
|
+
style: recipeStyle ? { ...recipeStyle, ...style } : style,
|
|
700
|
+
className: cn(
|
|
701
|
+
buttonVariants({ variant: effVariant, size: effSize, rounded, fullWidth }),
|
|
702
|
+
aliased.style?.className,
|
|
703
|
+
// Outline buttons always carry an input-style border.
|
|
704
|
+
effVariant === "outline" && inputBorderClasses(true),
|
|
705
|
+
// Filled/ghost/plain/link/success/warning/info/soft/subtle buttons only get a
|
|
706
|
+
// border when the consumer explicitly opts in via `bordered`. Global theming
|
|
707
|
+
// should not outline every filled button.
|
|
708
|
+
effVariant !== "outline" && bordered === true && cn(
|
|
709
|
+
"border",
|
|
710
|
+
"border-muted-foreground"
|
|
711
|
+
),
|
|
712
|
+
className
|
|
713
|
+
),
|
|
714
|
+
onClick: handleClick,
|
|
715
|
+
...props,
|
|
716
|
+
children: renderedChild
|
|
717
|
+
}
|
|
718
|
+
);
|
|
719
|
+
}
|
|
720
|
+
);
|
|
721
|
+
Button.displayName = "Button";
|
|
722
|
+
var NButton = Button;
|
|
723
|
+
function assignRef(ref, node) {
|
|
724
|
+
if (!ref) return;
|
|
725
|
+
if (typeof ref === "function") ref(node);
|
|
726
|
+
else ref.current = node;
|
|
727
|
+
}
|
|
728
|
+
function applyViewportLayout(node, axis) {
|
|
729
|
+
node.style.width = "100%";
|
|
730
|
+
node.style.height = "100%";
|
|
731
|
+
node.style.minWidth = "0";
|
|
732
|
+
node.style.minHeight = "0";
|
|
733
|
+
node.style.overflowX = axis === "x" || axis === "both" ? "auto" : "hidden";
|
|
734
|
+
node.style.overflowY = axis === "y" || axis === "both" ? "auto" : "hidden";
|
|
735
|
+
}
|
|
736
|
+
function najmScrollOptions(axis, autoHide, options) {
|
|
737
|
+
return {
|
|
738
|
+
scrollbars: { theme: "os-theme-najm", autoHide, autoHideDelay: 500, clickScroll: true },
|
|
739
|
+
overflow: {
|
|
740
|
+
x: axis === "x" || axis === "both" ? "scroll" : "hidden",
|
|
741
|
+
y: axis === "y" || axis === "both" ? "scroll" : "hidden"
|
|
742
|
+
},
|
|
743
|
+
...options
|
|
744
|
+
};
|
|
745
|
+
}
|
|
746
|
+
function useNajmScrollViewport({
|
|
747
|
+
axis = "y",
|
|
748
|
+
autoHide = "never",
|
|
749
|
+
options
|
|
750
|
+
} = {}) {
|
|
751
|
+
const hostRef = React2.useRef(null);
|
|
752
|
+
const viewportRef = React2.useRef(null);
|
|
753
|
+
React2.useEffect(() => {
|
|
754
|
+
const target = hostRef.current;
|
|
755
|
+
const viewport = viewportRef.current;
|
|
756
|
+
if (!target || !viewport) return;
|
|
757
|
+
const instance = OverlayScrollbars(
|
|
758
|
+
{ target, elements: { viewport } },
|
|
759
|
+
najmScrollOptions(axis, autoHide, options)
|
|
760
|
+
);
|
|
761
|
+
const containWheel = (event) => event.stopPropagation();
|
|
762
|
+
viewport.addEventListener("wheel", containWheel, { passive: true });
|
|
763
|
+
return () => {
|
|
764
|
+
viewport.removeEventListener("wheel", containWheel);
|
|
765
|
+
instance.destroy();
|
|
766
|
+
};
|
|
767
|
+
}, [axis, autoHide, options]);
|
|
768
|
+
return { hostRef, viewportRef };
|
|
769
|
+
}
|
|
770
|
+
function NajmScroll({ className, axis = "y", autoHide = "never", viewportRef, events, options, element, children, style, ...props }) {
|
|
771
|
+
return /* @__PURE__ */ jsx(
|
|
772
|
+
OverlayScrollbarsComponent,
|
|
773
|
+
{
|
|
774
|
+
className: cn(className),
|
|
775
|
+
style: {
|
|
776
|
+
...style,
|
|
777
|
+
overflow: "hidden",
|
|
778
|
+
minHeight: 0,
|
|
779
|
+
minWidth: 0
|
|
780
|
+
},
|
|
781
|
+
element,
|
|
782
|
+
defer: true,
|
|
783
|
+
options: najmScrollOptions(axis, autoHide, options || void 0),
|
|
784
|
+
events: {
|
|
785
|
+
...events,
|
|
786
|
+
initialized: (instance, ...rest) => {
|
|
787
|
+
const viewport = instance.elements().viewport;
|
|
788
|
+
applyViewportLayout(viewport, axis);
|
|
789
|
+
assignRef(viewportRef, viewport);
|
|
790
|
+
events?.initialized?.(instance, ...rest);
|
|
791
|
+
},
|
|
792
|
+
updated: (instance, ...rest) => {
|
|
793
|
+
applyViewportLayout(instance.elements().viewport, axis);
|
|
794
|
+
events?.updated?.(instance, ...rest);
|
|
795
|
+
},
|
|
796
|
+
destroyed: (instance, ...rest) => {
|
|
797
|
+
assignRef(viewportRef, null);
|
|
798
|
+
events?.destroyed?.(instance, ...rest);
|
|
799
|
+
}
|
|
800
|
+
},
|
|
801
|
+
...props,
|
|
802
|
+
children
|
|
803
|
+
}
|
|
804
|
+
);
|
|
805
|
+
}
|
|
806
|
+
var TableStoreContext = createContext(null);
|
|
807
|
+
var useTableStore = { use: {} };
|
|
808
|
+
var handler = {
|
|
809
|
+
get: (_, prop) => () => {
|
|
810
|
+
const store = useContext(TableStoreContext);
|
|
811
|
+
if (!store) throw new Error("useTableStore must be used within NTable");
|
|
812
|
+
return store.use[prop]();
|
|
813
|
+
}
|
|
814
|
+
};
|
|
815
|
+
useTableStore.use = new Proxy({}, handler);
|
|
816
|
+
function formatJsonValue(value) {
|
|
817
|
+
if (typeof value === "string") return value;
|
|
818
|
+
try {
|
|
819
|
+
return JSON.stringify(value ?? null, null, 2) ?? String(value);
|
|
820
|
+
} catch {
|
|
821
|
+
return String(value);
|
|
822
|
+
}
|
|
823
|
+
}
|
|
824
|
+
function NTableJson() {
|
|
825
|
+
const viewMode = useTableStore.use.viewMode();
|
|
826
|
+
const renderJson = useTableStore.use.renderJson();
|
|
827
|
+
const jsonValue = useTableStore.use.jsonValue();
|
|
828
|
+
if (viewMode !== "json") return null;
|
|
829
|
+
return /* @__PURE__ */ jsx("div", { className: "flex-1 flex flex-col min-h-0 overflow-hidden", children: renderJson?.() ?? /* @__PURE__ */ jsx(NajmScroll, { axis: "both", className: "h-full min-h-0 rounded-md border border-border bg-muted/40", children: /* @__PURE__ */ jsx("pre", { className: "p-4 font-mono text-xs leading-relaxed text-foreground", children: formatJsonValue(jsonValue) }) }) });
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
export { Button, NAJM_COMPONENT_NAMES, NButton, NIcon, NTableJson, NajmScroll, RADIUS_VALUE_MAP, TableStoreContext, buttonVariants, cn, defineNajmDesignConfig, defineNajmThemeConfig, inputBorderClasses, parseNajmDesignConfig, parseNajmThemeConfig, resolveRadiusValue, resolveVariantAlias, sidebarBorderClasses, stringifyNajmDesignConfig, stringifyNajmThemeConfig, surfaceBorderClasses, useNajmScrollViewport, useTableStore };
|