najm-kit 2.9.0 → 2.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1,9 +1,9 @@
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';
3
+ import { useResolvedFormDevTools, useNBranding } from './chunk-HML2JZXT.mjs';
4
+ export { FormDevToolsProvider, NBrandingProvider, NBrandingStateProvider, NajmFormatProvider, buildFormFill, normalizeBranding, useNBranding, useNBrandingEditor, useNajmFormat, useNajmFormatContext } from './chunk-HML2JZXT.mjs';
5
+ import { normalizeImageSources, useImageChain, useNBadgeDefaults, mergeBadgeMaps, resolveStatusColor, resolveBadgeStatusLabel, colorTextClass, useResolvedPaginationLabels } from './chunk-FDONJASN.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-FDONJASN.mjs';
7
7
  import { inputBorderClasses, Button, NIcon, NajmScroll, surfaceBorderClasses, useNajmScrollViewport, buttonVariants, NButton, useTableStore, TableStoreContext, sidebarBorderClasses, NTableJson } from './chunk-JUYT2ISO.mjs';
8
8
  export { Button, NButton, NIcon, NTableJson, NajmScroll, TableStoreContext, buttonVariants, inputBorderClasses, sidebarBorderClasses, surfaceBorderClasses, useTableStore } from './chunk-JUYT2ISO.mjs';
9
9
  import { useNajmComponentStyle, cn, NajmThemeContainerCtx, useNajmThemeMode, useNajmDesign, composePreset } from './chunk-KVZACF4G.mjs';
