najm-kit 2.8.2 → 2.10.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/CHANGELOG.md +71 -27
- package/README.md +477 -237
- package/dist/{NajmUIProvider-BSbXaqak.d.ts → NajmUIProvider-BnReyojl.d.ts} +99 -163
- package/dist/adapters/app.d.ts +5 -1
- package/dist/adapters/app.mjs +3 -3
- package/dist/adapters/next.d.ts +28 -2
- package/dist/adapters/next.mjs +2 -2
- package/dist/chunk-7H6NFBQT.mjs +75 -0
- package/dist/{chunk-IRFFSAO2.mjs → chunk-EUQOTPLV.mjs} +26 -2
- package/dist/{chunk-USZUOJMK.mjs → chunk-FDONJASN.mjs} +163 -3
- package/dist/{chunk-GHMR45H3.mjs → chunk-HML2JZXT.mjs} +1 -1
- package/dist/chunk-JUYT2ISO.mjs +404 -0
- package/dist/{chunk-6OOBAEH2.mjs → chunk-TFHWLE7N.mjs} +1 -403
- package/dist/design-config-D_x1GCu3.d.ts +17 -0
- package/dist/design-types-Rkpt8Pg1.d.ts +159 -0
- package/dist/index.d.ts +60 -77
- package/dist/index.mjs +202 -220
- package/dist/json.mjs +3 -2
- package/dist/server/index.d.ts +3 -0
- package/dist/server/index.mjs +2 -0
- package/dist/server/react.d.ts +16 -0
- package/dist/server/react.mjs +23 -0
- package/dist/server/reactClientGuard.d.ts +2 -0
- package/dist/server/reactClientGuard.mjs +4 -0
- package/dist/uiBootstrap-Ci6K5j5t.d.ts +93 -0
- package/package.json +16 -2
|
@@ -1,118 +1,3 @@
|
|
|
1
|
-
import { useNajmComponentStyle, cn } from './chunk-KVZACF4G.mjs';
|
|
2
|
-
import * as React2 from 'react';
|
|
3
|
-
import React2__default, { createContext, useContext } from 'react';
|
|
4
|
-
import * as LucideIcons from 'lucide-react';
|
|
5
|
-
import { LoaderCircleIcon } from 'lucide-react';
|
|
6
|
-
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
7
|
-
import { Slot } from '@radix-ui/react-slot';
|
|
8
|
-
import { cva } from 'class-variance-authority';
|
|
9
|
-
import { OverlayScrollbars } from 'overlayscrollbars';
|
|
10
|
-
import { OverlayScrollbarsComponent } from 'overlayscrollbars-react';
|
|
11
|
-
|
|
12
|
-
function toPascalCase(value) {
|
|
13
|
-
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("");
|
|
14
|
-
}
|
|
15
|
-
function isImageSource(value) {
|
|
16
|
-
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);
|
|
17
|
-
}
|
|
18
|
-
function isComponentSource(value) {
|
|
19
|
-
return typeof value === "function" || Boolean(value && typeof value === "object" && "$$typeof" in value);
|
|
20
|
-
}
|
|
21
|
-
var NIcon = ({
|
|
22
|
-
icon = "circle",
|
|
23
|
-
size = 24,
|
|
24
|
-
alt = "",
|
|
25
|
-
className,
|
|
26
|
-
style,
|
|
27
|
-
onClick,
|
|
28
|
-
...rest
|
|
29
|
-
}) => {
|
|
30
|
-
const dimensionStyle = {
|
|
31
|
-
width: size,
|
|
32
|
-
height: size,
|
|
33
|
-
...style
|
|
34
|
-
};
|
|
35
|
-
if (React2__default.isValidElement(icon)) {
|
|
36
|
-
return React2__default.cloneElement(icon, {
|
|
37
|
-
className: cn(className, icon.props.className),
|
|
38
|
-
onClick,
|
|
39
|
-
...rest
|
|
40
|
-
});
|
|
41
|
-
}
|
|
42
|
-
if (icon && typeof icon === "object" && "src" in icon) {
|
|
43
|
-
return /* @__PURE__ */ jsx(
|
|
44
|
-
"img",
|
|
45
|
-
{
|
|
46
|
-
alt: icon.alt ?? alt,
|
|
47
|
-
className: cn("inline-block shrink-0 object-contain", className),
|
|
48
|
-
src: icon.src,
|
|
49
|
-
style: dimensionStyle,
|
|
50
|
-
onClick,
|
|
51
|
-
...rest
|
|
52
|
-
}
|
|
53
|
-
);
|
|
54
|
-
}
|
|
55
|
-
if (isComponentSource(icon)) {
|
|
56
|
-
const IconComponent = icon;
|
|
57
|
-
return /* @__PURE__ */ jsx(IconComponent, { size, className, onClick, style, ...rest });
|
|
58
|
-
}
|
|
59
|
-
if (typeof icon === "string") {
|
|
60
|
-
if (isImageSource(icon)) {
|
|
61
|
-
return /* @__PURE__ */ jsx(
|
|
62
|
-
"img",
|
|
63
|
-
{
|
|
64
|
-
alt,
|
|
65
|
-
className: cn("inline-block shrink-0 object-contain", className),
|
|
66
|
-
src: icon,
|
|
67
|
-
style: dimensionStyle,
|
|
68
|
-
onClick,
|
|
69
|
-
...rest
|
|
70
|
-
}
|
|
71
|
-
);
|
|
72
|
-
}
|
|
73
|
-
const pascalCaseIcon = toPascalCase(icon);
|
|
74
|
-
if (LucideIcons[pascalCaseIcon]) {
|
|
75
|
-
const LucideIcon = LucideIcons[pascalCaseIcon];
|
|
76
|
-
return /* @__PURE__ */ jsx(LucideIcon, { size, className, onClick, style, ...rest });
|
|
77
|
-
}
|
|
78
|
-
return null;
|
|
79
|
-
}
|
|
80
|
-
return null;
|
|
81
|
-
};
|
|
82
|
-
NIcon.displayName = "NIcon";
|
|
83
|
-
|
|
84
|
-
// src/theme/borders.ts
|
|
85
|
-
var SURFACE_BORDER_CLASSES = {
|
|
86
|
-
all: "najm-border border-border",
|
|
87
|
-
top: "najm-border-t border-border",
|
|
88
|
-
right: "najm-border-r border-border",
|
|
89
|
-
bottom: "najm-border-b border-border",
|
|
90
|
-
left: "najm-border-l border-border"
|
|
91
|
-
};
|
|
92
|
-
var SIDEBAR_BORDER_CLASSES = {
|
|
93
|
-
all: "najm-border border-sidebar-border",
|
|
94
|
-
top: "najm-border-t border-sidebar-border",
|
|
95
|
-
right: "najm-border-r border-sidebar-border",
|
|
96
|
-
bottom: "najm-border-b border-sidebar-border",
|
|
97
|
-
left: "najm-border-l border-sidebar-border"
|
|
98
|
-
};
|
|
99
|
-
var BORDER_RESET_CLASSES = {
|
|
100
|
-
all: "border-0",
|
|
101
|
-
top: "border-t-0",
|
|
102
|
-
right: "border-r-0",
|
|
103
|
-
bottom: "border-b-0",
|
|
104
|
-
left: "border-l-0"
|
|
105
|
-
};
|
|
106
|
-
function surfaceBorderClasses(bordered = true, side = "all") {
|
|
107
|
-
return bordered === false ? BORDER_RESET_CLASSES[side] : SURFACE_BORDER_CLASSES[side];
|
|
108
|
-
}
|
|
109
|
-
function sidebarBorderClasses(bordered = true, side = "all") {
|
|
110
|
-
return bordered === false ? BORDER_RESET_CLASSES[side] : SIDEBAR_BORDER_CLASSES[side];
|
|
111
|
-
}
|
|
112
|
-
function inputBorderClasses(bordered = true) {
|
|
113
|
-
return bordered === false ? "border-0" : "najm-border border-input";
|
|
114
|
-
}
|
|
115
|
-
|
|
116
1
|
// src/theme/design-types.ts
|
|
117
2
|
var NAJM_COMPONENT_NAMES = [
|
|
118
3
|
"button",
|
|
@@ -536,292 +421,5 @@ function resolveVariantAlias(variants, variant) {
|
|
|
536
421
|
}
|
|
537
422
|
return { variant: current, style };
|
|
538
423
|
}
|
|
539
|
-
var buttonVariants = cva(
|
|
540
|
-
[
|
|
541
|
-
"relative inline-flex shrink-0 cursor-pointer items-center justify-center gap-2 whitespace-nowrap text-sm font-medium outline-none transition-all",
|
|
542
|
-
"disabled:pointer-events-none disabled:opacity-50 data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50",
|
|
543
|
-
"focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
|
|
544
|
-
"aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40",
|
|
545
|
-
"[&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4"
|
|
546
|
-
].join(" "),
|
|
547
|
-
{
|
|
548
|
-
variants: {
|
|
549
|
-
variant: {
|
|
550
|
-
default: "bg-primary text-primary-foreground shadow-xs hover:bg-primary/90",
|
|
551
|
-
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",
|
|
552
|
-
outline: "border border-input bg-transparent text-foreground shadow-xs hover:bg-accent hover:text-accent-foreground",
|
|
553
|
-
secondary: "bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80",
|
|
554
|
-
tertiary: "bg-tertiary text-tertiary-foreground shadow-xs hover:bg-tertiary/80",
|
|
555
|
-
ghost: "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
|
|
556
|
-
link: "h-auto p-0 text-primary underline-offset-4 hover:underline",
|
|
557
|
-
success: "bg-emerald-600 text-white shadow-xs hover:bg-emerald-700",
|
|
558
|
-
warning: "bg-amber-400 text-slate-950 shadow-xs hover:bg-amber-500",
|
|
559
|
-
info: "bg-sky-600 text-white shadow-xs hover:bg-sky-700",
|
|
560
|
-
soft: "bg-primary/10 text-primary shadow-none hover:bg-primary/15",
|
|
561
|
-
subtle: "bg-muted text-foreground shadow-none hover:bg-muted/80",
|
|
562
|
-
plain: "bg-transparent shadow-none hover:bg-transparent"
|
|
563
|
-
},
|
|
564
|
-
size: {
|
|
565
|
-
"2xs": "h-5 gap-1 px-1.5 text-[11px] [&_svg:not([class*='size-'])]:size-3",
|
|
566
|
-
xs: "h-6 gap-1 px-2 text-xs [&_svg:not([class*='size-'])]:size-3",
|
|
567
|
-
sm: "h-8 gap-1.5 px-3 has-[>svg]:px-2.5",
|
|
568
|
-
default: "h-9 px-4 py-2 has-[>svg]:px-3",
|
|
569
|
-
md: "h-9 px-4 py-2 has-[>svg]:px-3",
|
|
570
|
-
lg: "h-10 px-6 has-[>svg]:px-4",
|
|
571
|
-
xl: "h-12 px-8 text-base [&_svg:not([class*='size-'])]:size-5",
|
|
572
|
-
"2xl": "h-14 px-10 text-base [&_svg:not([class*='size-'])]:size-5",
|
|
573
|
-
icon: "size-9",
|
|
574
|
-
"icon-xs": "size-6 [&_svg:not([class*='size-'])]:size-3",
|
|
575
|
-
"icon-sm": "size-8",
|
|
576
|
-
"icon-lg": "size-10 [&_svg:not([class*='size-'])]:size-5",
|
|
577
|
-
"icon-xl": "size-12 [&_svg:not([class*='size-'])]:size-5"
|
|
578
|
-
},
|
|
579
|
-
rounded: {
|
|
580
|
-
none: "rounded-none",
|
|
581
|
-
sm: "rounded-sm",
|
|
582
|
-
default: "rounded-md",
|
|
583
|
-
md: "rounded-md",
|
|
584
|
-
lg: "rounded-lg",
|
|
585
|
-
xl: "rounded-xl",
|
|
586
|
-
"2xl": "rounded-2xl",
|
|
587
|
-
full: "rounded-full"
|
|
588
|
-
},
|
|
589
|
-
fullWidth: {
|
|
590
|
-
true: "w-full",
|
|
591
|
-
false: ""
|
|
592
|
-
}
|
|
593
|
-
},
|
|
594
|
-
defaultVariants: {
|
|
595
|
-
variant: "default",
|
|
596
|
-
size: "default",
|
|
597
|
-
rounded: "default",
|
|
598
|
-
fullWidth: false
|
|
599
|
-
}
|
|
600
|
-
}
|
|
601
|
-
);
|
|
602
|
-
function isPromiseLike(value) {
|
|
603
|
-
return Boolean(value && typeof value.then === "function");
|
|
604
|
-
}
|
|
605
|
-
var defaultLoader = /* @__PURE__ */ jsx(LoaderCircleIcon, { "aria-hidden": "true", className: "animate-spin" });
|
|
606
|
-
function renderIcon(icon) {
|
|
607
|
-
if (!icon) return null;
|
|
608
|
-
return /* @__PURE__ */ jsx(NIcon, { "aria-hidden": "true", icon, className: "shrink-0" });
|
|
609
|
-
}
|
|
610
|
-
var Button = React2.forwardRef(
|
|
611
|
-
({
|
|
612
|
-
className,
|
|
613
|
-
variant,
|
|
614
|
-
size,
|
|
615
|
-
rounded,
|
|
616
|
-
fullWidth,
|
|
617
|
-
asChild = false,
|
|
618
|
-
loading = false,
|
|
619
|
-
autoLoading = true,
|
|
620
|
-
disabledWhileLoading = true,
|
|
621
|
-
loadingText,
|
|
622
|
-
loader = defaultLoader,
|
|
623
|
-
loaderPosition = "left",
|
|
624
|
-
leftIcon,
|
|
625
|
-
rightIcon,
|
|
626
|
-
bordered,
|
|
627
|
-
disabled,
|
|
628
|
-
children,
|
|
629
|
-
onClick,
|
|
630
|
-
style,
|
|
631
|
-
...props
|
|
632
|
-
}, ref) => {
|
|
633
|
-
const recipe = useNajmComponentStyle("button");
|
|
634
|
-
const aliased = resolveVariantAlias(
|
|
635
|
-
recipe?.variants,
|
|
636
|
-
variant ?? recipe?.defaultVariant ?? "default"
|
|
637
|
-
);
|
|
638
|
-
const effVariant = variant ?? aliased.variant ?? recipe?.defaultVariant;
|
|
639
|
-
const effSize = size ?? recipe?.defaultSize;
|
|
640
|
-
const recipeRadius = rounded === void 0 ? resolveRadiusValue(recipe?.radius) : void 0;
|
|
641
|
-
const recipeStyle = recipeRadius ? { borderRadius: recipeRadius } : void 0;
|
|
642
|
-
const [pending, setPending] = React2.useState(false);
|
|
643
|
-
const isLoading = loading || pending;
|
|
644
|
-
const isDisabled = disabled || disabledWhileLoading && isLoading;
|
|
645
|
-
const Comp = asChild ? Slot : "button";
|
|
646
|
-
const handleClick = React2.useCallback(
|
|
647
|
-
(event) => {
|
|
648
|
-
if (isDisabled) {
|
|
649
|
-
event.preventDefault();
|
|
650
|
-
return;
|
|
651
|
-
}
|
|
652
|
-
const result = onClick?.(event);
|
|
653
|
-
if (autoLoading && isPromiseLike(result)) {
|
|
654
|
-
setPending(true);
|
|
655
|
-
void result.then(
|
|
656
|
-
() => setPending(false),
|
|
657
|
-
() => setPending(false)
|
|
658
|
-
);
|
|
659
|
-
}
|
|
660
|
-
},
|
|
661
|
-
[autoLoading, isDisabled, onClick]
|
|
662
|
-
);
|
|
663
|
-
const child = asChild ? React2.Children.only(children) : null;
|
|
664
|
-
const childContent = asChild && React2.isValidElement(child) ? child.props.children : children;
|
|
665
|
-
const content = loadingText && isLoading ? loadingText : childContent;
|
|
666
|
-
const loaderNode = isLoading ? loader : null;
|
|
667
|
-
const leftIconNode = renderIcon(leftIcon);
|
|
668
|
-
const rightIconNode = renderIcon(rightIcon);
|
|
669
|
-
const showCenteredLoader = Boolean(loaderNode && loaderPosition === "center");
|
|
670
|
-
const renderedContent = showCenteredLoader ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
671
|
-
/* @__PURE__ */ jsxs("span", { className: "invisible inline-flex items-center gap-2", children: [
|
|
672
|
-
leftIconNode,
|
|
673
|
-
content,
|
|
674
|
-
rightIconNode
|
|
675
|
-
] }),
|
|
676
|
-
/* @__PURE__ */ jsx("span", { className: "absolute inset-0 inline-flex items-center justify-center", children: loaderNode })
|
|
677
|
-
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
678
|
-
loaderNode && loaderPosition === "left" ? loaderNode : leftIconNode,
|
|
679
|
-
content,
|
|
680
|
-
loaderNode && loaderPosition === "right" ? loaderNode : rightIconNode
|
|
681
|
-
] });
|
|
682
|
-
const renderedChild = asChild && React2.isValidElement(child) ? React2.cloneElement(child, void 0, renderedContent) : renderedContent;
|
|
683
|
-
return /* @__PURE__ */ jsx(
|
|
684
|
-
Comp,
|
|
685
|
-
{
|
|
686
|
-
ref,
|
|
687
|
-
"data-slot": "button",
|
|
688
|
-
"data-loading": isLoading || void 0,
|
|
689
|
-
"data-disabled": isDisabled || void 0,
|
|
690
|
-
"data-bordered": effVariant === "outline" ? "true" : bordered === false ? "false" : bordered ? "true" : void 0,
|
|
691
|
-
"aria-busy": isLoading || void 0,
|
|
692
|
-
"aria-disabled": asChild && isDisabled ? true : void 0,
|
|
693
|
-
disabled: !asChild ? isDisabled : void 0,
|
|
694
|
-
style: recipeStyle ? { ...recipeStyle, ...style } : style,
|
|
695
|
-
className: cn(
|
|
696
|
-
buttonVariants({ variant: effVariant, size: effSize, rounded, fullWidth }),
|
|
697
|
-
aliased.style?.className,
|
|
698
|
-
// Outline buttons always carry an input-style border.
|
|
699
|
-
effVariant === "outline" && inputBorderClasses(true),
|
|
700
|
-
// Filled/ghost/plain/link/success/warning/info/soft/subtle buttons only get a
|
|
701
|
-
// border when the consumer explicitly opts in via `bordered`. Global theming
|
|
702
|
-
// should not outline every filled button.
|
|
703
|
-
effVariant !== "outline" && bordered === true && cn(
|
|
704
|
-
"border",
|
|
705
|
-
"border-muted-foreground"
|
|
706
|
-
),
|
|
707
|
-
className
|
|
708
|
-
),
|
|
709
|
-
onClick: handleClick,
|
|
710
|
-
...props,
|
|
711
|
-
children: renderedChild
|
|
712
|
-
}
|
|
713
|
-
);
|
|
714
|
-
}
|
|
715
|
-
);
|
|
716
|
-
Button.displayName = "Button";
|
|
717
|
-
var NButton = Button;
|
|
718
|
-
function assignRef(ref, node) {
|
|
719
|
-
if (!ref) return;
|
|
720
|
-
if (typeof ref === "function") ref(node);
|
|
721
|
-
else ref.current = node;
|
|
722
|
-
}
|
|
723
|
-
function applyViewportLayout(node, axis) {
|
|
724
|
-
node.style.width = "100%";
|
|
725
|
-
node.style.height = "100%";
|
|
726
|
-
node.style.minWidth = "0";
|
|
727
|
-
node.style.minHeight = "0";
|
|
728
|
-
node.style.overflowX = axis === "x" || axis === "both" ? "auto" : "hidden";
|
|
729
|
-
node.style.overflowY = axis === "y" || axis === "both" ? "auto" : "hidden";
|
|
730
|
-
}
|
|
731
|
-
function najmScrollOptions(axis, autoHide, options) {
|
|
732
|
-
return {
|
|
733
|
-
scrollbars: { theme: "os-theme-najm", autoHide, autoHideDelay: 500, clickScroll: true },
|
|
734
|
-
overflow: {
|
|
735
|
-
x: axis === "x" || axis === "both" ? "scroll" : "hidden",
|
|
736
|
-
y: axis === "y" || axis === "both" ? "scroll" : "hidden"
|
|
737
|
-
},
|
|
738
|
-
...options
|
|
739
|
-
};
|
|
740
|
-
}
|
|
741
|
-
function useNajmScrollViewport({
|
|
742
|
-
axis = "y",
|
|
743
|
-
autoHide = "never",
|
|
744
|
-
options
|
|
745
|
-
} = {}) {
|
|
746
|
-
const hostRef = React2.useRef(null);
|
|
747
|
-
const viewportRef = React2.useRef(null);
|
|
748
|
-
React2.useEffect(() => {
|
|
749
|
-
const target = hostRef.current;
|
|
750
|
-
const viewport = viewportRef.current;
|
|
751
|
-
if (!target || !viewport) return;
|
|
752
|
-
const instance = OverlayScrollbars(
|
|
753
|
-
{ target, elements: { viewport } },
|
|
754
|
-
najmScrollOptions(axis, autoHide, options)
|
|
755
|
-
);
|
|
756
|
-
const containWheel = (event) => event.stopPropagation();
|
|
757
|
-
viewport.addEventListener("wheel", containWheel, { passive: true });
|
|
758
|
-
return () => {
|
|
759
|
-
viewport.removeEventListener("wheel", containWheel);
|
|
760
|
-
instance.destroy();
|
|
761
|
-
};
|
|
762
|
-
}, [axis, autoHide, options]);
|
|
763
|
-
return { hostRef, viewportRef };
|
|
764
|
-
}
|
|
765
|
-
function NajmScroll({ className, axis = "y", autoHide = "never", viewportRef, events, options, element, children, style, ...props }) {
|
|
766
|
-
return /* @__PURE__ */ jsx(
|
|
767
|
-
OverlayScrollbarsComponent,
|
|
768
|
-
{
|
|
769
|
-
className: cn(className),
|
|
770
|
-
style: {
|
|
771
|
-
...style,
|
|
772
|
-
overflow: "hidden",
|
|
773
|
-
minHeight: 0,
|
|
774
|
-
minWidth: 0
|
|
775
|
-
},
|
|
776
|
-
element,
|
|
777
|
-
defer: true,
|
|
778
|
-
options: najmScrollOptions(axis, autoHide, options || void 0),
|
|
779
|
-
events: {
|
|
780
|
-
...events,
|
|
781
|
-
initialized: (instance, ...rest) => {
|
|
782
|
-
const viewport = instance.elements().viewport;
|
|
783
|
-
applyViewportLayout(viewport, axis);
|
|
784
|
-
assignRef(viewportRef, viewport);
|
|
785
|
-
events?.initialized?.(instance, ...rest);
|
|
786
|
-
},
|
|
787
|
-
updated: (instance, ...rest) => {
|
|
788
|
-
applyViewportLayout(instance.elements().viewport, axis);
|
|
789
|
-
events?.updated?.(instance, ...rest);
|
|
790
|
-
},
|
|
791
|
-
destroyed: (instance, ...rest) => {
|
|
792
|
-
assignRef(viewportRef, null);
|
|
793
|
-
events?.destroyed?.(instance, ...rest);
|
|
794
|
-
}
|
|
795
|
-
},
|
|
796
|
-
...props,
|
|
797
|
-
children
|
|
798
|
-
}
|
|
799
|
-
);
|
|
800
|
-
}
|
|
801
|
-
var TableStoreContext = createContext(null);
|
|
802
|
-
var useTableStore = { use: {} };
|
|
803
|
-
var handler = {
|
|
804
|
-
get: (_, prop) => () => {
|
|
805
|
-
const store = useContext(TableStoreContext);
|
|
806
|
-
if (!store) throw new Error("useTableStore must be used within NTable");
|
|
807
|
-
return store.use[prop]();
|
|
808
|
-
}
|
|
809
|
-
};
|
|
810
|
-
useTableStore.use = new Proxy({}, handler);
|
|
811
|
-
function formatJsonValue(value) {
|
|
812
|
-
if (typeof value === "string") return value;
|
|
813
|
-
try {
|
|
814
|
-
return JSON.stringify(value ?? null, null, 2) ?? String(value);
|
|
815
|
-
} catch {
|
|
816
|
-
return String(value);
|
|
817
|
-
}
|
|
818
|
-
}
|
|
819
|
-
function NTableJson() {
|
|
820
|
-
const viewMode = useTableStore.use.viewMode();
|
|
821
|
-
const renderJson = useTableStore.use.renderJson();
|
|
822
|
-
const jsonValue = useTableStore.use.jsonValue();
|
|
823
|
-
if (viewMode !== "json") return null;
|
|
824
|
-
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) }) }) });
|
|
825
|
-
}
|
|
826
424
|
|
|
827
|
-
export {
|
|
425
|
+
export { NAJM_COMPONENT_NAMES, RADIUS_VALUE_MAP, defineNajmDesignConfig, defineNajmThemeConfig, parseNajmDesignConfig, parseNajmThemeConfig, resolveRadiusValue, resolveVariantAlias, stringifyNajmDesignConfig, stringifyNajmThemeConfig };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { a as NajmDesignConfig, d as NajmVariantStyle } from './design-types-Rkpt8Pg1.js';
|
|
2
|
+
|
|
3
|
+
/** Keeps authored TypeScript design objects type-checked without changing them. */
|
|
4
|
+
declare function defineNajmDesignConfig(config: NajmDesignConfig): NajmDesignConfig;
|
|
5
|
+
/** Parses and validates a design config (theme + typography + component recipes). */
|
|
6
|
+
declare function parseNajmDesignConfig(input: unknown): NajmDesignConfig;
|
|
7
|
+
declare function stringifyNajmDesignConfig(config: NajmDesignConfig, space?: number): string;
|
|
8
|
+
/**
|
|
9
|
+
* Resolves a variant against its recipe, following `use` aliases while guarding
|
|
10
|
+
* against loops. Returns the effective variant name and merged style.
|
|
11
|
+
*/
|
|
12
|
+
declare function resolveVariantAlias(variants: Record<string, NajmVariantStyle> | undefined, variant: string): {
|
|
13
|
+
variant: string;
|
|
14
|
+
style?: NajmVariantStyle;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export { defineNajmDesignConfig as d, parseNajmDesignConfig as p, resolveVariantAlias as r, stringifyNajmDesignConfig as s };
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
type NajmMode = 'light' | 'dark';
|
|
2
|
+
type NajmAccent = 'neutral' | 'emerald' | 'green' | 'slate' | 'blue' | 'violet';
|
|
3
|
+
type NajmPreset = 'light' | 'dark' | 'dark-emerald' | 'dark-green' | 'dark-slate' | 'dark-blue' | 'dark-violet';
|
|
4
|
+
interface NajmAppearance {
|
|
5
|
+
/** Global border thickness, e.g. `'0'`, `'1px'`, `'2px'`. `'0'` hides borders. */
|
|
6
|
+
borderWidth?: string;
|
|
7
|
+
}
|
|
8
|
+
interface NajmThemeTokens {
|
|
9
|
+
background?: string;
|
|
10
|
+
foreground?: string;
|
|
11
|
+
card?: string;
|
|
12
|
+
'card-foreground'?: string;
|
|
13
|
+
popover?: string;
|
|
14
|
+
'popover-foreground'?: string;
|
|
15
|
+
primary?: string;
|
|
16
|
+
'primary-foreground'?: string;
|
|
17
|
+
secondary?: string;
|
|
18
|
+
'secondary-foreground'?: string;
|
|
19
|
+
tertiary?: string;
|
|
20
|
+
'tertiary-foreground'?: string;
|
|
21
|
+
muted?: string;
|
|
22
|
+
'muted-foreground'?: string;
|
|
23
|
+
accent?: string;
|
|
24
|
+
'accent-foreground'?: string;
|
|
25
|
+
destructive?: string;
|
|
26
|
+
'destructive-foreground'?: string;
|
|
27
|
+
border?: string;
|
|
28
|
+
input?: string;
|
|
29
|
+
ring?: string;
|
|
30
|
+
sidebar?: string;
|
|
31
|
+
'sidebar-foreground'?: string;
|
|
32
|
+
'sidebar-primary'?: string;
|
|
33
|
+
'sidebar-primary-foreground'?: string;
|
|
34
|
+
'sidebar-accent'?: string;
|
|
35
|
+
'sidebar-accent-foreground'?: string;
|
|
36
|
+
'sidebar-border'?: string;
|
|
37
|
+
'sidebar-ring'?: string;
|
|
38
|
+
'chart-1'?: string;
|
|
39
|
+
'chart-2'?: string;
|
|
40
|
+
'chart-3'?: string;
|
|
41
|
+
'chart-4'?: string;
|
|
42
|
+
'chart-5'?: string;
|
|
43
|
+
radius?: string;
|
|
44
|
+
}
|
|
45
|
+
/** Serializable theme settings suitable for JSON files, APIs, or local storage. */
|
|
46
|
+
interface NajmThemeConfig {
|
|
47
|
+
preset?: NajmPreset;
|
|
48
|
+
mode?: NajmMode;
|
|
49
|
+
accent?: NajmAccent;
|
|
50
|
+
tokens?: NajmThemeTokens;
|
|
51
|
+
/**
|
|
52
|
+
* Per-mode token overrides authored on top of the composed preset. Keeps
|
|
53
|
+
* light and dark customizations independent: editing a token in one mode
|
|
54
|
+
* records it here so it survives switching to the other mode and back.
|
|
55
|
+
* Providers resolve this field on top of the composed mode/accent preset.
|
|
56
|
+
*/
|
|
57
|
+
overrides?: Partial<Record<NajmMode, NajmThemeTokens>>;
|
|
58
|
+
accentOnly?: boolean;
|
|
59
|
+
appearance?: NajmAppearance;
|
|
60
|
+
radius?: string;
|
|
61
|
+
}
|
|
62
|
+
interface NajmThemeProviderProps {
|
|
63
|
+
/** Serializable theme settings. Explicit provider props override this config. */
|
|
64
|
+
config?: NajmThemeConfig;
|
|
65
|
+
preset?: NajmPreset;
|
|
66
|
+
mode?: NajmMode;
|
|
67
|
+
accent?: NajmAccent;
|
|
68
|
+
tokens?: NajmThemeTokens;
|
|
69
|
+
/** When true, only inject accent tokens (primary, ring, accent and their foregrounds).
|
|
70
|
+
* Everything else (bg, card, fg…) is inherited from the parent cascade. */
|
|
71
|
+
accentOnly?: boolean;
|
|
72
|
+
/** App-wide UI preferences (currently global border width). */
|
|
73
|
+
appearance?: NajmAppearance;
|
|
74
|
+
/** Global base radius, for example `0`, `0.5rem`, or `0.75rem`. */
|
|
75
|
+
radius?: string;
|
|
76
|
+
className?: string;
|
|
77
|
+
asChild?: boolean;
|
|
78
|
+
children: React.ReactNode;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
type NajmDensity = "compact" | "default" | "comfortable";
|
|
82
|
+
/** Tailwind's mobile-first viewport breakpoints, plus the default value. */
|
|
83
|
+
type NajmResponsiveBreakpoint = "base" | "sm" | "md" | "lg" | "xl" | "2xl";
|
|
84
|
+
/**
|
|
85
|
+
* A scalar value for every viewport, or mobile-first breakpoint overrides.
|
|
86
|
+
* For example: `{ base: 164, lg: 200, xl: 240 }`.
|
|
87
|
+
*/
|
|
88
|
+
type NajmResponsiveValue<T> = T | Partial<Record<NajmResponsiveBreakpoint, T>>;
|
|
89
|
+
type NajmComponentRadius = "inherit" | "none" | "xs" | "sm" | "md" | "lg" | "xl" | "full" | string;
|
|
90
|
+
interface NajmSlotStyle {
|
|
91
|
+
className?: string;
|
|
92
|
+
radius?: NajmComponentRadius;
|
|
93
|
+
borderWidth?: string;
|
|
94
|
+
padding?: string;
|
|
95
|
+
paddingTop?: string;
|
|
96
|
+
}
|
|
97
|
+
interface NajmVariantStyle {
|
|
98
|
+
/** Reuse another variant's recipe. Example: primary badge uses secondary. */
|
|
99
|
+
use?: string;
|
|
100
|
+
className?: string;
|
|
101
|
+
tokens?: Record<string, string>;
|
|
102
|
+
}
|
|
103
|
+
interface NajmComponentStyleConfig {
|
|
104
|
+
/** Render components that support it as a card-like surface. */
|
|
105
|
+
card?: boolean;
|
|
106
|
+
/** Sidebar-only: render section titles above grouped nav items. */
|
|
107
|
+
showSectionLabels?: boolean;
|
|
108
|
+
/** Sidebar-only: render separator lines between nav item sections. */
|
|
109
|
+
showSectionSeparators?: boolean;
|
|
110
|
+
/** Sidebar-only: expanded width in px (default 240). Supports responsive overrides. */
|
|
111
|
+
expandedWidth?: NajmResponsiveValue<number>;
|
|
112
|
+
/** Sidebar-only: collapsed width in px (default 64). Supports responsive overrides. */
|
|
113
|
+
collapsedWidth?: NajmResponsiveValue<number>;
|
|
114
|
+
/** Sidebar-only: mobile drawer width in px. Defaults to the expanded width. */
|
|
115
|
+
mobileWidth?: NajmResponsiveValue<number>;
|
|
116
|
+
defaultVariant?: string;
|
|
117
|
+
defaultSize?: string;
|
|
118
|
+
density?: NajmDensity;
|
|
119
|
+
/** NTable-only: CSS color used for the table header and add button. */
|
|
120
|
+
headerColor?: string;
|
|
121
|
+
/** NTable-only: CSS color used for table header text and add button text. */
|
|
122
|
+
headerTextColor?: string;
|
|
123
|
+
/** NTable-only: CSS color used for table container and row borders. */
|
|
124
|
+
borderColor?: string;
|
|
125
|
+
radius?: NajmComponentRadius;
|
|
126
|
+
borderWidth?: string;
|
|
127
|
+
slots?: Record<string, NajmSlotStyle>;
|
|
128
|
+
variants?: Record<string, NajmVariantStyle>;
|
|
129
|
+
}
|
|
130
|
+
type NajmComponentName = "button" | "badge" | "card" | "table" | "tabs" | "dialog" | "alert" | "sidebar" | "pageHeader" | "input" | "select" | "dropdown" | "sheet" | "popover" | "tooltip" | "progress" | "avatar";
|
|
131
|
+
type NajmComponentThemeConfig = Partial<Record<NajmComponentName, NajmComponentStyleConfig>>;
|
|
132
|
+
interface NajmTypographyConfig {
|
|
133
|
+
fontSans?: string;
|
|
134
|
+
fontHeading?: string;
|
|
135
|
+
fontMono?: string;
|
|
136
|
+
baseSize?: string;
|
|
137
|
+
scale?: "compact" | "default" | "comfortable";
|
|
138
|
+
lineHeight?: string;
|
|
139
|
+
letterSpacing?: string;
|
|
140
|
+
}
|
|
141
|
+
interface NajmLayoutConfig {
|
|
142
|
+
/** Page inline padding, usually used by NPageLayout. */
|
|
143
|
+
pageGutter?: string;
|
|
144
|
+
/** Vertical page padding and stacked section gap, usually used by NPageLayout. */
|
|
145
|
+
sectionGap?: string;
|
|
146
|
+
}
|
|
147
|
+
interface NajmDesignConfig {
|
|
148
|
+
version: 1;
|
|
149
|
+
theme: NajmThemeConfig;
|
|
150
|
+
typography?: NajmTypographyConfig;
|
|
151
|
+
components?: NajmComponentThemeConfig;
|
|
152
|
+
layout?: NajmLayoutConfig;
|
|
153
|
+
}
|
|
154
|
+
declare const NAJM_COMPONENT_NAMES: readonly NajmComponentName[];
|
|
155
|
+
/** Maps a NajmComponentRadius keyword to a CSS value (or var). */
|
|
156
|
+
declare const RADIUS_VALUE_MAP: Record<string, string>;
|
|
157
|
+
declare function resolveRadiusValue(radius: NajmComponentRadius | undefined): string | undefined;
|
|
158
|
+
|
|
159
|
+
export { type NajmComponentThemeConfig as N, RADIUS_VALUE_MAP as R, type NajmDesignConfig as a, type NajmLayoutConfig as b, type NajmTypographyConfig as c, type NajmVariantStyle as d, type NajmMode as e, type NajmThemeProviderProps as f, type NajmAppearance as g, type NajmThemeConfig as h, type NajmAccent as i, type NajmThemeTokens as j, type NajmPreset as k, type NajmComponentName as l, type NajmComponentStyleConfig as m, type NajmResponsiveBreakpoint as n, type NajmResponsiveValue as o, NAJM_COMPONENT_NAMES as p, type NajmComponentRadius as q, type NajmDensity as r, type NajmSlotStyle as s, resolveRadiusValue as t };
|