najm-kit 2.9.0 → 2.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1,11 +1,13 @@
1
1
  import { resolveAvatarSrc } from './chunk-BEGOH366.mjs';
2
2
  export { isPlaceholderAvatar, resolveAvatarSrc } from './chunk-BEGOH366.mjs';
3
- import { useResolvedFormDevTools, useNBranding } from './chunk-GHMR45H3.mjs';
4
- export { FormDevToolsProvider, NBrandingProvider, NBrandingStateProvider, NajmFormatProvider, buildFormFill, normalizeBranding, useNBranding, useNBrandingEditor, useNajmFormat, useNajmFormatContext } from './chunk-GHMR45H3.mjs';
5
- import { useResolvedPaginationLabels } from './chunk-USZUOJMK.mjs';
6
- export { DEFAULT_PAGINATION_KEY_PREFIX, DEFAULT_TIME_ZONE, EMPTY_DESIGN, NTableDefaultsProvider, NajmDesignEditorProvider, NajmPreferencesProvider, NajmUIProvider, buildPaginationLabels, useNTableDefaults, useNajmDesignEditor, useNajmPreferencesContext, useNajmTheme, useNajmTimeZone } from './chunk-USZUOJMK.mjs';
7
- import { inputBorderClasses, Button, NIcon, NajmScroll, surfaceBorderClasses, useNajmScrollViewport, buttonVariants, NButton, useTableStore, TableStoreContext, sidebarBorderClasses, NTableJson } from './chunk-JUYT2ISO.mjs';
8
- export { Button, NButton, NIcon, NTableJson, NajmScroll, TableStoreContext, buttonVariants, inputBorderClasses, sidebarBorderClasses, surfaceBorderClasses, useTableStore } from './chunk-JUYT2ISO.mjs';
3
+ import { NLoadingState, NErrorState, NEmptyState, useResolvedFormDevTools, useNBranding } from './chunk-2GFWF46W.mjs';
4
+ export { FormDevToolsProvider, NBrandingProvider, NBrandingStateProvider, NEmptyState, NErrorState, NForbiddenState, NLoadingState, NNotFoundState, NPageLayout, NSpinner, NajmFormatProvider, buildFormFill, normalizeBranding, useNBranding, useNBrandingEditor, useNajmFormat, useNajmFormatContext } from './chunk-2GFWF46W.mjs';
5
+ import { normalizeImageSources, useImageChain, useNBadgeDefaults, mergeBadgeMaps, resolveStatusColor, resolveBadgeStatusLabel, colorTextClass, useResolvedPaginationLabels } from './chunk-EEBLEDNI.mjs';
6
+ export { DEFAULT_PAGINATION_KEY_PREFIX, DEFAULT_TIME_ZONE, EMPTY_DESIGN, NAJM_COLOR_TEXT_CLASSES, NAJM_STATUS_COLORS, NTableDefaultsProvider, NajmDesignEditorProvider, NajmPreferencesProvider, NajmUIProvider, buildPaginationLabels, colorTextClass, findStatusColor, normalizeStatusToken, resolveStatusColor, statusTextClass, useNTableDefaults, useNajmDesignEditor, useNajmPreferencesContext, useNajmTheme, useNajmTimeZone } from './chunk-EEBLEDNI.mjs';
7
+ import { NajmScroll, useNajmScrollViewport, useTableStore, TableStoreContext, NTableJson } from './chunk-K7T7X6PX.mjs';
8
+ export { NTableJson, NajmScroll, TableStoreContext, useTableStore } from './chunk-K7T7X6PX.mjs';
9
+ import { inputBorderClasses, Button, NIcon, surfaceBorderClasses, buttonVariants, NButton, sidebarBorderClasses } from './chunk-XZL32HFR.mjs';
10
+ export { Button, NButton, NIcon, buttonVariants, inputBorderClasses, sidebarBorderClasses, surfaceBorderClasses } from './chunk-XZL32HFR.mjs';
9
11
  import { useNajmComponentStyle, cn, NajmThemeContainerCtx, useNajmThemeMode, useNajmDesign, composePreset } from './chunk-KVZACF4G.mjs';
10
12
  export { NajmDesignProvider, NajmThemeProvider, cn, composePreset, resolvePreset, useNajmAppearance, useNajmComponentStyle, useNajmDesign, useNajmThemeMode } from './chunk-KVZACF4G.mjs';
11
13
  export { DEFAULT_CARD_BREAKPOINT, DEFAULT_CARD_PAGINATION_KEY_PREFIX, buildCardPaginationLabels, createCardPagination, useCardViewport, useDesktopTableMode, useMediaQuery } from './chunk-OUS7OYVA.mjs';