@@ -15,8 +15,8 @@ export { DEFAULT_PLACEHOLDER, formatCurrency, formatDate, formatDateTime, format
15
15
  export { DEFAULT_MAX_PAGE_SIZE, DEFAULT_PAGE_SIZE, cleanQuery, createOffsetPagination, fetchOffsetPage, getPageIndex } from './chunk-2NX2VKS2.mjs';
16
16
  import { resolveRadiusValue, resolveVariantAlias, parseNajmDesignConfig } from './chunk-TFHWLE7N.mjs';
17
17
  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';
18
+ import * as React61 from 'react';
19
+ import React61__default, { createContext, useRef, useMemo, useState, useEffect, useContext, useCallback, useLayoutEffect, isValidElement } from 'react';
20
20
  import * as TabsPrimitive from '@radix-ui/react-tabs';
21
21
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
22
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';
@@ -262,7 +262,7 @@ function NTabs({
262
262
  }
263
263
  var PORTAL_LAYER_STYLE_ID = "najm-kit-portal-layer-styles";
264
264
  function useNajmPortalLayerStyles() {
265
- React60.useInsertionEffect(() => {
265
+ React61.useInsertionEffect(() => {
266
266
  if (typeof document === "undefined") return;
267
267
  if (document.getElementById(PORTAL_LAYER_STYLE_ID)) return;
268
268
  const style = document.createElement("style");
@@ -293,7 +293,7 @@ var tooltipContentVariants = cva(
293
293
  }
294
294
  );
295
295
  function TooltipContent({ className, sideOffset = 4, variant, children, ...props }) {
296
- const container = React60.useContext(NajmThemeContainerCtx);
296
+ const container = React61.useContext(NajmThemeContainerCtx);
297
297
  useNajmPortalLayerStyles();
298
298
  return /* @__PURE__ */ jsx(TooltipPrimitive.Portal, { container: container ?? void 0, children: /* @__PURE__ */ jsx(
299
299
  TooltipPrimitive.Content,
@@ -443,7 +443,7 @@ var ERROR_BORDER = "border !border-red-600";
443
443
  var FOCUS_INTERACTIVE_BASE = "border focus-within:border-primary";
444
444
  var HOVER_INTERACTIVE_BASE = "hover:border-primary";
445
445
  var STATIC_BASE = "border";
446
- var BaseInput = React60__default.forwardRef(
446
+ var BaseInput = React61__default.forwardRef(
447
447
  ({ children, variant = "default", status = "default", bordered, borderColor, className, style, disabled = false, onHover, onClick, hasIcon, ...rest }, ref) => {
448
448
  const recipe = useNajmComponentStyle("input");
449
449
  const isGhost = variant === "ghost";
@@ -495,7 +495,7 @@ function PopoverAnchor({ ...props }) {
495
495
  return /* @__PURE__ */ jsx(PopoverPrimitive.Anchor, { "data-slot": "popover-anchor", ...props });
496
496
  }
497
497
  function PopoverContent({ className, align = "center", sideOffset = 4, ...props }) {
498
- const container = React60.useContext(NajmThemeContainerCtx);
498
+ const container = React61.useContext(NajmThemeContainerCtx);
499
499
  useNajmPortalLayerStyles();
500
500
  return /* @__PURE__ */ jsx(PopoverPrimitive.Portal, { container: container ?? void 0, children: /* @__PURE__ */ jsx(
501
501
  PopoverPrimitive.Content,
@@ -604,7 +604,7 @@ function SwatchesColorPicker({
604
604
  hideSwatches = false
605
605
  }) {
606
606
  const inputRef = useRef(null);
607
- const themeContainer = React60__default.useContext(NajmThemeContainerCtx);
607
+ const themeContainer = React61__default.useContext(NajmThemeContainerCtx);
608
608
  const resolvedValue = resolvePickerColor(value, themeContainer);
609
609
  return /* @__PURE__ */ jsxs(
610
610
  BaseInput,
@@ -674,7 +674,7 @@ function PopoverColorPicker({
674
674
  formats = DEFAULT_FORMATS,
675
675
  output = "preserve"
676
676
  }) {
677
- const themeContainer = React60__default.useContext(NajmThemeContainerCtx);
677
+ const themeContainer = React61__default.useContext(NajmThemeContainerCtx);
678
678
  const resolvedValue = resolvePickerColor(value, themeContainer);
679
679
  const initialFormat = formats.includes(detectFormat(resolvedValue)) ? detectFormat(resolvedValue) : formats[0] ?? "hex";
680
680
  const [activeFormat, setActiveFormat] = useState(initialFormat);
@@ -931,7 +931,7 @@ function SheetClose({ ...props }) {
931
931
  return /* @__PURE__ */ jsx(SheetPrimitive.Close, { "data-slot": "sheet-close", ...props });
932
932
  }
933
933
  function SheetPortal({ ...props }) {
934
- const container = React60.useContext(NajmThemeContainerCtx);
934
+ const container = React61.useContext(NajmThemeContainerCtx);
935
935
  return /* @__PURE__ */ jsx(SheetPrimitive.Portal, { "data-slot": "sheet-portal", container: container ?? void 0, ...props });
936
936
  }
937
937
  function SheetOverlay({ className, ...props }) {
@@ -1080,7 +1080,7 @@ function DialogTrigger({ ...props }) {
1080
1080
  return /* @__PURE__ */ jsx(SheetPrimitive.Trigger, { "data-slot": "dialog-trigger", ...props });
1081
1081
  }
1082
1082
  function DialogPortal({ ...props }) {
1083
- const container = React60.useContext(NajmThemeContainerCtx);
1083
+ const container = React61.useContext(NajmThemeContainerCtx);
1084
1084
  return /* @__PURE__ */ jsx(SheetPrimitive.Portal, { "data-slot": "dialog-portal", container: container ?? void 0, ...props });
1085
1085
  }
1086
1086
  function DialogClose({ ...props }) {
@@ -1111,8 +1111,8 @@ function getDefaultPadding() {
1111
1111
  return window.matchMedia(MOBILE_PADDING_QUERY).matches ? "sm" : "md";
1112
1112
  }
1113
1113
  function useResponsivePadding(value) {
1114
- const [resolved, setResolved] = React60.useState(() => value ?? getDefaultPadding());
1115
- React60.useEffect(() => {
1114
+ const [resolved, setResolved] = React61.useState(() => value ?? getDefaultPadding());
1115
+ React61.useEffect(() => {
1116
1116
  if (value) {
1117
1117
  setResolved(value);
1118
1118
  return;
@@ -1176,7 +1176,7 @@ var sizeClasses2 = {
1176
1176
  md: "h-8 w-8",
1177
1177
  lg: "h-10 w-10"
1178
1178
  };
1179
- var IconButton = React60.forwardRef(
1179
+ var IconButton = React61.forwardRef(
1180
1180
  ({
1181
1181
  className,
1182
1182
  variant = "ghost",
@@ -1258,10 +1258,10 @@ function NPageHeaderTop({ children, className }) {
1258
1258
  }
1259
1259
  NPageHeaderTop.displayName = "NPageHeaderTop";
1260
1260
  function isPageHeaderSlot(child, slot) {
1261
- return React60__default.isValidElement(child) && child.type === slot;
1261
+ return React61__default.isValidElement(child) && child.type === slot;
1262
1262
  }
1263
1263
  function getSlotElements(children, slot) {
1264
- const matches = React60__default.Children.toArray(children).filter((child) => isPageHeaderSlot(child, slot));
1264
+ const matches = React61__default.Children.toArray(children).filter((child) => isPageHeaderSlot(child, slot));
1265
1265
  return matches.length > 0 ? matches : void 0;
1266
1266
  }
1267
1267
  var responsiveClasses = {
@@ -1674,8 +1674,8 @@ function NDialogSecondaryButton(_props) {
1674
1674
  function parseDirectDialogSlots(children) {
1675
1675
  const body = [];
1676
1676
  const parsed = {};
1677
- React60__default.Children.forEach(children, (child) => {
1678
- if (!React60__default.isValidElement(child)) {
1677
+ React61__default.Children.forEach(children, (child) => {
1678
+ if (!React61__default.isValidElement(child)) {
1679
1679
  body.push(child);
1680
1680
  return;
1681
1681
  }
@@ -1748,15 +1748,15 @@ var dialogVariants = cva(
1748
1748
  );
1749
1749
  var CONTENT_ACTIONS_SELECTOR = '[data-najm-dialog-actions="content"], [data-najm-wizard-form="true"]';
1750
1750
  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) => {
1751
+ const [contentElement, setContentElement] = React61__default.useState(null);
1752
+ const [contentOwnsActions, setContentOwnsActions] = React61__default.useState(false);
1753
+ const contentElementRef = React61__default.useRef(null);
1754
+ const handleContentElementRef = React61__default.useCallback((node) => {
1755
1755
  if (contentElementRef.current === node) return;
1756
1756
  contentElementRef.current = node;
1757
1757
  setContentElement(node);
1758
1758
  }, []);
1759
- React60__default.useLayoutEffect(() => {
1759
+ React61__default.useLayoutEffect(() => {
1760
1760
  if (!contentElement) {
1761
1761
  setContentOwnsActions((current) => current ? false : current);
1762
1762
  return;
@@ -2009,8 +2009,8 @@ function NDirectDialog({
2009
2009
  const resolvedHeaderClassName = cn(slots.header?.className, headerClassName);
2010
2010
  const resolvedTitleClassName = cn(slots.header?.titleClassName, titleClassName);
2011
2011
  const resolvedDescriptionClassName = cn(slots.description?.className, descriptionClassName);
2012
- const [internalOpen, setInternalOpen] = React60__default.useState(defaultOpen);
2013
- const [primaryLoading, setPrimaryLoading] = React60__default.useState(false);
2012
+ const [internalOpen, setInternalOpen] = React61__default.useState(defaultOpen);
2013
+ const [primaryLoading, setPrimaryLoading] = React61__default.useState(false);
2014
2014
  const isControlled = open !== void 0;
2015
2015
  const currentOpen = isControlled ? open : internalOpen;
2016
2016
  const setOpen = (nextOpen) => {
@@ -2292,7 +2292,7 @@ function useDialog(store) {
2292
2292
  description: options.description,
2293
2293
  size: options.size || "sm",
2294
2294
  className: options.className,
2295
- render: ({ dialog, zIndex, confirm, cancel, onOpenChange }) => React60__default.createElement(NDeleteDialog, {
2295
+ render: ({ dialog, zIndex, confirm, cancel, onOpenChange }) => React61__default.createElement(NDeleteDialog, {
2296
2296
  itemName: options.itemName,
2297
2297
  itemType: options.itemType,
2298
2298
  icon: options.icon,
@@ -2408,77 +2408,6 @@ function Checkbox({ className, ...props }) {
2408
2408
  }
2409
2409
  );
2410
2410
  }
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
2411
  var badgeVariants = cva(
2483
2412
  "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
2413
  {
@@ -2588,29 +2517,37 @@ function Badge({
2588
2517
  }) {
2589
2518
  const Comp = asChild ? Slot : "span";
2590
2519
  const recipe = useNajmComponentStyle("badge");
2520
+ const ambient = useNBadgeDefaults();
2521
+ const statusDefaults = status ? ambient?.defaults : void 0;
2522
+ const effectiveLook = look ?? statusDefaults?.look;
2523
+ const effectiveShape = shape ?? statusDefaults?.shape;
2524
+ const effectiveSize = size ?? statusDefaults?.size;
2525
+ const effectiveShowIcon = showIcon ?? statusDefaults?.showIcon;
2526
+ const effectiveStatusMap = mergeBadgeMaps(statusDefaults?.statusMap, statusMap);
2527
+ const effectiveIconMap = mergeBadgeMaps(statusDefaults?.iconMap, iconMap);
2591
2528
  const aliased = resolveVariantAlias(
2592
2529
  recipe?.variants,
2593
2530
  variant ?? recipe?.defaultVariant ?? "default"
2594
2531
  );
2595
2532
  const effVariant = variant ?? aliased.variant ?? recipe?.defaultVariant;
2596
- const recipeRadius = shape === void 0 ? resolveRadiusValue(recipe?.radius) : void 0;
2533
+ const recipeRadius = effectiveShape === void 0 ? resolveRadiusValue(recipe?.radius) : void 0;
2597
2534
  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);
2535
+ const resolvedColor = status ? resolveStatusColor(status, effectiveStatusMap, color ?? "neutral") : color ?? "primary";
2536
+ const resolvedLabel = label ?? (typeof children === "string" ? children : void 0) ?? (status ? resolveBadgeStatusLabel(status, statusDefaults, ambient?.t) ?? humanizeToken(status) : void 0);
2600
2537
  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";
2538
+ const resolvedIcon = icon ?? (resolvedColor ? effectiveIconMap?.[resolvedColor] : void 0);
2539
+ const iconNode = renderIcon(effectiveShowIcon ? resolvedIcon : icon);
2540
+ const isMinimal = effectiveLook === "minimal" || effectiveLook === "text";
2604
2541
  if (isMinimal) {
2605
2542
  const textColor = colorTextClass(resolvedColor);
2606
- const sizeClass = SIZE_TEXT_MAP[size ?? "md"] ?? "text-sm";
2543
+ const sizeClass = SIZE_TEXT_MAP[effectiveSize ?? "md"] ?? "text-sm";
2607
2544
  return /* @__PURE__ */ jsxs(
2608
2545
  Comp,
2609
2546
  {
2610
2547
  "data-slot": "badge",
2611
2548
  className: cn(
2612
2549
  "inline-flex items-center gap-1.5 font-medium bg-transparent border-0",
2613
- look === "text" ? "px-0" : void 0,
2550
+ effectiveLook === "text" ? "px-0" : void 0,
2614
2551
  textColor,
2615
2552
  sizeClass,
2616
2553
  className
@@ -2625,7 +2562,12 @@ function Badge({
2625
2562
  }
2626
2563
  );
2627
2564
  }
2628
- const classes = resolvedColor ? badgeColorVariants({ color: resolvedColor, look, size, shape }) : badgeVariants({ variant: effVariant });
2565
+ const classes = resolvedColor ? badgeColorVariants({
2566
+ color: resolvedColor,
2567
+ look: effectiveLook,
2568
+ size: effectiveSize,
2569
+ shape: effectiveShape
2570
+ }) : badgeVariants({ variant: effVariant });
2629
2571
  return /* @__PURE__ */ jsxs(Comp, { "data-slot": "badge", className: cn(classes, aliased.style?.className, className), style: recipeStyle, ...props, children: [
2630
2572
  iconPosition === "left" && iconNode,
2631
2573
  content,
@@ -2644,8 +2586,8 @@ function resolveIcon(icon) {
2644
2586
  }
2645
2587
  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
2588
  const [open, setOpen] = useState(false);
2647
- const triggerRef = React60__default.useRef(null);
2648
- const pointerDismissedRef = React60__default.useRef(false);
2589
+ const triggerRef = React61__default.useRef(null);
2590
+ const pointerDismissedRef = React61__default.useRef(false);
2649
2591
  const shouldDisplayIcon = Boolean(icon) && showIcon && value.length === 0;
2650
2592
  const iconProps = getIconColorProps(iconColor, "h-4 w-4");
2651
2593
  const handleSelect = (itemValue) => {
@@ -2761,7 +2703,7 @@ function SelectScrollDownButton({ className, ...props }) {
2761
2703
  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
2704
  }
2763
2705
  function SelectContent({ className, children, position = "popper", style, ...props }) {
2764
- const container = React60.useContext(NajmThemeContainerCtx);
2706
+ const container = React61.useContext(NajmThemeContainerCtx);
2765
2707
  const recipe = useNajmComponentStyle("select");
2766
2708
  const contentSlot = recipe?.slots?.content;
2767
2709
  const borderWidth = contentSlot?.borderWidth ?? recipe?.borderWidth;
@@ -2844,9 +2786,9 @@ var SelectInput = ({ placeholder = "", ariaLabel, value, onChange, icon, showIco
2844
2786
  (item) => typeof item === "string" ? item === value : item.value === value
2845
2787
  );
2846
2788
  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);
2789
+ const [open, setOpen] = React61__default.useState(false);
2790
+ const triggerRef = React61__default.useRef(null);
2791
+ const pointerDismissedRef = React61__default.useRef(false);
2850
2792
  return /* @__PURE__ */ jsxs("div", { className: cn("group relative", className), children: [
2851
2793
  /* @__PURE__ */ jsxs(
2852
2794
  BaseInput,
@@ -3714,7 +3656,7 @@ function CollapsibleSection({
3714
3656
  children,
3715
3657
  disabled
3716
3658
  }) {
3717
- const [open, setOpen] = React60.useState(true);
3659
+ const [open, setOpen] = React61.useState(true);
3718
3660
  const titleText = typeof title === "string" || typeof title === "number" ? String(title) : "Section";
3719
3661
  return /* @__PURE__ */ jsxs(
3720
3662
  Collapsible,
@@ -4032,7 +3974,7 @@ function TokenGroupSection({
4032
3974
  disabled,
4033
3975
  labels
4034
3976
  }) {
4035
- const [open, setOpen] = React60.useState(groupId === "surface" || groupId === "brand");
3977
+ const [open, setOpen] = React61.useState(groupId === "surface" || groupId === "brand");
4036
3978
  const labelText = typeof label === "string" || typeof label === "number" ? String(label) : "Group";
4037
3979
  return /* @__PURE__ */ jsxs(
4038
3980
  Collapsible,
@@ -4364,7 +4306,7 @@ function normalizeCode(value, numeric, length) {
4364
4306
  const normalized = numeric ? value.replace(/\D/g, "") : value.replace(/\s/g, "");
4365
4307
  return normalized.slice(0, length);
4366
4308
  }
4367
- var OtpInput = React60__default.forwardRef(
4309
+ var OtpInput = React61__default.forwardRef(
4368
4310
  ({
4369
4311
  value,
4370
4312
  onChange,
@@ -4546,8 +4488,8 @@ var TextAreaInput = ({ value, onChange, placeholder = "", className = "", varian
4546
4488
  };
4547
4489
  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
4490
  const [open, setOpen] = useState(false);
4549
- const triggerRef = React60__default.useRef(null);
4550
- const pointerDismissedRef = React60__default.useRef(false);
4491
+ const triggerRef = React61__default.useRef(null);
4492
+ const pointerDismissedRef = React61__default.useRef(false);
4551
4493
  const [query, setQuery] = useState("");
4552
4494
  const normalizedItems = items.map((item) => typeof item === "string" ? { value: item, label: item } : item);
4553
4495
  const selectedItem = normalizedItems.find((item) => item.value === value);
@@ -5934,7 +5876,7 @@ function DropdownMenuSubContent({ className, children, style, ...props }) {
5934
5876
  );
5935
5877
  }
5936
5878
  function DropdownMenuContent({ className, children, sideOffset = 4, style, ...props }) {
5937
- const container = React60.useContext(NajmThemeContainerCtx);
5879
+ const container = React61.useContext(NajmThemeContainerCtx);
5938
5880
  const surface = useDropdownSurfaceRecipe("content");
5939
5881
  const { hostRef, viewportRef } = useNajmScrollViewport();
5940
5882
  useNajmPortalLayerStyles();
@@ -6338,8 +6280,8 @@ function NSlider({
6338
6280
  return Array.isArray(v) ? [...v] : [v];
6339
6281
  };
6340
6282
  const initialRadix = toRadix(controlledValue ?? defaultValue);
6341
- const [internalValues, setInternalValues] = React60.useState(initialRadix);
6342
- const [active, setActive] = React60.useState(null);
6283
+ const [internalValues, setInternalValues] = React61.useState(initialRadix);
6284
+ const [active, setActive] = React61.useState(null);
6343
6285
  const currentValues = controlledValue !== void 0 ? toRadix(controlledValue) : internalValues;
6344
6286
  const handleRadix = (arr) => {
6345
6287
  setInternalValues(arr);
@@ -6496,13 +6438,13 @@ function NThemePresets({
6496
6438
  disabled = false,
6497
6439
  className
6498
6440
  }) {
6499
- const [saveOpen, setSaveOpen] = React60.useState(false);
6500
- const [name, setName] = React60.useState("");
6501
- const [pendingDelete, setPendingDelete] = React60.useState(
6441
+ const [saveOpen, setSaveOpen] = React61.useState(false);
6442
+ const [name, setName] = React61.useState("");
6443
+ const [pendingDelete, setPendingDelete] = React61.useState(
6502
6444
  null
6503
6445
  );
6504
- const [busy, setBusy] = React60.useState(false);
6505
- const rows = React60.useMemo(
6446
+ const [busy, setBusy] = React61.useState(false);
6447
+ const rows = React61.useMemo(
6506
6448
  () => [
6507
6449
  ...savedDesign ? [
6508
6450
  {
@@ -6754,12 +6696,12 @@ function NThemeCustomizer({
6754
6696
  }) {
6755
6697
  const inheritedMode = useNajmThemeMode();
6756
6698
  const resolvedPreviewMode = previewMode ?? inheritedMode ?? value.theme.mode ?? "light";
6757
- const visibleTabs = React60.useMemo(() => buildTabs(tabs), [tabs]);
6699
+ const visibleTabs = React61.useMemo(() => buildTabs(tabs), [tabs]);
6758
6700
  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(() => {
6701
+ const [activeTab, setActiveTab] = React61.useState(TAB_VALUE[firstTab]);
6702
+ const [fileError, setFileError] = React61.useState(false);
6703
+ const fileInputRef = React61.useRef(null);
6704
+ React61.useEffect(() => {
6763
6705
  setActiveTab(TAB_VALUE[firstTab]);
6764
6706
  }, [firstTab]);
6765
6707
  const themeLabel = resolveLabel("themeTab", labels);
@@ -6771,7 +6713,7 @@ function NThemeCustomizer({
6771
6713
  const invalidThemeFileLabel = resolveLabel("invalidThemeFile", labels);
6772
6714
  const defaultOptionLabel = resolveLabel("defaultOption", labels);
6773
6715
  const colorSwatchFallbackLabel = resolveLabel("colorSwatchFallback", labels);
6774
- const tokenLabels = React60.useMemo(() => {
6716
+ const tokenLabels = React61.useMemo(() => {
6775
6717
  const out = {};
6776
6718
  const knownTokens = [
6777
6719
  "background",
@@ -7575,7 +7517,7 @@ function Alert({
7575
7517
  );
7576
7518
  }
7577
7519
  var NAlert = Alert;
7578
- var NativeSelect = React60.forwardRef(
7520
+ var NativeSelect = React61.forwardRef(
7579
7521
  ({ className, options, placeholder, value, ...props }, ref) => {
7580
7522
  const hasValue = value !== void 0 && value !== "";
7581
7523
  return /* @__PURE__ */ jsxs("div", { className: "relative", children: [
@@ -7628,10 +7570,20 @@ function ScrollArea({ className, children, ...props }) {
7628
7570
  }
7629
7571
  ) });
7630
7572
  }
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) });
7573
+ function NImage({ src, fallback, alt = "", onError, ...rest }) {
7574
+ const chain = useImageChain(normalizeImageSources([src, fallback]));
7575
+ return /* @__PURE__ */ jsx(
7576
+ "img",
7577
+ {
7578
+ ...rest,
7579
+ alt,
7580
+ src: chain.src ?? src,
7581
+ onError: (event) => {
7582
+ chain.markFailed();
7583
+ onError?.(event);
7584
+ }
7585
+ }
7586
+ );
7635
7587
  }
7636
7588
  var avatarVariants = cva(
7637
7589
  "relative flex shrink-0 overflow-hidden",
@@ -7723,7 +7675,7 @@ function Avatar({
7723
7675
  ...props
7724
7676
  }) {
7725
7677
  const hasShortcut = src !== void 0 || fallback !== void 0;
7726
- const hasChildren = React60.Children.count(children) > 0;
7678
+ const hasChildren = React61.Children.count(children) > 0;
7727
7679
  return /* @__PURE__ */ jsxs(
7728
7680
  AvatarPrimitive.Root,
7729
7681
  {
@@ -7817,9 +7769,9 @@ function AvatarGroup({ ring = true, className, children, ...props }) {
7817
7769
  "data-slot": "avatar-group",
7818
7770
  className: cn("flex -space-x-2", className),
7819
7771
  ...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 });
7772
+ children: ring ? React61.Children.map(children, (child) => {
7773
+ if (React61.isValidElement(child) && child.type === Avatar) {
7774
+ return React61.cloneElement(child, { ring: true, ...child.props });
7823
7775
  }
7824
7776
  return child;
7825
7777
  }) : children
@@ -7886,7 +7838,7 @@ function Swap({
7886
7838
  className,
7887
7839
  ...props
7888
7840
  }) {
7889
- const [internalChecked, setInternalChecked] = React60.useState(defaultChecked);
7841
+ const [internalChecked, setInternalChecked] = React61.useState(defaultChecked);
7890
7842
  const isControlled = controlledChecked !== void 0 || controlledState !== void 0;
7891
7843
  const currentState = getDerivedState(
7892
7844
  isControlled ? controlledChecked ?? false : internalChecked,
@@ -7894,7 +7846,7 @@ function Swap({
7894
7846
  );
7895
7847
  const dataState = currentState === "indeterminate" ? "indeterminate" : currentState ? "on" : "off";
7896
7848
  const ariaPressed = currentState === "indeterminate" ? "mixed" : currentState;
7897
- const handleClick = React60.useCallback((event) => {
7849
+ const handleClick = React61.useCallback((event) => {
7898
7850
  onClick?.(event);
7899
7851
  if (event.defaultPrevented) return;
7900
7852
  if (disabled) return;
@@ -8019,7 +7971,7 @@ var toneClasses = {
8019
7971
  ring: "border-primary/30"
8020
7972
  }
8021
7973
  };
8022
- var StatusPill = React60.forwardRef(
7974
+ var StatusPill = React61.forwardRef(
8023
7975
  ({ className, tone = "neutral", pulse = false, label, ...props }, ref) => {
8024
7976
  const c = toneClasses[tone];
8025
7977
  return /* @__PURE__ */ jsxs(
@@ -8078,20 +8030,20 @@ function Toaster({ toastOptions, ...props }) {
8078
8030
  );
8079
8031
  }
8080
8032
  var Form = FormProvider;
8081
- var FormFieldContext = React60.createContext({});
8033
+ var FormFieldContext = React61.createContext({});
8082
8034
  var FormField = ({ ...props }) => /* @__PURE__ */ jsx(FormFieldContext.Provider, { value: { name: props.name }, children: /* @__PURE__ */ jsx(Controller, { ...props }) });
8083
8035
  var useFormField = () => {
8084
- const fieldContext = React60.useContext(FormFieldContext);
8085
- const itemContext = React60.useContext(FormItemContext);
8036
+ const fieldContext = React61.useContext(FormFieldContext);
8037
+ const itemContext = React61.useContext(FormItemContext);
8086
8038
  const { getFieldState, formState } = useFormContext();
8087
8039
  const fieldState = getFieldState(fieldContext.name, formState);
8088
8040
  if (!fieldContext) throw new Error("useFormField should be used within <FormField>");
8089
8041
  const { id } = itemContext;
8090
8042
  return { id, name: fieldContext.name, formItemId: `${id}-form-item`, formDescriptionId: `${id}-form-item-description`, formMessageId: `${id}-form-item-message`, ...fieldState };
8091
8043
  };
8092
- var FormItemContext = React60.createContext({});
8044
+ var FormItemContext = React61.createContext({});
8093
8045
  function FormItem({ className, ...props }) {
8094
- const id = React60.useId();
8046
+ const id = React61.useId();
8095
8047
  return /* @__PURE__ */ jsx(FormItemContext.Provider, { value: { id }, children: /* @__PURE__ */ jsx("div", { "data-slot": "form-item", className: cn("grid gap-2", className), ...props }) });
8096
8048
  }
8097
8049
  function FormLabel({ className, ...props }) {
@@ -8235,7 +8187,7 @@ function NErrorState({ title = "Something went wrong", message, onRetry, retryLa
8235
8187
  ] });
8236
8188
  }
8237
8189
  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;
8190
+ const iconContent = icon ? React61__default.isValidElement(icon) ? icon : React61__default.createElement(icon, { className: "h-8 w-8" }) : null;
8239
8191
  return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col items-center justify-center gap-3 py-12", className), children: [
8240
8192
  iconContent && /* @__PURE__ */ jsx("div", { className: "text-muted-foreground/50", children: iconContent }),
8241
8193
  /* @__PURE__ */ jsxs("div", { className: "text-center", children: [
@@ -8245,7 +8197,7 @@ function NEmptyState({ title = "No data", description, icon, action, className }
8245
8197
  action && /* @__PURE__ */ jsx("div", { className: "mt-2", children: action })
8246
8198
  ] });
8247
8199
  }
8248
- var NErrorBoundary = class extends React60__default.Component {
8200
+ var NErrorBoundary = class extends React61__default.Component {
8249
8201
  constructor(props) {
8250
8202
  super(props);
8251
8203
  this.state = { hasError: false, error: null };
@@ -8393,11 +8345,6 @@ function nameToColor(name) {
8393
8345
  function getInitials(name) {
8394
8346
  return name.split(" ").map((part) => part.charAt(0)).join("").toUpperCase().slice(0, 2);
8395
8347
  }
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
8348
  function NAvatar({
8402
8349
  src,
8403
8350
  title,
@@ -8411,30 +8358,63 @@ function NAvatar({
8411
8358
  subtitle,
8412
8359
  meta,
8413
8360
  className,
8414
- classNames
8361
+ classNames,
8362
+ imageProps
8415
8363
  }) {
8416
8364
  const label = title || fallback || "";
8417
8365
  const imageVersion = srcVersion ?? version;
8418
- const resolvedSrc = resolveAvatarSrc(src, void 0);
8419
- const imageSrc = resolvedSrc ? withVersion(resolvedSrc, imageVersion) : fallbackSrc;
8366
+ const sources = normalizeImageSources(
8367
+ [resolveAvatarSrc(src, void 0), fallbackSrc],
8368
+ imageVersion
8369
+ );
8370
+ const chain = useImageChain(sources);
8420
8371
  const { bg, text } = nameToColor(label);
8421
8372
  const hasText = Boolean(title || subtitle || meta);
8422
8373
  const fallbackText = fallback && !title ? fallback : label ? getInitials(label) : "?";
8423
8374
  const shapeClass = SHAPE_CLASSES[shape];
8375
+ const {
8376
+ onLoad: onImageLoad,
8377
+ onError: onImageError,
8378
+ loading: imageLoading,
8379
+ ...restImageProps
8380
+ } = imageProps ?? {};
8381
+ const imageRef = React61__default.useRef(null);
8382
+ const { markLoaded } = chain;
8383
+ React61__default.useEffect(() => {
8384
+ const element = imageRef.current;
8385
+ if (element?.complete && element.naturalWidth > 0) markLoaded();
8386
+ }, [chain.src, markLoaded]);
8387
+ const showImage = Boolean(chain.src) && !chain.exhausted;
8388
+ const showFallback = !showImage || !chain.loaded;
8424
8389
  return /* @__PURE__ */ jsxs("div", { className: cn("flex items-center gap-3", classNames?.root, className), children: [
8425
8390
  /* @__PURE__ */ jsxs(
8426
8391
  Avatar,
8427
8392
  {
8428
- className: cn(SIZE_CLASSES[size], shapeClass, "flex justify-center items-center overflow-hidden", classNames?.avatar),
8393
+ className: cn(SIZE_CLASSES[size], shapeClass, "flex justify-center items-center overflow-hidden bg-muted", classNames?.avatar),
8429
8394
  children: [
8430
- imageSrc && /* @__PURE__ */ jsx(
8431
- AvatarImage,
8395
+ showImage && /* @__PURE__ */ jsx(
8396
+ "img",
8432
8397
  {
8433
- src: imageSrc,
8398
+ ...restImageProps,
8399
+ ref: imageRef,
8400
+ "data-slot": "avatar-image",
8401
+ src: chain.src,
8434
8402
  alt: alt || label,
8435
- className: cn("object-cover", classNames?.image)
8403
+ loading: imageLoading ?? "lazy",
8404
+ className: cn("absolute inset-0 size-full object-cover", classNames?.image),
8405
+ onLoad: (event) => {
8406
+ markLoaded();
8407
+ onImageLoad?.(event);
8408
+ },
8409
+ onError: (event) => {
8410
+ chain.markFailed();
8411
+ onImageError?.(event);
8412
+ }
8436
8413
  }
8437
8414
  ),
8415
+ showFallback && // Mounted by this component rather than by Radix's loading status:
8416
+ // the status is driven by a preloader we deliberately do not use, so
8417
+ // the visibility decision belongs here alongside the chain state.
8438
8418
  /* @__PURE__ */ jsx(
8439
8419
  AvatarFallback,
8440
8420
  {
@@ -8555,8 +8535,8 @@ function NCard({
8555
8535
  let footerClassName;
8556
8536
  let mediaSlot = null;
8557
8537
  const mainChildren = [];
8558
- React60__default.Children.forEach(children, (child) => {
8559
- if (!React60__default.isValidElement(child)) {
8538
+ React61__default.Children.forEach(children, (child) => {
8539
+ if (!React61__default.isValidElement(child)) {
8560
8540
  mainChildren.push(child);
8561
8541
  return;
8562
8542
  }
@@ -8732,7 +8712,7 @@ function truncateByCharacters(text, maxCharacters, suffix = "...") {
8732
8712
  const str = String(text);
8733
8713
  return str.length <= maxCharacters ? str : str.slice(0, maxCharacters) + suffix;
8734
8714
  }
8735
- var CardDensityContext = React60__default.createContext("default");
8715
+ var CardDensityContext = React61__default.createContext("default");
8736
8716
  function NCardInfo({
8737
8717
  icon: Icon2,
8738
8718
  label,
@@ -8745,7 +8725,7 @@ function NCardInfo({
8745
8725
  className,
8746
8726
  ...props
8747
8727
  }) {
8748
- const inheritedDensity = React60__default.useContext(CardDensityContext);
8728
+ const inheritedDensity = React61__default.useContext(CardDensityContext);
8749
8729
  const resolvedDensity = density ?? inheritedDensity;
8750
8730
  const isTruncated = typeof value === "string" && value.length > maxChars;
8751
8731
  const displayValue = isTruncated ? truncateByCharacters(value, maxChars) : value;
@@ -9994,7 +9974,7 @@ function NContextMenu({ x, y, items, onAction, onClose, className }) {
9994
9974
  children: items.map((item) => {
9995
9975
  const Icon2 = item.icon;
9996
9976
  const hasSub = !!item.submenu?.length;
9997
- return /* @__PURE__ */ jsxs(React60__default.Fragment, { children: [
9977
+ return /* @__PURE__ */ jsxs(React61__default.Fragment, { children: [
9998
9978
  item.separatorBefore && /* @__PURE__ */ jsx("div", { className: "my-1 border-t border-border/60" }),
9999
9979
  /* @__PURE__ */ jsxs(
10000
9980
  "div",
@@ -10466,19 +10446,19 @@ function Combobox({
10466
10446
  allowFreeText = false,
10467
10447
  disabled = false
10468
10448
  }) {
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(() => {
10449
+ const [open, setOpen] = React61.useState(false);
10450
+ const [query, setQuery] = React61.useState("");
10451
+ const [highlight, setHighlight] = React61.useState(0);
10452
+ const wrapperRef = React61.useRef(null);
10453
+ const inputRef = React61.useRef(null);
10454
+ const filtered = React61.useMemo(() => {
10475
10455
  const q = query.trim().toLowerCase();
10476
10456
  if (!q) return options;
10477
10457
  return options.filter(
10478
10458
  (opt) => opt.label.toLowerCase().includes(q) || opt.value.toLowerCase().includes(q)
10479
10459
  );
10480
10460
  }, [options, query]);
10481
- React60.useEffect(() => {
10461
+ React61.useEffect(() => {
10482
10462
  if (!open) return;
10483
10463
  const onClick = (e) => {
10484
10464
  if (wrapperRef.current && !wrapperRef.current.contains(e.target)) {
@@ -10489,7 +10469,7 @@ function Combobox({
10489
10469
  document.addEventListener("mousedown", onClick);
10490
10470
  return () => document.removeEventListener("mousedown", onClick);
10491
10471
  }, [open]);
10492
- React60.useEffect(() => {
10472
+ React61.useEffect(() => {
10493
10473
  if (open) {
10494
10474
  setHighlight(0);
10495
10475
  requestAnimationFrame(() => inputRef.current?.focus());
@@ -10497,7 +10477,7 @@ function Combobox({
10497
10477
  setQuery("");
10498
10478
  }
10499
10479
  }, [open]);
10500
- const selectedLabel = React60.useMemo(() => {
10480
+ const selectedLabel = React61.useMemo(() => {
10501
10481
  const match = options.find((o) => o.value === value);
10502
10482
  return match?.label ?? value;
10503
10483
  }, [options, value]);
@@ -11871,8 +11851,8 @@ function useTable(effectiveViewModeOverride) {
11871
11851
  ...effectiveColumns,
11872
11852
  {
11873
11853
  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 }),
11854
+ header: () => isMenuActions ? null : React61__default.createElement("div", { className: "flex w-full justify-start text-left" }, "Actions"),
11855
+ cell: ({ row }) => React61__default.createElement(TableActionCell, { row, onView, onEdit, onDelete, openRowMenu, menuButton, bordered }),
11876
11856
  enableSorting: false,
11877
11857
  enableHiding: false
11878
11858
  }
@@ -12136,10 +12116,10 @@ function EditableCell({ cell, onCellEdit }) {
12136
12116
  const columnId = cell.column.id;
12137
12117
  const editor = meta.editor || "text";
12138
12118
  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(() => {
12119
+ const [editing, setEditing] = React61__default.useState(false);
12120
+ const [value, setValue] = React61__default.useState(initial);
12121
+ const [saving, setSaving] = React61__default.useState(false);
12122
+ React61__default.useEffect(() => {
12143
12123
  if (!editing) setValue(initial);
12144
12124
  }, [initial, editing]);
12145
12125
  const commit = async (next) => {
@@ -12310,7 +12290,7 @@ function NTableContent({ effectiveMode }) {
12310
12290
  const isExpanded = canExpand && row.getIsExpanded();
12311
12291
  const totalCols = row.getVisibleCells().length + (showCheckbox ? 1 : 0) + (hasExpansion ? 1 : 0);
12312
12292
  const rowClassName = getRowClassName?.(row.original);
12313
- return /* @__PURE__ */ jsxs(React60__default.Fragment, { children: [
12293
+ return /* @__PURE__ */ jsxs(React61__default.Fragment, { children: [
12314
12294
  /* @__PURE__ */ jsxs(
12315
12295
  TableRow,
12316
12296
  {
@@ -12569,7 +12549,7 @@ function NTableCardSkeleton({ surface }) {
12569
12549
  }
12570
12550
  function NTableLoadingSkeleton({ rows }) {
12571
12551
  const rawColumns = useTableStore.use.columns();
12572
- const responsiveColumns = React60__default.useMemo(() => filterResponsiveColumns(rawColumns), [rawColumns]);
12552
+ const responsiveColumns = React61__default.useMemo(() => filterResponsiveColumns(rawColumns), [rawColumns]);
12573
12553
  const columns = responsiveColumns;
12574
12554
  const showCheckbox = useTableStore.use.showCheckbox();
12575
12555
  const headerClassName = useTableStore.use.headerClassName();
@@ -12692,19 +12672,19 @@ function useCardContinuation({
12692
12672
  rowCount,
12693
12673
  viewportRef
12694
12674
  }) {
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);
12675
+ const [internalPending, setInternalPending] = React61__default.useState(false);
12676
+ const [internalError, setInternalError] = React61__default.useState(null);
12677
+ const [announcement, setAnnouncement] = React61__default.useState("");
12678
+ const [viewportReady, setViewportReady] = React61__default.useState(false);
12679
+ const pendingRef = React61__default.useRef(false);
12680
+ const previousRowCountRef = React61__default.useRef(rowCount);
12681
+ const configRef = React61__default.useRef(config);
12702
12682
  configRef.current = config;
12703
12683
  const enabled = Boolean(config);
12704
12684
  const pending = Boolean(config?.loadingMore || internalPending);
12705
12685
  const error = config?.loadMoreError ?? internalError;
12706
12686
  const hasNextPage = Boolean(config?.hasNextPage);
12707
- const load = React60__default.useCallback(async () => {
12687
+ const load = React61__default.useCallback(async () => {
12708
12688
  const current = configRef.current;
12709
12689
  if (!current) return;
12710
12690
  if (pendingRef.current || current.loadingMore || !current.hasNextPage) return;
@@ -12729,13 +12709,13 @@ function useCardContinuation({
12729
12709
  load,
12730
12710
  { rootMargin: config?.rootMargin ?? DEFAULT_ROOT_MARGIN }
12731
12711
  );
12732
- React60__default.useLayoutEffect(() => {
12712
+ React61__default.useLayoutEffect(() => {
12733
12713
  const node = viewportRef.current ?? null;
12734
12714
  scrollContainerRef.current = node;
12735
12715
  const ready = Boolean(node);
12736
12716
  setViewportReady((value) => value === ready ? value : ready);
12737
12717
  });
12738
- React60__default.useEffect(() => {
12718
+ React61__default.useEffect(() => {
12739
12719
  const previous = previousRowCountRef.current;
12740
12720
  previousRowCountRef.current = rowCount;
12741
12721
  if (!configRef.current) return;
@@ -12745,10 +12725,10 @@ function useCardContinuation({
12745
12725
  configRef.current.itemsLoadedLabel?.(appended) ?? `${appended} more ${appended === 1 ? "item" : "items"} loaded.`
12746
12726
  );
12747
12727
  }, [rowCount]);
12748
- React60__default.useEffect(() => {
12728
+ React61__default.useEffect(() => {
12749
12729
  if (!pending) doneLoading();
12750
12730
  }, [pending, doneLoading]);
12751
- React60__default.useEffect(() => {
12731
+ React61__default.useEffect(() => {
12752
12732
  if (!enabled || !hasNextPage || error) return;
12753
12733
  return observe();
12754
12734
  }, [enabled, hasNextPage, error, observe, viewportReady, rowCount]);
@@ -12802,7 +12782,7 @@ function NTableCards({ effectiveMode }) {
12802
12782
  const cardPagination = useTableStore.use.cardPagination();
12803
12783
  const cardColumnCount = useTableStore.use.cardColumnCount();
12804
12784
  const surface = useTableSurfaceAppearance(bordered, borderColor);
12805
- const viewportRef = React60__default.useRef(null);
12785
+ const viewportRef = React61__default.useRef(null);
12806
12786
  const continuationConfig = cardPagination.mode === "infinite" ? cardPagination : null;
12807
12787
  const continuation = useCardContinuation({
12808
12788
  config: continuationConfig,
@@ -13023,17 +13003,17 @@ function CardLoadMorePagination({
13023
13003
  bordered,
13024
13004
  className
13025
13005
  }) {
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();
13006
+ const [internalPending, setInternalPending] = React61__default.useState(false);
13007
+ const [internalError, setInternalError] = React61__default.useState(null);
13008
+ const [announcement, setAnnouncement] = React61__default.useState("");
13009
+ const buttonRef = React61__default.useRef(null);
13010
+ const pendingRef = React61__default.useRef(false);
13011
+ const restoreFocusRef = React61__default.useRef(false);
13012
+ const previousRowCountRef = React61__default.useRef(rowCount);
13013
+ const errorId = React61__default.useId();
13034
13014
  const pending = Boolean(config.loadingMore || internalPending);
13035
13015
  const error = config.loadMoreError ?? internalError;
13036
- React60__default.useEffect(() => {
13016
+ React61__default.useEffect(() => {
13037
13017
  const previous = previousRowCountRef.current;
13038
13018
  if (rowCount > previous) {
13039
13019
  const appended = rowCount - previous;
@@ -13043,7 +13023,7 @@ function CardLoadMorePagination({
13043
13023
  }
13044
13024
  previousRowCountRef.current = rowCount;
13045
13025
  }, [config.itemsLoadedLabel, rowCount]);
13046
- React60__default.useEffect(() => {
13026
+ React61__default.useEffect(() => {
13047
13027
  if (pending || !restoreFocusRef.current) return;
13048
13028
  restoreFocusRef.current = false;
13049
13029
  const frame = requestAnimationFrame(() => buttonRef.current?.focus());
@@ -13113,9 +13093,9 @@ function CardLoadMorePagination({
13113
13093
  var navButtonClass = "h-8 w-8 p-0 text-foreground disabled:text-muted-foreground disabled:opacity-70";
13114
13094
  var chevronClass = "h-4 w-4 rtl:-scale-x-100";
13115
13095
  function useLowerBoundPageCountWarning(manualPagination, pageCount, pagination) {
13116
- const previous = React60__default.useRef(null);
13117
- const warned = React60__default.useRef(false);
13118
- React60__default.useEffect(() => {
13096
+ const previous = React61__default.useRef(null);
13097
+ const warned = React61__default.useRef(false);
13098
+ React61__default.useEffect(() => {
13119
13099
  if (typeof console === "undefined") return;
13120
13100
  if (typeof process !== "undefined" && process.env?.NODE_ENV === "production") return;
13121
13101
  if (!manualPagination || pageCount === void 0 || !pagination) {
@@ -15005,7 +14985,7 @@ function NNavbar({
15005
14985
  (userMenuActions.length > 0 || onLogout) && /* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
15006
14986
  userMenuActions.map((action) => {
15007
14987
  const ActionIcon = action.icon;
15008
- return /* @__PURE__ */ jsxs(React60__default.Fragment, { children: [
14988
+ return /* @__PURE__ */ jsxs(React61__default.Fragment, { children: [
15009
14989
  action.separator && /* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
15010
14990
  /* @__PURE__ */ jsxs(DropdownMenuItem, { onClick: action.onClick, className: "cursor-pointer", children: [
15011
14991
  ActionIcon && /* @__PURE__ */ jsx(ActionIcon, { className: "h-4 w-4 mr-2" }),
@@ -15275,4 +15255,4 @@ function NGridItem({
15275
15255
  return /* @__PURE__ */ jsx("div", { className: itemClassName, ...props, children });
15276
15256
  }
15277
15257
 
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 };
15258
+ 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, 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, createDialogStore, createTableStore, detectFormat, dialogVariants, filterResponsiveColumns, 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 };