najm-kit 2.1.36 → 2.1.38

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, 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(
@@ -1621,6 +1626,23 @@ var PRESET_COLORS = [
1621
1626
  "#000000"
1622
1627
  ];
1623
1628
  var DEFAULT_FORMATS = ["hex", "rgb", "hsl", "oklch"];
1629
+ var CSS_VAR_RE = /^var\(\s*(--[\w-]+)\s*(?:,\s*(.+))?\)$/;
1630
+ function resolvePickerColor(value, themeContainer) {
1631
+ let current = value.trim();
1632
+ const seen = /* @__PURE__ */ new Set();
1633
+ for (let depth = 0; depth < 10; depth += 1) {
1634
+ if (parseColor(current)) return current;
1635
+ const match = current.match(CSS_VAR_RE);
1636
+ if (!match) return current;
1637
+ const [, property, fallback] = match;
1638
+ if (seen.has(property)) return fallback?.trim() || current;
1639
+ seen.add(property);
1640
+ const target = themeContainer ?? (typeof document !== "undefined" ? document.documentElement : null);
1641
+ const resolved = target?.style.getPropertyValue(property).trim() || (target && typeof getComputedStyle === "function" ? getComputedStyle(target).getPropertyValue(property).trim() : "");
1642
+ current = resolved || fallback?.trim() || current;
1643
+ }
1644
+ return current;
1645
+ }
1624
1646
  function ColorPickerInput(props) {
1625
1647
  if (props.mode === "popover") {
1626
1648
  return /* @__PURE__ */ jsx(PopoverColorPicker, { ...props });
@@ -1640,6 +1662,8 @@ function SwatchesColorPicker({
1640
1662
  hideSwatches = false
1641
1663
  }) {
1642
1664
  const inputRef = useRef(null);
1665
+ const themeContainer = React__default.useContext(NajmThemeContainerCtx);
1666
+ const resolvedValue = resolvePickerColor(value, themeContainer);
1643
1667
  return /* @__PURE__ */ jsxs(
1644
1668
  BaseInput,
1645
1669
  {
@@ -1665,7 +1689,7 @@ function SwatchesColorPicker({
1665
1689
  {
1666
1690
  ref: inputRef,
1667
1691
  type: "color",
1668
- value: toPickerHex(value),
1692
+ value: toPickerHex(resolvedValue),
1669
1693
  onChange: (e) => onChange(e.target.value),
1670
1694
  disabled,
1671
1695
  className: "sr-only"
@@ -1708,7 +1732,9 @@ function PopoverColorPicker({
1708
1732
  formats = DEFAULT_FORMATS,
1709
1733
  output = "preserve"
1710
1734
  }) {
1711
- const initialFormat = formats.includes(detectFormat(value)) ? detectFormat(value) : formats[0] ?? "hex";
1735
+ const themeContainer = React__default.useContext(NajmThemeContainerCtx);
1736
+ const resolvedValue = resolvePickerColor(value, themeContainer);
1737
+ const initialFormat = formats.includes(detectFormat(resolvedValue)) ? detectFormat(resolvedValue) : formats[0] ?? "hex";
1712
1738
  const [activeFormat, setActiveFormat] = useState(initialFormat);
1713
1739
  const [draft, setDraft] = useState(value);
1714
1740
  useEffect(() => {
@@ -1754,7 +1780,7 @@ function PopoverColorPicker({
1754
1780
  "span",
1755
1781
  {
1756
1782
  className: "w-8 h-8 rounded-md border border-border shrink-0",
1757
- style: { backgroundColor: toPickerHex(value) }
1783
+ style: { backgroundColor: value }
1758
1784
  }
1759
1785
  ),
1760
1786
  /* @__PURE__ */ jsx("span", { className: "text-sm text-muted-foreground font-mono truncate", children: value })
@@ -1765,7 +1791,9 @@ function PopoverColorPicker({
1765
1791
  /* @__PURE__ */ jsx(
1766
1792
  HexColorPicker,
1767
1793
  {
1768
- color: toPickerHex(draft),
1794
+ color: toPickerHex(
1795
+ draft === value ? resolvedValue : resolvePickerColor(draft, themeContainer)
1796
+ ),
1769
1797
  onChange: handlePickerChange,
1770
1798
  style: { width: "100%" }
1771
1799
  }
@@ -1951,34 +1979,179 @@ function ResetButton({
1951
1979
  }
1952
1980
  );
1953
1981
  }
1954
- var NativeSelect = React.forwardRef(
1955
- ({ className, options, placeholder, value, ...props }, ref) => {
1956
- const hasValue = value !== void 0 && value !== "";
1957
- return /* @__PURE__ */ jsxs("div", { className: "relative", children: [
1958
- /* @__PURE__ */ jsxs(
1959
- "select",
1960
- {
1961
- ref,
1962
- value,
1963
- className: cn(
1964
- "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",
1965
- "hover:border-muted-foreground/30 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
1966
- "disabled:cursor-not-allowed disabled:opacity-50",
1967
- !hasValue && "text-muted-foreground",
1968
- className
1969
- ),
1970
- ...props,
1971
- children: [
1972
- placeholder && /* @__PURE__ */ jsx("option", { value: "", disabled: true, children: placeholder }),
1973
- options.map((opt) => /* @__PURE__ */ jsx("option", { value: opt.value, children: opt.label }, opt.value))
1974
- ]
1975
- }
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
1976
1999
  ),
1977
- /* @__PURE__ */ jsx(ChevronDown, { className: "pointer-events-none absolute right-2 top-1/2 size-4 -translate-y-1/2 text-muted-foreground" })
1978
- ] });
1979
- }
1980
- );
1981
- 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
+ };
1982
2155
  var TRACK = {
1983
2156
  xs: "h-3 w-5",
1984
2157
  sm: "h-4 w-7",
@@ -2415,16 +2588,16 @@ function ThemeCustomizerComponentsLayoutTab({
2415
2588
  label: labels.pageGutter,
2416
2589
  disabled,
2417
2590
  children: /* @__PURE__ */ jsx(
2418
- NativeSelect,
2591
+ SelectInput,
2419
2592
  {
2420
2593
  value: layout.pageGutter ?? "",
2421
- onChange: (e) => onChange(setLayoutField(value, "pageGutter", e.target.value || void 0)),
2422
- options: [
2594
+ onChange: (next) => onChange(setLayoutField(value, "pageGutter", next || void 0)),
2595
+ items: [
2423
2596
  toOption(labels.defaultOption, ""),
2424
2597
  ...LAYOUT_SIZE_VALUES.map((value2) => ({ value: value2, label: value2 }))
2425
2598
  ],
2426
2599
  disabled,
2427
- "aria-label": typeof labels.pageGutter === "string" ? labels.pageGutter : "Page gutter"
2600
+ ariaLabel: typeof labels.pageGutter === "string" ? labels.pageGutter : "Page gutter"
2428
2601
  }
2429
2602
  )
2430
2603
  }
@@ -2435,54 +2608,54 @@ function ThemeCustomizerComponentsLayoutTab({
2435
2608
  label: labels.sectionGap,
2436
2609
  disabled,
2437
2610
  children: /* @__PURE__ */ jsx(
2438
- NativeSelect,
2611
+ SelectInput,
2439
2612
  {
2440
2613
  value: layout.sectionGap ?? "",
2441
- onChange: (e) => onChange(setLayoutField(value, "sectionGap", e.target.value || void 0)),
2442
- options: [
2614
+ onChange: (next) => onChange(setLayoutField(value, "sectionGap", next || void 0)),
2615
+ items: [
2443
2616
  toOption(labels.defaultOption, ""),
2444
2617
  ...LAYOUT_SIZE_VALUES.map((value2) => ({ value: value2, label: value2 }))
2445
2618
  ],
2446
2619
  disabled,
2447
- "aria-label": typeof labels.sectionGap === "string" ? labels.sectionGap : "Section gap"
2620
+ ariaLabel: typeof labels.sectionGap === "string" ? labels.sectionGap : "Section gap"
2448
2621
  }
2449
2622
  )
2450
2623
  }
2451
2624
  ),
2452
2625
  /* @__PURE__ */ jsx(CustomizerField, { label: labels.globalBorderWidth, disabled, children: /* @__PURE__ */ jsx(
2453
- NativeSelect,
2626
+ SelectInput,
2454
2627
  {
2455
2628
  value: value.theme.appearance?.borderWidth ?? "1px",
2456
- onChange: (event) => onChange(setThemeField(value, "appearance", {
2629
+ onChange: (next) => onChange(setThemeField(value, "appearance", {
2457
2630
  ...value.theme.appearance ?? {},
2458
- borderWidth: event.target.value
2631
+ borderWidth: next
2459
2632
  })),
2460
- options: BORDER_WIDTH_VALUES.map((borderWidth) => ({ value: borderWidth, label: borderWidth })),
2633
+ items: BORDER_WIDTH_VALUES.map((borderWidth) => ({ value: borderWidth, label: borderWidth })),
2461
2634
  disabled,
2462
- "aria-label": typeof labels.globalBorderWidth === "string" ? labels.globalBorderWidth : "Border width"
2635
+ ariaLabel: typeof labels.globalBorderWidth === "string" ? labels.globalBorderWidth : "Border width"
2463
2636
  }
2464
2637
  ) }),
2465
2638
  /* @__PURE__ */ jsx(CustomizerField, { label: labels.inputBorderWidth, disabled, children: /* @__PURE__ */ jsx(
2466
- NativeSelect,
2639
+ SelectInput,
2467
2640
  {
2468
2641
  value: components.input?.borderWidth ?? "",
2469
- onChange: (e) => onChange(setComponentField(value, "input", "borderWidth", e.target.value || void 0)),
2470
- options: [
2642
+ onChange: (next) => onChange(setComponentField(value, "input", "borderWidth", next || void 0)),
2643
+ items: [
2471
2644
  toOption(labels.defaultOption, ""),
2472
2645
  ...COMPONENT_BORDER_WIDTH_VALUES.map((value2) => ({ value: value2, label: value2 }))
2473
2646
  ],
2474
2647
  disabled,
2475
- "aria-label": typeof labels.inputBorderWidth === "string" ? labels.inputBorderWidth : "Input border width"
2648
+ ariaLabel: typeof labels.inputBorderWidth === "string" ? labels.inputBorderWidth : "Input border width"
2476
2649
  }
2477
2650
  ) }),
2478
2651
  /* @__PURE__ */ jsx(CustomizerField, { className: "col-span-2", label: labels.globalRadius, disabled, children: /* @__PURE__ */ jsx(
2479
- NativeSelect,
2652
+ SelectInput,
2480
2653
  {
2481
2654
  value: value.theme.radius ?? "8px",
2482
- onChange: (event) => onChange(setThemeField(value, "radius", event.target.value)),
2483
- 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 })),
2484
2657
  disabled,
2485
- "aria-label": typeof labels.globalRadius === "string" ? labels.globalRadius : "Radius"
2658
+ ariaLabel: typeof labels.globalRadius === "string" ? labels.globalRadius : "Radius"
2486
2659
  }
2487
2660
  ) })
2488
2661
  ] }) }),
@@ -2744,7 +2917,18 @@ var THEME_TOKEN_GROUPS = [
2744
2917
  {
2745
2918
  id: "surface",
2746
2919
  label: "Surface",
2747
- tokens: ["background", "foreground", "card", "card-foreground", "popover", "popover-foreground"]
2920
+ tokens: [
2921
+ "background",
2922
+ "foreground",
2923
+ "card",
2924
+ "card-foreground",
2925
+ "popover",
2926
+ "popover-foreground",
2927
+ "muted",
2928
+ "muted-foreground",
2929
+ "destructive",
2930
+ "destructive-foreground"
2931
+ ]
2748
2932
  },
2749
2933
  {
2750
2934
  id: "brand",
@@ -2760,11 +2944,6 @@ var THEME_TOKEN_GROUPS = [
2760
2944
  "accent-foreground"
2761
2945
  ]
2762
2946
  },
2763
- {
2764
- id: "feedback",
2765
- label: "Feedback",
2766
- tokens: ["muted", "muted-foreground", "destructive", "destructive-foreground"]
2767
- },
2768
2947
  {
2769
2948
  id: "border-focus",
2770
2949
  label: "Border & Focus",
@@ -2830,6 +3009,9 @@ var DEFAULT_LABELS = {
2830
3009
  darkMode: "Dark",
2831
3010
  resetField: "Reset",
2832
3011
  resetSection: "Reset section",
3012
+ importTheme: "Import",
3013
+ exportTheme: "Export",
3014
+ invalidThemeFile: "Invalid theme file",
2833
3015
  colorSwatchFallback: "Color",
2834
3016
  defaultOption: "Default",
2835
3017
  themeSection: "Theme",
@@ -2879,12 +3061,12 @@ function ThemeCustomizerThemeTab({
2879
3061
  onChange,
2880
3062
  previewMode,
2881
3063
  onPreviewModeChange,
2882
- showPreviewMode = true,
3064
+ showPreviewMode = false,
2883
3065
  labels,
2884
3066
  disabled
2885
3067
  }) {
2886
3068
  return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3", children: [
2887
- 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: [
2888
3070
  /* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-muted-foreground", children: labels.previewMode }),
2889
3071
  /* @__PURE__ */ jsx(
2890
3072
  SegmentedControl,
@@ -3115,16 +3297,16 @@ function ThemeCustomizerTypographyTab({
3115
3297
  label: labels.baseSize,
3116
3298
  disabled,
3117
3299
  children: /* @__PURE__ */ jsx(
3118
- NativeSelect,
3300
+ SelectInput,
3119
3301
  {
3120
3302
  value: typography.baseSize ?? "",
3121
- onChange: (e) => handleTypography("baseSize", e.target.value || void 0),
3122
- options: [
3303
+ onChange: (next) => handleTypography("baseSize", next || void 0),
3304
+ items: [
3123
3305
  toOption(labels.defaultOption, ""),
3124
3306
  ...FONT_SIZE_VALUES.map((value2) => ({ value: value2, label: value2 }))
3125
3307
  ],
3126
3308
  disabled,
3127
- "aria-label": typeof labels.baseSize === "string" ? labels.baseSize : "Base size"
3309
+ ariaLabel: typeof labels.baseSize === "string" ? labels.baseSize : "Base size"
3128
3310
  }
3129
3311
  )
3130
3312
  }
@@ -3158,14 +3340,14 @@ function ThemeCustomizerTypographyTab({
3158
3340
  )
3159
3341
  ] }) : null,
3160
3342
  /* @__PURE__ */ jsx(CustomizerField, { label: labels.scale, disabled, children: /* @__PURE__ */ jsx(
3161
- NativeSelect,
3343
+ SelectInput,
3162
3344
  {
3163
3345
  value: typography.scale ?? "",
3164
- onChange: (e) => handleTypography(
3346
+ onChange: (next) => handleTypography(
3165
3347
  "scale",
3166
- e.target.value || void 0
3348
+ next || void 0
3167
3349
  ),
3168
- options: [
3350
+ items: [
3169
3351
  toOption(labels.defaultOption, ""),
3170
3352
  ...SCALE_VALUES.map((o) => ({
3171
3353
  value: o.value,
@@ -3175,33 +3357,33 @@ function ThemeCustomizerTypographyTab({
3175
3357
  }))
3176
3358
  ],
3177
3359
  disabled,
3178
- "aria-label": typeof labels.scale === "string" ? labels.scale : "Scale"
3360
+ ariaLabel: typeof labels.scale === "string" ? labels.scale : "Scale"
3179
3361
  }
3180
3362
  ) }),
3181
3363
  /* @__PURE__ */ jsx(CustomizerField, { label: labels.lineHeight, disabled, children: /* @__PURE__ */ jsx(
3182
- NativeSelect,
3364
+ SelectInput,
3183
3365
  {
3184
3366
  value: typography.lineHeight ?? "",
3185
- onChange: (e) => handleTypography("lineHeight", e.target.value || void 0),
3186
- options: [
3367
+ onChange: (next) => handleTypography("lineHeight", next || void 0),
3368
+ items: [
3187
3369
  toOption(labels.defaultOption, ""),
3188
3370
  ...LINE_HEIGHT_VALUES.map((value2) => ({ value: value2, label: value2 }))
3189
3371
  ],
3190
3372
  disabled,
3191
- "aria-label": typeof labels.lineHeight === "string" ? labels.lineHeight : "Line height"
3373
+ ariaLabel: typeof labels.lineHeight === "string" ? labels.lineHeight : "Line height"
3192
3374
  }
3193
3375
  ) }),
3194
3376
  /* @__PURE__ */ jsx(CustomizerField, { label: labels.letterSpacing, disabled, children: /* @__PURE__ */ jsx(
3195
- NativeSelect,
3377
+ SelectInput,
3196
3378
  {
3197
3379
  value: typography.letterSpacing ?? "",
3198
- onChange: (e) => handleTypography("letterSpacing", e.target.value || void 0),
3199
- options: [
3380
+ onChange: (next) => handleTypography("letterSpacing", next || void 0),
3381
+ items: [
3200
3382
  toOption(labels.defaultOption, ""),
3201
3383
  ...LETTER_SPACING_VALUES.map((value2) => ({ value: value2, label: value2 }))
3202
3384
  ],
3203
3385
  disabled,
3204
- "aria-label": typeof labels.letterSpacing === "string" ? labels.letterSpacing : "Letter spacing"
3386
+ ariaLabel: typeof labels.letterSpacing === "string" ? labels.letterSpacing : "Letter spacing"
3205
3387
  }
3206
3388
  ) })
3207
3389
  ] })
@@ -3238,18 +3420,33 @@ function FontSelect({
3238
3420
  label,
3239
3421
  disabled,
3240
3422
  children: /* @__PURE__ */ jsx(
3241
- NativeSelect,
3423
+ SelectInput,
3242
3424
  {
3243
3425
  value: value ?? "",
3244
- onChange: (e) => onChange(e.target.value || void 0),
3245
- options,
3426
+ onChange: (next) => onChange(next || void 0),
3427
+ items: options,
3246
3428
  disabled,
3247
- "aria-label": typeof label === "string" ? label : "Font"
3429
+ ariaLabel: typeof label === "string" ? label : "Font"
3248
3430
  }
3249
3431
  )
3250
3432
  }
3251
3433
  );
3252
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
+ }
3253
3450
  var DEFAULT_TABS = [
3254
3451
  "theme",
3255
3452
  "typography"
@@ -3288,7 +3485,11 @@ function NThemeCustomizer({
3288
3485
  onChange,
3289
3486
  previewMode,
3290
3487
  onPreviewModeChange,
3291
- showPreviewMode = true,
3488
+ showPreviewMode = false,
3489
+ showFileActions = true,
3490
+ showResetAction = true,
3491
+ exportFileName,
3492
+ onImportError,
3292
3493
  showTabs = true,
3293
3494
  tabs,
3294
3495
  fontOptions,
@@ -3296,9 +3497,13 @@ function NThemeCustomizer({
3296
3497
  disabled = false,
3297
3498
  className
3298
3499
  }) {
3500
+ const inheritedMode = useNajmThemeMode();
3501
+ const resolvedPreviewMode = previewMode ?? inheritedMode ?? value.theme.mode ?? "light";
3299
3502
  const visibleTabs = React.useMemo(() => buildTabs(tabs), [tabs]);
3300
3503
  const firstTab = visibleTabs[0] ?? "theme";
3301
3504
  const [activeTab, setActiveTab] = React.useState(TAB_VALUE[firstTab]);
3505
+ const [fileError, setFileError] = React.useState(false);
3506
+ const fileInputRef = React.useRef(null);
3302
3507
  React.useEffect(() => {
3303
3508
  setActiveTab(TAB_VALUE[firstTab]);
3304
3509
  }, [firstTab]);
@@ -3306,6 +3511,9 @@ function NThemeCustomizer({
3306
3511
  const typographyLabel = resolveLabel("typographyTab", labels);
3307
3512
  const resetSectionLabel = resolveLabel("resetSection", labels);
3308
3513
  const resetFieldLabel = resolveLabel("resetField", labels);
3514
+ const importThemeLabel = resolveLabel("importTheme", labels);
3515
+ const exportThemeLabel = resolveLabel("exportTheme", labels);
3516
+ const invalidThemeFileLabel = resolveLabel("invalidThemeFile", labels);
3309
3517
  const defaultOptionLabel = resolveLabel("defaultOption", labels);
3310
3518
  const colorSwatchFallbackLabel = resolveLabel("colorSwatchFallback", labels);
3311
3519
  const tokenLabels = React.useMemo(() => {
@@ -3358,9 +3566,9 @@ function NThemeCustomizer({
3358
3566
  value,
3359
3567
  factoryValue,
3360
3568
  onChange,
3361
- previewMode,
3569
+ previewMode: resolvedPreviewMode,
3362
3570
  onPreviewModeChange,
3363
- showPreviewMode,
3571
+ showPreviewMode: showPreviewMode && Boolean(onPreviewModeChange),
3364
3572
  disabled,
3365
3573
  labels: {
3366
3574
  resetField: resetFieldLabel,
@@ -3463,6 +3671,32 @@ function NThemeCustomizer({
3463
3671
  if (target === TAB_VALUE.theme) handleResetTheme();
3464
3672
  else handleResetTypography();
3465
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
+ };
3466
3700
  const directContent = items[0]?.content ?? themeContent;
3467
3701
  return /* @__PURE__ */ jsxs(
3468
3702
  "div",
@@ -3489,21 +3723,65 @@ function NThemeCustomizer({
3489
3723
  }
3490
3724
  }
3491
3725
  ) : directContent,
3492
- /* @__PURE__ */ jsx("div", { className: "flex items-center justify-end", children: /* @__PURE__ */ jsxs(
3493
- NButton,
3494
- {
3495
- type: "button",
3496
- variant: "outline",
3497
- size: "sm",
3498
- onClick: handleReset,
3499
- disabled,
3500
- "aria-label": typeof resetSectionLabel === "string" || typeof resetSectionLabel === "number" ? String(resetSectionLabel) : "Reset section",
3501
- children: [
3502
- /* @__PURE__ */ jsx(RotateCcw, { className: "size-3.5" }),
3503
- /* @__PURE__ */ jsx("span", { children: resetSectionLabel })
3504
- ]
3505
- }
3506
- ) })
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
3507
3785
  ]
3508
3786
  }
3509
3787
  );
@@ -4071,7 +4349,7 @@ function Textarea({ className, ...props }) {
4071
4349
  }
4072
4350
  );
4073
4351
  }
4074
- function Label({ className, ...props }) {
4352
+ function Label2({ className, ...props }) {
4075
4353
  return /* @__PURE__ */ jsx(
4076
4354
  LabelPrimitive.Root,
4077
4355
  {
@@ -5752,94 +6030,34 @@ function DropdownMenuSeparator({ className, ...props }) {
5752
6030
  function DropdownMenuShortcut({ className, ...props }) {
5753
6031
  return /* @__PURE__ */ jsx("span", { "data-slot": "dropdown-menu-shortcut", className: cn("text-muted-foreground ml-auto text-xs tracking-widest", className), ...props });
5754
6032
  }
5755
- function Select({ ...props }) {
5756
- return /* @__PURE__ */ jsx(SelectPrimitive.Root, { "data-slot": "select", ...props });
5757
- }
5758
- function SelectGroup({ ...props }) {
5759
- return /* @__PURE__ */ jsx(SelectPrimitive.Group, { "data-slot": "select-group", ...props });
5760
- }
5761
- function SelectValue({ ...props }) {
5762
- return /* @__PURE__ */ jsx(SelectPrimitive.Value, { "data-slot": "select-value", ...props });
5763
- }
5764
- function SelectTrigger({ className, children, ...props }) {
5765
- return /* @__PURE__ */ jsxs(
5766
- SelectPrimitive.Trigger,
5767
- {
5768
- "data-slot": "select-trigger",
5769
- className: cn(
5770
- "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",
5771
- className
5772
- ),
5773
- ...props,
5774
- children: [
5775
- children,
5776
- /* @__PURE__ */ jsx(SelectPrimitive.Icon, { asChild: true, children: /* @__PURE__ */ jsx(ChevronDownIcon, { className: "size-4 opacity-50" }) })
5777
- ]
5778
- }
5779
- );
5780
- }
5781
- function SelectScrollUpButton({ className, ...props }) {
5782
- 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" }) });
5783
- }
5784
- function SelectScrollDownButton({ className, ...props }) {
5785
- 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" }) });
5786
- }
5787
- function SelectContent({ className, children, position = "popper", style, ...props }) {
5788
- const container = React.useContext(NajmThemeContainerCtx);
5789
- const recipe = useNajmComponentStyle("select");
5790
- const contentSlot = recipe?.slots?.content;
5791
- const borderWidth = contentSlot?.borderWidth ?? recipe?.borderWidth;
5792
- const radius = resolveRadiusValue(contentSlot?.radius ?? recipe?.radius);
5793
- const recipeStyle = {
5794
- ...radius ? { borderRadius: radius } : {},
5795
- ...borderWidth !== void 0 ? {
5796
- borderWidth,
5797
- borderStyle: borderWidth === "0" ? "none" : "solid",
5798
- borderColor: "var(--border)"
5799
- } : {}
5800
- };
5801
- useNajmPortalLayerStyles();
5802
- return /* @__PURE__ */ jsx(SelectPrimitive.Portal, { container: container ?? void 0, children: /* @__PURE__ */ jsxs(
5803
- SelectPrimitive.Content,
5804
- {
5805
- "data-slot": "select-content",
5806
- className: cn(
5807
- "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",
5808
- 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)]",
5809
- contentSlot?.className,
5810
- 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
+ }
5811
6055
  ),
5812
- style: { ...recipeStyle, ...style },
5813
- position,
5814
- ...props,
5815
- children: [
5816
- /* @__PURE__ */ jsx(SelectScrollUpButton, {}),
5817
- /* @__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 }),
5818
- /* @__PURE__ */ jsx(SelectScrollDownButton, {})
5819
- ]
5820
- }
5821
- ) });
5822
- }
5823
- function SelectLabel({ className, ...props }) {
5824
- return /* @__PURE__ */ jsx(SelectPrimitive.Label, { "data-slot": "select-label", className: cn("text-muted-foreground px-2 py-1.5 text-xs", className), ...props });
5825
- }
5826
- function SelectItem({ className, children, ...props }) {
5827
- return /* @__PURE__ */ jsxs(
5828
- SelectPrimitive.Item,
5829
- {
5830
- "data-slot": "select-item",
5831
- 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),
5832
- ...props,
5833
- children: [
5834
- /* @__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" }) }) }),
5835
- /* @__PURE__ */ jsx(SelectPrimitive.ItemText, { children })
5836
- ]
5837
- }
5838
- );
5839
- }
5840
- function SelectSeparator({ className, ...props }) {
5841
- return /* @__PURE__ */ jsx(SelectPrimitive.Separator, { "data-slot": "select-separator", className: cn("bg-muted pointer-events-none -mx-1 my-1 h-px", className), ...props });
5842
- }
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";
5843
6061
  function Checkbox({ className, ...props }) {
5844
6062
  return /* @__PURE__ */ jsx(
5845
6063
  CheckboxPrimitive.Root,
@@ -6569,7 +6787,7 @@ function FormItem({ className, ...props }) {
6569
6787
  }
6570
6788
  function FormLabel({ className, ...props }) {
6571
6789
  const { error, formItemId } = useFormField();
6572
- 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 });
6573
6791
  }
6574
6792
  function FormControl({ ...props }) {
6575
6793
  const { error, formItemId, formDescriptionId, formMessageId } = useFormField();
@@ -7322,14 +7540,14 @@ function NSectionInfo({
7322
7540
  const displayValue = isTruncated ? truncateByCharacters(stringValue, maxChars) : value;
7323
7541
  return /* @__PURE__ */ jsxs("div", { className: cn("flex items-center gap-2", className), children: [
7324
7542
  Icon2 && /* @__PURE__ */ jsx(Icon2, { className: cn("w-4 h-4", iconColor) }),
7325
- /* @__PURE__ */ jsxs(Label, { className: "text-sm text-muted-foreground", children: [
7543
+ /* @__PURE__ */ jsxs(Label2, { className: "text-sm text-muted-foreground", children: [
7326
7544
  label,
7327
7545
  ":"
7328
7546
  ] }),
7329
7547
  isTruncated ? /* @__PURE__ */ jsxs(Tooltip, { children: [
7330
- /* @__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 }) }),
7331
7549
  /* @__PURE__ */ jsx(TooltipContent, { children: /* @__PURE__ */ jsx("p", { className: "max-w-xs", children: stringValue }) })
7332
- ] }) : /* @__PURE__ */ jsx(Label, { className: cn("text-sm", valueColor), children: displayValue })
7550
+ ] }) : /* @__PURE__ */ jsx(Label2, { className: cn("text-sm", valueColor), children: displayValue })
7333
7551
  ] });
7334
7552
  }
7335
7553
  function NSection({
@@ -7343,7 +7561,7 @@ function NSection({
7343
7561
  return /* @__PURE__ */ jsxs("div", { className: cn(background, "flex flex-col gap-1 rounded-lg p-4", className), children: [
7344
7562
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 mb-3", children: [
7345
7563
  /* @__PURE__ */ jsx(Icon2, { className: cn("w-5 h-5", iconColor) }),
7346
- /* @__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 })
7347
7565
  ] }),
7348
7566
  /* @__PURE__ */ jsx("div", { className: "space-y-1", children })
7349
7567
  ] });
@@ -7432,10 +7650,10 @@ function NSectionHeaderRoot({
7432
7650
  );
7433
7651
  }
7434
7652
  function NSectionHeaderTitle({ children, className }) {
7435
- 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 });
7436
7654
  }
7437
7655
  function NSectionHeaderSubtitle({ children, className }) {
7438
- 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 });
7439
7657
  }
7440
7658
  function NSectionHeaderContent({ children, className }) {
7441
7659
  return /* @__PURE__ */ jsx("div", { className: cn("mt-3", className), children });
@@ -8747,15 +8965,6 @@ function NFolderIcon({ size = "md", className }) {
8747
8965
  const iconSize = size === "xl" ? 72 : size === "lg" ? 56 : size === "md" ? 28 : 18;
8748
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 }) });
8749
8967
  }
8750
- function getIconColorProps(iconColor, baseClassName = "") {
8751
- if (!iconColor) return { className: cn(baseClassName, "text-muted-foreground"), style: {} };
8752
- if (iconColor.startsWith("text-")) return { className: cn(baseClassName, iconColor), style: {} };
8753
- return { className: baseClassName, style: { color: iconColor } };
8754
- }
8755
- function resolveIcon(icon) {
8756
- if (!icon) return null;
8757
- return /* @__PURE__ */ jsx(NIcon, { icon, size: 16 });
8758
- }
8759
8968
  var TextInput = ({ value, onChange, placeholder = "", icon, showIcon = true, iconColor, className = "", variant = "default", status = "default", bordered, borderColor, disabled = false, ...props }) => {
8760
8969
  const shouldDisplayIcon = Boolean(icon) && showIcon;
8761
8970
  const iconProps = getIconColorProps(iconColor, "h-4 w-4");
@@ -8810,41 +9019,10 @@ var TextAreaInput = ({ value, onChange, placeholder = "", className = "", varian
8810
9019
  }
8811
9020
  );
8812
9021
  };
8813
- function renderItems(items) {
8814
- return items.map((item) => {
8815
- const value = typeof item === "string" ? item : item.value;
8816
- const label = typeof item === "string" ? item : item.label;
8817
- return /* @__PURE__ */ jsx(SelectItem, { value, children: label }, value);
8818
- });
8819
- }
8820
- var SelectInput = ({ placeholder = "", value, onChange, icon, showIcon = true, iconColor, items, className = "", dropdownClassName, variant = "default", status = "default", bordered, borderColor, disabled = false }) => {
8821
- const shouldDisplayIcon = Boolean(icon) && showIcon && !value;
8822
- const iconProps = getIconColorProps(iconColor, "h-4 w-4");
8823
- const displayLabel = value ? (() => {
8824
- const found = items.find((i) => typeof i === "string" ? i === value : i.value === value);
8825
- return typeof found === "string" ? found : found?.label ?? value;
8826
- })() : "";
8827
- return /* @__PURE__ */ jsxs("div", { className: cn("relative", className), children: [
8828
- /* @__PURE__ */ jsxs(BaseInput, { variant, status, bordered, borderColor, className: "pointer-events-none", children: [
8829
- shouldDisplayIcon && /* @__PURE__ */ jsx("span", { className: iconProps.className, style: iconProps.style, children: resolveIcon(icon) }),
8830
- /* @__PURE__ */ jsx("span", { className: cn("flex-1 truncate text-sm", !displayLabel && "text-muted-foreground"), children: displayLabel || placeholder }),
8831
- /* @__PURE__ */ jsx(ChevronDown, { className: "h-4 w-4 shrink-0 opacity-50" })
8832
- ] }),
8833
- /* @__PURE__ */ jsxs(Select, { onValueChange: onChange, value: String(value || ""), disabled, children: [
8834
- /* @__PURE__ */ jsx(
8835
- SelectTrigger,
8836
- {
8837
- className: "absolute inset-0 w-full h-full opacity-0",
8838
- disabled,
8839
- "aria-label": placeholder || "Select"
8840
- }
8841
- ),
8842
- /* @__PURE__ */ jsx(SelectContent, { className: dropdownClassName, children: renderItems(items) })
8843
- ] }, String(value))
8844
- ] });
8845
- };
8846
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 }) => {
8847
9023
  const [open, setOpen] = useState(false);
9024
+ const triggerRef = React__default.useRef(null);
9025
+ const pointerDismissedRef = React__default.useRef(false);
8848
9026
  const [query, setQuery] = useState("");
8849
9027
  const normalizedItems = items.map((item) => typeof item === "string" ? { value: item, label: item } : item);
8850
9028
  const selectedItem = normalizedItems.find((item) => item.value === value);
@@ -8863,47 +9041,82 @@ var ComboboxInput = ({ placeholder = "Select...", searchPlaceholder = "Search...
8863
9041
  setOpen(o);
8864
9042
  if (!o) setQuery("");
8865
9043
  }, children: [
8866
- /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, disabled, children: /* @__PURE__ */ jsxs(BaseInput, { variant, status, bordered, borderColor, className: cn("cursor-pointer", className), children: [
8867
- shouldDisplayIcon && /* @__PURE__ */ jsx("span", { className: iconProps.className, style: iconProps.style, children: resolveIcon(icon) }),
8868
- /* @__PURE__ */ jsx("span", { className: cn("flex-1 truncate text-sm", !displayLabel && "text-muted-foreground"), children: displayLabel || placeholder }),
8869
- /* @__PURE__ */ jsx(ChevronsUpDown, { className: "h-4 w-4 shrink-0 opacity-50" })
8870
- ] }) }),
8871
- /* @__PURE__ */ jsx(PopoverContent, { className: "w-[var(--radix-popover-trigger-width)] p-0", align: "start", children: /* @__PURE__ */ jsxs(Command, { children: [
8872
- /* @__PURE__ */ jsx(
8873
- CommandInput,
8874
- {
8875
- placeholder: searchPlaceholder,
8876
- className: "h-9",
8877
- value: query,
8878
- onValueChange: setQuery,
8879
- onKeyDown: (e) => {
8880
- if (e.key === "Enter" && showFreeTextOption) {
8881
- e.preventDefault();
8882
- 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
+ }
8883
9094
  }
8884
- }
8885
- }
8886
- ),
8887
- /* @__PURE__ */ jsxs(CommandList, { children: [
8888
- /* @__PURE__ */ jsx(CommandEmpty, { children: emptyMessage }),
8889
- /* @__PURE__ */ jsxs(CommandGroup, { children: [
8890
- showFreeTextOption && /* @__PURE__ */ jsxs(CommandItem, { value: trimmedQuery, onSelect: () => commit(trimmedQuery), className: "cursor-pointer", children: [
8891
- /* @__PURE__ */ jsx(Check, { className: "mr-2 h-4 w-4 opacity-0" }),
8892
- 'Use "',
8893
- trimmedQuery,
8894
- '"'
8895
- ] }, "__free_text__"),
8896
- 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: [
8897
- /* @__PURE__ */ jsx(Check, { className: cn("mr-2 h-4 w-4", value === item.value ? "opacity-100" : "opacity-0") }),
8898
- item.label
8899
- ] }, 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
+ ] })
8900
9111
  ] })
8901
- ] })
8902
- ] }) })
9112
+ }
9113
+ )
8903
9114
  ] });
8904
9115
  };
8905
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 }) => {
8906
9117
  const [open, setOpen] = useState(false);
9118
+ const triggerRef = React__default.useRef(null);
9119
+ const pointerDismissedRef = React__default.useRef(false);
8907
9120
  const shouldDisplayIcon = Boolean(icon) && showIcon && value.length === 0;
8908
9121
  const iconProps = getIconColorProps(iconColor, "h-4 w-4");
8909
9122
  const handleSelect = (itemValue) => {
@@ -8916,37 +9129,71 @@ var MultiSelectInput = ({ placeholder = "Select items...", value = [], onChange,
8916
9129
  const displayedItems = value.slice(0, maxDisplay);
8917
9130
  const remainingCount = value.length - maxDisplay;
8918
9131
  return /* @__PURE__ */ jsxs(Popover, { open, onOpenChange: setOpen, children: [
8919
- /* @__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: [
8920
- shouldDisplayIcon && /* @__PURE__ */ jsx("span", { className: iconProps.className, style: iconProps.style, children: resolveIcon(icon) }),
8921
- /* @__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: [
8922
- displayedItems.map((itemValue) => /* @__PURE__ */ jsxs(Badge, { variant: "secondary", className: "text-xs px-2 py-0.5 gap-1", children: [
8923
- getItemLabel(itemValue),
8924
- !disabled && /* @__PURE__ */ jsx("button", { type: "button", onClick: (e) => {
8925
- e.stopPropagation();
8926
- onChange(value.filter((v) => v !== itemValue));
8927
- }, className: "ml-1 hover:text-destructive", children: /* @__PURE__ */ jsx(X, { className: "h-3 w-3" }) })
8928
- ] }, itemValue)),
8929
- remainingCount > 0 && /* @__PURE__ */ jsxs(Badge, { variant: "secondary", className: "text-xs px-2 py-0.5", children: [
8930
- "+",
8931
- remainingCount,
8932
- " 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
+ }) })
8933
9194
  ] })
8934
- ] }) }),
8935
- 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" })
8936
- ] }) }),
8937
- /* @__PURE__ */ jsx(PopoverContent, { className: "w-[var(--radix-popover-trigger-width)] p-0", align: "start", children: /* @__PURE__ */ jsxs(Command, { children: [
8938
- showSearch && /* @__PURE__ */ jsx(CommandInput, { placeholder: searchPlaceholder, className: "h-9" }),
8939
- /* @__PURE__ */ jsx(CommandEmpty, { children: emptyMessage }),
8940
- /* @__PURE__ */ jsx(CommandGroup, { className: "max-h-[300px] najm-overlay-scroll-y", children: items.map((item) => {
8941
- const itemValue = typeof item === "string" ? item : item.value;
8942
- const itemLabel = typeof item === "string" ? item : item.label;
8943
- const isSelected = value.includes(itemValue);
8944
- return /* @__PURE__ */ jsxs(CommandItem, { onSelect: () => handleSelect(itemValue), className: "flex items-center gap-2 cursor-pointer", children: [
8945
- /* @__PURE__ */ jsx(Checkbox, { checked: isSelected, onCheckedChange: () => handleSelect(itemValue), className: "pointer-events-none" }),
8946
- /* @__PURE__ */ jsx("span", { className: "flex-1", children: itemLabel })
8947
- ] }, itemValue);
8948
- }) })
8949
- ] }) })
9195
+ }
9196
+ )
8950
9197
  ] });
8951
9198
  };
8952
9199
  var layoutVariants = cva("flex items-start", { variants: { layout: { column: "flex-col gap-4", row: "flex-row gap-7" } }, defaultVariants: { layout: "row" } });
@@ -8955,14 +9202,14 @@ var RadioGroupInput = ({ value, onChange, className = "", variant = "default", s
8955
9202
  const itemLabel = typeof item === "string" ? item : item.label;
8956
9203
  return /* @__PURE__ */ jsxs("div", { className: "flex items-center space-y-0", children: [
8957
9204
  /* @__PURE__ */ jsx(RadioGroupItem, { value: itemValue }),
8958
- /* @__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 })
8959
9206
  ] }, itemValue);
8960
9207
  }) }) });
8961
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: [
8962
9209
  /* @__PURE__ */ jsx(Checkbox, { checked: value, onCheckedChange: onChange, className: cn("cursor-pointer transition-colors duration-200 border-primary", checkboxClassName) }),
8963
9210
  /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
8964
- /* @__PURE__ */ jsx(Label, { className: "cursor-pointer text-muted-foreground", onClick: () => onChange(!value), children: label }),
8965
- 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 })
8966
9213
  ] })
8967
9214
  ] });