@@ -15,11 +17,11 @@ export { DEFAULT_PLACEHOLDER, formatCurrency, formatDate, formatDateTime, format
15
17
  export { DEFAULT_MAX_PAGE_SIZE, DEFAULT_PAGE_SIZE, cleanQuery, createOffsetPagination, fetchOffsetPage, getPageIndex } from './chunk-2NX2VKS2.mjs';
16
18
  import { resolveRadiusValue, resolveVariantAlias, parseNajmDesignConfig } from './chunk-TFHWLE7N.mjs';
17
19
  export { NAJM_COMPONENT_NAMES, RADIUS_VALUE_MAP, defineNajmDesignConfig, defineNajmThemeConfig, parseNajmDesignConfig, parseNajmThemeConfig, resolveRadiusValue, resolveVariantAlias, stringifyNajmDesignConfig, stringifyNajmThemeConfig } from './chunk-TFHWLE7N.mjs';
18
- import * as React60 from 'react';
19
- import React60__default, { createContext, useRef, useMemo, useState, useEffect, useContext, useCallback, useLayoutEffect, isValidElement } from 'react';
20
+ import * as React61 from 'react';
21
+ import React61__default, { createContext, useRef, useMemo, useState, useEffect, useContext, useCallback, useLayoutEffect, isValidElement } from 'react';
20
22
  import * as TabsPrimitive from '@radix-ui/react-tabs';
21
23
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
22
- import { ChevronDown, AlertTriangle, RefreshCw, X, XIcon, Menu, Search, SearchIcon, CheckIcon, ChevronUp, ChevronDownIcon, ChevronUpIcon, Eye, EyeOff, ChevronsUpDown, Check, CircleIcon, ChevronLeftIcon, ChevronRightIcon, Calendar as Calendar$1, FileUp, Folder, UploadCloud, CheckCircle2, AlertCircle, Camera, Star, Globe, Clock, Trash2, Plus, Upload, Download, RotateCcw, Table as Table$1, FileJson, ChevronRight, ArrowUpDown, Loader2, MoreVertical, Edit, ChevronsLeft, ChevronLeft, ChevronsRight, Pencil, Merge, PanelLeftOpen, PanelLeftClose, LogOut, Image, ArrowUp, ArrowDown, CheckSquare, FilePlus, FolderPlus, Share2, Move, ClipboardPaste, Copy, Scissors, LoaderCircleIcon, LoaderPinwheelIcon, LoaderIcon, ArrowUpRight, ArrowDownRight, SlidersHorizontal, Columns3, Settings, Filter, SearchX, Inbox, List, LayoutGrid, Code, FolderOpen } from 'lucide-react';
24
+ import { ChevronDown, AlertTriangle, RefreshCw, X, XIcon, Menu, Search, SearchIcon, CheckIcon, ChevronUp, ChevronDownIcon, ChevronUpIcon, Eye, EyeOff, ChevronsUpDown, Check, CircleIcon, ChevronLeftIcon, ChevronRightIcon, Calendar as Calendar$1, FileUp, Folder, UploadCloud, CheckCircle2, AlertCircle, Camera, Star, Globe, Clock, Trash2, Plus, Upload, Download, RotateCcw, Table as Table$1, FileJson, ChevronRight, ArrowUpDown, Loader2, Copy, MoreVertical, Edit, ChevronsLeft, ChevronLeft, ChevronsRight, Pencil, Merge, PanelLeftOpen, PanelLeftClose, LogOut, Image, ArrowUp, ArrowDown, CheckSquare, FilePlus, FolderPlus, Share2, Move, ClipboardPaste, Scissors, ArrowUpRight, ArrowDownRight, SlidersHorizontal, Columns3, Settings, Filter, SearchX, Inbox, List, LayoutGrid, Code, FolderOpen } from 'lucide-react';
23
25
  import * as TooltipPrimitive from '@radix-ui/react-tooltip';
24
26
  import { cva } from 'class-variance-authority';
25
27
  import { HexColorPicker } from 'react-colorful';
@@ -51,6 +53,9 @@ import { FormProvider, Controller, useFormContext, useForm, useFieldArray } from
51
53
  import { zodResolver } from '@hookform/resolvers/zod';
52
54
  import { getExpandedRowModel, getSortedRowModel, getPaginationRowModel, getFilteredRowModel, getCoreRowModel, useReactTable, flexRender } from '@tanstack/react-table';
53
55
 
56
+ // src/theme/focus.ts
57
+ var focusRingClasses = "outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50";
58
+ var focusRingWithinClasses = "focus-visible:ring-[3px] focus-visible:ring-ring/50 has-[:focus-visible]:ring-[3px] has-[:focus-visible]:ring-ring/50";
54
59
  function Tabs({
55
60
  className,
56
61
  variant = "pills",
@@ -134,7 +139,8 @@ function TabsTrigger({
134
139
  {
135
140
  "data-slot": "tabs-trigger",
136
141
  className: cn(
137
- "inline-flex cursor-pointer items-center justify-center gap-1.5 text-sm font-medium whitespace-nowrap text-muted-foreground transition-[color,box-shadow] outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
142
+ "inline-flex cursor-pointer items-center justify-center gap-1.5 text-sm font-medium whitespace-nowrap text-muted-foreground transition-[color,box-shadow] disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
143
+ focusRingClasses,
138
144
  triggerVariantMap[variant],
139
145
  className
140
146
  ),
@@ -143,7 +149,14 @@ function TabsTrigger({
143
149
  );
144
150
  }
145
151
  function TabsContent({ className, ...props }) {
146
- return /* @__PURE__ */ jsx(TabsPrimitive.Content, { "data-slot": "tabs-content", className: cn("flex-1 outline-none", className), ...props });
152
+ return /* @__PURE__ */ jsx(
153
+ TabsPrimitive.Content,
154
+ {
155
+ "data-slot": "tabs-content",
156
+ className: cn("flex-1", focusRingClasses, className),
157
+ ...props
158
+ }
159
+ );
147
160
  }
148
161
 
149
162
  // src/components/tabs/tabColors.ts
@@ -262,7 +275,7 @@ function NTabs({
262
275
  }
263
276
  var PORTAL_LAYER_STYLE_ID = "najm-kit-portal-layer-styles";
264
277
  function useNajmPortalLayerStyles() {
265
- React60.useInsertionEffect(() => {
278
+ React61.useInsertionEffect(() => {
266
279
  if (typeof document === "undefined") return;
267
280
  if (document.getElementById(PORTAL_LAYER_STYLE_ID)) return;
268
281
  const style = document.createElement("style");
@@ -293,7 +306,7 @@ var tooltipContentVariants = cva(
293
306
  }
294
307
  );
295
308
  function TooltipContent({ className, sideOffset = 4, variant, children, ...props }) {
296
- const container = React60.useContext(NajmThemeContainerCtx);
309
+ const container = React61.useContext(NajmThemeContainerCtx);
297
310
  useNajmPortalLayerStyles();
298
311
  return /* @__PURE__ */ jsx(TooltipPrimitive.Portal, { container: container ?? void 0, children: /* @__PURE__ */ jsx(
299
312
  TooltipPrimitive.Content,
@@ -443,7 +456,7 @@ var ERROR_BORDER = "border !border-red-600";
443
456
  var FOCUS_INTERACTIVE_BASE = "border focus-within:border-primary";
444
457
  var HOVER_INTERACTIVE_BASE = "hover:border-primary";
445
458
  var STATIC_BASE = "border";
446
- var BaseInput = React60__default.forwardRef(
459
+ var BaseInput = React61__default.forwardRef(
447
460
  ({ children, variant = "default", status = "default", bordered, borderColor, className, style, disabled = false, onHover, onClick, hasIcon, ...rest }, ref) => {
448
461
  const recipe = useNajmComponentStyle("input");
449
462
  const isGhost = variant === "ghost";
@@ -472,6 +485,13 @@ var BaseInput = React60__default.forwardRef(
472
485
  style: recipeRadius ? { borderRadius: recipeRadius, ...style } : style,
473
486
  className: cn(
474
487
  inputVariants({ variant, status, hasIcon, disabled }),
488
+ // The wrapper is what the user reads as "the field": the inner
489
+ // control is stripped of its own ring precisely so this element can
490
+ // carry the border. Until this was added, the border merely changed
491
+ // colour on focus — a 1px hue shift and nothing else — and the number
492
+ // fields and the multi-select trigger came out of the acceptance walk
493
+ // as tab stops with no visible indicator at all.
494
+ !isGhost && focusRingWithinClasses,
475
495
  !isGhost && borderClass,
476
496
  !isGhost && colorClass,
477
497
  className
@@ -495,7 +515,7 @@ function PopoverAnchor({ ...props }) {
495
515
  return /* @__PURE__ */ jsx(PopoverPrimitive.Anchor, { "data-slot": "popover-anchor", ...props });
496
516
  }
497
517
  function PopoverContent({ className, align = "center", sideOffset = 4, ...props }) {
498
- const container = React60.useContext(NajmThemeContainerCtx);
518
+ const container = React61.useContext(NajmThemeContainerCtx);
499
519
  useNajmPortalLayerStyles();
500
520
  return /* @__PURE__ */ jsx(PopoverPrimitive.Portal, { container: container ?? void 0, children: /* @__PURE__ */ jsx(
501
521
  PopoverPrimitive.Content,
@@ -604,7 +624,7 @@ function SwatchesColorPicker({
604
624
  hideSwatches = false
605
625
  }) {
606
626
  const inputRef = useRef(null);
607
- const themeContainer = React60__default.useContext(NajmThemeContainerCtx);
627
+ const themeContainer = React61__default.useContext(NajmThemeContainerCtx);
608
628
  const resolvedValue = resolvePickerColor(value, themeContainer);
609
629
  return /* @__PURE__ */ jsxs(
610
630
  BaseInput,
@@ -674,7 +694,7 @@ function PopoverColorPicker({
674
694
  formats = DEFAULT_FORMATS,
675
695
  output = "preserve"
676
696
  }) {
677
- const themeContainer = React60__default.useContext(NajmThemeContainerCtx);
697
+ const themeContainer = React61__default.useContext(NajmThemeContainerCtx);
678
698
  const resolvedValue = resolvePickerColor(value, themeContainer);
679
699
  const initialFormat = formats.includes(detectFormat(resolvedValue)) ? detectFormat(resolvedValue) : formats[0] ?? "hex";
680
700
  const [activeFormat, setActiveFormat] = useState(initialFormat);
@@ -835,8 +855,18 @@ function SegmentedControl({
835
855
  function Collapsible({ ...props }) {
836
856
  return /* @__PURE__ */ jsx(CollapsiblePrimitive.Root, { "data-slot": "collapsible", ...props });
837
857
  }
838
- function CollapsibleTrigger2({ ...props }) {
839
- return /* @__PURE__ */ jsx(CollapsiblePrimitive.CollapsibleTrigger, { "data-slot": "collapsible-trigger", ...props });
858
+ function CollapsibleTrigger2({
859
+ className,
860
+ ...props
861
+ }) {
862
+ return /* @__PURE__ */ jsx(
863
+ CollapsiblePrimitive.CollapsibleTrigger,
864
+ {
865
+ "data-slot": "collapsible-trigger",
866
+ className: cn(focusRingClasses, className),
867
+ ...props
868
+ }
869
+ );
840
870
  }
841
871
  function CollapsibleContent2({ ...props }) {
842
872
  return /* @__PURE__ */ jsx(CollapsiblePrimitive.CollapsibleContent, { "data-slot": "collapsible-content", ...props });
@@ -931,7 +961,7 @@ function SheetClose({ ...props }) {
931
961
  return /* @__PURE__ */ jsx(SheetPrimitive.Close, { "data-slot": "sheet-close", ...props });
932
962
  }
933
963
  function SheetPortal({ ...props }) {
934
- const container = React60.useContext(NajmThemeContainerCtx);
964
+ const container = React61.useContext(NajmThemeContainerCtx);
935
965
  return /* @__PURE__ */ jsx(SheetPrimitive.Portal, { "data-slot": "sheet-portal", container: container ?? void 0, ...props });
936
966
  }
937
967
  function SheetOverlay({ className, ...props }) {
@@ -1080,7 +1110,7 @@ function DialogTrigger({ ...props }) {
1080
1110
  return /* @__PURE__ */ jsx(SheetPrimitive.Trigger, { "data-slot": "dialog-trigger", ...props });
1081
1111
  }
1082
1112
  function DialogPortal({ ...props }) {
1083
- const container = React60.useContext(NajmThemeContainerCtx);
1113
+ const container = React61.useContext(NajmThemeContainerCtx);
1084
1114
  return /* @__PURE__ */ jsx(SheetPrimitive.Portal, { "data-slot": "dialog-portal", container: container ?? void 0, ...props });
1085
1115
  }
1086
1116
  function DialogClose({ ...props }) {
@@ -1111,8 +1141,8 @@ function getDefaultPadding() {
1111
1141
  return window.matchMedia(MOBILE_PADDING_QUERY).matches ? "sm" : "md";
1112
1142
  }
1113
1143
  function useResponsivePadding(value) {
1114
- const [resolved, setResolved] = React60.useState(() => value ?? getDefaultPadding());
1115
- React60.useEffect(() => {
1144
+ const [resolved, setResolved] = React61.useState(() => value ?? getDefaultPadding());
1145
+ React61.useEffect(() => {
1116
1146
  if (value) {
1117
1147
  setResolved(value);
1118
1148
  return;
@@ -1126,9 +1156,18 @@ function useResponsivePadding(value) {
1126
1156
  }, [value]);
1127
1157
  return resolved;
1128
1158
  }
1129
- function DialogContent({ className, children, padding, hideClose = false, ...props }) {
1159
+ function DialogContent({
1160
+ className,
1161
+ children,
1162
+ padding,
1163
+ hideClose = false,
1164
+ onOpenAutoFocus,
1165
+ onCloseAutoFocus,
1166
+ ...props
1167
+ }) {
1130
1168
  const resolvedPadding = useResponsivePadding(padding);
1131
1169
  const portalClassName = useNPortalScope();
1170
+ const openerRef = React61.useRef(null);
1132
1171
  return /* @__PURE__ */ jsx(DialogPortal, { "data-slot": "dialog-portal", children: /* @__PURE__ */ jsxs("div", { className: portalClassName, children: [
1133
1172
  /* @__PURE__ */ jsx(DialogOverlay, {}),
1134
1173
  /* @__PURE__ */ jsxs(
@@ -1136,6 +1175,22 @@ function DialogContent({ className, children, padding, hideClose = false, ...pro
1136
1175
  {
1137
1176
  "data-slot": "dialog-content",
1138
1177
  "data-padding": resolvedPadding,
1178
+ onOpenAutoFocus: (event) => {
1179
+ const active = document.activeElement;
1180
+ openerRef.current = active instanceof HTMLElement && active !== document.body ? active : null;
1181
+ onOpenAutoFocus?.(event);
1182
+ },
1183
+ onCloseAutoFocus: (event) => {
1184
+ onCloseAutoFocus?.(event);
1185
+ if (event.defaultPrevented) return;
1186
+ const opener = openerRef.current;
1187
+ setTimeout(() => {
1188
+ if (!opener?.isConnected) return;
1189
+ const active = document.activeElement;
1190
+ const lost = !active || active === document.body || active === document.documentElement || !active.isConnected;
1191
+ if (lost) opener.focus();
1192
+ }, 0);
1193
+ },
1139
1194
  className: cn(
1140
1195
  "bg-card text-card-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 fixed top-[50%] left-[50%] z-50 grid w-full max-w-sm translate-x-[-50%] translate-y-[-50%] gap-4 rounded-none lg:rounded-lg najm-border border-border shadow-lg duration-200",
1141
1196
  dialogPaddingMap[resolvedPadding],
@@ -1176,7 +1231,7 @@ var sizeClasses2 = {
1176
1231
  md: "h-8 w-8",
1177
1232
  lg: "h-10 w-10"
1178
1233
  };
1179
- var IconButton = React60.forwardRef(
1234
+ var IconButton = React61.forwardRef(
1180
1235
  ({
1181
1236
  className,
1182
1237
  variant = "ghost",
@@ -1258,10 +1313,10 @@ function NPageHeaderTop({ children, className }) {
1258
1313
  }
1259
1314
  NPageHeaderTop.displayName = "NPageHeaderTop";
1260
1315
  function isPageHeaderSlot(child, slot) {
1261
- return React60__default.isValidElement(child) && child.type === slot;
1316
+ return React61__default.isValidElement(child) && child.type === slot;
1262
1317
  }
1263
1318
  function getSlotElements(children, slot) {
1264
- const matches = React60__default.Children.toArray(children).filter((child) => isPageHeaderSlot(child, slot));
1319
+ const matches = React61__default.Children.toArray(children).filter((child) => isPageHeaderSlot(child, slot));
1265
1320
  return matches.length > 0 ? matches : void 0;
1266
1321
  }
1267
1322
  var responsiveClasses = {
@@ -1674,8 +1729,8 @@ function NDialogSecondaryButton(_props) {
1674
1729
  function parseDirectDialogSlots(children) {
1675
1730
  const body = [];
1676
1731
  const parsed = {};
1677
- React60__default.Children.forEach(children, (child) => {
1678
- if (!React60__default.isValidElement(child)) {
1732
+ React61__default.Children.forEach(children, (child) => {
1733
+ if (!React61__default.isValidElement(child)) {
1679
1734
  body.push(child);
1680
1735
  return;
1681
1736
  }
@@ -1748,15 +1803,15 @@ var dialogVariants = cva(
1748
1803
  );
1749
1804
  var CONTENT_ACTIONS_SELECTOR = '[data-najm-dialog-actions="content"], [data-najm-wizard-form="true"]';
1750
1805
  function useContentOwnsActions() {
1751
- const [contentElement, setContentElement] = React60__default.useState(null);
1752
- const [contentOwnsActions, setContentOwnsActions] = React60__default.useState(false);
1753
- const contentElementRef = React60__default.useRef(null);
1754
- const handleContentElementRef = React60__default.useCallback((node) => {
1806
+ const [contentElement, setContentElement] = React61__default.useState(null);
1807
+ const [contentOwnsActions, setContentOwnsActions] = React61__default.useState(false);
1808
+ const contentElementRef = React61__default.useRef(null);
1809
+ const handleContentElementRef = React61__default.useCallback((node) => {
1755
1810
  if (contentElementRef.current === node) return;
1756
1811
  contentElementRef.current = node;
1757
1812
  setContentElement(node);
1758
1813
  }, []);
1759
- React60__default.useLayoutEffect(() => {
1814
+ React61__default.useLayoutEffect(() => {
1760
1815
  if (!contentElement) {
1761
1816
  setContentOwnsActions((current) => current ? false : current);
1762
1817
  return;
@@ -2009,8 +2064,8 @@ function NDirectDialog({
2009
2064
  const resolvedHeaderClassName = cn(slots.header?.className, headerClassName);
2010
2065
  const resolvedTitleClassName = cn(slots.header?.titleClassName, titleClassName);
2011
2066
  const resolvedDescriptionClassName = cn(slots.description?.className, descriptionClassName);
2012
- const [internalOpen, setInternalOpen] = React60__default.useState(defaultOpen);
2013
- const [primaryLoading, setPrimaryLoading] = React60__default.useState(false);
2067
+ const [internalOpen, setInternalOpen] = React61__default.useState(defaultOpen);
2068
+ const [primaryLoading, setPrimaryLoading] = React61__default.useState(false);
2014
2069
  const isControlled = open !== void 0;
2015
2070
  const currentOpen = isControlled ? open : internalOpen;
2016
2071
  const setOpen = (nextOpen) => {
@@ -2292,7 +2347,7 @@ function useDialog(store) {
2292
2347
  description: options.description,
2293
2348
  size: options.size || "sm",
2294
2349
  className: options.className,
2295
- render: ({ dialog, zIndex, confirm, cancel, onOpenChange }) => React60__default.createElement(NDeleteDialog, {
2350
+ render: ({ dialog, zIndex, confirm, cancel, onOpenChange }) => React61__default.createElement(NDeleteDialog, {
2296
2351
  itemName: options.itemName,
2297
2352
  itemType: options.itemType,
2298
2353
  icon: options.icon,
@@ -2408,77 +2463,6 @@ function Checkbox({ className, ...props }) {
2408
2463
  }
2409
2464
  );
2410
2465
  }
2411
-
2412
- // src/components/Badge/status.ts
2413
- var NAJM_STATUS_COLORS = {
2414
- active: "success",
2415
- approved: "success",
2416
- completed: "success",
2417
- confirmed: "success",
2418
- delivered: "success",
2419
- paid: "success",
2420
- published: "success",
2421
- succeeded: "success",
2422
- validated: "success",
2423
- verified: "success",
2424
- in_preparation: "warning",
2425
- in_progress: "warning",
2426
- out_for_delivery: "warning",
2427
- pending: "warning",
2428
- pending_email_verification: "warning",
2429
- pending_review: "warning",
2430
- processing: "warning",
2431
- submitted: "warning",
2432
- paused: "info",
2433
- purchased: "info",
2434
- scheduled: "info",
2435
- archived: "neutral",
2436
- cancelled: "neutral",
2437
- canceled: "neutral",
2438
- closed: "neutral",
2439
- draft: "neutral",
2440
- inactive: "neutral",
2441
- stopped: "neutral",
2442
- unknown: "neutral",
2443
- blocked: "destructive",
2444
- expired: "destructive",
2445
- failed: "destructive",
2446
- refunded: "destructive",
2447
- rejected: "destructive",
2448
- suspended: "destructive"
2449
- };
2450
- var NAJM_COLOR_TEXT_CLASSES = {
2451
- primary: "text-primary",
2452
- secondary: "text-secondary-foreground",
2453
- accent: "text-accent-foreground",
2454
- neutral: "text-muted-foreground",
2455
- info: "text-info",
2456
- success: "text-success",
2457
- warning: "text-warning",
2458
- destructive: "text-destructive"
2459
- };
2460
- function normalizeStatus(status) {
2461
- return status.trim().toLowerCase().replace(/[\s-]+/g, "_");
2462
- }
2463
- function lookup(map, status, normalized) {
2464
- if (!map) return void 0;
2465
- return map[status] ?? map[normalized];
2466
- }
2467
- function findStatusColor(status, statusMap) {
2468
- if (!status) return void 0;
2469
- const normalized = normalizeStatus(status);
2470
- return lookup(statusMap, status, normalized) ?? lookup(NAJM_STATUS_COLORS, status, normalized);
2471
- }
2472
- function resolveStatusColor(status, statusMap, fallback = "neutral") {
2473
- return findStatusColor(status, statusMap) ?? fallback;
2474
- }
2475
- function colorTextClass(color) {
2476
- return NAJM_COLOR_TEXT_CLASSES[color] ?? "text-foreground";
2477
- }
2478
- function statusTextClass(status, statusMap, fallback) {
2479
- const color = findStatusColor(status, statusMap) ?? fallback;
2480
- return color ? colorTextClass(color) : "";
2481
- }
2482
2466
  var badgeVariants = cva(
2483
2467
  "inline-flex items-center justify-center rounded-md border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden",
2484
2468
  {
@@ -2588,29 +2572,37 @@ function Badge({
2588
2572
  }) {
2589
2573
  const Comp = asChild ? Slot : "span";
2590
2574
  const recipe = useNajmComponentStyle("badge");
2575
+ const ambient = useNBadgeDefaults();
2576
+ const statusDefaults = status ? ambient?.defaults : void 0;
2577
+ const effectiveLook = look ?? statusDefaults?.look;
2578
+ const effectiveShape = shape ?? statusDefaults?.shape;
2579
+ const effectiveSize = size ?? statusDefaults?.size;
2580
+ const effectiveShowIcon = showIcon ?? statusDefaults?.showIcon;
2581
+ const effectiveStatusMap = mergeBadgeMaps(statusDefaults?.statusMap, statusMap);
2582
+ const effectiveIconMap = mergeBadgeMaps(statusDefaults?.iconMap, iconMap);
2591
2583
  const aliased = resolveVariantAlias(
2592
2584
  recipe?.variants,
2593
2585
  variant ?? recipe?.defaultVariant ?? "default"
2594
2586
  );
2595
2587
  const effVariant = variant ?? aliased.variant ?? recipe?.defaultVariant;
2596
- const recipeRadius = shape === void 0 ? resolveRadiusValue(recipe?.radius) : void 0;
2588
+ const recipeRadius = effectiveShape === void 0 ? resolveRadiusValue(recipe?.radius) : void 0;
2597
2589
  const recipeStyle = recipeRadius ? { borderRadius: recipeRadius, ...style } : style;
2598
- const resolvedColor = status ? resolveStatusColor(status, statusMap, color ?? "neutral") : color ?? "primary";
2599
- const resolvedLabel = label ?? (typeof children === "string" ? children : void 0) ?? (status ? humanizeToken(status) : void 0);
2590
+ const resolvedColor = status ? resolveStatusColor(status, effectiveStatusMap, color ?? "neutral") : color ?? "primary";
2591
+ const resolvedLabel = label ?? (typeof children === "string" ? children : void 0) ?? (status ? resolveBadgeStatusLabel(status, statusDefaults, ambient?.t) ?? humanizeToken(status) : void 0);
2600
2592
  const content = typeof children !== "string" && children ? children : resolvedLabel ?? children;
2601
- const resolvedIcon = icon ?? (resolvedColor ? iconMap?.[resolvedColor] : void 0);
2602
- const iconNode = renderIcon(showIcon ? resolvedIcon : icon);
2603
- const isMinimal = look === "minimal" || look === "text";
2593
+ const resolvedIcon = icon ?? (resolvedColor ? effectiveIconMap?.[resolvedColor] : void 0);
2594
+ const iconNode = renderIcon(effectiveShowIcon ? resolvedIcon : icon);
2595
+ const isMinimal = effectiveLook === "minimal" || effectiveLook === "text";
2604
2596
  if (isMinimal) {
2605
2597
  const textColor = colorTextClass(resolvedColor);
2606
- const sizeClass = SIZE_TEXT_MAP[size ?? "md"] ?? "text-sm";
2598
+ const sizeClass = SIZE_TEXT_MAP[effectiveSize ?? "md"] ?? "text-sm";
2607
2599
  return /* @__PURE__ */ jsxs(
2608
2600
  Comp,
2609
2601
  {
2610
2602
  "data-slot": "badge",
2611
2603
  className: cn(
2612
2604
  "inline-flex items-center gap-1.5 font-medium bg-transparent border-0",
2613
- look === "text" ? "px-0" : void 0,
2605
+ effectiveLook === "text" ? "px-0" : void 0,
2614
2606
  textColor,
2615
2607
  sizeClass,
2616
2608
  className
@@ -2625,7 +2617,12 @@ function Badge({
2625
2617
  }
2626
2618
  );
2627
2619
  }
2628
- const classes = resolvedColor ? badgeColorVariants({ color: resolvedColor, look, size, shape }) : badgeVariants({ variant: effVariant });
2620
+ const classes = resolvedColor ? badgeColorVariants({
2621
+ color: resolvedColor,
2622
+ look: effectiveLook,
2623
+ size: effectiveSize,
2624
+ shape: effectiveShape
2625
+ }) : badgeVariants({ variant: effVariant });
2629
2626
  return /* @__PURE__ */ jsxs(Comp, { "data-slot": "badge", className: cn(classes, aliased.style?.className, className), style: recipeStyle, ...props, children: [
2630
2627
  iconPosition === "left" && iconNode,
2631
2628
  content,
@@ -2644,8 +2641,8 @@ function resolveIcon(icon) {
2644
2641
  }
2645
2642
  var MultiSelectInput = ({ ariaLabel, 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 }) => {
2646
2643
  const [open, setOpen] = useState(false);
2647
- const triggerRef = React60__default.useRef(null);
2648
- const pointerDismissedRef = React60__default.useRef(false);
2644
+ const triggerRef = React61__default.useRef(null);
2645
+ const pointerDismissedRef = React61__default.useRef(false);
2649
2646
  const shouldDisplayIcon = Boolean(icon) && showIcon && value.length === 0;
2650
2647
  const iconProps = getIconColorProps(iconColor, "h-4 w-4");
2651
2648
  const handleSelect = (itemValue) => {
@@ -2761,7 +2758,7 @@ function SelectScrollDownButton({ className, ...props }) {
2761
2758
  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" }) });
2762
2759
  }
2763
2760
  function SelectContent({ className, children, position = "popper", style, ...props }) {
2764
- const container = React60.useContext(NajmThemeContainerCtx);
2761
+ const container = React61.useContext(NajmThemeContainerCtx);
2765
2762
  const recipe = useNajmComponentStyle("select");
2766
2763
  const contentSlot = recipe?.slots?.content;
2767
2764
  const borderWidth = contentSlot?.borderWidth ?? recipe?.borderWidth;
@@ -2844,9 +2841,9 @@ var SelectInput = ({ placeholder = "", ariaLabel, value, onChange, icon, showIco
2844
2841
  (item) => typeof item === "string" ? item === value : item.value === value
2845
2842
  );
2846
2843
  const displayLabel = typeof found === "string" ? found : found?.label ?? value;
2847
- const [open, setOpen] = React60__default.useState(false);
2848
- const triggerRef = React60__default.useRef(null);
2849
- const pointerDismissedRef = React60__default.useRef(false);
2844
+ const [open, setOpen] = React61__default.useState(false);
2845
+ const triggerRef = React61__default.useRef(null);
2846
+ const pointerDismissedRef = React61__default.useRef(false);
2850
2847
  return /* @__PURE__ */ jsxs("div", { className: cn("group relative", className), children: [
2851
2848
  /* @__PURE__ */ jsxs(
2852
2849
  BaseInput,
@@ -3714,7 +3711,7 @@ function CollapsibleSection({
3714
3711
  children,
3715
3712
  disabled
3716
3713
  }) {
3717
- const [open, setOpen] = React60.useState(true);
3714
+ const [open, setOpen] = React61.useState(true);
3718
3715
  const titleText = typeof title === "string" || typeof title === "number" ? String(title) : "Section";
3719
3716
  return /* @__PURE__ */ jsxs(
3720
3717
  Collapsible,
@@ -3734,7 +3731,8 @@ function CollapsibleSection({
3734
3731
  className: cn(
3735
3732
  "flex w-full items-center justify-between gap-2 px-3 py-2 text-xs font-semibold uppercase tracking-wide",
3736
3733
  "text-muted-foreground hover:text-foreground",
3737
- "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:rounded-md",
3734
+ focusRingClasses,
3735
+ "focus-visible:rounded-md",
3738
3736
  "disabled:pointer-events-none disabled:opacity-50"
3739
3737
  ),
3740
3738
  children: [
@@ -4032,7 +4030,7 @@ function TokenGroupSection({
4032
4030
  disabled,
4033
4031
  labels
4034
4032
  }) {
4035
- const [open, setOpen] = React60.useState(groupId === "surface" || groupId === "brand");
4033
+ const [open, setOpen] = React61.useState(groupId === "surface" || groupId === "brand");
4036
4034
  const labelText = typeof label === "string" || typeof label === "number" ? String(label) : "Group";
4037
4035
  return /* @__PURE__ */ jsxs(
4038
4036
  Collapsible,
@@ -4052,7 +4050,8 @@ function TokenGroupSection({
4052
4050
  className: cn(
4053
4051
  "flex w-full items-center justify-between gap-2 px-3 py-2 text-xs font-semibold uppercase tracking-wide",
4054
4052
  "text-muted-foreground hover:text-foreground",
4055
- "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:rounded-md",
4053
+ focusRingClasses,
4054
+ "focus-visible:rounded-md",
4056
4055
  "disabled:pointer-events-none disabled:opacity-50"
4057
4056
  ),
4058
4057
  "aria-label": labelText,
@@ -4364,7 +4363,7 @@ function normalizeCode(value, numeric, length) {
4364
4363
  const normalized = numeric ? value.replace(/\D/g, "") : value.replace(/\s/g, "");
4365
4364
  return normalized.slice(0, length);
4366
4365
  }
4367
- var OtpInput = React60__default.forwardRef(
4366
+ var OtpInput = React61__default.forwardRef(
4368
4367
  ({
4369
4368
  value,
4370
4369
  onChange,
@@ -4546,8 +4545,8 @@ var TextAreaInput = ({ value, onChange, placeholder = "", className = "", varian
4546
4545
  };
4547
4546
  var ComboboxInput = ({ placeholder = "Select...", searchPlaceholder = "Search...", emptyMessage = "No results found.", loading = false, loadingMessage = "Loading...", onSearchChange, shouldFilter = true, value, onChange, icon, showIcon = true, iconColor, items = [], className = "", variant = "default", status = "default", bordered, borderColor, disabled = false, allowFreeText = false }) => {
4548
4547
  const [open, setOpen] = useState(false);
4549
- const triggerRef = React60__default.useRef(null);
4550
- const pointerDismissedRef = React60__default.useRef(false);
4548
+ const triggerRef = React61__default.useRef(null);
4549
+ const pointerDismissedRef = React61__default.useRef(false);
4551
4550
  const [query, setQuery] = useState("");
4552
4551
  const normalizedItems = items.map((item) => typeof item === "string" ? { value: item, label: item } : item);
4553
4552
  const selectedItem = normalizedItems.find((item) => item.value === value);
@@ -5934,7 +5933,7 @@ function DropdownMenuSubContent({ className, children, style, ...props }) {
5934
5933
  );
5935
5934
  }
5936
5935
  function DropdownMenuContent({ className, children, sideOffset = 4, style, ...props }) {
5937
- const container = React60.useContext(NajmThemeContainerCtx);
5936
+ const container = React61.useContext(NajmThemeContainerCtx);
5938
5937
  const surface = useDropdownSurfaceRecipe("content");
5939
5938
  const { hostRef, viewportRef } = useNajmScrollViewport();
5940
5939
  useNajmPortalLayerStyles();
@@ -6338,8 +6337,8 @@ function NSlider({
6338
6337
  return Array.isArray(v) ? [...v] : [v];
6339
6338
  };
6340
6339
  const initialRadix = toRadix(controlledValue ?? defaultValue);
6341
- const [internalValues, setInternalValues] = React60.useState(initialRadix);
6342
- const [active, setActive] = React60.useState(null);
6340
+ const [internalValues, setInternalValues] = React61.useState(initialRadix);
6341
+ const [active, setActive] = React61.useState(null);
6343
6342
  const currentValues = controlledValue !== void 0 ? toRadix(controlledValue) : internalValues;
6344
6343
  const handleRadix = (arr) => {
6345
6344
  setInternalValues(arr);
@@ -6496,13 +6495,13 @@ function NThemePresets({
6496
6495
  disabled = false,
6497
6496
  className
6498
6497
  }) {
6499
- const [saveOpen, setSaveOpen] = React60.useState(false);
6500
- const [name, setName] = React60.useState("");
6501
- const [pendingDelete, setPendingDelete] = React60.useState(
6498
+ const [saveOpen, setSaveOpen] = React61.useState(false);
6499
+ const [name, setName] = React61.useState("");
6500
+ const [pendingDelete, setPendingDelete] = React61.useState(
6502
6501
  null
6503
6502
  );
6504
- const [busy, setBusy] = React60.useState(false);
6505
- const rows = React60.useMemo(
6503
+ const [busy, setBusy] = React61.useState(false);
6504
+ const rows = React61.useMemo(
6506
6505
  () => [
6507
6506
  ...savedDesign ? [
6508
6507
  {
@@ -6754,12 +6753,12 @@ function NThemeCustomizer({
6754
6753
  }) {
6755
6754
  const inheritedMode = useNajmThemeMode();
6756
6755
  const resolvedPreviewMode = previewMode ?? inheritedMode ?? value.theme.mode ?? "light";
6757
- const visibleTabs = React60.useMemo(() => buildTabs(tabs), [tabs]);
6756
+ const visibleTabs = React61.useMemo(() => buildTabs(tabs), [tabs]);
6758
6757
  const firstTab = visibleTabs[0] ?? "theme";
6759
- const [activeTab, setActiveTab] = React60.useState(TAB_VALUE[firstTab]);
6760
- const [fileError, setFileError] = React60.useState(false);
6761
- const fileInputRef = React60.useRef(null);
6762
- React60.useEffect(() => {
6758
+ const [activeTab, setActiveTab] = React61.useState(TAB_VALUE[firstTab]);
6759
+ const [fileError, setFileError] = React61.useState(false);
6760
+ const fileInputRef = React61.useRef(null);
6761
+ React61.useEffect(() => {
6763
6762
  setActiveTab(TAB_VALUE[firstTab]);
6764
6763
  }, [firstTab]);
6765
6764
  const themeLabel = resolveLabel("themeTab", labels);
@@ -6771,7 +6770,7 @@ function NThemeCustomizer({
6771
6770
  const invalidThemeFileLabel = resolveLabel("invalidThemeFile", labels);
6772
6771
  const defaultOptionLabel = resolveLabel("defaultOption", labels);
6773
6772
  const colorSwatchFallbackLabel = resolveLabel("colorSwatchFallback", labels);
6774
- const tokenLabels = React60.useMemo(() => {
6773
+ const tokenLabels = React61.useMemo(() => {
6775
6774
  const out = {};
6776
6775
  const knownTokens = [
6777
6776
  "background",
@@ -7575,7 +7574,7 @@ function Alert({
7575
7574
  );
7576
7575
  }
7577
7576
  var NAlert = Alert;
7578
- var NativeSelect = React60.forwardRef(
7577
+ var NativeSelect = React61.forwardRef(
7579
7578
  ({ className, options, placeholder, value, ...props }, ref) => {
7580
7579
  const hasValue = value !== void 0 && value !== "";
7581
7580
  return /* @__PURE__ */ jsxs("div", { className: "relative", children: [
@@ -7628,10 +7627,20 @@ function ScrollArea({ className, children, ...props }) {
7628
7627
  }
7629
7628
  ) });
7630
7629
  }
7631
- function NImage({ src, fallback, alt = "", ...rest }) {
7632
- const [failed, setFailed] = useState(null);
7633
- const resolved = failed === src && fallback ? fallback : src;
7634
- return /* @__PURE__ */ jsx("img", { ...rest, alt, src: resolved, onError: () => setFailed(src) });
7630
+ function NImage({ src, fallback, alt = "", onError, ...rest }) {
7631
+ const chain = useImageChain(normalizeImageSources([src, fallback]));
7632
+ return /* @__PURE__ */ jsx(
7633
+ "img",
7634
+ {
7635
+ ...rest,
7636
+ alt,
7637
+ src: chain.src ?? src,
7638
+ onError: (event) => {
7639
+ chain.markFailed();
7640
+ onError?.(event);
7641
+ }
7642
+ }
7643
+ );
7635
7644
  }
7636
7645
  var avatarVariants = cva(
7637
7646
  "relative flex shrink-0 overflow-hidden",
@@ -7723,7 +7732,7 @@ function Avatar({
7723
7732
  ...props
7724
7733
  }) {
7725
7734
  const hasShortcut = src !== void 0 || fallback !== void 0;
7726
- const hasChildren = React60.Children.count(children) > 0;
7735
+ const hasChildren = React61.Children.count(children) > 0;
7727
7736
  return /* @__PURE__ */ jsxs(
7728
7737
  AvatarPrimitive.Root,
7729
7738
  {
@@ -7817,9 +7826,9 @@ function AvatarGroup({ ring = true, className, children, ...props }) {
7817
7826
  "data-slot": "avatar-group",
7818
7827
  className: cn("flex -space-x-2", className),
7819
7828
  ...props,
7820
- children: ring ? React60.Children.map(children, (child) => {
7821
- if (React60.isValidElement(child) && child.type === Avatar) {
7822
- return React60.cloneElement(child, { ring: true, ...child.props });
7829
+ children: ring ? React61.Children.map(children, (child) => {
7830
+ if (React61.isValidElement(child) && child.type === Avatar) {
7831
+ return React61.cloneElement(child, { ring: true, ...child.props });
7823
7832
  }
7824
7833
  return child;
7825
7834
  }) : children
@@ -7886,7 +7895,7 @@ function Swap({
7886
7895
  className,
7887
7896
  ...props
7888
7897
  }) {
7889
- const [internalChecked, setInternalChecked] = React60.useState(defaultChecked);
7898
+ const [internalChecked, setInternalChecked] = React61.useState(defaultChecked);
7890
7899
  const isControlled = controlledChecked !== void 0 || controlledState !== void 0;
7891
7900
  const currentState = getDerivedState(
7892
7901
  isControlled ? controlledChecked ?? false : internalChecked,
@@ -7894,7 +7903,7 @@ function Swap({
7894
7903
  );
7895
7904
  const dataState = currentState === "indeterminate" ? "indeterminate" : currentState ? "on" : "off";
7896
7905
  const ariaPressed = currentState === "indeterminate" ? "mixed" : currentState;
7897
- const handleClick = React60.useCallback((event) => {
7906
+ const handleClick = React61.useCallback((event) => {
7898
7907
  onClick?.(event);
7899
7908
  if (event.defaultPrevented) return;
7900
7909
  if (disabled) return;
@@ -8019,7 +8028,7 @@ var toneClasses = {
8019
8028
  ring: "border-primary/30"
8020
8029
  }
8021
8030
  };
8022
- var StatusPill = React60.forwardRef(
8031
+ var StatusPill = React61.forwardRef(
8023
8032
  ({ className, tone = "neutral", pulse = false, label, ...props }, ref) => {
8024
8033
  const c = toneClasses[tone];
8025
8034
  return /* @__PURE__ */ jsxs(
@@ -8078,20 +8087,20 @@ function Toaster({ toastOptions, ...props }) {
8078
8087
  );
8079
8088
  }
8080
8089
  var Form = FormProvider;
8081
- var FormFieldContext = React60.createContext({});
8090
+ var FormFieldContext = React61.createContext({});
8082
8091
  var FormField = ({ ...props }) => /* @__PURE__ */ jsx(FormFieldContext.Provider, { value: { name: props.name }, children: /* @__PURE__ */ jsx(Controller, { ...props }) });
8083
8092
  var useFormField = () => {
8084
- const fieldContext = React60.useContext(FormFieldContext);
8085
- const itemContext = React60.useContext(FormItemContext);
8093
+ const fieldContext = React61.useContext(FormFieldContext);
8094
+ const itemContext = React61.useContext(FormItemContext);
8086
8095
  const { getFieldState, formState } = useFormContext();
8087
8096
  const fieldState = getFieldState(fieldContext.name, formState);
8088
8097
  if (!fieldContext) throw new Error("useFormField should be used within <FormField>");
8089
8098
  const { id } = itemContext;
8090
8099
  return { id, name: fieldContext.name, formItemId: `${id}-form-item`, formDescriptionId: `${id}-form-item-description`, formMessageId: `${id}-form-item-message`, ...fieldState };
8091
8100
  };
8092
- var FormItemContext = React60.createContext({});
8101
+ var FormItemContext = React61.createContext({});
8093
8102
  function FormItem({ className, ...props }) {
8094
- const id = React60.useId();
8103
+ const id = React61.useId();
8095
8104
  return /* @__PURE__ */ jsx(FormItemContext.Provider, { value: { id }, children: /* @__PURE__ */ jsx("div", { "data-slot": "form-item", className: cn("grid gap-2", className), ...props }) });
8096
8105
  }
8097
8106
  function FormLabel({ className, ...props }) {
@@ -8136,116 +8145,7 @@ function TableCell({ className, ...props }) {
8136
8145
  function TableCaption({ className, ...props }) {
8137
8146
  return /* @__PURE__ */ jsx("caption", { "data-slot": "table-caption", className: cn("text-muted-foreground mt-4 text-sm", className), ...props });
8138
8147
  }
8139
- var Default = ({ className, ...props }) => /* @__PURE__ */ jsx(LoaderIcon, { className: cn("animate-spin", className), ...props });
8140
- var Circle = ({ className, ...props }) => /* @__PURE__ */ jsx(LoaderCircleIcon, { className: cn("animate-spin", className), ...props });
8141
- var Pinwheel = ({ className, ...props }) => /* @__PURE__ */ jsx(LoaderPinwheelIcon, { className: cn("animate-spin", className), ...props });
8142
- var CircleFilled = ({ className, size = 24, ...props }) => /* @__PURE__ */ jsxs("div", { className: "relative", style: { width: size, height: size }, children: [
8143
- /* @__PURE__ */ jsx("div", { className: "absolute inset-0 rotate-180", children: /* @__PURE__ */ jsx(LoaderCircleIcon, { className: cn("animate-spin", className, "text-foreground opacity-20"), size, ...props }) }),
8144
- /* @__PURE__ */ jsx(LoaderCircleIcon, { className: cn("relative animate-spin", className), size, ...props })
8145
- ] });
8146
- var Ellipsis = ({ size = 24, ...props }) => /* @__PURE__ */ jsxs("svg", { height: size, viewBox: "0 0 24 24", width: size, xmlns: "http://www.w3.org/2000/svg", ...props, children: [
8147
- /* @__PURE__ */ jsx("title", { children: "Loading..." }),
8148
- /* @__PURE__ */ jsx("circle", { cx: "4", cy: "12", fill: "currentColor", r: "2", children: /* @__PURE__ */ jsx("animate", { attributeName: "cy", begin: "0;ellipsis3.end+0.25s", calcMode: "spline", dur: "0.6s", id: "ellipsis1", keySplines: ".33,.66,.66,1;.33,0,.66,.33", values: "12;6;12" }) }),
8149
- /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", fill: "currentColor", r: "2", children: /* @__PURE__ */ jsx("animate", { attributeName: "cy", begin: "ellipsis1.begin+0.1s", calcMode: "spline", dur: "0.6s", keySplines: ".33,.66,.66,1;.33,0,.66,.33", values: "12;6;12" }) }),
8150
- /* @__PURE__ */ jsx("circle", { cx: "20", cy: "12", fill: "currentColor", r: "2", children: /* @__PURE__ */ jsx("animate", { attributeName: "cy", begin: "ellipsis1.begin+0.2s", calcMode: "spline", dur: "0.6s", id: "ellipsis3", keySplines: ".33,.66,.66,1;.33,0,.66,.33", values: "12;6;12" }) })
8151
- ] });
8152
- var Ring = ({ size = 24, ...props }) => /* @__PURE__ */ jsxs("svg", { height: size, stroke: "currentColor", viewBox: "0 0 44 44", width: size, xmlns: "http://www.w3.org/2000/svg", ...props, children: [
8153
- /* @__PURE__ */ jsx("title", { children: "Loading..." }),
8154
- /* @__PURE__ */ jsxs("g", { fill: "none", fillRule: "evenodd", strokeWidth: "2", children: [
8155
- /* @__PURE__ */ jsxs("circle", { cx: "22", cy: "22", r: "1", children: [
8156
- /* @__PURE__ */ jsx("animate", { attributeName: "r", begin: "0s", calcMode: "spline", dur: "1.8s", keySplines: "0.165, 0.84, 0.44, 1", keyTimes: "0; 1", repeatCount: "indefinite", values: "1; 20" }),
8157
- /* @__PURE__ */ jsx("animate", { attributeName: "stroke-opacity", begin: "0s", calcMode: "spline", dur: "1.8s", keySplines: "0.3, 0.61, 0.355, 1", keyTimes: "0; 1", repeatCount: "indefinite", values: "1; 0" })
8158
- ] }),
8159
- /* @__PURE__ */ jsxs("circle", { cx: "22", cy: "22", r: "1", children: [
8160
- /* @__PURE__ */ jsx("animate", { attributeName: "r", begin: "-0.9s", calcMode: "spline", dur: "1.8s", keySplines: "0.165, 0.84, 0.44, 1", keyTimes: "0; 1", repeatCount: "indefinite", values: "1; 20" }),
8161
- /* @__PURE__ */ jsx("animate", { attributeName: "stroke-opacity", begin: "-0.9s", calcMode: "spline", dur: "1.8s", keySplines: "0.3, 0.61, 0.355, 1", keyTimes: "0; 1", repeatCount: "indefinite", values: "1; 0" })
8162
- ] })
8163
- ] })
8164
- ] });
8165
- var Bars = ({ size = 24, ...props }) => /* @__PURE__ */ jsxs("svg", { height: size, viewBox: "0 0 24 24", width: size, xmlns: "http://www.w3.org/2000/svg", ...props, children: [
8166
- /* @__PURE__ */ jsx("title", { children: "Loading..." }),
8167
- /* @__PURE__ */ jsx("rect", { fill: "currentColor", height: "4", rx: "1", width: "4", x: "1", y: "10", children: /* @__PURE__ */ jsx("animate", { attributeName: "opacity", begin: "0s", dur: "0.6s", keyTimes: "0;0.5;1", repeatCount: "indefinite", values: "1;0.3;1" }) }),
8168
- /* @__PURE__ */ jsx("rect", { fill: "currentColor", height: "4", rx: "1", width: "4", x: "10", y: "10", children: /* @__PURE__ */ jsx("animate", { attributeName: "opacity", begin: "0.1s", dur: "0.6s", keyTimes: "0;0.5;1", repeatCount: "indefinite", values: "1;0.3;1" }) }),
8169
- /* @__PURE__ */ jsx("rect", { fill: "currentColor", height: "4", rx: "1", width: "4", x: "19", y: "10", children: /* @__PURE__ */ jsx("animate", { attributeName: "opacity", begin: "0.2s", dur: "0.6s", keyTimes: "0;0.5;1", repeatCount: "indefinite", values: "1;0.3;1" }) })
8170
- ] });
8171
- var Infinite = ({ size = 24, ...props }) => /* @__PURE__ */ jsxs(
8172
- "svg",
8173
- {
8174
- height: size,
8175
- preserveAspectRatio: "xMidYMid",
8176
- viewBox: "0 0 100 100",
8177
- width: size,
8178
- xmlns: "http://www.w3.org/2000/svg",
8179
- ...props,
8180
- children: [
8181
- /* @__PURE__ */ jsx("title", { children: "Loading..." }),
8182
- /* @__PURE__ */ jsx(
8183
- "path",
8184
- {
8185
- d: "M24.3 30C11.4 30 5 43.3 5 50s6.4 20 19.3 20c19.3 0 32.1-40 51.4-40 C88.6 30 95 43.3 95 50s-6.4 20-19.3 20C56.4 70 43.6 30 24.3 30z",
8186
- fill: "none",
8187
- stroke: "currentColor",
8188
- strokeDasharray: "205.271142578125 51.317785644531256",
8189
- strokeLinecap: "round",
8190
- strokeWidth: "10",
8191
- style: { transform: "scale(0.8)", transformOrigin: "50px 50px" },
8192
- children: /* @__PURE__ */ jsx(
8193
- "animate",
8194
- {
8195
- attributeName: "stroke-dashoffset",
8196
- dur: "2s",
8197
- keyTimes: "0;1",
8198
- repeatCount: "indefinite",
8199
- values: "0;256.58892822265625"
8200
- }
8201
- )
8202
- }
8203
- )
8204
- ]
8205
- }
8206
- );
8207
- var spinnerVariants = {
8208
- default: Default,
8209
- circle: Circle,
8210
- pinwheel: Pinwheel,
8211
- "circle-filled": CircleFilled,
8212
- ellipsis: Ellipsis,
8213
- ring: Ring,
8214
- bars: Bars,
8215
- infinite: Infinite
8216
- };
8217
- function NSpinner({ variant = "default", size = 24, className, ...props }) {
8218
- const Component = spinnerVariants[variant] || Default;
8219
- return /* @__PURE__ */ jsx(Component, { className, size, ...props });
8220
- }
8221
- function NLoadingState({ label = "Loading...", className, fullScreen = false, spinnerVariant = "circle", spinnerSize = 32 }) {
8222
- return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col items-center justify-center gap-3 py-8", fullScreen && "fixed inset-0 z-50 bg-background/80", className), children: [
8223
- /* @__PURE__ */ jsx(NSpinner, { variant: spinnerVariant, size: spinnerSize }),
8224
- label && /* @__PURE__ */ jsx("p", { className: "text-muted-foreground text-sm", children: label })
8225
- ] });
8226
- }
8227
- function NErrorState({ title = "Something went wrong", message, onRetry, retryLabel = "Try again", className, icon }) {
8228
- return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col items-center justify-center gap-4 py-8", className), children: [
8229
- /* @__PURE__ */ jsx("div", { className: "text-destructive", children: icon || /* @__PURE__ */ jsx(AlertTriangle, { className: "h-10 w-10" }) }),
8230
- /* @__PURE__ */ jsxs("div", { className: "text-center", children: [
8231
- /* @__PURE__ */ jsx("h3", { className: "font-semibold text-foreground", children: title }),
8232
- message && /* @__PURE__ */ jsx("p", { className: "text-muted-foreground text-sm mt-1", children: message })
8233
- ] }),
8234
- onRetry && /* @__PURE__ */ jsx(Button, { variant: "outline", onClick: onRetry, children: retryLabel })
8235
- ] });
8236
- }
8237
- function NEmptyState({ title = "No data", description, icon, action, className }) {
8238
- const iconContent = icon ? React60__default.isValidElement(icon) ? icon : React60__default.createElement(icon, { className: "h-8 w-8" }) : null;
8239
- return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col items-center justify-center gap-3 py-12", className), children: [
8240
- iconContent && /* @__PURE__ */ jsx("div", { className: "text-muted-foreground/50", children: iconContent }),
8241
- /* @__PURE__ */ jsxs("div", { className: "text-center", children: [
8242
- /* @__PURE__ */ jsx("h3", { className: "font-semibold text-foreground", children: title }),
8243
- description && /* @__PURE__ */ jsx("p", { className: "text-muted-foreground text-sm mt-1", children: description })
8244
- ] }),
8245
- action && /* @__PURE__ */ jsx("div", { className: "mt-2", children: action })
8246
- ] });
8247
- }
8248
- var NErrorBoundary = class extends React60__default.Component {
8148
+ var NErrorBoundary = class extends React61__default.Component {
8249
8149
  constructor(props) {
8250
8150
  super(props);
8251
8151
  this.state = { hasError: false, error: null };
@@ -8393,11 +8293,6 @@ function nameToColor(name) {
8393
8293
  function getInitials(name) {
8394
8294
  return name.split(" ").map((part) => part.charAt(0)).join("").toUpperCase().slice(0, 2);
8395
8295
  }
8396
- function withVersion(src, version) {
8397
- if (!version || src.startsWith("data:") || src.startsWith("blob:")) return src;
8398
- const separator = src.includes("?") ? "&" : "?";
8399
- return `${src}${separator}v=${encodeURIComponent(String(version))}`;
8400
- }
8401
8296
  function NAvatar({
8402
8297
  src,
8403
8298
  title,
@@ -8411,30 +8306,63 @@ function NAvatar({
8411
8306
  subtitle,
8412
8307
  meta,
8413
8308
  className,
8414
- classNames
8309
+ classNames,
8310
+ imageProps
8415
8311
  }) {
8416
8312
  const label = title || fallback || "";
8417
8313
  const imageVersion = srcVersion ?? version;
8418
- const resolvedSrc = resolveAvatarSrc(src, void 0);
8419
- const imageSrc = resolvedSrc ? withVersion(resolvedSrc, imageVersion) : fallbackSrc;
8314
+ const sources = normalizeImageSources(
8315
+ [resolveAvatarSrc(src, void 0), fallbackSrc],
8316
+ imageVersion
8317
+ );
8318
+ const chain = useImageChain(sources);
8420
8319
  const { bg, text } = nameToColor(label);
8421
8320
  const hasText = Boolean(title || subtitle || meta);
8422
8321
  const fallbackText = fallback && !title ? fallback : label ? getInitials(label) : "?";
8423
8322
  const shapeClass = SHAPE_CLASSES[shape];
8323
+ const {
8324
+ onLoad: onImageLoad,
8325
+ onError: onImageError,
8326
+ loading: imageLoading,
8327
+ ...restImageProps
8328
+ } = imageProps ?? {};
8329
+ const imageRef = React61__default.useRef(null);
8330
+ const { markLoaded } = chain;
8331
+ React61__default.useEffect(() => {
8332
+ const element = imageRef.current;
8333
+ if (element?.complete && element.naturalWidth > 0) markLoaded();
8334
+ }, [chain.src, markLoaded]);
8335
+ const showImage = Boolean(chain.src) && !chain.exhausted;
8336
+ const showFallback = !showImage || !chain.loaded;
8424
8337
  return /* @__PURE__ */ jsxs("div", { className: cn("flex items-center gap-3", classNames?.root, className), children: [
8425
8338
  /* @__PURE__ */ jsxs(
8426
8339
  Avatar,
8427
8340
  {
8428
- className: cn(SIZE_CLASSES[size], shapeClass, "flex justify-center items-center overflow-hidden", classNames?.avatar),
8341
+ className: cn(SIZE_CLASSES[size], shapeClass, "flex justify-center items-center overflow-hidden bg-muted", classNames?.avatar),
8429
8342
  children: [
8430
- imageSrc && /* @__PURE__ */ jsx(
8431
- AvatarImage,
8343
+ showImage && /* @__PURE__ */ jsx(
8344
+ "img",
8432
8345
  {
8433
- src: imageSrc,
8346
+ ...restImageProps,
8347
+ ref: imageRef,
8348
+ "data-slot": "avatar-image",
8349
+ src: chain.src,
8434
8350
  alt: alt || label,
8435
- className: cn("object-cover", classNames?.image)
8351
+ loading: imageLoading ?? "lazy",
8352
+ className: cn("absolute inset-0 size-full object-cover", classNames?.image),
8353
+ onLoad: (event) => {
8354
+ markLoaded();
8355
+ onImageLoad?.(event);
8356
+ },
8357
+ onError: (event) => {
8358
+ chain.markFailed();
8359
+ onImageError?.(event);
8360
+ }
8436
8361
  }
8437
8362
  ),
8363
+ showFallback && // Mounted by this component rather than by Radix's loading status:
8364
+ // the status is driven by a preloader we deliberately do not use, so
8365
+ // the visibility decision belongs here alongside the chain state.
8438
8366
  /* @__PURE__ */ jsx(
8439
8367
  AvatarFallback,
8440
8368
  {
@@ -8555,8 +8483,8 @@ function NCard({
8555
8483
  let footerClassName;
8556
8484
  let mediaSlot = null;
8557
8485
  const mainChildren = [];
8558
- React60__default.Children.forEach(children, (child) => {
8559
- if (!React60__default.isValidElement(child)) {
8486
+ React61__default.Children.forEach(children, (child) => {
8487
+ if (!React61__default.isValidElement(child)) {
8560
8488
  mainChildren.push(child);
8561
8489
  return;
8562
8490
  }
@@ -8732,7 +8660,7 @@ function truncateByCharacters(text, maxCharacters, suffix = "...") {
8732
8660
  const str = String(text);
8733
8661
  return str.length <= maxCharacters ? str : str.slice(0, maxCharacters) + suffix;
8734
8662
  }
8735
- var CardDensityContext = React60__default.createContext("default");
8663
+ var CardDensityContext = React61__default.createContext("default");
8736
8664
  function NCardInfo({
8737
8665
  icon: Icon2,
8738
8666
  label,
@@ -8745,7 +8673,7 @@ function NCardInfo({
8745
8673
  className,
8746
8674
  ...props
8747
8675
  }) {
8748
- const inheritedDensity = React60__default.useContext(CardDensityContext);
8676
+ const inheritedDensity = React61__default.useContext(CardDensityContext);
8749
8677
  const resolvedDensity = density ?? inheritedDensity;
8750
8678
  const isTruncated = typeof value === "string" && value.length > maxChars;
8751
8679
  const displayValue = isTruncated ? truncateByCharacters(value, maxChars) : value;
@@ -9994,7 +9922,7 @@ function NContextMenu({ x, y, items, onAction, onClose, className }) {
9994
9922
  children: items.map((item) => {
9995
9923
  const Icon2 = item.icon;
9996
9924
  const hasSub = !!item.submenu?.length;
9997
- return /* @__PURE__ */ jsxs(React60__default.Fragment, { children: [
9925
+ return /* @__PURE__ */ jsxs(React61__default.Fragment, { children: [
9998
9926
  item.separatorBefore && /* @__PURE__ */ jsx("div", { className: "my-1 border-t border-border/60" }),
9999
9927
  /* @__PURE__ */ jsxs(
10000
9928
  "div",
@@ -10395,6 +10323,224 @@ function FloatingSelectSegment({
10395
10323
  )) })
10396
10324
  ] });
10397
10325
  }
10326
+ var DEFAULT_COPY_LABEL = "Copy details";
10327
+ var DEFAULT_COPIED_LABEL = "Copied";
10328
+ var DEFAULT_COPY_ERROR_LABEL = "Copy failed";
10329
+ var DEFAULT_HEADER_ICON = "circle-check";
10330
+ var REVERT_MS = 2e3;
10331
+ function defaultCopyText(fields) {
10332
+ return fields.map((f) => `${f.label}: ${f.value}`).join("\n");
10333
+ }
10334
+ function resolveClipboard() {
10335
+ if (typeof navigator === "undefined") return null;
10336
+ const clipboard = navigator.clipboard;
10337
+ if (!clipboard || typeof clipboard.writeText !== "function") return null;
10338
+ return { writeText: clipboard.writeText.bind(clipboard) };
10339
+ }
10340
+ function NCredentialsCard({
10341
+ fields,
10342
+ title,
10343
+ description,
10344
+ icon,
10345
+ copyLabel = DEFAULT_COPY_LABEL,
10346
+ copiedLabel = DEFAULT_COPIED_LABEL,
10347
+ copyErrorLabel = DEFAULT_COPY_ERROR_LABEL,
10348
+ copyText,
10349
+ hideCopyAction = false,
10350
+ onCopy,
10351
+ onCopyError,
10352
+ actions,
10353
+ className,
10354
+ classNames
10355
+ }) {
10356
+ const [status, setStatus] = React61.useState("idle");
10357
+ const revertTimer = React61.useRef(null);
10358
+ const mountedRef = React61.useRef(true);
10359
+ const requestTokenRef = React61.useRef(0);
10360
+ React61.useEffect(() => {
10361
+ mountedRef.current = true;
10362
+ return () => {
10363
+ mountedRef.current = false;
10364
+ if (revertTimer.current) clearTimeout(revertTimer.current);
10365
+ revertTimer.current = null;
10366
+ };
10367
+ }, []);
10368
+ const scheduleRevert = React61.useCallback(() => {
10369
+ if (revertTimer.current) clearTimeout(revertTimer.current);
10370
+ revertTimer.current = setTimeout(() => {
10371
+ revertTimer.current = null;
10372
+ if (mountedRef.current) setStatus("idle");
10373
+ }, REVERT_MS);
10374
+ }, []);
10375
+ const handleCopy = React61.useCallback(() => {
10376
+ if (status === "pending") return;
10377
+ if (revertTimer.current) {
10378
+ clearTimeout(revertTimer.current);
10379
+ revertTimer.current = null;
10380
+ }
10381
+ const token = ++requestTokenRef.current;
10382
+ const isStale = () => !mountedRef.current || token !== requestTokenRef.current;
10383
+ let text;
10384
+ try {
10385
+ text = (copyText ?? defaultCopyText)(fields);
10386
+ } catch (error) {
10387
+ if (isStale()) return;
10388
+ setStatus("error");
10389
+ onCopyError?.(error);
10390
+ scheduleRevert();
10391
+ return;
10392
+ }
10393
+ const clipboard = resolveClipboard();
10394
+ if (!clipboard) {
10395
+ if (isStale()) return;
10396
+ setStatus("error");
10397
+ onCopyError?.(new Error("Clipboard is not available in this context."));
10398
+ scheduleRevert();
10399
+ return;
10400
+ }
10401
+ setStatus("pending");
10402
+ let promise;
10403
+ try {
10404
+ promise = clipboard.writeText(text);
10405
+ } catch (error) {
10406
+ if (isStale()) return;
10407
+ setStatus("error");
10408
+ onCopyError?.(error);
10409
+ scheduleRevert();
10410
+ return;
10411
+ }
10412
+ promise.then(
10413
+ () => {
10414
+ if (isStale()) return;
10415
+ setStatus("success");
10416
+ onCopy?.();
10417
+ scheduleRevert();
10418
+ },
10419
+ (error) => {
10420
+ if (isStale()) return;
10421
+ setStatus("error");
10422
+ onCopyError?.(error);
10423
+ scheduleRevert();
10424
+ }
10425
+ );
10426
+ }, [copyText, fields, onCopy, onCopyError, scheduleRevert, status]);
10427
+ const showHeader = Boolean(title || description);
10428
+ const showFields = fields.length > 0;
10429
+ const showActions = !hideCopyAction || Boolean(actions);
10430
+ const buttonLabel = status === "success" ? copiedLabel : status === "error" ? copyErrorLabel : copyLabel;
10431
+ const headerIcon = icon ?? DEFAULT_HEADER_ICON;
10432
+ return /* @__PURE__ */ jsxs(
10433
+ "div",
10434
+ {
10435
+ className: cn(
10436
+ "flex flex-col rounded-lg border bg-card p-5 shadow-sm",
10437
+ classNames?.root,
10438
+ className
10439
+ ),
10440
+ "data-testid": "credentials-card",
10441
+ children: [
10442
+ showHeader && /* @__PURE__ */ jsxs("div", { className: cn("flex items-start gap-3 mb-4", classNames?.header), children: [
10443
+ /* @__PURE__ */ jsx(
10444
+ "div",
10445
+ {
10446
+ className: "flex items-center justify-center w-10 h-10 rounded-full bg-muted shrink-0",
10447
+ "data-testid": "credentials-card-header-icon",
10448
+ children: /* @__PURE__ */ jsx(
10449
+ NIcon,
10450
+ {
10451
+ "aria-hidden": "true",
10452
+ icon: headerIcon,
10453
+ className: "w-5 h-5 text-muted-foreground"
10454
+ }
10455
+ )
10456
+ }
10457
+ ),
10458
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
10459
+ title && /* @__PURE__ */ jsx("h3", { className: "text-lg font-semibold text-foreground", children: title }),
10460
+ description && /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: description })
10461
+ ] })
10462
+ ] }),
10463
+ showFields && /* @__PURE__ */ jsx("dl", { className: cn("space-y-3", classNames?.list), "data-testid": "credentials-card-list", children: fields.map((field, index) => {
10464
+ const useMono = field.mono ?? true;
10465
+ const breakAll = field.breakAll ?? true;
10466
+ return /* @__PURE__ */ jsxs(
10467
+ "div",
10468
+ {
10469
+ className: cn(
10470
+ "flex items-center gap-3 rounded-xl bg-background px-4 py-3",
10471
+ classNames?.field
10472
+ ),
10473
+ "data-testid": "credentials-card-field",
10474
+ children: [
10475
+ field.icon && /* @__PURE__ */ jsx(
10476
+ NIcon,
10477
+ {
10478
+ "aria-hidden": "true",
10479
+ icon: field.icon,
10480
+ className: "w-4 h-4 text-muted-foreground shrink-0"
10481
+ }
10482
+ ),
10483
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
10484
+ /* @__PURE__ */ jsx("dt", { className: "text-xs text-muted-foreground", children: field.label }),
10485
+ /* @__PURE__ */ jsx(
10486
+ "dd",
10487
+ {
10488
+ dir: "auto",
10489
+ className: cn(
10490
+ "text-sm text-foreground font-semibold",
10491
+ useMono && "font-mono",
10492
+ breakAll && "break-all"
10493
+ ),
10494
+ children: field.value
10495
+ }
10496
+ )
10497
+ ] })
10498
+ ]
10499
+ },
10500
+ `${field.label}-${index}`
10501
+ );
10502
+ }) }),
10503
+ showActions && /* @__PURE__ */ jsxs(
10504
+ "div",
10505
+ {
10506
+ className: cn(
10507
+ "mt-5 flex justify-end gap-3 flex-wrap",
10508
+ classNames?.actions
10509
+ ),
10510
+ "data-testid": "credentials-card-actions",
10511
+ children: [
10512
+ !hideCopyAction && /* @__PURE__ */ jsx(
10513
+ Button,
10514
+ {
10515
+ type: "button",
10516
+ variant: "outline",
10517
+ leftIcon: status === "success" ? Check : status === "error" ? X : Copy,
10518
+ onClick: handleCopy,
10519
+ loading: status === "pending",
10520
+ disabledWhileLoading: true,
10521
+ "data-testid": "credentials-card-copy",
10522
+ children: buttonLabel
10523
+ }
10524
+ ),
10525
+ actions
10526
+ ]
10527
+ }
10528
+ ),
10529
+ /* @__PURE__ */ jsx(
10530
+ "span",
10531
+ {
10532
+ "aria-live": "polite",
10533
+ role: "status",
10534
+ className: "sr-only",
10535
+ "data-testid": "credentials-card-status",
10536
+ children: status === "success" ? copiedLabel : status === "error" ? copyErrorLabel : ""
10537
+ }
10538
+ )
10539
+ ]
10540
+ }
10541
+ );
10542
+ }
10543
+ NCredentialsCard.displayName = "NCredentialsCard";
10398
10544
  function SearchField({ value, onChange, placeholder = "Search...", className }) {
10399
10545
  return /* @__PURE__ */ jsxs("div", { className: `relative ${className ?? ""}`, children: [
10400
10546
  /* @__PURE__ */ jsx(Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 h-3.5 w-3.5 text-muted-foreground" }),
@@ -10466,19 +10612,19 @@ function Combobox({
10466
10612
  allowFreeText = false,
10467
10613
  disabled = false
10468
10614
  }) {
10469
- const [open, setOpen] = React60.useState(false);
10470
- const [query, setQuery] = React60.useState("");
10471
- const [highlight, setHighlight] = React60.useState(0);
10472
- const wrapperRef = React60.useRef(null);
10473
- const inputRef = React60.useRef(null);
10474
- const filtered = React60.useMemo(() => {
10615
+ const [open, setOpen] = React61.useState(false);
10616
+ const [query, setQuery] = React61.useState("");
10617
+ const [highlight, setHighlight] = React61.useState(0);
10618
+ const wrapperRef = React61.useRef(null);
10619
+ const inputRef = React61.useRef(null);
10620
+ const filtered = React61.useMemo(() => {
10475
10621
  const q = query.trim().toLowerCase();
10476
10622
  if (!q) return options;
10477
10623
  return options.filter(
10478
10624
  (opt) => opt.label.toLowerCase().includes(q) || opt.value.toLowerCase().includes(q)
10479
10625
  );
10480
10626
  }, [options, query]);
10481
- React60.useEffect(() => {
10627
+ React61.useEffect(() => {
10482
10628
  if (!open) return;
10483
10629
  const onClick = (e) => {
10484
10630
  if (wrapperRef.current && !wrapperRef.current.contains(e.target)) {
@@ -10489,7 +10635,7 @@ function Combobox({
10489
10635
  document.addEventListener("mousedown", onClick);
10490
10636
  return () => document.removeEventListener("mousedown", onClick);
10491
10637
  }, [open]);
10492
- React60.useEffect(() => {
10638
+ React61.useEffect(() => {
10493
10639
  if (open) {
10494
10640
  setHighlight(0);
10495
10641
  requestAnimationFrame(() => inputRef.current?.focus());
@@ -10497,7 +10643,7 @@ function Combobox({
10497
10643
  setQuery("");
10498
10644
  }
10499
10645
  }, [open]);
10500
- const selectedLabel = React60.useMemo(() => {
10646
+ const selectedLabel = React61.useMemo(() => {
10501
10647
  const match = options.find((o) => o.value === value);
10502
10648
  return match?.label ?? value;
10503
10649
  }, [options, value]);
@@ -11871,8 +12017,8 @@ function useTable(effectiveViewModeOverride) {
11871
12017
  ...effectiveColumns,
11872
12018
  {
11873
12019
  id: "actions",
11874
- header: () => isMenuActions ? null : React60__default.createElement("div", { className: "flex w-full justify-start text-left" }, "Actions"),
11875
- cell: ({ row }) => React60__default.createElement(TableActionCell, { row, onView, onEdit, onDelete, openRowMenu, menuButton, bordered }),
12020
+ header: () => isMenuActions ? null : React61__default.createElement("div", { className: "flex w-full justify-start text-left" }, "Actions"),
12021
+ cell: ({ row }) => React61__default.createElement(TableActionCell, { row, onView, onEdit, onDelete, openRowMenu, menuButton, bordered }),
11876
12022
  enableSorting: false,
11877
12023
  enableHiding: false
11878
12024
  }
@@ -12136,10 +12282,10 @@ function EditableCell({ cell, onCellEdit }) {
12136
12282
  const columnId = cell.column.id;
12137
12283
  const editor = meta.editor || "text";
12138
12284
  const initial = cell.getValue();
12139
- const [editing, setEditing] = React60__default.useState(false);
12140
- const [value, setValue] = React60__default.useState(initial);
12141
- const [saving, setSaving] = React60__default.useState(false);
12142
- React60__default.useEffect(() => {
12285
+ const [editing, setEditing] = React61__default.useState(false);
12286
+ const [value, setValue] = React61__default.useState(initial);
12287
+ const [saving, setSaving] = React61__default.useState(false);
12288
+ React61__default.useEffect(() => {
12143
12289
  if (!editing) setValue(initial);
12144
12290
  }, [initial, editing]);
12145
12291
  const commit = async (next) => {
@@ -12310,7 +12456,7 @@ function NTableContent({ effectiveMode }) {
12310
12456
  const isExpanded = canExpand && row.getIsExpanded();
12311
12457
  const totalCols = row.getVisibleCells().length + (showCheckbox ? 1 : 0) + (hasExpansion ? 1 : 0);
12312
12458
  const rowClassName = getRowClassName?.(row.original);
12313
- return /* @__PURE__ */ jsxs(React60__default.Fragment, { children: [
12459
+ return /* @__PURE__ */ jsxs(React61__default.Fragment, { children: [
12314
12460
  /* @__PURE__ */ jsxs(
12315
12461
  TableRow,
12316
12462
  {
@@ -12569,7 +12715,7 @@ function NTableCardSkeleton({ surface }) {
12569
12715
  }
12570
12716
  function NTableLoadingSkeleton({ rows }) {
12571
12717
  const rawColumns = useTableStore.use.columns();
12572
- const responsiveColumns = React60__default.useMemo(() => filterResponsiveColumns(rawColumns), [rawColumns]);
12718
+ const responsiveColumns = React61__default.useMemo(() => filterResponsiveColumns(rawColumns), [rawColumns]);
12573
12719
  const columns = responsiveColumns;
12574
12720
  const showCheckbox = useTableStore.use.showCheckbox();
12575
12721
  const headerClassName = useTableStore.use.headerClassName();
@@ -12692,19 +12838,19 @@ function useCardContinuation({
12692
12838
  rowCount,
12693
12839
  viewportRef
12694
12840
  }) {
12695
- const [internalPending, setInternalPending] = React60__default.useState(false);
12696
- const [internalError, setInternalError] = React60__default.useState(null);
12697
- const [announcement, setAnnouncement] = React60__default.useState("");
12698
- const [viewportReady, setViewportReady] = React60__default.useState(false);
12699
- const pendingRef = React60__default.useRef(false);
12700
- const previousRowCountRef = React60__default.useRef(rowCount);
12701
- const configRef = React60__default.useRef(config);
12841
+ const [internalPending, setInternalPending] = React61__default.useState(false);
12842
+ const [internalError, setInternalError] = React61__default.useState(null);
12843
+ const [announcement, setAnnouncement] = React61__default.useState("");
12844
+ const [viewportReady, setViewportReady] = React61__default.useState(false);
12845
+ const pendingRef = React61__default.useRef(false);
12846
+ const previousRowCountRef = React61__default.useRef(rowCount);
12847
+ const configRef = React61__default.useRef(config);
12702
12848
  configRef.current = config;
12703
12849
  const enabled = Boolean(config);
12704
12850
  const pending = Boolean(config?.loadingMore || internalPending);
12705
12851
  const error = config?.loadMoreError ?? internalError;
12706
12852
  const hasNextPage = Boolean(config?.hasNextPage);
12707
- const load = React60__default.useCallback(async () => {
12853
+ const load = React61__default.useCallback(async () => {
12708
12854
  const current = configRef.current;
12709
12855
  if (!current) return;
12710
12856
  if (pendingRef.current || current.loadingMore || !current.hasNextPage) return;
@@ -12729,13 +12875,13 @@ function useCardContinuation({
12729
12875
  load,
12730
12876
  { rootMargin: config?.rootMargin ?? DEFAULT_ROOT_MARGIN }
12731
12877
  );
12732
- React60__default.useLayoutEffect(() => {
12878
+ React61__default.useLayoutEffect(() => {
12733
12879
  const node = viewportRef.current ?? null;
12734
12880
  scrollContainerRef.current = node;
12735
12881
  const ready = Boolean(node);
12736
12882
  setViewportReady((value) => value === ready ? value : ready);
12737
12883
  });
12738
- React60__default.useEffect(() => {
12884
+ React61__default.useEffect(() => {
12739
12885
  const previous = previousRowCountRef.current;
12740
12886
  previousRowCountRef.current = rowCount;
12741
12887
  if (!configRef.current) return;
@@ -12745,10 +12891,10 @@ function useCardContinuation({
12745
12891
  configRef.current.itemsLoadedLabel?.(appended) ?? `${appended} more ${appended === 1 ? "item" : "items"} loaded.`
12746
12892
  );
12747
12893
  }, [rowCount]);
12748
- React60__default.useEffect(() => {
12894
+ React61__default.useEffect(() => {
12749
12895
  if (!pending) doneLoading();
12750
12896
  }, [pending, doneLoading]);
12751
- React60__default.useEffect(() => {
12897
+ React61__default.useEffect(() => {
12752
12898
  if (!enabled || !hasNextPage || error) return;
12753
12899
  return observe();
12754
12900
  }, [enabled, hasNextPage, error, observe, viewportReady, rowCount]);
@@ -12802,7 +12948,7 @@ function NTableCards({ effectiveMode }) {
12802
12948
  const cardPagination = useTableStore.use.cardPagination();
12803
12949
  const cardColumnCount = useTableStore.use.cardColumnCount();
12804
12950
  const surface = useTableSurfaceAppearance(bordered, borderColor);
12805
- const viewportRef = React60__default.useRef(null);
12951
+ const viewportRef = React61__default.useRef(null);
12806
12952
  const continuationConfig = cardPagination.mode === "infinite" ? cardPagination : null;
12807
12953
  const continuation = useCardContinuation({
12808
12954
  config: continuationConfig,
@@ -13023,17 +13169,17 @@ function CardLoadMorePagination({
13023
13169
  bordered,
13024
13170
  className
13025
13171
  }) {
13026
- const [internalPending, setInternalPending] = React60__default.useState(false);
13027
- const [internalError, setInternalError] = React60__default.useState(null);
13028
- const [announcement, setAnnouncement] = React60__default.useState("");
13029
- const buttonRef = React60__default.useRef(null);
13030
- const pendingRef = React60__default.useRef(false);
13031
- const restoreFocusRef = React60__default.useRef(false);
13032
- const previousRowCountRef = React60__default.useRef(rowCount);
13033
- const errorId = React60__default.useId();
13172
+ const [internalPending, setInternalPending] = React61__default.useState(false);
13173
+ const [internalError, setInternalError] = React61__default.useState(null);
13174
+ const [announcement, setAnnouncement] = React61__default.useState("");
13175
+ const buttonRef = React61__default.useRef(null);
13176
+ const pendingRef = React61__default.useRef(false);
13177
+ const restoreFocusRef = React61__default.useRef(false);
13178
+ const previousRowCountRef = React61__default.useRef(rowCount);
13179
+ const errorId = React61__default.useId();
13034
13180
  const pending = Boolean(config.loadingMore || internalPending);
13035
13181
  const error = config.loadMoreError ?? internalError;
13036
- React60__default.useEffect(() => {
13182
+ React61__default.useEffect(() => {
13037
13183
  const previous = previousRowCountRef.current;
13038
13184
  if (rowCount > previous) {
13039
13185
  const appended = rowCount - previous;
@@ -13043,7 +13189,7 @@ function CardLoadMorePagination({
13043
13189
  }
13044
13190
  previousRowCountRef.current = rowCount;
13045
13191
  }, [config.itemsLoadedLabel, rowCount]);
13046
- React60__default.useEffect(() => {
13192
+ React61__default.useEffect(() => {
13047
13193
  if (pending || !restoreFocusRef.current) return;
13048
13194
  restoreFocusRef.current = false;
13049
13195
  const frame = requestAnimationFrame(() => buttonRef.current?.focus());
@@ -13113,9 +13259,9 @@ function CardLoadMorePagination({
13113
13259
  var navButtonClass = "h-8 w-8 p-0 text-foreground disabled:text-muted-foreground disabled:opacity-70";
13114
13260
  var chevronClass = "h-4 w-4 rtl:-scale-x-100";
13115
13261
  function useLowerBoundPageCountWarning(manualPagination, pageCount, pagination) {
13116
- const previous = React60__default.useRef(null);
13117
- const warned = React60__default.useRef(false);
13118
- React60__default.useEffect(() => {
13262
+ const previous = React61__default.useRef(null);
13263
+ const warned = React61__default.useRef(false);
13264
+ React61__default.useEffect(() => {
13119
13265
  if (typeof console === "undefined") return;
13120
13266
  if (typeof process !== "undefined" && process.env?.NODE_ENV === "production") return;
13121
13267
  if (!manualPagination || pageCount === void 0 || !pagination) {
@@ -15005,7 +15151,7 @@ function NNavbar({
15005
15151
  (userMenuActions.length > 0 || onLogout) && /* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
15006
15152
  userMenuActions.map((action) => {
15007
15153
  const ActionIcon = action.icon;
15008
- return /* @__PURE__ */ jsxs(React60__default.Fragment, { children: [
15154
+ return /* @__PURE__ */ jsxs(React61__default.Fragment, { children: [
15009
15155
  action.separator && /* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
15010
15156
  /* @__PURE__ */ jsxs(DropdownMenuItem, { onClick: action.onClick, className: "cursor-pointer", children: [
15011
15157
  ActionIcon && /* @__PURE__ */ jsx(ActionIcon, { className: "h-4 w-4 mr-2" }),
@@ -15158,37 +15304,6 @@ function NCommandPalette({
15158
15304
  ] })
15159
15305
  ] });
15160
15306
  }
15161
- function NPageLayout({
15162
- as: Comp = "main",
15163
- className,
15164
- style,
15165
- ...props
15166
- }) {
15167
- const { layout } = useNajmDesign();
15168
- const pageGutter = layout?.pageGutter ?? "var(--page-gutter, 24px)";
15169
- const sectionGap = layout?.sectionGap ?? "var(--section-gap, 20px)";
15170
- return /* @__PURE__ */ jsx(
15171
- Comp,
15172
- {
15173
- className: cn("flex min-w-0 flex-col", className),
15174
- style: {
15175
- /**
15176
- * Published so descendants can cancel the page padding exactly. A
15177
- * full-bleed child (a non-card NPageHeader) cannot guess these: the
15178
- * design config resolves them to literals, not to the `--page-gutter`
15179
- * / `--section-gap` fallbacks.
15180
- */
15181
- "--najm-page-gutter": pageGutter,
15182
- "--najm-section-gap": sectionGap,
15183
- gap: sectionGap,
15184
- paddingInline: pageGutter,
15185
- paddingBlock: sectionGap,
15186
- ...style
15187
- },
15188
- ...props
15189
- }
15190
- );
15191
- }
15192
15307
  function NInspectorSheet({ open, onClose, title, children }) {
15193
15308
  useEffect(() => {
15194
15309
  const handleKey = (e) => {
@@ -15275,4 +15390,4 @@ function NGridItem({
15275
15390
  return /* @__PURE__ */ jsx("div", { className: itemClassName, ...props, children });
15276
15391
  }
15277
15392
 
15278
- export { Alert, NCard as AsyncCard, Avatar, AvatarFallback, AvatarFormInput, AvatarGroup, AvatarImage, AvatarInput, AvatarStatus, Badge, BaseInput, 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, Indicator4 as Indicator, Input, Label2 as Label, LangInput, MultiSelectInput, NAJM_COLOR_TEXT_CLASSES, NAJM_SAVED_THEME_VALUE, NAJM_STATUS_COLORS, NAlert, NAppShell, NCard as NAsyncCard, NAvatar, NBadge, NBarChart, NBulkActionsBar, NCard, NCardAction, NCardFooter, NCardInfo, NCardMedia, NCardSection, NChartSkeleton, 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, NImage, NIndicator, NInspectorSheet, NLineChart, NLoadingState, NMultiDialog, NNavbar, NPageHeader, NPageHeaderActions, NPageHeaderCompactActions, NPageHeaderFilters, NPageHeaderTop, NPageLayout, NPieChart, NPortalScopeProvider, NProgress, NRowActions, NSection, NSectionHeader, NSectionInfo, NSectionWithInfo, NSheet, NSidebar, NSidebarBrand, NSidebarContent, NSidebarFooter, NSidebarHeader, NSidebarItem, NSidebarMobile, NSidebarProvider, NSidebarSection, NSkeleton, NSkeletonCalendar, NSkeletonChart, NSkeletonDonut, NSkeletonEventList, NSkeletonWidget, NSkeletonWidgets, NSlider, NSmartPasteDialog, NSpinner, NStatCard, NStatCardSkeleton, NStatusBreakdown, Swap as NSwap, NTable, NTableCardRoot, NTableCards, NTableContent, NTableHeader, NTableLoadingSkeleton, NTablePagination, NTableRowSkeleton, NTableSkeleton, NTabs, NThemeCustomizer, NThemePresets, NUploader, NViewBody, NViewToggle, NativeSelect, NumberInput, OtpInput, PasswordInput, PhoneInput, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, PrefixProvider, Progress, 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, Tabs, TabsContent, TabsList, TabsTrigger, TextAreaInput, TextInput, Textarea, TimeInput, TimeZoneInput, Toaster, Toggle, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, VariantProvider, WizardForm, alertVariants, avatarVariants, badgeColorVariants, badgeVariants, buildDefaultFileColumns, buildPageItems, colorTextClass, createDialogStore, createTableStore, detectFormat, dialogVariants, filterResponsiveColumns, findStatusColor, formatColor, formatFileBytes, formatFileRelative, getIconColorProps, getNChartColor, getNextEditorTabValue, hiddenBelowClasses, indicatorVariants, normalizeThemeFileName, parseColor, parseThemeFile, resolveHiddenBelowClass, resolveSlot, resolveStatusColor, sliderVariants, statusTextClass, stringifyThemeFile, swapVariants, toPickerHex, toggleVariants, tooltipContentVariants, truncateByCharacters, useClickOutside, useContextMenu, useDebouncedValue, useDelayedLoading, useDialog, useDialogStore, useDynamicPageSize, useFormField, useFormSubmission, useInfiniteScroll, useKeyboard, useLocalStorageState, useNForm, useNPortalScope, useNSidebar, usePrefix, useSelection, useStepNavigation, useStorageContextMenu, useStoreSync, useTable, useTableKeyboard, useVariant, useVariantPreset };
15393
+ export { Alert, NCard as AsyncCard, Avatar, AvatarFallback, AvatarFormInput, AvatarGroup, AvatarImage, AvatarInput, AvatarStatus, Badge, BaseInput, 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, Indicator4 as Indicator, Input, Label2 as Label, LangInput, MultiSelectInput, NAJM_SAVED_THEME_VALUE, NAlert, NAppShell, NCard as NAsyncCard, NAvatar, NBadge, NBarChart, NBulkActionsBar, NCard, NCardAction, NCardFooter, NCardInfo, NCardMedia, NCardSection, NChartSkeleton, NCommandPalette, NConfirmDialog, NContextMenu, NCredentialsCard, NDataCardShell, NDeleteDialog, NDeleteDialogContent, NDetailCard, NDetailItem, NDetailList, NDialog, NDialogDescription, NDialogHeader, NDialogPrimaryButton, NDialogSecondaryButton, NDonutCard, NEditorTabs, NErrorBoundary, NFileBrowser, NFileTypeIcon, NFilterBar, NFolderIcon, NForm, NFormSectionHeader, NGrid, NGridItem, NImage, NIndicator, NInspectorSheet, NLineChart, NMultiDialog, NNavbar, NPageHeader, NPageHeaderActions, NPageHeaderCompactActions, NPageHeaderFilters, NPageHeaderTop, NPieChart, NPortalScopeProvider, NProgress, NRowActions, NSection, NSectionHeader, NSectionInfo, NSectionWithInfo, NSheet, NSidebar, NSidebarBrand, NSidebarContent, NSidebarFooter, NSidebarHeader, NSidebarItem, NSidebarMobile, NSidebarProvider, NSidebarSection, NSkeleton, NSkeletonCalendar, NSkeletonChart, NSkeletonDonut, NSkeletonEventList, NSkeletonWidget, NSkeletonWidgets, NSlider, NSmartPasteDialog, NStatCard, NStatCardSkeleton, NStatusBreakdown, Swap as NSwap, NTable, NTableCardRoot, NTableCards, NTableContent, NTableHeader, NTableLoadingSkeleton, NTablePagination, NTableRowSkeleton, NTableSkeleton, NTabs, NThemeCustomizer, NThemePresets, NUploader, NViewBody, NViewToggle, NativeSelect, NumberInput, OtpInput, PasswordInput, PhoneInput, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, PrefixProvider, Progress, 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, Tabs, TabsContent, TabsList, TabsTrigger, TextAreaInput, TextInput, Textarea, TimeInput, TimeZoneInput, Toaster, Toggle, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, VariantProvider, WizardForm, alertVariants, avatarVariants, badgeColorVariants, badgeVariants, buildDefaultFileColumns, buildPageItems, createDialogStore, createTableStore, detectFormat, dialogVariants, filterResponsiveColumns, focusRingClasses, focusRingWithinClasses, formatColor, formatFileBytes, formatFileRelative, getIconColorProps, getNChartColor, getNextEditorTabValue, hiddenBelowClasses, indicatorVariants, normalizeThemeFileName, parseColor, parseThemeFile, resolveHiddenBelowClass, resolveSlot, sliderVariants, stringifyThemeFile, swapVariants, toPickerHex, toggleVariants, tooltipContentVariants, truncateByCharacters, useClickOutside, useContextMenu, useDebouncedValue, useDelayedLoading, useDialog, useDialogStore, useDynamicPageSize, useFormField, useFormSubmission, useInfiniteScroll, useKeyboard, useLocalStorageState, useNForm, useNPortalScope, useNSidebar, usePrefix, useSelection, useStepNavigation, useStorageContextMenu, useStoreSync, useTable, useTableKeyboard, useVariant, useVariantPreset };