najm-kit 2.1.37 → 2.1.39

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/index.mjs CHANGED
@@ -6,20 +6,20 @@ import { clsx } from 'clsx';
6
6
  import { twMerge } from 'tailwind-merge';
7
7
  import * as TabsPrimitive from '@radix-ui/react-tabs';
8
8
  import * as LucideIcons from 'lucide-react';
9
- import { ChevronDown, AlertTriangle, RefreshCw, LoaderCircleIcon, RotateCcw, X, XIcon, Menu, Search, ChevronRightIcon, CheckIcon, CircleIcon, ChevronDownIcon, ChevronUpIcon, ChevronLeftIcon, SearchIcon, Table as Table$1, FileJson, ChevronRight, ArrowUpDown, Loader2, ChevronUp, Folder, Eye, EyeOff, ChevronsUpDown, Check, Calendar as Calendar$1, FileUp, UploadCloud, CheckCircle2, AlertCircle, Star, Globe, Clock, Upload, Plus, Trash2, MoreVertical, Edit, ChevronsLeft, ChevronLeft, ChevronsRight, Pencil, Merge, PanelLeftOpen, PanelLeftClose, LogOut, Image, ArrowUp, ArrowDown, CheckSquare, FilePlus, FolderPlus, Share2, Move, ClipboardPaste, Copy, Scissors, Download, LoaderPinwheelIcon, LoaderIcon, ArrowUpRight, ArrowDownRight, SlidersHorizontal, Columns3, Settings, Filter, SearchX, Inbox, List, LayoutGrid, Code, FolderOpen } from 'lucide-react';
9
+ import { ChevronDown, AlertTriangle, RefreshCw, LoaderCircleIcon, ChevronDownIcon, ChevronUpIcon, CheckIcon, Upload, Download, RotateCcw, X, XIcon, Menu, Search, ChevronRightIcon, CircleIcon, ChevronLeftIcon, SearchIcon, Table as Table$1, FileJson, ChevronRight, ArrowUpDown, Loader2, ChevronUp, Folder, Eye, EyeOff, ChevronsUpDown, Check, Calendar as Calendar$1, FileUp, UploadCloud, CheckCircle2, AlertCircle, Camera, Star, Globe, Clock, Plus, Trash2, MoreVertical, Edit, ChevronsLeft, ChevronLeft, ChevronsRight, Pencil, Merge, PanelLeftOpen, PanelLeftClose, LogOut, Image, ArrowUp, ArrowDown, CheckSquare, FilePlus, FolderPlus, Share2, Move, ClipboardPaste, Copy, Scissors, LoaderPinwheelIcon, LoaderIcon, ArrowUpRight, ArrowDownRight, SlidersHorizontal, Columns3, Settings, Filter, SearchX, Inbox, List, LayoutGrid, Code, FolderOpen } from 'lucide-react';
10
10
  import * as TooltipPrimitive from '@radix-ui/react-tooltip';
11
11
  import { cva } from 'class-variance-authority';
12
12
  import { HexColorPicker } from 'react-colorful';
13
13
  import * as PopoverPrimitive from '@radix-ui/react-popover';
14
14
  import { converter, parse, formatHsl, formatRgb, formatHex } from 'culori';
15
15
  import * as CollapsiblePrimitive from '@radix-ui/react-collapsible';
16
+ import * as SelectPrimitive from '@radix-ui/react-select';
16
17
  import * as SwitchPrimitive from '@radix-ui/react-switch';
17
18
  import * as LabelPrimitive from '@radix-ui/react-label';
18
19
  import * as SheetPrimitive from '@radix-ui/react-dialog';
19
20
  import { OverlayScrollbarsComponent } from 'overlayscrollbars-react';
20
21
  import { create } from 'zustand';
21
22
  import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';
22
- import * as SelectPrimitive from '@radix-ui/react-select';
23
23
  import * as CheckboxPrimitive from '@radix-ui/react-checkbox';
24
24
  import * as RadioGroupPrimitive from '@radix-ui/react-radio-group';
25
25
  import * as ProgressPrimitive from '@radix-ui/react-progress';