8968
9215
  var layoutVariants2 = cva("flex items-start", {
@@ -9009,11 +9256,11 @@ function CheckboxGroupInput({
9009
9256
  }
9010
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: [
9011
9258
  /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
9012
- /* @__PURE__ */ jsxs(Label, { className: "flex items-center gap-2", children: [
9259
+ /* @__PURE__ */ jsxs(Label2, { className: "flex items-center gap-2", children: [
9013
9260
  iconPosition === "label" && icon && showIcon && /* @__PURE__ */ jsx("span", { className: "w-4 h-4", children: resolveIcon(icon) }),
9014
9261
  label
9015
9262
  ] }),
9016
- 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 })
9017
9264
  ] }),
9018
9265
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
9019
9266
  iconPosition === "input" && icon && showIcon && /* @__PURE__ */ jsx("span", { className: "w-4 h-4", children: resolveIcon(icon) }),
@@ -9026,7 +9273,7 @@ var DateInput = ({ value, onChange, placeholder = "Pick a date", className = "",
9026
9273
  const toDate = (val) => typeof val === "string" ? parseISO(val) : val;
9027
9274
  return /* @__PURE__ */ jsxs(BaseInput, { variant, status, bordered, borderColor, className, children: [
9028
9275
  /* @__PURE__ */ jsxs(Popover, { children: [
9029
- /* @__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 }) }) }),
9030
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" }) })
9031
9278
  ] }),
9032
9279
  !icon && showIcon && /* @__PURE__ */ jsx(Calendar$1, { className: iconProps.className, style: iconProps.style })
@@ -9051,9 +9298,9 @@ var FileInput = ({ value, onChange, placeholder = "No file chosen", icon, showIc
9051
9298
  /* @__PURE__ */ jsx("input", { type: "file", ref: fileInputRef, onChange: (e) => onChange(e.target.files?.[0] || null), className: "hidden" }),
9052
9299
  /* @__PURE__ */ jsxs("div", { className: "bg-muted flex h-full items-center px-3", children: [
9053
9300
  showIcon && (icon ? /* @__PURE__ */ jsx("span", { className: iconProps.className, style: iconProps.style, children: resolveIcon(icon) }) : /* @__PURE__ */ jsx(FileUp, { className: cn(iconProps.className) })),
9054
- /* @__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" })
9055
9302
  ] }),
9056
- /* @__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 }) })
9057
9304
  ] });
9058
9305
  };
9059
9306
  function formatBytes2(bytes) {
@@ -10224,7 +10471,7 @@ function NFormSectionHeader({
10224
10471
  ),
10225
10472
  children: [
10226
10473
  Icon2 && /* @__PURE__ */ jsx(Icon2, { className: "w-4 h-4 shrink-0 text-current" }),
10227
- /* @__PURE__ */ jsx(Label, { className: "text-sm font-semibold leading-none text-current", children: title })
10474
+ /* @__PURE__ */ jsx(Label2, { className: "text-sm font-semibold leading-none text-current", children: title })
10228
10475
  ]
10229
10476
  }
10230
10477
  );
@@ -14139,4 +14386,4 @@ function NGridItem({
14139
14386
  return /* @__PURE__ */ jsx("div", { className: itemClassName, ...props, children });
14140
14387
  }
14141
14388
 
14142
- 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 };
14389
+ 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, 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 };