@@ -254,6 +254,10 @@ function resolveThemeTokens({
254
254
  return null;
255
255
  }
256
256
  var NajmThemeDepthContext = React.createContext(0);
257
+ var NajmThemeModeContext = React.createContext(void 0);
258
+ function useNajmThemeMode() {
259
+ return React.useContext(NajmThemeModeContext);
260
+ }
257
261
  var NajmThemeContainerCtx = React.createContext(null);
258
262
  var DEFAULT_APPEARANCE = {};
259
263
  var NajmAppearanceContext = React.createContext(DEFAULT_APPEARANCE);
@@ -274,6 +278,7 @@ function NajmThemeProvider({
274
278
  children
275
279
  }) {
276
280
  const depth = React.useContext(NajmThemeDepthContext);
281
+ const parentMode = React.useContext(NajmThemeModeContext);
277
282
  const parentAppearance = React.useContext(NajmAppearanceContext);
278
283
  const effectivePreset = preset ?? config?.preset;
279
284
  const effectiveMode = mode ?? config?.mode;
@@ -322,7 +327,7 @@ function NajmThemeProvider({
322
327
  () => ({ ...parentAppearance, ...config?.appearance ?? {}, ...appearance ?? {} }),
323
328
  [parentAppearance, config?.appearance, appearance]
324
329
  );
325
- return /* @__PURE__ */ jsx(NajmThemeDepthContext.Provider, { value: depth + 1, children: /* @__PURE__ */ jsx(NajmAppearanceContext.Provider, { value: resolvedAppearance, children: /* @__PURE__ */ jsx(NajmThemeContainerCtx.Provider, { value: container, children: /* @__PURE__ */ jsx(
330
+ return /* @__PURE__ */ jsx(NajmThemeDepthContext.Provider, { value: depth + 1, children: /* @__PURE__ */ jsx(NajmThemeModeContext.Provider, { value: effectiveMode ?? parentMode, children: /* @__PURE__ */ jsx(NajmAppearanceContext.Provider, { value: resolvedAppearance, children: /* @__PURE__ */ jsx(NajmThemeContainerCtx.Provider, { value: container, children: /* @__PURE__ */ jsx(
326
331
  Comp,
327
332
  {
328
333
  ref: handleContainerRef,
@@ -332,7 +337,7 @@ function NajmThemeProvider({
332
337
  style,
333
338
  children
334
339
  }
335
- ) }) }) });
340
+ ) }) }) }) });
336
341
  }
337
342
  function cn(...inputs) {
338
343
  return twMerge(clsx(inputs));
@@ -1514,7 +1519,7 @@ var BaseInput = React__default.forwardRef(
1514
1519
  colorClass = PRESETS2[borderColor] ?? (NO_SHADE.has(borderColor) ? `border-${borderColor}` : `border-${borderColor}-600`);
1515
1520
  } else {
1516
1521
  const restingBorderClass = inputBorderClasses(isBordered);
1517
- borderClass = isBordered ? `${STATIC_BASE} ${restingBorderClass} hover:border-input focus-within:border-primary/70` : restingBorderClass;
1522
+ borderClass = isBordered ? `${STATIC_BASE} ${restingBorderClass} [&:not(:focus-within):not([data-state=open]):hover]:border-input focus-within:border-ring data-[state=open]:border-ring` : restingBorderClass;
1518
1523
  }
1519
1524
  }
1520
1525
  return /* @__PURE__ */ jsx(
@@ -1974,34 +1979,179 @@ function ResetButton({
1974
1979
  }
1975
1980
  );
1976
1981
  }
1977
- var NativeSelect = React.forwardRef(
1978
- ({ className, options, placeholder, value, ...props }, ref) => {
1979
- const hasValue = value !== void 0 && value !== "";
1980
- return /* @__PURE__ */ jsxs("div", { className: "relative", children: [
1981
- /* @__PURE__ */ jsxs(
1982
- "select",
1983
- {
1984
- ref,
1985
- value,
1986
- className: cn(
1987
- "flex h-10 w-full appearance-none rounded-md border border-input bg-card px-3 py-1.5 pr-8 text-sm text-foreground shadow-sm transition-colors",
1988
- "hover:border-muted-foreground/30 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
1989
- "disabled:cursor-not-allowed disabled:opacity-50",
1990
- !hasValue && "text-muted-foreground",
1991
- className
1992
- ),
1993
- ...props,
1994
- children: [
1995
- placeholder && /* @__PURE__ */ jsx("option", { value: "", disabled: true, children: placeholder }),
1996
- options.map((opt) => /* @__PURE__ */ jsx("option", { value: opt.value, children: opt.label }, opt.value))
1997
- ]
1998
- }
1982
+ function Select({ ...props }) {
1983
+ return /* @__PURE__ */ jsx(SelectPrimitive.Root, { "data-slot": "select", ...props });
1984
+ }
1985
+ function SelectGroup({ ...props }) {
1986
+ return /* @__PURE__ */ jsx(SelectPrimitive.Group, { "data-slot": "select-group", ...props });
1987
+ }
1988
+ function SelectValue({ ...props }) {
1989
+ return /* @__PURE__ */ jsx(SelectPrimitive.Value, { "data-slot": "select-value", ...props });
1990
+ }
1991
+ function SelectTrigger({ className, children, ...props }) {
1992
+ return /* @__PURE__ */ jsxs(
1993
+ SelectPrimitive.Trigger,
1994
+ {
1995
+ "data-slot": "select-trigger",
1996
+ className: cn(
1997
+ "border-input data-[placeholder]:text-muted-foreground [&_svg:not([class*='text-'])]:text-muted-foreground flex h-9 w-full cursor-pointer items-center justify-between gap-2 rounded-md border bg-transparent px-3 py-2 text-sm whitespace-nowrap shadow-xs transition-[color,box-shadow] outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-1.5 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
1998
+ className
1999
1999
  ),
2000
- /* @__PURE__ */ jsx(ChevronDown, { className: "pointer-events-none absolute right-2 top-1/2 size-4 -translate-y-1/2 text-muted-foreground" })
2001
- ] });
2002
- }
2003
- );
2004
- NativeSelect.displayName = "NativeSelect";
2000
+ ...props,
2001
+ children: [
2002
+ children,
2003
+ /* @__PURE__ */ jsx(SelectPrimitive.Icon, { asChild: true, children: /* @__PURE__ */ jsx(ChevronDownIcon, { className: "size-4 opacity-50" }) })
2004
+ ]
2005
+ }
2006
+ );
2007
+ }
2008
+ function SelectScrollUpButton({ className, ...props }) {
2009
+ return /* @__PURE__ */ jsx(SelectPrimitive.ScrollUpButton, { "data-slot": "select-scroll-up-button", className: cn("flex cursor-default items-center justify-center py-1", className), ...props, children: /* @__PURE__ */ jsx(ChevronUpIcon, { className: "size-4" }) });
2010
+ }
2011
+ function SelectScrollDownButton({ className, ...props }) {
2012
+ return /* @__PURE__ */ jsx(SelectPrimitive.ScrollDownButton, { "data-slot": "select-scroll-down-button", className: cn("flex cursor-default items-center justify-center py-1", className), ...props, children: /* @__PURE__ */ jsx(ChevronDownIcon, { className: "size-4" }) });
2013
+ }
2014
+ function SelectContent({ className, children, position = "popper", style, ...props }) {
2015
+ const container = React.useContext(NajmThemeContainerCtx);
2016
+ const recipe = useNajmComponentStyle("select");
2017
+ const contentSlot = recipe?.slots?.content;
2018
+ const borderWidth = contentSlot?.borderWidth ?? recipe?.borderWidth;
2019
+ const radius = resolveRadiusValue(contentSlot?.radius ?? recipe?.radius);
2020
+ const recipeStyle = {
2021
+ ...radius ? { borderRadius: radius } : {},
2022
+ ...borderWidth !== void 0 ? {
2023
+ borderWidth,
2024
+ borderStyle: borderWidth === "0" ? "none" : "solid",
2025
+ borderColor: "var(--border)"
2026
+ } : {}
2027
+ };
2028
+ useNajmPortalLayerStyles();
2029
+ return /* @__PURE__ */ jsx(SelectPrimitive.Portal, { container: container ?? void 0, children: /* @__PURE__ */ jsxs(
2030
+ SelectPrimitive.Content,
2031
+ {
2032
+ "data-slot": "select-content",
2033
+ className: cn(
2034
+ "bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 relative z-[10000] max-h-(--radix-select-content-available-height) min-w-[8rem] overflow-hidden rounded-md shadow-md",
2035
+ position === "popper" && "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1 w-[var(--radix-select-trigger-width)]",
2036
+ contentSlot?.className,
2037
+ className
2038
+ ),
2039
+ style: { ...recipeStyle, ...style },
2040
+ position,
2041
+ ...props,
2042
+ children: [
2043
+ /* @__PURE__ */ jsx(SelectScrollUpButton, {}),
2044
+ /* @__PURE__ */ jsx(SelectPrimitive.Viewport, { className: cn("p-1", position === "popper" && "h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]"), children }),
2045
+ /* @__PURE__ */ jsx(SelectScrollDownButton, {})
2046
+ ]
2047
+ }
2048
+ ) });
2049
+ }
2050
+ function SelectLabel({ className, ...props }) {
2051
+ return /* @__PURE__ */ jsx(SelectPrimitive.Label, { "data-slot": "select-label", className: cn("text-muted-foreground px-2 py-1.5 text-xs", className), ...props });
2052
+ }
2053
+ function SelectItem({ className, children, ...props }) {
2054
+ return /* @__PURE__ */ jsxs(
2055
+ SelectPrimitive.Item,
2056
+ {
2057
+ "data-slot": "select-item",
2058
+ className: cn("focus:bg-accent focus:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground relative flex w-full cursor-pointer items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-none select-none data-[disabled]:pointer-events-none data-[disabled]:cursor-not-allowed data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2", className),
2059
+ ...props,
2060
+ children: [
2061
+ /* @__PURE__ */ jsx("span", { className: "absolute right-2 flex size-3.5 items-center justify-center", children: /* @__PURE__ */ jsx(SelectPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx(CheckIcon, { className: "size-4" }) }) }),
2062
+ /* @__PURE__ */ jsx(SelectPrimitive.ItemText, { children })
2063
+ ]
2064
+ }
2065
+ );
2066
+ }
2067
+ function SelectSeparator({ className, ...props }) {
2068
+ return /* @__PURE__ */ jsx(SelectPrimitive.Separator, { "data-slot": "select-separator", className: cn("bg-muted pointer-events-none -mx-1 my-1 h-px", className), ...props });
2069
+ }
2070
+ function getIconColorProps(iconColor, baseClassName = "") {
2071
+ if (!iconColor) return { className: cn(baseClassName, "text-muted-foreground"), style: {} };
2072
+ if (iconColor.startsWith("text-")) return { className: cn(baseClassName, iconColor), style: {} };
2073
+ return { className: baseClassName, style: { color: iconColor } };
2074
+ }
2075
+ function resolveIcon(icon) {
2076
+ if (!icon) return null;
2077
+ return /* @__PURE__ */ jsx(NIcon, { icon, size: 16 });
2078
+ }
2079
+ var EMPTY_VALUE = "__najm_select_empty_value__";
2080
+ function renderItems(items) {
2081
+ return items.map((item) => {
2082
+ const value = typeof item === "string" ? item : item.value;
2083
+ const label = typeof item === "string" ? item : item.label;
2084
+ const internalValue = value === "" ? EMPTY_VALUE : value;
2085
+ return /* @__PURE__ */ jsx(SelectItem, { value: internalValue, children: label }, internalValue);
2086
+ });
2087
+ }
2088
+ var SelectInput = ({ placeholder = "", ariaLabel, value, onChange, icon, showIcon = true, iconColor, items, className = "", dropdownClassName, variant = "default", status = "default", bordered, borderColor, disabled = false }) => {
2089
+ const shouldDisplayIcon = Boolean(icon) && showIcon && !value;
2090
+ const iconProps = getIconColorProps(iconColor, "h-4 w-4");
2091
+ const found = items.find(
2092
+ (item) => typeof item === "string" ? item === value : item.value === value
2093
+ );
2094
+ const displayLabel = typeof found === "string" ? found : found?.label ?? value;
2095
+ const [open, setOpen] = React__default.useState(false);
2096
+ const triggerRef = React__default.useRef(null);
2097
+ const pointerDismissedRef = React__default.useRef(false);
2098
+ return /* @__PURE__ */ jsxs("div", { className: cn("group relative", className), children: [
2099
+ /* @__PURE__ */ jsxs(
2100
+ BaseInput,
2101
+ {
2102
+ variant,
2103
+ status,
2104
+ bordered,
2105
+ borderColor,
2106
+ "data-state": open ? "open" : "closed",
2107
+ className: "pointer-events-none group-focus-within:border-ring",
2108
+ children: [
2109
+ shouldDisplayIcon && /* @__PURE__ */ jsx("span", { className: iconProps.className, style: iconProps.style, children: resolveIcon(icon) }),
2110
+ /* @__PURE__ */ jsx("span", { className: cn("flex-1 truncate text-sm", !displayLabel && "text-muted-foreground"), children: displayLabel || placeholder }),
2111
+ /* @__PURE__ */ jsx(ChevronDown, { className: "h-4 w-4 shrink-0 opacity-50" })
2112
+ ]
2113
+ }
2114
+ ),
2115
+ /* @__PURE__ */ jsxs(
2116
+ Select,
2117
+ {
2118
+ onValueChange: (next) => onChange(next === EMPTY_VALUE ? "" : next),
2119
+ value: value === "" ? EMPTY_VALUE : String(value),
2120
+ disabled,
2121
+ open,
2122
+ onOpenChange: setOpen,
2123
+ children: [
2124
+ /* @__PURE__ */ jsx(
2125
+ SelectTrigger,
2126
+ {
2127
+ ref: triggerRef,
2128
+ className: "absolute inset-0 h-full w-full opacity-0 focus-visible:border-transparent focus-visible:ring-0",
2129
+ disabled,
2130
+ "aria-label": ariaLabel || placeholder || "Select"
2131
+ }
2132
+ ),
2133
+ /* @__PURE__ */ jsx(
2134
+ SelectContent,
2135
+ {
2136
+ className: dropdownClassName,
2137
+ onPointerDownOutside: () => {
2138
+ pointerDismissedRef.current = true;
2139
+ },
2140
+ onCloseAutoFocus: (event) => {
2141
+ if (!pointerDismissedRef.current) return;
2142
+ event.preventDefault();
2143
+ pointerDismissedRef.current = false;
2144
+ triggerRef.current?.blur();
2145
+ },
2146
+ children: renderItems(items)
2147
+ }
2148
+ )
2149
+ ]
2150
+ },
2151
+ value === "" ? EMPTY_VALUE : String(value)
2152
+ )
2153
+ ] });
2154
+ };
2005
2155
  var TRACK = {
2006
2156
  xs: "h-3 w-5",
2007
2157
  sm: "h-4 w-7",
@@ -2438,16 +2588,16 @@ function ThemeCustomizerComponentsLayoutTab({
2438
2588
  label: labels.pageGutter,
2439
2589
  disabled,
2440
2590
  children: /* @__PURE__ */ jsx(
2441
- NativeSelect,
2591
+ SelectInput,
2442
2592
  {
2443
2593
  value: layout.pageGutter ?? "",
2444
- onChange: (e) => onChange(setLayoutField(value, "pageGutter", e.target.value || void 0)),
2445
- options: [
2594
+ onChange: (next) => onChange(setLayoutField(value, "pageGutter", next || void 0)),
2595
+ items: [
2446
2596
  toOption(labels.defaultOption, ""),
2447
2597
  ...LAYOUT_SIZE_VALUES.map((value2) => ({ value: value2, label: value2 }))
2448
2598
  ],
2449
2599
  disabled,
2450
- "aria-label": typeof labels.pageGutter === "string" ? labels.pageGutter : "Page gutter"
2600
+ ariaLabel: typeof labels.pageGutter === "string" ? labels.pageGutter : "Page gutter"
2451
2601
  }
2452
2602
  )
2453
2603
  }
@@ -2458,54 +2608,54 @@ function ThemeCustomizerComponentsLayoutTab({
2458
2608
  label: labels.sectionGap,
2459
2609
  disabled,
2460
2610
  children: /* @__PURE__ */ jsx(
2461
- NativeSelect,
2611
+ SelectInput,
2462
2612
  {
2463
2613
  value: layout.sectionGap ?? "",
2464
- onChange: (e) => onChange(setLayoutField(value, "sectionGap", e.target.value || void 0)),
2465
- options: [
2614
+ onChange: (next) => onChange(setLayoutField(value, "sectionGap", next || void 0)),
2615
+ items: [
2466
2616
  toOption(labels.defaultOption, ""),
2467
2617
  ...LAYOUT_SIZE_VALUES.map((value2) => ({ value: value2, label: value2 }))
2468
2618
  ],
2469
2619
  disabled,
2470
- "aria-label": typeof labels.sectionGap === "string" ? labels.sectionGap : "Section gap"
2620
+ ariaLabel: typeof labels.sectionGap === "string" ? labels.sectionGap : "Section gap"
2471
2621
  }
2472
2622
  )
2473
2623
  }
2474
2624
  ),
2475
2625
  /* @__PURE__ */ jsx(CustomizerField, { label: labels.globalBorderWidth, disabled, children: /* @__PURE__ */ jsx(
2476
- NativeSelect,
2626
+ SelectInput,
2477
2627
  {
2478
2628
  value: value.theme.appearance?.borderWidth ?? "1px",
2479
- onChange: (event) => onChange(setThemeField(value, "appearance", {
2629
+ onChange: (next) => onChange(setThemeField(value, "appearance", {
2480
2630
  ...value.theme.appearance ?? {},
2481
- borderWidth: event.target.value
2631
+ borderWidth: next
2482
2632
  })),
2483
- options: BORDER_WIDTH_VALUES.map((borderWidth) => ({ value: borderWidth, label: borderWidth })),
2633
+ items: BORDER_WIDTH_VALUES.map((borderWidth) => ({ value: borderWidth, label: borderWidth })),
2484
2634
  disabled,
2485
- "aria-label": typeof labels.globalBorderWidth === "string" ? labels.globalBorderWidth : "Border width"
2635
+ ariaLabel: typeof labels.globalBorderWidth === "string" ? labels.globalBorderWidth : "Border width"
2486
2636
  }
2487
2637
  ) }),
2488
2638
  /* @__PURE__ */ jsx(CustomizerField, { label: labels.inputBorderWidth, disabled, children: /* @__PURE__ */ jsx(
2489
- NativeSelect,
2639
+ SelectInput,
2490
2640
  {
2491
2641
  value: components.input?.borderWidth ?? "",
2492
- onChange: (e) => onChange(setComponentField(value, "input", "borderWidth", e.target.value || void 0)),
2493
- options: [
2642
+ onChange: (next) => onChange(setComponentField(value, "input", "borderWidth", next || void 0)),
2643
+ items: [
2494
2644
  toOption(labels.defaultOption, ""),
2495
2645
  ...COMPONENT_BORDER_WIDTH_VALUES.map((value2) => ({ value: value2, label: value2 }))
2496
2646
  ],
2497
2647
  disabled,
2498
- "aria-label": typeof labels.inputBorderWidth === "string" ? labels.inputBorderWidth : "Input border width"
2648
+ ariaLabel: typeof labels.inputBorderWidth === "string" ? labels.inputBorderWidth : "Input border width"
2499
2649
  }
2500
2650
  ) }),
2501
2651
  /* @__PURE__ */ jsx(CustomizerField, { className: "col-span-2", label: labels.globalRadius, disabled, children: /* @__PURE__ */ jsx(
2502
- NativeSelect,
2652
+ SelectInput,
2503
2653
  {
2504
2654
  value: value.theme.radius ?? "8px",
2505
- onChange: (event) => onChange(setThemeField(value, "radius", event.target.value)),
2506
- options: RADIUS_VALUES.map((radius) => ({ value: radius, label: radius })),
2655
+ onChange: (next) => onChange(setThemeField(value, "radius", next)),
2656
+ items: RADIUS_VALUES.map((radius) => ({ value: radius, label: radius })),
2507
2657
  disabled,
2508
- "aria-label": typeof labels.globalRadius === "string" ? labels.globalRadius : "Radius"
2658
+ ariaLabel: typeof labels.globalRadius === "string" ? labels.globalRadius : "Radius"
2509
2659
  }
2510
2660
  ) })
2511
2661
  ] }) }),
@@ -2859,6 +3009,9 @@ var DEFAULT_LABELS = {
2859
3009
  darkMode: "Dark",
2860
3010
  resetField: "Reset",
2861
3011
  resetSection: "Reset section",
3012
+ importTheme: "Import",
3013
+ exportTheme: "Export",
3014
+ invalidThemeFile: "Invalid theme file",
2862
3015
  colorSwatchFallback: "Color",
2863
3016
  defaultOption: "Default",
2864
3017
  themeSection: "Theme",
@@ -2908,12 +3061,12 @@ function ThemeCustomizerThemeTab({
2908
3061
  onChange,
2909
3062
  previewMode,
2910
3063
  onPreviewModeChange,
2911
- showPreviewMode = true,
3064
+ showPreviewMode = false,
2912
3065
  labels,
2913
3066
  disabled
2914
3067
  }) {
2915
3068
  return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3", children: [
2916
- showPreviewMode && /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1.5", children: [
3069
+ showPreviewMode && onPreviewModeChange && /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1.5", children: [
2917
3070
  /* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-muted-foreground", children: labels.previewMode }),
2918
3071
  /* @__PURE__ */ jsx(
2919
3072
  SegmentedControl,
@@ -3144,16 +3297,16 @@ function ThemeCustomizerTypographyTab({
3144
3297
  label: labels.baseSize,
3145
3298
  disabled,
3146
3299
  children: /* @__PURE__ */ jsx(
3147
- NativeSelect,
3300
+ SelectInput,
3148
3301
  {
3149
3302
  value: typography.baseSize ?? "",
3150
- onChange: (e) => handleTypography("baseSize", e.target.value || void 0),
3151
- options: [
3303
+ onChange: (next) => handleTypography("baseSize", next || void 0),
3304
+ items: [
3152
3305
  toOption(labels.defaultOption, ""),
3153
3306
  ...FONT_SIZE_VALUES.map((value2) => ({ value: value2, label: value2 }))
3154
3307
  ],
3155
3308
  disabled,
3156
- "aria-label": typeof labels.baseSize === "string" ? labels.baseSize : "Base size"
3309
+ ariaLabel: typeof labels.baseSize === "string" ? labels.baseSize : "Base size"
3157
3310
  }
3158
3311
  )
3159
3312
  }
@@ -3187,14 +3340,14 @@ function ThemeCustomizerTypographyTab({
3187
3340
  )
3188
3341
  ] }) : null,
3189
3342
  /* @__PURE__ */ jsx(CustomizerField, { label: labels.scale, disabled, children: /* @__PURE__ */ jsx(
3190
- NativeSelect,
3343
+ SelectInput,
3191
3344
  {
3192
3345
  value: typography.scale ?? "",
3193
- onChange: (e) => handleTypography(
3346
+ onChange: (next) => handleTypography(
3194
3347
  "scale",
3195
- e.target.value || void 0
3348
+ next || void 0
3196
3349
  ),
3197
- options: [
3350
+ items: [
3198
3351
  toOption(labels.defaultOption, ""),
3199
3352
  ...SCALE_VALUES.map((o) => ({
3200
3353
  value: o.value,
@@ -3204,33 +3357,33 @@ function ThemeCustomizerTypographyTab({
3204
3357
  }))
3205
3358
  ],
3206
3359
  disabled,
3207
- "aria-label": typeof labels.scale === "string" ? labels.scale : "Scale"
3360
+ ariaLabel: typeof labels.scale === "string" ? labels.scale : "Scale"
3208
3361
  }
3209
3362
  ) }),
3210
3363
  /* @__PURE__ */ jsx(CustomizerField, { label: labels.lineHeight, disabled, children: /* @__PURE__ */ jsx(
3211
- NativeSelect,
3364
+ SelectInput,
3212
3365
  {
3213
3366
  value: typography.lineHeight ?? "",
3214
- onChange: (e) => handleTypography("lineHeight", e.target.value || void 0),
3215
- options: [
3367
+ onChange: (next) => handleTypography("lineHeight", next || void 0),
3368
+ items: [
3216
3369
  toOption(labels.defaultOption, ""),
3217
3370
  ...LINE_HEIGHT_VALUES.map((value2) => ({ value: value2, label: value2 }))
3218
3371
  ],
3219
3372
  disabled,
3220
- "aria-label": typeof labels.lineHeight === "string" ? labels.lineHeight : "Line height"
3373
+ ariaLabel: typeof labels.lineHeight === "string" ? labels.lineHeight : "Line height"
3221
3374
  }
3222
3375
  ) }),
3223
3376
  /* @__PURE__ */ jsx(CustomizerField, { label: labels.letterSpacing, disabled, children: /* @__PURE__ */ jsx(
3224
- NativeSelect,
3377
+ SelectInput,
3225
3378
  {
3226
3379
  value: typography.letterSpacing ?? "",
3227
- onChange: (e) => handleTypography("letterSpacing", e.target.value || void 0),
3228
- options: [
3380
+ onChange: (next) => handleTypography("letterSpacing", next || void 0),
3381
+ items: [
3229
3382
  toOption(labels.defaultOption, ""),
3230
3383
  ...LETTER_SPACING_VALUES.map((value2) => ({ value: value2, label: value2 }))
3231
3384
  ],
3232
3385
  disabled,
3233
- "aria-label": typeof labels.letterSpacing === "string" ? labels.letterSpacing : "Letter spacing"
3386
+ ariaLabel: typeof labels.letterSpacing === "string" ? labels.letterSpacing : "Letter spacing"
3234
3387
  }
3235
3388
  ) })
3236
3389
  ] })
@@ -3267,18 +3420,33 @@ function FontSelect({
3267
3420
  label,
3268
3421
  disabled,
3269
3422
  children: /* @__PURE__ */ jsx(
3270
- NativeSelect,
3423
+ SelectInput,
3271
3424
  {
3272
3425
  value: value ?? "",
3273
- onChange: (e) => onChange(e.target.value || void 0),
3274
- options,
3426
+ onChange: (next) => onChange(next || void 0),
3427
+ items: options,
3275
3428
  disabled,
3276
- "aria-label": typeof label === "string" ? label : "Font"
3429
+ ariaLabel: typeof label === "string" ? label : "Font"
3277
3430
  }
3278
3431
  )
3279
3432
  }
3280
3433
  );
3281
3434
  }
3435
+
3436
+ // src/components/ThemeCustomizer/theme-customizer-file.ts
3437
+ var DEFAULT_THEME_FILE_NAME = "najm-theme.json";
3438
+ function parseThemeFile(content) {
3439
+ return parseNajmDesignConfig(JSON.parse(content));
3440
+ }
3441
+ function stringifyThemeFile(config) {
3442
+ return `${JSON.stringify(config, null, 2)}
3443
+ `;
3444
+ }
3445
+ function normalizeThemeFileName(fileName) {
3446
+ const trimmed = fileName?.trim();
3447
+ if (!trimmed) return DEFAULT_THEME_FILE_NAME;
3448
+ return trimmed.toLowerCase().endsWith(".json") ? trimmed : `${trimmed}.json`;
3449
+ }
3282
3450
  var DEFAULT_TABS = [
3283
3451
  "theme",
3284
3452
  "typography"
@@ -3317,7 +3485,11 @@ function NThemeCustomizer({
3317
3485
  onChange,
3318
3486
  previewMode,
3319
3487
  onPreviewModeChange,
3320
- showPreviewMode = true,
3488
+ showPreviewMode = false,
3489
+ showFileActions = true,
3490
+ showResetAction = true,
3491
+ exportFileName,
3492
+ onImportError,
3321
3493
  showTabs = true,
3322
3494
  tabs,
3323
3495
  fontOptions,
@@ -3325,9 +3497,13 @@ function NThemeCustomizer({
3325
3497
  disabled = false,
3326
3498
  className
3327
3499
  }) {
3500
+ const inheritedMode = useNajmThemeMode();
3501
+ const resolvedPreviewMode = previewMode ?? inheritedMode ?? value.theme.mode ?? "light";
3328
3502
  const visibleTabs = React.useMemo(() => buildTabs(tabs), [tabs]);
3329
3503
  const firstTab = visibleTabs[0] ?? "theme";
3330
3504
  const [activeTab, setActiveTab] = React.useState(TAB_VALUE[firstTab]);
3505
+ const [fileError, setFileError] = React.useState(false);
3506
+ const fileInputRef = React.useRef(null);
3331
3507
  React.useEffect(() => {
3332
3508
  setActiveTab(TAB_VALUE[firstTab]);
3333
3509
  }, [firstTab]);
@@ -3335,6 +3511,9 @@ function NThemeCustomizer({
3335
3511
  const typographyLabel = resolveLabel("typographyTab", labels);
3336
3512
  const resetSectionLabel = resolveLabel("resetSection", labels);
3337
3513
  const resetFieldLabel = resolveLabel("resetField", labels);
3514
+ const importThemeLabel = resolveLabel("importTheme", labels);
3515
+ const exportThemeLabel = resolveLabel("exportTheme", labels);
3516
+ const invalidThemeFileLabel = resolveLabel("invalidThemeFile", labels);
3338
3517
  const defaultOptionLabel = resolveLabel("defaultOption", labels);
3339
3518
  const colorSwatchFallbackLabel = resolveLabel("colorSwatchFallback", labels);
3340
3519
  const tokenLabels = React.useMemo(() => {
@@ -3387,9 +3566,9 @@ function NThemeCustomizer({
3387
3566
  value,
3388
3567
  factoryValue,
3389
3568
  onChange,
3390
- previewMode,
3569
+ previewMode: resolvedPreviewMode,
3391
3570
  onPreviewModeChange,
3392
- showPreviewMode,
3571
+ showPreviewMode: showPreviewMode && Boolean(onPreviewModeChange),
3393
3572
  disabled,
3394
3573
  labels: {
3395
3574
  resetField: resetFieldLabel,
@@ -3492,6 +3671,32 @@ function NThemeCustomizer({
3492
3671
  if (target === TAB_VALUE.theme) handleResetTheme();
3493
3672
  else handleResetTypography();
3494
3673
  };
3674
+ const handleImportFile = async (event) => {
3675
+ const input = event.currentTarget;
3676
+ const file = input.files?.[0];
3677
+ input.value = "";
3678
+ if (!file) return;
3679
+ try {
3680
+ const imported = parseThemeFile(await file.text());
3681
+ setFileError(false);
3682
+ onChange(imported);
3683
+ } catch (cause) {
3684
+ const error = cause instanceof Error ? cause : new Error(String(cause));
3685
+ setFileError(true);
3686
+ onImportError?.(error);
3687
+ }
3688
+ };
3689
+ const handleExportFile = () => {
3690
+ const blob = new Blob([stringifyThemeFile(value)], {
3691
+ type: "application/json"
3692
+ });
3693
+ const url = URL.createObjectURL(blob);
3694
+ const anchor = document.createElement("a");
3695
+ anchor.href = url;
3696
+ anchor.download = normalizeThemeFileName(exportFileName);
3697
+ anchor.click();
3698
+ URL.revokeObjectURL(url);
3699
+ };
3495
3700
  const directContent = items[0]?.content ?? themeContent;
3496
3701
  return /* @__PURE__ */ jsxs(
3497
3702
  "div",
@@ -3518,21 +3723,65 @@ function NThemeCustomizer({
3518
3723
  }
3519
3724
  }
3520
3725
  ) : directContent,
3521
- /* @__PURE__ */ jsx("div", { className: "flex items-center justify-end", children: /* @__PURE__ */ jsxs(
3522
- NButton,
3523
- {
3524
- type: "button",
3525
- variant: "outline",
3526
- size: "sm",
3527
- onClick: handleReset,
3528
- disabled,
3529
- "aria-label": typeof resetSectionLabel === "string" || typeof resetSectionLabel === "number" ? String(resetSectionLabel) : "Reset section",
3530
- children: [
3531
- /* @__PURE__ */ jsx(RotateCcw, { className: "size-3.5" }),
3532
- /* @__PURE__ */ jsx("span", { children: resetSectionLabel })
3533
- ]
3534
- }
3535
- ) })
3726
+ fileError ? /* @__PURE__ */ jsx("p", { role: "alert", className: "text-xs text-destructive", children: invalidThemeFileLabel }) : null,
3727
+ showFileActions || showResetAction ? /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center justify-between gap-2", children: [
3728
+ showFileActions ? /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
3729
+ /* @__PURE__ */ jsx(
3730
+ "input",
3731
+ {
3732
+ ref: fileInputRef,
3733
+ type: "file",
3734
+ accept: ".json,application/json",
3735
+ className: "sr-only",
3736
+ disabled,
3737
+ onChange: (event) => void handleImportFile(event)
3738
+ }
3739
+ ),
3740
+ /* @__PURE__ */ jsxs(
3741
+ NButton,
3742
+ {
3743
+ type: "button",
3744
+ variant: "outline",
3745
+ size: "sm",
3746
+ onClick: () => fileInputRef.current?.click(),
3747
+ disabled,
3748
+ children: [
3749
+ /* @__PURE__ */ jsx(Upload, { className: "size-3.5" }),
3750
+ /* @__PURE__ */ jsx("span", { children: importThemeLabel })
3751
+ ]
3752
+ }
3753
+ ),
3754
+ /* @__PURE__ */ jsxs(
3755
+ NButton,
3756
+ {
3757
+ type: "button",
3758
+ variant: "outline",
3759
+ size: "sm",
3760
+ onClick: handleExportFile,
3761
+ disabled,
3762
+ children: [
3763
+ /* @__PURE__ */ jsx(Download, { className: "size-3.5" }),
3764
+ /* @__PURE__ */ jsx("span", { children: exportThemeLabel })
3765
+ ]
3766
+ }
3767
+ )
3768
+ ] }) : null,
3769
+ showResetAction ? /* @__PURE__ */ jsxs(
3770
+ NButton,
3771
+ {
3772
+ type: "button",
3773
+ variant: "outline",
3774
+ size: "sm",
3775
+ onClick: handleReset,
3776
+ disabled,
3777
+ "aria-label": typeof resetSectionLabel === "string" || typeof resetSectionLabel === "number" ? String(resetSectionLabel) : "Reset section",
3778
+ children: [
3779
+ /* @__PURE__ */ jsx(RotateCcw, { className: "size-3.5" }),
3780
+ /* @__PURE__ */ jsx("span", { children: resetSectionLabel })
3781
+ ]
3782
+ }
3783
+ ) : null
3784
+ ] }) : null
3536
3785
  ]
3537
3786
  }
3538
3787
  );
@@ -4100,7 +4349,7 @@ function Textarea({ className, ...props }) {
4100
4349
  }
4101
4350
  );
4102
4351
  }
4103
- function Label({ className, ...props }) {
4352
+ function Label2({ className, ...props }) {
4104
4353
  return /* @__PURE__ */ jsx(
4105
4354
  LabelPrimitive.Root,
4106
4355
  {
@@ -5781,94 +6030,34 @@ function DropdownMenuSeparator({ className, ...props }) {
5781
6030
  function DropdownMenuShortcut({ className, ...props }) {
5782
6031
  return /* @__PURE__ */ jsx("span", { "data-slot": "dropdown-menu-shortcut", className: cn("text-muted-foreground ml-auto text-xs tracking-widest", className), ...props });
5783
6032
  }
5784
- function Select({ ...props }) {
5785
- return /* @__PURE__ */ jsx(SelectPrimitive.Root, { "data-slot": "select", ...props });
5786
- }
5787
- function SelectGroup({ ...props }) {
5788
- return /* @__PURE__ */ jsx(SelectPrimitive.Group, { "data-slot": "select-group", ...props });
5789
- }
5790
- function SelectValue({ ...props }) {
5791
- return /* @__PURE__ */ jsx(SelectPrimitive.Value, { "data-slot": "select-value", ...props });
5792
- }
5793
- function SelectTrigger({ className, children, ...props }) {
5794
- return /* @__PURE__ */ jsxs(
5795
- SelectPrimitive.Trigger,
5796
- {
5797
- "data-slot": "select-trigger",
5798
- className: cn(
5799
- "border-input data-[placeholder]:text-muted-foreground [&_svg:not([class*='text-'])]:text-muted-foreground flex h-9 w-full cursor-pointer items-center justify-between gap-2 rounded-md border bg-transparent px-3 py-2 text-sm whitespace-nowrap shadow-xs transition-[color,box-shadow] outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-1.5 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
5800
- className
5801
- ),
5802
- ...props,
5803
- children: [
5804
- children,
5805
- /* @__PURE__ */ jsx(SelectPrimitive.Icon, { asChild: true, children: /* @__PURE__ */ jsx(ChevronDownIcon, { className: "size-4 opacity-50" }) })
5806
- ]
5807
- }
5808
- );
5809
- }
5810
- function SelectScrollUpButton({ className, ...props }) {
5811
- return /* @__PURE__ */ jsx(SelectPrimitive.ScrollUpButton, { "data-slot": "select-scroll-up-button", className: cn("flex cursor-default items-center justify-center py-1", className), ...props, children: /* @__PURE__ */ jsx(ChevronUpIcon, { className: "size-4" }) });
5812
- }
5813
- function SelectScrollDownButton({ className, ...props }) {
5814
- return /* @__PURE__ */ jsx(SelectPrimitive.ScrollDownButton, { "data-slot": "select-scroll-down-button", className: cn("flex cursor-default items-center justify-center py-1", className), ...props, children: /* @__PURE__ */ jsx(ChevronDownIcon, { className: "size-4" }) });
5815
- }
5816
- function SelectContent({ className, children, position = "popper", style, ...props }) {
5817
- const container = React.useContext(NajmThemeContainerCtx);
5818
- const recipe = useNajmComponentStyle("select");
5819
- const contentSlot = recipe?.slots?.content;
5820
- const borderWidth = contentSlot?.borderWidth ?? recipe?.borderWidth;
5821
- const radius = resolveRadiusValue(contentSlot?.radius ?? recipe?.radius);
5822
- const recipeStyle = {
5823
- ...radius ? { borderRadius: radius } : {},
5824
- ...borderWidth !== void 0 ? {
5825
- borderWidth,
5826
- borderStyle: borderWidth === "0" ? "none" : "solid",
5827
- borderColor: "var(--border)"
5828
- } : {}
5829
- };
5830
- useNajmPortalLayerStyles();
5831
- return /* @__PURE__ */ jsx(SelectPrimitive.Portal, { container: container ?? void 0, children: /* @__PURE__ */ jsxs(
5832
- SelectPrimitive.Content,
5833
- {
5834
- "data-slot": "select-content",
5835
- className: cn(
5836
- "bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 relative z-[10000] max-h-(--radix-select-content-available-height) min-w-[8rem] overflow-hidden rounded-md shadow-md",
5837
- position === "popper" && "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1 w-[var(--radix-select-trigger-width)]",
5838
- contentSlot?.className,
5839
- className
6033
+ var NativeSelect = React.forwardRef(
6034
+ ({ className, options, placeholder, value, ...props }, ref) => {
6035
+ const hasValue = value !== void 0 && value !== "";
6036
+ return /* @__PURE__ */ jsxs("div", { className: "relative", children: [
6037
+ /* @__PURE__ */ jsxs(
6038
+ "select",
6039
+ {
6040
+ ref,
6041
+ value,
6042
+ className: cn(
6043
+ "flex h-10 w-full appearance-none rounded-md border border-input bg-card px-3 py-1.5 pr-8 text-sm text-foreground shadow-sm transition-colors",
6044
+ "hover:border-muted-foreground/30 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
6045
+ "disabled:cursor-not-allowed disabled:opacity-50",
6046
+ !hasValue && "text-muted-foreground",
6047
+ className
6048
+ ),
6049
+ ...props,
6050
+ children: [
6051
+ placeholder && /* @__PURE__ */ jsx("option", { value: "", disabled: true, children: placeholder }),
6052
+ options.map((opt) => /* @__PURE__ */ jsx("option", { value: opt.value, children: opt.label }, opt.value))
6053
+ ]
6054
+ }
5840
6055
  ),
5841
- style: { ...recipeStyle, ...style },
5842
- position,
5843
- ...props,
5844
- children: [
5845
- /* @__PURE__ */ jsx(SelectScrollUpButton, {}),
5846
- /* @__PURE__ */ jsx(SelectPrimitive.Viewport, { className: cn("p-1", position === "popper" && "h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]"), children }),
5847
- /* @__PURE__ */ jsx(SelectScrollDownButton, {})
5848
- ]
5849
- }
5850
- ) });
5851
- }
5852
- function SelectLabel({ className, ...props }) {
5853
- return /* @__PURE__ */ jsx(SelectPrimitive.Label, { "data-slot": "select-label", className: cn("text-muted-foreground px-2 py-1.5 text-xs", className), ...props });
5854
- }
5855
- function SelectItem({ className, children, ...props }) {
5856
- return /* @__PURE__ */ jsxs(
5857
- SelectPrimitive.Item,
5858
- {
5859
- "data-slot": "select-item",
5860
- className: cn("focus:bg-accent focus:text-accent-foreground [&_svg:not([class*='text-'])]:text-muted-foreground relative flex w-full cursor-pointer items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-none select-none data-[disabled]:pointer-events-none data-[disabled]:cursor-not-allowed data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2", className),
5861
- ...props,
5862
- children: [
5863
- /* @__PURE__ */ jsx("span", { className: "absolute right-2 flex size-3.5 items-center justify-center", children: /* @__PURE__ */ jsx(SelectPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx(CheckIcon, { className: "size-4" }) }) }),
5864
- /* @__PURE__ */ jsx(SelectPrimitive.ItemText, { children })
5865
- ]
5866
- }
5867
- );
5868
- }
5869
- function SelectSeparator({ className, ...props }) {
5870
- return /* @__PURE__ */ jsx(SelectPrimitive.Separator, { "data-slot": "select-separator", className: cn("bg-muted pointer-events-none -mx-1 my-1 h-px", className), ...props });
5871
- }
6056
+ /* @__PURE__ */ jsx(ChevronDown, { className: "pointer-events-none absolute right-2 top-1/2 size-4 -translate-y-1/2 text-muted-foreground" })
6057
+ ] });
6058
+ }
6059
+ );
6060
+ NativeSelect.displayName = "NativeSelect";
5872
6061
  function Checkbox({ className, ...props }) {
5873
6062
  return /* @__PURE__ */ jsx(
5874
6063
  CheckboxPrimitive.Root,
@@ -6598,7 +6787,7 @@ function FormItem({ className, ...props }) {
6598
6787
  }
6599
6788
  function FormLabel({ className, ...props }) {
6600
6789
  const { error, formItemId } = useFormField();
6601
- return /* @__PURE__ */ jsx(Label, { "data-slot": "form-label", "data-error": !!error, className: cn("data-[error=true]:text-destructive", className), htmlFor: formItemId, ...props });
6790
+ return /* @__PURE__ */ jsx(Label2, { "data-slot": "form-label", "data-error": !!error, className: cn("data-[error=true]:text-destructive", className), htmlFor: formItemId, ...props });
6602
6791
  }
6603
6792
  function FormControl({ ...props }) {
6604
6793
  const { error, formItemId, formDescriptionId, formMessageId } = useFormField();
@@ -7351,14 +7540,14 @@ function NSectionInfo({
7351
7540
  const displayValue = isTruncated ? truncateByCharacters(stringValue, maxChars) : value;
7352
7541
  return /* @__PURE__ */ jsxs("div", { className: cn("flex items-center gap-2", className), children: [
7353
7542
  Icon2 && /* @__PURE__ */ jsx(Icon2, { className: cn("w-4 h-4", iconColor) }),
7354
- /* @__PURE__ */ jsxs(Label, { className: "text-sm text-muted-foreground", children: [
7543
+ /* @__PURE__ */ jsxs(Label2, { className: "text-sm text-muted-foreground", children: [
7355
7544
  label,
7356
7545
  ":"
7357
7546
  ] }),
7358
7547
  isTruncated ? /* @__PURE__ */ jsxs(Tooltip, { children: [
7359
- /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(Label, { className: cn("text-sm cursor-help", valueColor), children: displayValue }) }),
7548
+ /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(Label2, { className: cn("text-sm cursor-help", valueColor), children: displayValue }) }),
7360
7549
  /* @__PURE__ */ jsx(TooltipContent, { children: /* @__PURE__ */ jsx("p", { className: "max-w-xs", children: stringValue }) })
7361
- ] }) : /* @__PURE__ */ jsx(Label, { className: cn("text-sm", valueColor), children: displayValue })
7550
+ ] }) : /* @__PURE__ */ jsx(Label2, { className: cn("text-sm", valueColor), children: displayValue })
7362
7551
  ] });
7363
7552
  }
7364
7553
  function NSection({
@@ -7372,7 +7561,7 @@ function NSection({
7372
7561
  return /* @__PURE__ */ jsxs("div", { className: cn(background, "flex flex-col gap-1 rounded-lg p-4", className), children: [
7373
7562
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 mb-3", children: [
7374
7563
  /* @__PURE__ */ jsx(Icon2, { className: cn("w-5 h-5", iconColor) }),
7375
- /* @__PURE__ */ jsx(Label, { className: "text-base font-medium text-foreground", children: title })
7564
+ /* @__PURE__ */ jsx(Label2, { className: "text-base font-medium text-foreground", children: title })
7376
7565
  ] }),
7377
7566
  /* @__PURE__ */ jsx("div", { className: "space-y-1", children })
7378
7567
  ] });
@@ -7461,10 +7650,10 @@ function NSectionHeaderRoot({
7461
7650
  );
7462
7651
  }
7463
7652
  function NSectionHeaderTitle({ children, className }) {
7464
- return /* @__PURE__ */ jsx(Label, { className: cn("text-2xl font-bold text-foreground block", className), children });
7653
+ return /* @__PURE__ */ jsx(Label2, { className: cn("text-2xl font-bold text-foreground block", className), children });
7465
7654
  }
7466
7655
  function NSectionHeaderSubtitle({ children, className }) {
7467
- return /* @__PURE__ */ jsx(Label, { className: cn("text-muted-foreground block", className), children });
7656
+ return /* @__PURE__ */ jsx(Label2, { className: cn("text-muted-foreground block", className), children });
7468
7657
  }
7469
7658
  function NSectionHeaderContent({ children, className }) {
7470
7659
  return /* @__PURE__ */ jsx("div", { className: cn("mt-3", className), children });
@@ -8776,15 +8965,6 @@ function NFolderIcon({ size = "md", className }) {
8776
8965
  const iconSize = size === "xl" ? 72 : size === "lg" ? 56 : size === "md" ? 28 : 18;
8777
8966
  return /* @__PURE__ */ jsx("span", { className: cn(dim, "inline-flex shrink-0 items-center justify-center", className), children: /* @__PURE__ */ jsx(Folder, { size: iconSize, className: "text-sky-500", fill: "currentColor", strokeWidth: 1.5 }) });
8778
8967
  }
8779
- function getIconColorProps(iconColor, baseClassName = "") {
8780
- if (!iconColor) return { className: cn(baseClassName, "text-muted-foreground"), style: {} };
8781
- if (iconColor.startsWith("text-")) return { className: cn(baseClassName, iconColor), style: {} };
8782
- return { className: baseClassName, style: { color: iconColor } };
8783
- }
8784
- function resolveIcon(icon) {
8785
- if (!icon) return null;
8786
- return /* @__PURE__ */ jsx(NIcon, { icon, size: 16 });
8787
- }
8788
8968
  var TextInput = ({ value, onChange, placeholder = "", icon, showIcon = true, iconColor, className = "", variant = "default", status = "default", bordered, borderColor, disabled = false, ...props }) => {
8789
8969
  const shouldDisplayIcon = Boolean(icon) && showIcon;
8790
8970
  const iconProps = getIconColorProps(iconColor, "h-4 w-4");
@@ -8839,41 +9019,10 @@ var TextAreaInput = ({ value, onChange, placeholder = "", className = "", varian
8839
9019
  }
8840
9020
  );
8841
9021
  };
8842
- function renderItems(items) {
8843
- return items.map((item) => {
8844
- const value = typeof item === "string" ? item : item.value;
8845
- const label = typeof item === "string" ? item : item.label;
8846
- return /* @__PURE__ */ jsx(SelectItem, { value, children: label }, value);
8847
- });
8848
- }
8849
- var SelectInput = ({ placeholder = "", value, onChange, icon, showIcon = true, iconColor, items, className = "", dropdownClassName, variant = "default", status = "default", bordered, borderColor, disabled = false }) => {
8850
- const shouldDisplayIcon = Boolean(icon) && showIcon && !value;
8851
- const iconProps = getIconColorProps(iconColor, "h-4 w-4");
8852
- const displayLabel = value ? (() => {
8853
- const found = items.find((i) => typeof i === "string" ? i === value : i.value === value);
8854
- return typeof found === "string" ? found : found?.label ?? value;
8855
- })() : "";
8856
- return /* @__PURE__ */ jsxs("div", { className: cn("relative", className), children: [
8857
- /* @__PURE__ */ jsxs(BaseInput, { variant, status, bordered, borderColor, className: "pointer-events-none", children: [
8858
- shouldDisplayIcon && /* @__PURE__ */ jsx("span", { className: iconProps.className, style: iconProps.style, children: resolveIcon(icon) }),
8859
- /* @__PURE__ */ jsx("span", { className: cn("flex-1 truncate text-sm", !displayLabel && "text-muted-foreground"), children: displayLabel || placeholder }),
8860
- /* @__PURE__ */ jsx(ChevronDown, { className: "h-4 w-4 shrink-0 opacity-50" })
8861
- ] }),
8862
- /* @__PURE__ */ jsxs(Select, { onValueChange: onChange, value: String(value || ""), disabled, children: [
8863
- /* @__PURE__ */ jsx(
8864
- SelectTrigger,
8865
- {
8866
- className: "absolute inset-0 w-full h-full opacity-0",
8867
- disabled,
8868
- "aria-label": placeholder || "Select"
8869
- }
8870
- ),
8871
- /* @__PURE__ */ jsx(SelectContent, { className: dropdownClassName, children: renderItems(items) })
8872
- ] }, String(value))
8873
- ] });
8874
- };
8875
9022
  var ComboboxInput = ({ placeholder = "Select...", searchPlaceholder = "Search...", emptyMessage = "No results found.", value, onChange, icon, showIcon = true, iconColor, items = [], className = "", variant = "default", status = "default", bordered, borderColor, disabled = false, allowFreeText = false }) => {
8876
9023
  const [open, setOpen] = useState(false);
9024
+ const triggerRef = React__default.useRef(null);
9025
+ const pointerDismissedRef = React__default.useRef(false);
8877
9026
  const [query, setQuery] = useState("");
8878
9027
  const normalizedItems = items.map((item) => typeof item === "string" ? { value: item, label: item } : item);
8879
9028
  const selectedItem = normalizedItems.find((item) => item.value === value);
@@ -8892,47 +9041,82 @@ var ComboboxInput = ({ placeholder = "Select...", searchPlaceholder = "Search...
8892
9041
  setOpen(o);
8893
9042
  if (!o) setQuery("");
8894
9043
  }, children: [
8895
- /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, disabled, children: /* @__PURE__ */ jsxs(BaseInput, { variant, status, bordered, borderColor, className: cn("cursor-pointer", className), children: [
8896
- shouldDisplayIcon && /* @__PURE__ */ jsx("span", { className: iconProps.className, style: iconProps.style, children: resolveIcon(icon) }),
8897
- /* @__PURE__ */ jsx("span", { className: cn("flex-1 truncate text-sm", !displayLabel && "text-muted-foreground"), children: displayLabel || placeholder }),
8898
- /* @__PURE__ */ jsx(ChevronsUpDown, { className: "h-4 w-4 shrink-0 opacity-50" })
8899
- ] }) }),
8900
- /* @__PURE__ */ jsx(PopoverContent, { className: "w-[var(--radix-popover-trigger-width)] p-0", align: "start", children: /* @__PURE__ */ jsxs(Command, { children: [
8901
- /* @__PURE__ */ jsx(
8902
- CommandInput,
8903
- {
8904
- placeholder: searchPlaceholder,
8905
- className: "h-9",
8906
- value: query,
8907
- onValueChange: setQuery,
8908
- onKeyDown: (e) => {
8909
- if (e.key === "Enter" && showFreeTextOption) {
8910
- e.preventDefault();
8911
- commit(trimmedQuery);
9044
+ /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, disabled, children: /* @__PURE__ */ jsxs(
9045
+ BaseInput,
9046
+ {
9047
+ ref: triggerRef,
9048
+ variant,
9049
+ status,
9050
+ bordered,
9051
+ borderColor,
9052
+ role: "combobox",
9053
+ tabIndex: disabled ? -1 : 0,
9054
+ "aria-expanded": open,
9055
+ className: cn(
9056
+ "cursor-pointer outline-none data-[state=open]:border-ring",
9057
+ className
9058
+ ),
9059
+ children: [
9060
+ shouldDisplayIcon && /* @__PURE__ */ jsx("span", { className: iconProps.className, style: iconProps.style, children: resolveIcon(icon) }),
9061
+ /* @__PURE__ */ jsx("span", { className: cn("flex-1 truncate text-sm", !displayLabel && "text-muted-foreground"), children: displayLabel || placeholder }),
9062
+ /* @__PURE__ */ jsx(ChevronsUpDown, { className: "h-4 w-4 shrink-0 opacity-50" })
9063
+ ]
9064
+ }
9065
+ ) }),
9066
+ /* @__PURE__ */ jsx(
9067
+ PopoverContent,
9068
+ {
9069
+ className: "w-[var(--radix-popover-trigger-width)] p-0",
9070
+ align: "start",
9071
+ onPointerDownOutside: () => {
9072
+ pointerDismissedRef.current = true;
9073
+ },
9074
+ onCloseAutoFocus: (event) => {
9075
+ if (!pointerDismissedRef.current) return;
9076
+ event.preventDefault();
9077
+ pointerDismissedRef.current = false;
9078
+ triggerRef.current?.blur();
9079
+ },
9080
+ children: /* @__PURE__ */ jsxs(Command, { children: [
9081
+ /* @__PURE__ */ jsx(
9082
+ CommandInput,
9083
+ {
9084
+ placeholder: searchPlaceholder,
9085
+ className: "h-9",
9086
+ value: query,
9087
+ onValueChange: setQuery,
9088
+ onKeyDown: (e) => {
9089
+ if (e.key === "Enter" && showFreeTextOption) {
9090
+ e.preventDefault();
9091
+ commit(trimmedQuery);
9092
+ }
9093
+ }
8912
9094
  }
8913
- }
8914
- }
8915
- ),
8916
- /* @__PURE__ */ jsxs(CommandList, { children: [
8917
- /* @__PURE__ */ jsx(CommandEmpty, { children: emptyMessage }),
8918
- /* @__PURE__ */ jsxs(CommandGroup, { children: [
8919
- showFreeTextOption && /* @__PURE__ */ jsxs(CommandItem, { value: trimmedQuery, onSelect: () => commit(trimmedQuery), className: "cursor-pointer", children: [
8920
- /* @__PURE__ */ jsx(Check, { className: "mr-2 h-4 w-4 opacity-0" }),
8921
- 'Use "',
8922
- trimmedQuery,
8923
- '"'
8924
- ] }, "__free_text__"),
8925
- normalizedItems.map((item) => /* @__PURE__ */ jsxs(CommandItem, { value: item.label, keywords: [item.value, item.label], onSelect: () => commit(value === item.value ? "" : item.value), className: "cursor-pointer", children: [
8926
- /* @__PURE__ */ jsx(Check, { className: cn("mr-2 h-4 w-4", value === item.value ? "opacity-100" : "opacity-0") }),
8927
- item.label
8928
- ] }, item.value))
9095
+ ),
9096
+ /* @__PURE__ */ jsxs(CommandList, { children: [
9097
+ /* @__PURE__ */ jsx(CommandEmpty, { children: emptyMessage }),
9098
+ /* @__PURE__ */ jsxs(CommandGroup, { children: [
9099
+ showFreeTextOption && /* @__PURE__ */ jsxs(CommandItem, { value: trimmedQuery, onSelect: () => commit(trimmedQuery), className: "cursor-pointer", children: [
9100
+ /* @__PURE__ */ jsx(Check, { className: "mr-2 h-4 w-4 opacity-0" }),
9101
+ 'Use "',
9102
+ trimmedQuery,
9103
+ '"'
9104
+ ] }, "__free_text__"),
9105
+ normalizedItems.map((item) => /* @__PURE__ */ jsxs(CommandItem, { value: item.label, keywords: [item.value, item.label], onSelect: () => commit(value === item.value ? "" : item.value), className: "cursor-pointer", children: [
9106
+ /* @__PURE__ */ jsx(Check, { className: cn("mr-2 h-4 w-4", value === item.value ? "opacity-100" : "opacity-0") }),
9107
+ item.label
9108
+ ] }, item.value))
9109
+ ] })
9110
+ ] })
8929
9111
  ] })
8930
- ] })
8931
- ] }) })
9112
+ }
9113
+ )
8932
9114
  ] });
8933
9115
  };
8934
9116
  var MultiSelectInput = ({ placeholder = "Select items...", value = [], onChange, icon, showIcon = true, iconColor, items, className = "", variant = "default", status = "default", bordered, borderColor, disabled = false, searchPlaceholder = "Search...", emptyMessage = "No items found.", maxDisplay = 3, showSearch = true }) => {
8935
9117
  const [open, setOpen] = useState(false);
9118
+ const triggerRef = React__default.useRef(null);
9119
+ const pointerDismissedRef = React__default.useRef(false);
8936
9120
  const shouldDisplayIcon = Boolean(icon) && showIcon && value.length === 0;
8937
9121
  const iconProps = getIconColorProps(iconColor, "h-4 w-4");
8938
9122
  const handleSelect = (itemValue) => {
@@ -8945,37 +9129,71 @@ var MultiSelectInput = ({ placeholder = "Select items...", value = [], onChange,
8945
9129
  const displayedItems = value.slice(0, maxDisplay);
8946
9130
  const remainingCount = value.length - maxDisplay;
8947
9131
  return /* @__PURE__ */ jsxs(Popover, { open, onOpenChange: setOpen, children: [
8948
- /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, disabled, children: /* @__PURE__ */ jsxs(BaseInput, { variant, status, bordered, borderColor, className: cn("gap-2 cursor-pointer", className, disabled && "cursor-not-allowed opacity-50"), children: [
8949
- shouldDisplayIcon && /* @__PURE__ */ jsx("span", { className: iconProps.className, style: iconProps.style, children: resolveIcon(icon) }),
8950
- /* @__PURE__ */ jsx("div", { className: "flex items-center gap-1 flex-1 overflow-hidden", children: value.length === 0 ? /* @__PURE__ */ jsx("span", { className: "text-muted-foreground text-sm", children: placeholder }) : /* @__PURE__ */ jsxs(Fragment, { children: [
8951
- displayedItems.map((itemValue) => /* @__PURE__ */ jsxs(Badge, { variant: "secondary", className: "text-xs px-2 py-0.5 gap-1", children: [
8952
- getItemLabel(itemValue),
8953
- !disabled && /* @__PURE__ */ jsx("button", { type: "button", onClick: (e) => {
8954
- e.stopPropagation();
8955
- onChange(value.filter((v) => v !== itemValue));
8956
- }, className: "ml-1 hover:text-destructive", children: /* @__PURE__ */ jsx(X, { className: "h-3 w-3" }) })
8957
- ] }, itemValue)),
8958
- remainingCount > 0 && /* @__PURE__ */ jsxs(Badge, { variant: "secondary", className: "text-xs px-2 py-0.5", children: [
8959
- "+",
8960
- remainingCount,
8961
- " more"
9132
+ /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, disabled, children: /* @__PURE__ */ jsxs(
9133
+ BaseInput,
9134
+ {
9135
+ ref: triggerRef,
9136
+ variant,
9137
+ status,
9138
+ bordered,
9139
+ borderColor,
9140
+ role: "combobox",
9141
+ tabIndex: disabled ? -1 : 0,
9142
+ "aria-expanded": open,
9143
+ className: cn(
9144
+ "gap-2 cursor-pointer outline-none data-[state=open]:border-ring",
9145
+ className,
9146
+ disabled && "cursor-not-allowed opacity-50"
9147
+ ),
9148
+ children: [
9149
+ shouldDisplayIcon && /* @__PURE__ */ jsx("span", { className: iconProps.className, style: iconProps.style, children: resolveIcon(icon) }),
9150
+ /* @__PURE__ */ jsx("div", { className: "flex items-center gap-1 flex-1 overflow-hidden", children: value.length === 0 ? /* @__PURE__ */ jsx("span", { className: "text-muted-foreground text-sm", children: placeholder }) : /* @__PURE__ */ jsxs(Fragment, { children: [
9151
+ displayedItems.map((itemValue) => /* @__PURE__ */ jsxs(Badge, { variant: "secondary", className: "text-xs px-2 py-0.5 gap-1", children: [
9152
+ getItemLabel(itemValue),
9153
+ !disabled && /* @__PURE__ */ jsx("button", { type: "button", onClick: (e) => {
9154
+ e.stopPropagation();
9155
+ onChange(value.filter((v) => v !== itemValue));
9156
+ }, className: "ml-1 hover:text-destructive", children: /* @__PURE__ */ jsx(X, { className: "h-3 w-3" }) })
9157
+ ] }, itemValue)),
9158
+ remainingCount > 0 && /* @__PURE__ */ jsxs(Badge, { variant: "secondary", className: "text-xs px-2 py-0.5", children: [
9159
+ "+",
9160
+ remainingCount,
9161
+ " more"
9162
+ ] })
9163
+ ] }) }),
9164
+ open ? /* @__PURE__ */ jsx(ChevronUp, { className: "h-4 w-4 text-muted-foreground ml-2 shrink-0" }) : /* @__PURE__ */ jsx(ChevronDown, { className: "h-4 w-4 text-muted-foreground ml-2 shrink-0" })
9165
+ ]
9166
+ }
9167
+ ) }),
9168
+ /* @__PURE__ */ jsx(
9169
+ PopoverContent,
9170
+ {
9171
+ className: "w-[var(--radix-popover-trigger-width)] p-0",
9172
+ align: "start",
9173
+ onPointerDownOutside: () => {
9174
+ pointerDismissedRef.current = true;
9175
+ },
9176
+ onCloseAutoFocus: (event) => {
9177
+ if (!pointerDismissedRef.current) return;
9178
+ event.preventDefault();
9179
+ pointerDismissedRef.current = false;
9180
+ triggerRef.current?.blur();
9181
+ },
9182
+ children: /* @__PURE__ */ jsxs(Command, { children: [
9183
+ showSearch && /* @__PURE__ */ jsx(CommandInput, { placeholder: searchPlaceholder, className: "h-9" }),
9184
+ /* @__PURE__ */ jsx(CommandEmpty, { children: emptyMessage }),
9185
+ /* @__PURE__ */ jsx(CommandGroup, { className: "max-h-[300px] najm-overlay-scroll-y", children: items.map((item) => {
9186
+ const itemValue = typeof item === "string" ? item : item.value;
9187
+ const itemLabel = typeof item === "string" ? item : item.label;
9188
+ const isSelected = value.includes(itemValue);
9189
+ return /* @__PURE__ */ jsxs(CommandItem, { onSelect: () => handleSelect(itemValue), className: "flex items-center gap-2 cursor-pointer", children: [
9190
+ /* @__PURE__ */ jsx(Checkbox, { checked: isSelected, onCheckedChange: () => handleSelect(itemValue), className: "pointer-events-none" }),
9191
+ /* @__PURE__ */ jsx("span", { className: "flex-1", children: itemLabel })
9192
+ ] }, itemValue);
9193
+ }) })
8962
9194
  ] })
8963
- ] }) }),
8964
- open ? /* @__PURE__ */ jsx(ChevronUp, { className: "h-4 w-4 text-muted-foreground ml-2 shrink-0" }) : /* @__PURE__ */ jsx(ChevronDown, { className: "h-4 w-4 text-muted-foreground ml-2 shrink-0" })
8965
- ] }) }),
8966
- /* @__PURE__ */ jsx(PopoverContent, { className: "w-[var(--radix-popover-trigger-width)] p-0", align: "start", children: /* @__PURE__ */ jsxs(Command, { children: [
8967
- showSearch && /* @__PURE__ */ jsx(CommandInput, { placeholder: searchPlaceholder, className: "h-9" }),
8968
- /* @__PURE__ */ jsx(CommandEmpty, { children: emptyMessage }),
8969
- /* @__PURE__ */ jsx(CommandGroup, { className: "max-h-[300px] najm-overlay-scroll-y", children: items.map((item) => {
8970
- const itemValue = typeof item === "string" ? item : item.value;
8971
- const itemLabel = typeof item === "string" ? item : item.label;
8972
- const isSelected = value.includes(itemValue);
8973
- return /* @__PURE__ */ jsxs(CommandItem, { onSelect: () => handleSelect(itemValue), className: "flex items-center gap-2 cursor-pointer", children: [
8974
- /* @__PURE__ */ jsx(Checkbox, { checked: isSelected, onCheckedChange: () => handleSelect(itemValue), className: "pointer-events-none" }),
8975
- /* @__PURE__ */ jsx("span", { className: "flex-1", children: itemLabel })
8976
- ] }, itemValue);
8977
- }) })
8978
- ] }) })
9195
+ }
9196
+ )
8979
9197
  ] });
8980
9198
  };
8981
9199
  var layoutVariants = cva("flex items-start", { variants: { layout: { column: "flex-col gap-4", row: "flex-row gap-7" } }, defaultVariants: { layout: "row" } });
@@ -8984,14 +9202,14 @@ var RadioGroupInput = ({ value, onChange, className = "", variant = "default", s
8984
9202
  const itemLabel = typeof item === "string" ? item : item.label;
8985
9203
  return /* @__PURE__ */ jsxs("div", { className: "flex items-center space-y-0", children: [
8986
9204
  /* @__PURE__ */ jsx(RadioGroupItem, { value: itemValue }),
8987
- /* @__PURE__ */ jsx(Label, { className: "text-sm font-normal peer-disabled:opacity-70 ml-1", children: itemLabel })
9205
+ /* @__PURE__ */ jsx(Label2, { className: "text-sm font-normal peer-disabled:opacity-70 ml-1", children: itemLabel })
8988
9206
  ] }, itemValue);
8989
9207
  }) }) });
8990
9208
  var CheckboxInput = ({ value, onChange, helper, label, checkboxClassName, className, variant = "default", status = "default", bordered, borderColor }) => /* @__PURE__ */ jsxs(BaseInput, { variant, status, bordered, borderColor, className: cn("flex gap-2 items-center", className), children: [
8991
9209
  /* @__PURE__ */ jsx(Checkbox, { checked: value, onCheckedChange: onChange, className: cn("cursor-pointer transition-colors duration-200 border-primary", checkboxClassName) }),
8992
9210
  /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
8993
- /* @__PURE__ */ jsx(Label, { className: "cursor-pointer text-muted-foreground", onClick: () => onChange(!value), children: label }),
8994
- helper && /* @__PURE__ */ jsx(Label, { className: "text-xs text-muted-foreground", children: helper })
9211
+ /* @__PURE__ */ jsx(Label2, { className: "cursor-pointer text-muted-foreground", onClick: () => onChange(!value), children: label }),
9212
+ helper && /* @__PURE__ */ jsx(Label2, { className: "text-xs text-muted-foreground", children: helper })
8995
9213
  ] })
8996
9214
  ] });
8997
9215
  var layoutVariants2 = cva("flex items-start", {
@@ -9038,11 +9256,11 @@ function CheckboxGroupInput({
9038
9256
  }
9039
9257
  var SwitchInput = ({ value, onChange, label = "", helper, className = "", variant = "default", status = "default", bordered, borderColor, icon, showIcon = true, iconPosition = "label", iconColor }) => /* @__PURE__ */ jsxs(BaseInput, { variant, status, bordered, borderColor, className: cn("gap-2 justify-between items-center", className), children: [
9040
9258
  /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
9041
- /* @__PURE__ */ jsxs(Label, { className: "flex items-center gap-2", children: [
9259
+ /* @__PURE__ */ jsxs(Label2, { className: "flex items-center gap-2", children: [
9042
9260
  iconPosition === "label" && icon && showIcon && /* @__PURE__ */ jsx("span", { className: "w-4 h-4", children: resolveIcon(icon) }),
9043
9261
  label
9044
9262
  ] }),
9045
- helper && /* @__PURE__ */ jsx(Label, { className: "text-xs text-muted-foreground", children: helper })
9263
+ helper && /* @__PURE__ */ jsx(Label2, { className: "text-xs text-muted-foreground", children: helper })
9046
9264
  ] }),
9047
9265
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
9048
9266
  iconPosition === "input" && icon && showIcon && /* @__PURE__ */ jsx("span", { className: "w-4 h-4", children: resolveIcon(icon) }),
@@ -9055,7 +9273,7 @@ var DateInput = ({ value, onChange, placeholder = "Pick a date", className = "",
9055
9273
  const toDate = (val) => typeof val === "string" ? parseISO(val) : val;
9056
9274
  return /* @__PURE__ */ jsxs(BaseInput, { variant, status, bordered, borderColor, className, children: [
9057
9275
  /* @__PURE__ */ jsxs(Popover, { children: [
9058
- /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx("div", { className: "w-full flex items-center cursor-pointer gap-2 justify-start text-left font-normal", children: /* @__PURE__ */ jsx(Label, { className: cn("cursor-pointer", value ? "text-foreground" : "text-muted-foreground"), children: value ? format(toDate(value), "PPP") : placeholder }) }) }),
9276
+ /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx("div", { className: "w-full flex items-center cursor-pointer gap-2 justify-start text-left font-normal", children: /* @__PURE__ */ jsx(Label2, { className: cn("cursor-pointer", value ? "text-foreground" : "text-muted-foreground"), children: value ? format(toDate(value), "PPP") : placeholder }) }) }),
9059
9277
  /* @__PURE__ */ jsx(PopoverContent, { className: "w-auto p-0", align: "start", children: /* @__PURE__ */ jsx(Calendar, { mode: "single", selected: toDate(value), onSelect: (date) => onChange(toDateString(date)), captionLayout: "dropdown" }) })
9060
9278
  ] }),
9061
9279
  !icon && showIcon && /* @__PURE__ */ jsx(Calendar$1, { className: iconProps.className, style: iconProps.style })
@@ -9080,9 +9298,9 @@ var FileInput = ({ value, onChange, placeholder = "No file chosen", icon, showIc
9080
9298
  /* @__PURE__ */ jsx("input", { type: "file", ref: fileInputRef, onChange: (e) => onChange(e.target.files?.[0] || null), className: "hidden" }),
9081
9299
  /* @__PURE__ */ jsxs("div", { className: "bg-muted flex h-full items-center px-3", children: [
9082
9300
  showIcon && (icon ? /* @__PURE__ */ jsx("span", { className: iconProps.className, style: iconProps.style, children: resolveIcon(icon) }) : /* @__PURE__ */ jsx(FileUp, { className: cn(iconProps.className) })),
9083
- /* @__PURE__ */ jsx(Label, { className: "flex cursor-pointer h-full justify-center items-center px-2 text-muted-foreground", children: "Choose File" })
9301
+ /* @__PURE__ */ jsx(Label2, { className: "flex cursor-pointer h-full justify-center items-center px-2 text-muted-foreground", children: "Choose File" })
9084
9302
  ] }),
9085
- /* @__PURE__ */ jsx(Label, { className: "ml-2 flex-1 text-foreground", children: displayFilename() || /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: placeholder }) })
9303
+ /* @__PURE__ */ jsx(Label2, { className: "ml-2 flex-1 text-foreground", children: displayFilename() || /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: placeholder }) })
9086
9304
  ] });
9087
9305
  };
9088
9306
  function formatBytes2(bytes) {
@@ -9277,6 +9495,8 @@ function ImageInput({
9277
9495
  value,
9278
9496
  onChange,
9279
9497
  previewClassName,
9498
+ previewStyle,
9499
+ contentClassName,
9280
9500
  showPreview = true,
9281
9501
  previewPosition = "top",
9282
9502
  allowClear = true,
@@ -9288,6 +9508,8 @@ function ImageInput({
9288
9508
  uploadIcon,
9289
9509
  title = "Click to upload",
9290
9510
  subtitle,
9511
+ titleClassName,
9512
+ subtitleClassName,
9291
9513
  replaceTitle = "Replace image",
9292
9514
  replaceSubtitle,
9293
9515
  trigger = "icon",
@@ -9326,15 +9548,16 @@ function ImageInput({
9326
9548
  const renderPreview = () => /* @__PURE__ */ jsx(
9327
9549
  "div",
9328
9550
  {
9551
+ style: previewStyle,
9329
9552
  className: cn(
9330
9553
  "flex relative group rounded-lg overflow-hidden border-2 border-dashed border-muted-foreground/60 hover:border-primary transition-colors",
9331
9554
  effectiveSize
9332
9555
  ),
9333
9556
  children: preview ? isDropzone ? /* @__PURE__ */ jsxs(Fragment, { children: [
9334
9557
  /* @__PURE__ */ jsx("img", { src: preview, alt: "Preview", className: "absolute inset-0 w-full h-full object-cover" }),
9335
- /* @__PURE__ */ jsxs("div", { className: "relative w-full h-full flex flex-col items-center justify-center gap-1.5 bg-black/40 text-white px-6 py-8 text-center", children: [
9336
- /* @__PURE__ */ jsx("span", { className: "text-sm font-medium", children: replaceTitle }),
9337
- effectiveReplaceSubtitle ? /* @__PURE__ */ jsx("span", { className: "text-xs opacity-80", children: effectiveReplaceSubtitle }) : null,
9558
+ /* @__PURE__ */ jsxs("div", { className: cn("relative w-full h-full flex flex-col items-center justify-center gap-1.5 bg-black/40 text-white px-6 py-8 text-center", contentClassName), children: [
9559
+ /* @__PURE__ */ jsx("span", { className: cn("text-sm font-medium", titleClassName), children: replaceTitle }),
9560
+ effectiveReplaceSubtitle ? /* @__PURE__ */ jsx("span", { className: cn("text-xs opacity-80", subtitleClassName), children: effectiveReplaceSubtitle }) : null,
9338
9561
  allowClear && /* @__PURE__ */ jsx(
9339
9562
  "button",
9340
9563
  {
@@ -9381,7 +9604,7 @@ function ImageInput({
9381
9604
  "div",
9382
9605
  {
9383
9606
  onClick: handleClick,
9384
- className: "w-full h-full flex flex-col items-center justify-center gap-2 cursor-pointer bg-muted/30 hover:bg-muted/50 transition-colors px-6 py-8 text-center",
9607
+ className: cn("w-full h-full flex flex-col items-center justify-center gap-2 cursor-pointer bg-muted/30 hover:bg-muted/50 transition-colors px-6 py-8 text-center", contentClassName),
9385
9608
  children: [
9386
9609
  (trigger === "icon" || trigger === "both") && /* @__PURE__ */ jsx("div", { className: "text-primary", children: uploadIcon ?? /* @__PURE__ */ jsx(Plus, { className: "h-8 w-8" }) }),
9387
9610
  (trigger === "button" || trigger === "both") && /* @__PURE__ */ jsx(
@@ -9392,8 +9615,8 @@ function ImageInput({
9392
9615
  children: buttonLabel
9393
9616
  }
9394
9617
  ),
9395
- /* @__PURE__ */ jsx("span", { className: "text-sm font-medium text-foreground", children: title }),
9396
- subtitle ? /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: subtitle }) : null
9618
+ /* @__PURE__ */ jsx("span", { className: cn("text-sm font-medium text-foreground", titleClassName), children: title }),
9619
+ subtitle ? /* @__PURE__ */ jsx("span", { className: cn("text-xs text-muted-foreground", subtitleClassName), children: subtitle }) : null
9397
9620
  ]
9398
9621
  }
9399
9622
  ) : /* @__PURE__ */ jsxs(
@@ -9432,6 +9655,57 @@ function ImageInput({
9432
9655
  renderFileInput()
9433
9656
  ] });
9434
9657
  }
9658
+ var AVATAR_SIZE_MAP = {
9659
+ sm: "size-16",
9660
+ md: "size-24",
9661
+ lg: "size-32",
9662
+ xl: "size-40"
9663
+ };
9664
+ var AVATAR_RADIUS_MAP = {
9665
+ none: "rounded-none",
9666
+ sm: "rounded-sm",
9667
+ md: "rounded-md",
9668
+ lg: "rounded-lg",
9669
+ xl: "rounded-xl",
9670
+ "2xl": "rounded-2xl",
9671
+ full: "rounded-full"
9672
+ };
9673
+ function AvatarInput({
9674
+ imageSize = "md",
9675
+ size,
9676
+ radius = "full",
9677
+ previewClassName,
9678
+ previewStyle,
9679
+ contentClassName,
9680
+ uploadIcon,
9681
+ title = "Upload photo",
9682
+ subtitleClassName,
9683
+ trigger = "icon",
9684
+ ...props
9685
+ }) {
9686
+ return /* @__PURE__ */ jsx(
9687
+ ImageInput,
9688
+ {
9689
+ ...props,
9690
+ imageSize,
9691
+ previewClassName: cn(
9692
+ AVATAR_SIZE_MAP[imageSize],
9693
+ "shrink-0",
9694
+ AVATAR_RADIUS_MAP[radius],
9695
+ previewClassName
9696
+ ),
9697
+ previewStyle: {
9698
+ ...previewStyle,
9699
+ ...size != null ? { width: size, height: size } : null
9700
+ },
9701
+ contentClassName: cn("gap-1 p-2", contentClassName),
9702
+ uploadIcon: uploadIcon ?? /* @__PURE__ */ jsx(Camera, { className: "size-6" }),
9703
+ title,
9704
+ subtitleClassName: cn("text-[10px] leading-tight", subtitleClassName),
9705
+ trigger
9706
+ }
9707
+ );
9708
+ }
9435
9709
  var StarRatingInput = ({ value, onChange, maxStars = 5, className = "", variant = "default", status = "default", bordered, borderColor }) => {
9436
9710
  const stars = Array.from({ length: maxStars }, (_, i) => /* @__PURE__ */ jsx(Star, { onClick: () => onChange(i + 1), className: cn("cursor-pointer h-8 w-8", i < value ? "fill-orange-400 text-orange-400" : "fill-[#d6d6d6] text-[#d6d6d6]") }, i));
9437
9711
  return /* @__PURE__ */ jsx(BaseInput, { variant, status, bordered, borderColor, className: cn("gap-2", className), children: stars });
@@ -10253,7 +10527,7 @@ function NFormSectionHeader({
10253
10527
  ),
10254
10528
  children: [
10255
10529
  Icon2 && /* @__PURE__ */ jsx(Icon2, { className: "w-4 h-4 shrink-0 text-current" }),
10256
- /* @__PURE__ */ jsx(Label, { className: "text-sm font-semibold leading-none text-current", children: title })
10530
+ /* @__PURE__ */ jsx(Label2, { className: "text-sm font-semibold leading-none text-current", children: title })
10257
10531
  ]
10258
10532
  }
10259
10533
  );
@@ -10279,6 +10553,7 @@ var Inputs = {
10279
10553
  date: DateInput,
10280
10554
  file: FileInput,
10281
10555
  image: ImageInput,
10556
+ avatar: AvatarInput,
10282
10557
  select: SelectInput,
10283
10558
  combobox: ComboboxInput,
10284
10559
  multiselect: MultiSelectInput,
@@ -10305,7 +10580,7 @@ var FormInput = ({ name, type, formLabel, formDescription, required = false, dis
10305
10580
  if (type === "multiselect" || type === "checkboxGroup") return [];
10306
10581
  if (type === "switch" || type === "checkbox") return false;
10307
10582
  if (type === "starRating" || type === "emoji" || type === "slider") return 0;
10308
- if (type === "image" || type === "file") return null;
10583
+ if (type === "image" || type === "avatar" || type === "file") return null;
10309
10584
  return "";
10310
10585
  };
10311
10586
  const presetInput = type === "textarea" ? preset.input?.replace(/\bh-\d+\b/g, "").trim() : preset.input;
@@ -10335,6 +10610,9 @@ var FormInput = ({ name, type, formLabel, formDescription, required = false, dis
10335
10610
  ] });
10336
10611
  } });
10337
10612
  };
10613
+ function AvatarFormInput(props) {
10614
+ return /* @__PURE__ */ jsx(FormInput, { ...props, type: "avatar" });
10615
+ }
10338
10616
  var DynamicArray = ({ name, children, title, onAdd, className, collapsible = true, defaultCollapsed = false, addLabel = "Click to add item", emptyLabel = "No items added yet." }) => {
10339
10617
  const { control } = useFormContext();
10340
10618
  const { fields, append, remove, replace } = useFieldArray({ control, name });
@@ -14168,4 +14446,4 @@ function NGridItem({
14168
14446
  return /* @__PURE__ */ jsx("div", { className: itemClassName, ...props, children });
14169
14447
  }
14170
14448
 
14171
- export { Alert, NCard as AsyncCard, Avatar, AvatarFallback, AvatarGroup, AvatarImage, AvatarStatus, Badge, BaseInput, Button, Calendar, Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Checkbox, CheckboxGroupInput, CheckboxInput, Collapsible, CollapsibleContent2 as CollapsibleContent, CollapsibleTrigger2 as CollapsibleTrigger, ColorArrayInput, ColorPickerInput, Combobox, ComboboxInput, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut, DateInput, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, DynamicArray_default as DynamicArray, EmojiInput, FileImportButton, FileInput, Form, FormControl, FormDescription, FormField, FormInput, FormItem, FormLabel, FormMessage, IconButton, ImageInput, Indicator, Input, Label, LangInput, MultiSelectInput, NAJM_COMPONENT_NAMES, NAlert, NAppShell, NCard as NAsyncCard, NAvatar, NBadge, NBulkActionsBar, NButton, NCard, NCardAction, NCardFooter, NCardInfo, NCardMedia, NCardSection, NCommandPalette, NConfirmDialog, NContextMenu, NDataCardShell, NDeleteDialog, NDeleteDialogContent, NDetailCard, NDetailItem, NDetailList, NDialog, NDialogDescription, NDialogHeader, NDialogPrimaryButton, NDialogSecondaryButton, NDonutCard, NEditorTabs, NEmptyState, NErrorBoundary, NErrorState, NFileBrowser, NFileTypeIcon, NFilterBar, NFolderIcon, NForm, NFormSectionHeader, NGrid, NGridItem, NIcon, NIndicator, NInspectorSheet, NLoadingState, NMultiDialog, NNavbar, NPageHeader, NPageHeaderActions, NPageHeaderCompactActions, NPageHeaderFilters, NPageHeaderTop, NPageLayout, NPortalScopeProvider, NProgress, NRowActions, NSection, NSectionHeader, NSectionInfo, NSectionWithInfo, NSheet, NSidebar, NSidebarContent, NSidebarFooter, NSidebarHeader, NSidebarItem, NSidebarLogo, NSidebarMobile, NSidebarSection, NSkeleton, NSkeletonCalendar, NSkeletonChart, NSkeletonDonut, NSkeletonEventList, NSkeletonWidget, NSkeletonWidgets, NSlider, NSmartPasteDialog, NSpinner, NStatCard, NStatCardSkeleton, Swap as NSwap, NTable, NTableCardRoot, NTableCards, NTableContent, NTableHeader, NTableJson, NTableLoadingSkeleton, NTablePagination, NTableRowSkeleton, NTableSkeleton, NTabs, NThemeCustomizer, NUploader, NViewBody, NViewToggle, NajmDesignProvider, NajmScroll, NajmThemeProvider, NativeSelect, NumberInput, PasswordInput, PhoneInput, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, PrefixProvider, Progress, RADIUS_VALUE_MAP, RadioGroup2 as RadioGroup, RadioGroupInput, RadioGroupItem, RepeatingFields, ScrollArea, SearchField, SearchField as SearchInput, SegmentedControl, Select, SelectContent, SelectGroup, SelectInput, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator3 as Separator, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetOverlay, SheetPortal, SheetTitle, SheetTrigger, SimpleTooltip, NSkeleton as Skeleton, Slider, SliderInput, StarRatingInput, StatusPill, StepIndicator, StepsHeader, StepsProgress, Swap, SwapIndeterminate, SwapOff, SwapOn, Switch, SwitchInput, TAB_COLORS, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, TableStoreContext, Tabs, TabsContent, TabsList, TabsTrigger, TextAreaInput, TextInput, Textarea, TimeInput, TimeZoneInput, Toaster, Toggle, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, VariantProvider, WizardForm, alertVariants, avatarVariants, badgeColorVariants, badgeVariants, buildDefaultFileColumns, buttonVariants, cn, composePreset, createDialogStore, createTableStore, defineNajmDesignConfig, defineNajmThemeConfig, detectFormat, dialogVariants, filterResponsiveColumns, formatColor, formatFileBytes, formatFileRelative, getIconColorProps, getNextEditorTabValue, hiddenBelowClasses, indicatorVariants, inputBorderClasses, parseColor, parseNajmDesignConfig, parseNajmThemeConfig, resolveHiddenBelowClass, resolvePreset, resolveRadiusValue, resolveSlot, resolveVariantAlias, sidebarBorderClasses, sliderVariants, stringifyNajmDesignConfig, stringifyNajmThemeConfig, surfaceBorderClasses, swapVariants, toPickerHex, toggleVariants, tooltipContentVariants, truncateByCharacters, useClickOutside, useContextMenu, useDebouncedValue, useDelayedLoading, useDialog, useDialogStore, useDynamicPageSize, useFormField, useFormSubmission, useInfiniteScroll, useKeyboard, useLocalStorageState, useNForm, useNPortalScope, useNajmAppearance, useNajmComponentStyle, useNajmDesign, usePrefix, useSelection, useStepNavigation, useStorageContextMenu, useStoreSync, useTable, useTableKeyboard, useTableStore, useVariant, useVariantPreset };
14449
+ export { Alert, NCard as AsyncCard, Avatar, AvatarFallback, AvatarFormInput, AvatarGroup, AvatarImage, AvatarInput, AvatarStatus, Badge, BaseInput, Button, Calendar, Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Checkbox, CheckboxGroupInput, CheckboxInput, Collapsible, CollapsibleContent2 as CollapsibleContent, CollapsibleTrigger2 as CollapsibleTrigger, ColorArrayInput, ColorPickerInput, Combobox, ComboboxInput, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut, DEFAULT_THEME_FILE_NAME, DateInput, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, DynamicArray_default as DynamicArray, EmojiInput, FileImportButton, FileInput, Form, FormControl, FormDescription, FormField, FormInput, FormItem, FormLabel, FormMessage, IconButton, ImageInput, Indicator, Input, Label2 as Label, LangInput, MultiSelectInput, NAJM_COMPONENT_NAMES, NAlert, NAppShell, NCard as NAsyncCard, NAvatar, NBadge, NBulkActionsBar, NButton, NCard, NCardAction, NCardFooter, NCardInfo, NCardMedia, NCardSection, NCommandPalette, NConfirmDialog, NContextMenu, NDataCardShell, NDeleteDialog, NDeleteDialogContent, NDetailCard, NDetailItem, NDetailList, NDialog, NDialogDescription, NDialogHeader, NDialogPrimaryButton, NDialogSecondaryButton, NDonutCard, NEditorTabs, NEmptyState, NErrorBoundary, NErrorState, NFileBrowser, NFileTypeIcon, NFilterBar, NFolderIcon, NForm, NFormSectionHeader, NGrid, NGridItem, NIcon, NIndicator, NInspectorSheet, NLoadingState, NMultiDialog, NNavbar, NPageHeader, NPageHeaderActions, NPageHeaderCompactActions, NPageHeaderFilters, NPageHeaderTop, NPageLayout, NPortalScopeProvider, NProgress, NRowActions, NSection, NSectionHeader, NSectionInfo, NSectionWithInfo, NSheet, NSidebar, NSidebarContent, NSidebarFooter, NSidebarHeader, NSidebarItem, NSidebarLogo, NSidebarMobile, NSidebarSection, NSkeleton, NSkeletonCalendar, NSkeletonChart, NSkeletonDonut, NSkeletonEventList, NSkeletonWidget, NSkeletonWidgets, NSlider, NSmartPasteDialog, NSpinner, NStatCard, NStatCardSkeleton, Swap as NSwap, NTable, NTableCardRoot, NTableCards, NTableContent, NTableHeader, NTableJson, NTableLoadingSkeleton, NTablePagination, NTableRowSkeleton, NTableSkeleton, NTabs, NThemeCustomizer, NUploader, NViewBody, NViewToggle, NajmDesignProvider, NajmScroll, NajmThemeProvider, NativeSelect, NumberInput, PasswordInput, PhoneInput, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, PrefixProvider, Progress, RADIUS_VALUE_MAP, RadioGroup2 as RadioGroup, RadioGroupInput, RadioGroupItem, RepeatingFields, ScrollArea, SearchField, SearchField as SearchInput, SegmentedControl, Select, SelectContent, SelectGroup, SelectInput, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator3 as Separator, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetOverlay, SheetPortal, SheetTitle, SheetTrigger, SimpleTooltip, NSkeleton as Skeleton, Slider, SliderInput, StarRatingInput, StatusPill, StepIndicator, StepsHeader, StepsProgress, Swap, SwapIndeterminate, SwapOff, SwapOn, Switch, SwitchInput, TAB_COLORS, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, TableStoreContext, Tabs, TabsContent, TabsList, TabsTrigger, TextAreaInput, TextInput, Textarea, TimeInput, TimeZoneInput, Toaster, Toggle, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, VariantProvider, WizardForm, alertVariants, avatarVariants, badgeColorVariants, badgeVariants, buildDefaultFileColumns, buttonVariants, cn, composePreset, createDialogStore, createTableStore, defineNajmDesignConfig, defineNajmThemeConfig, detectFormat, dialogVariants, filterResponsiveColumns, formatColor, formatFileBytes, formatFileRelative, getIconColorProps, getNextEditorTabValue, hiddenBelowClasses, indicatorVariants, inputBorderClasses, normalizeThemeFileName, parseColor, parseNajmDesignConfig, parseNajmThemeConfig, parseThemeFile, resolveHiddenBelowClass, resolvePreset, resolveRadiusValue, resolveSlot, resolveVariantAlias, sidebarBorderClasses, sliderVariants, stringifyNajmDesignConfig, stringifyNajmThemeConfig, stringifyThemeFile, surfaceBorderClasses, swapVariants, toPickerHex, toggleVariants, tooltipContentVariants, truncateByCharacters, useClickOutside, useContextMenu, useDebouncedValue, useDelayedLoading, useDialog, useDialogStore, useDynamicPageSize, useFormField, useFormSubmission, useInfiniteScroll, useKeyboard, useLocalStorageState, useNForm, useNPortalScope, useNajmAppearance, useNajmComponentStyle, useNajmDesign, useNajmThemeMode, usePrefix, useSelection, useStepNavigation, useStorageContextMenu, useStoreSync, useTable, useTableKeyboard, useTableStore, useVariant, useVariantPreset };