najm-kit 2.8.2 → 2.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1,9 +1,11 @@
1
- import { useResolvedFormDevTools, useNBranding } from './chunk-GHMR45H3.mjs';
2
- export { FormDevToolsProvider, NBrandingProvider, NBrandingStateProvider, NajmFormatProvider, buildFormFill, normalizeBranding, useNBranding, useNBrandingEditor, useNajmFormat, useNajmFormatContext } from './chunk-GHMR45H3.mjs';
3
- import { useResolvedPaginationLabels } from './chunk-USZUOJMK.mjs';
4
- export { DEFAULT_PAGINATION_KEY_PREFIX, DEFAULT_TIME_ZONE, EMPTY_DESIGN, NTableDefaultsProvider, NajmDesignEditorProvider, NajmPreferencesProvider, NajmUIProvider, buildPaginationLabels, useNTableDefaults, useNajmDesignEditor, useNajmPreferencesContext, useNajmTheme, useNajmTimeZone } from './chunk-USZUOJMK.mjs';
5
- import { resolveRadiusValue, inputBorderClasses, Button, NIcon, NajmScroll, surfaceBorderClasses, useNajmScrollViewport, resolveVariantAlias, buttonVariants, NButton, parseNajmDesignConfig, useTableStore, TableStoreContext, sidebarBorderClasses, NTableJson } from './chunk-6OOBAEH2.mjs';
6
- export { Button, NAJM_COMPONENT_NAMES, NButton, NIcon, NTableJson, NajmScroll, RADIUS_VALUE_MAP, TableStoreContext, buttonVariants, defineNajmDesignConfig, defineNajmThemeConfig, inputBorderClasses, parseNajmDesignConfig, parseNajmThemeConfig, resolveRadiusValue, resolveVariantAlias, sidebarBorderClasses, stringifyNajmDesignConfig, stringifyNajmThemeConfig, surfaceBorderClasses, useTableStore } from './chunk-6OOBAEH2.mjs';
1
+ import { resolveAvatarSrc } from './chunk-BEGOH366.mjs';
2
+ export { isPlaceholderAvatar, resolveAvatarSrc } from './chunk-BEGOH366.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
+ 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';
7
9
  import { useNajmComponentStyle, cn, NajmThemeContainerCtx, useNajmThemeMode, useNajmDesign, composePreset } from './chunk-KVZACF4G.mjs';
8
10
  export { NajmDesignProvider, NajmThemeProvider, cn, composePreset, resolvePreset, useNajmAppearance, useNajmComponentStyle, useNajmDesign, useNajmThemeMode } from './chunk-KVZACF4G.mjs';
9
11
  export { DEFAULT_CARD_BREAKPOINT, DEFAULT_CARD_PAGINATION_KEY_PREFIX, buildCardPaginationLabels, createCardPagination, useCardViewport, useDesktopTableMode, useMediaQuery } from './chunk-OUS7OYVA.mjs';
@@ -11,10 +13,10 @@ import './chunk-F5KXJCCJ.mjs';
11
13
  import { humanizeToken } from './chunk-JABLSOQN.mjs';
12
14
  export { DEFAULT_PLACEHOLDER, formatCurrency, formatDate, formatDateTime, formatNumber, formatPercent, formatRelativeTime, formatTime, humanizeToken, localDateInput, slugify } from './chunk-JABLSOQN.mjs';
13
15
  export { DEFAULT_MAX_PAGE_SIZE, DEFAULT_PAGE_SIZE, cleanQuery, createOffsetPagination, fetchOffsetPage, getPageIndex } from './chunk-2NX2VKS2.mjs';
14
- import { resolveAvatarSrc } from './chunk-BEGOH366.mjs';
15
- export { isPlaceholderAvatar, resolveAvatarSrc } from './chunk-BEGOH366.mjs';
16
- import * as React60 from 'react';
17
- import React60__default, { createContext, useRef, useMemo, useState, useEffect, useContext, useCallback, useLayoutEffect, isValidElement } from 'react';
16
+ import { resolveRadiusValue, resolveVariantAlias, parseNajmDesignConfig } from './chunk-TFHWLE7N.mjs';
17
+ export { NAJM_COMPONENT_NAMES, RADIUS_VALUE_MAP, defineNajmDesignConfig, defineNajmThemeConfig, parseNajmDesignConfig, parseNajmThemeConfig, resolveRadiusValue, resolveVariantAlias, stringifyNajmDesignConfig, stringifyNajmThemeConfig } from './chunk-TFHWLE7N.mjs';
18
+ import * as React61 from 'react';
19
+ import React61__default, { createContext, useRef, useMemo, useState, useEffect, useContext, useCallback, useLayoutEffect, isValidElement } from 'react';
18
20
  import * as TabsPrimitive from '@radix-ui/react-tabs';
19
21
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
20
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';
@@ -260,7 +262,7 @@ function NTabs({
260
262
  }
261
263
  var PORTAL_LAYER_STYLE_ID = "najm-kit-portal-layer-styles";
262
264
  function useNajmPortalLayerStyles() {
263
- React60.useInsertionEffect(() => {
265
+ React61.useInsertionEffect(() => {
264
266
  if (typeof document === "undefined") return;
265
267
  if (document.getElementById(PORTAL_LAYER_STYLE_ID)) return;
266
268
  const style = document.createElement("style");
@@ -291,7 +293,7 @@ var tooltipContentVariants = cva(
291
293
  }
292
294
  );
293
295
  function TooltipContent({ className, sideOffset = 4, variant, children, ...props }) {
294
- const container = React60.useContext(NajmThemeContainerCtx);
296
+ const container = React61.useContext(NajmThemeContainerCtx);
295
297
  useNajmPortalLayerStyles();
296
298
  return /* @__PURE__ */ jsx(TooltipPrimitive.Portal, { container: container ?? void 0, children: /* @__PURE__ */ jsx(
297
299
  TooltipPrimitive.Content,
@@ -441,7 +443,7 @@ var ERROR_BORDER = "border !border-red-600";
441
443
  var FOCUS_INTERACTIVE_BASE = "border focus-within:border-primary";
442
444
  var HOVER_INTERACTIVE_BASE = "hover:border-primary";
443
445
  var STATIC_BASE = "border";
444
- var BaseInput = React60__default.forwardRef(
446
+ var BaseInput = React61__default.forwardRef(
445
447
  ({ children, variant = "default", status = "default", bordered, borderColor, className, style, disabled = false, onHover, onClick, hasIcon, ...rest }, ref) => {
446
448
  const recipe = useNajmComponentStyle("input");
447
449
  const isGhost = variant === "ghost";
@@ -493,7 +495,7 @@ function PopoverAnchor({ ...props }) {
493
495
  return /* @__PURE__ */ jsx(PopoverPrimitive.Anchor, { "data-slot": "popover-anchor", ...props });
494
496
  }
495
497
  function PopoverContent({ className, align = "center", sideOffset = 4, ...props }) {
496
- const container = React60.useContext(NajmThemeContainerCtx);
498
+ const container = React61.useContext(NajmThemeContainerCtx);
497
499
  useNajmPortalLayerStyles();
498
500
  return /* @__PURE__ */ jsx(PopoverPrimitive.Portal, { container: container ?? void 0, children: /* @__PURE__ */ jsx(
499
501
  PopoverPrimitive.Content,
@@ -602,7 +604,7 @@ function SwatchesColorPicker({
602
604
  hideSwatches = false
603
605
  }) {
604
606
  const inputRef = useRef(null);
605
- const themeContainer = React60__default.useContext(NajmThemeContainerCtx);
607
+ const themeContainer = React61__default.useContext(NajmThemeContainerCtx);
606
608
  const resolvedValue = resolvePickerColor(value, themeContainer);
607
609
  return /* @__PURE__ */ jsxs(
608
610
  BaseInput,
@@ -672,7 +674,7 @@ function PopoverColorPicker({
672
674
  formats = DEFAULT_FORMATS,
673
675
  output = "preserve"
674
676
  }) {
675
- const themeContainer = React60__default.useContext(NajmThemeContainerCtx);
677
+ const themeContainer = React61__default.useContext(NajmThemeContainerCtx);
676
678
  const resolvedValue = resolvePickerColor(value, themeContainer);
677
679
  const initialFormat = formats.includes(detectFormat(resolvedValue)) ? detectFormat(resolvedValue) : formats[0] ?? "hex";
678
680
  const [activeFormat, setActiveFormat] = useState(initialFormat);
@@ -929,7 +931,7 @@ function SheetClose({ ...props }) {
929
931
  return /* @__PURE__ */ jsx(SheetPrimitive.Close, { "data-slot": "sheet-close", ...props });
930
932
  }
931
933
  function SheetPortal({ ...props }) {
932
- const container = React60.useContext(NajmThemeContainerCtx);
934
+ const container = React61.useContext(NajmThemeContainerCtx);
933
935
  return /* @__PURE__ */ jsx(SheetPrimitive.Portal, { "data-slot": "sheet-portal", container: container ?? void 0, ...props });
934
936
  }
935
937
  function SheetOverlay({ className, ...props }) {
@@ -1078,7 +1080,7 @@ function DialogTrigger({ ...props }) {
1078
1080
  return /* @__PURE__ */ jsx(SheetPrimitive.Trigger, { "data-slot": "dialog-trigger", ...props });
1079
1081
  }
1080
1082
  function DialogPortal({ ...props }) {
1081
- const container = React60.useContext(NajmThemeContainerCtx);
1083
+ const container = React61.useContext(NajmThemeContainerCtx);
1082
1084
  return /* @__PURE__ */ jsx(SheetPrimitive.Portal, { "data-slot": "dialog-portal", container: container ?? void 0, ...props });
1083
1085
  }
1084
1086
  function DialogClose({ ...props }) {
@@ -1109,8 +1111,8 @@ function getDefaultPadding() {
1109
1111
  return window.matchMedia(MOBILE_PADDING_QUERY).matches ? "sm" : "md";
1110
1112
  }
1111
1113
  function useResponsivePadding(value) {
1112
- const [resolved, setResolved] = React60.useState(() => value ?? getDefaultPadding());
1113
- React60.useEffect(() => {
1114
+ const [resolved, setResolved] = React61.useState(() => value ?? getDefaultPadding());
1115
+ React61.useEffect(() => {
1114
1116
  if (value) {
1115
1117
  setResolved(value);
1116
1118
  return;
@@ -1174,7 +1176,7 @@ var sizeClasses2 = {
1174
1176
  md: "h-8 w-8",
1175
1177
  lg: "h-10 w-10"
1176
1178
  };
1177
- var IconButton = React60.forwardRef(
1179
+ var IconButton = React61.forwardRef(
1178
1180
  ({
1179
1181
  className,
1180
1182
  variant = "ghost",
@@ -1256,10 +1258,10 @@ function NPageHeaderTop({ children, className }) {
1256
1258
  }
1257
1259
  NPageHeaderTop.displayName = "NPageHeaderTop";
1258
1260
  function isPageHeaderSlot(child, slot) {
1259
- return React60__default.isValidElement(child) && child.type === slot;
1261
+ return React61__default.isValidElement(child) && child.type === slot;
1260
1262
  }
1261
1263
  function getSlotElements(children, slot) {
1262
- 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));
1263
1265
  return matches.length > 0 ? matches : void 0;
1264
1266
  }
1265
1267
  var responsiveClasses = {
@@ -1672,8 +1674,8 @@ function NDialogSecondaryButton(_props) {
1672
1674
  function parseDirectDialogSlots(children) {
1673
1675
  const body = [];
1674
1676
  const parsed = {};
1675
- React60__default.Children.forEach(children, (child) => {
1676
- if (!React60__default.isValidElement(child)) {
1677
+ React61__default.Children.forEach(children, (child) => {
1678
+ if (!React61__default.isValidElement(child)) {
1677
1679
  body.push(child);
1678
1680
  return;
1679
1681
  }
@@ -1746,15 +1748,15 @@ var dialogVariants = cva(
1746
1748
  );
1747
1749
  var CONTENT_ACTIONS_SELECTOR = '[data-najm-dialog-actions="content"], [data-najm-wizard-form="true"]';
1748
1750
  function useContentOwnsActions() {
1749
- const [contentElement, setContentElement] = React60__default.useState(null);
1750
- const [contentOwnsActions, setContentOwnsActions] = React60__default.useState(false);
1751
- const contentElementRef = React60__default.useRef(null);
1752
- 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) => {
1753
1755
  if (contentElementRef.current === node) return;
1754
1756
  contentElementRef.current = node;
1755
1757
  setContentElement(node);
1756
1758
  }, []);
1757
- React60__default.useLayoutEffect(() => {
1759
+ React61__default.useLayoutEffect(() => {
1758
1760
  if (!contentElement) {
1759
1761
  setContentOwnsActions((current) => current ? false : current);
1760
1762
  return;
@@ -2007,8 +2009,8 @@ function NDirectDialog({
2007
2009
  const resolvedHeaderClassName = cn(slots.header?.className, headerClassName);
2008
2010
  const resolvedTitleClassName = cn(slots.header?.titleClassName, titleClassName);
2009
2011
  const resolvedDescriptionClassName = cn(slots.description?.className, descriptionClassName);
2010
- const [internalOpen, setInternalOpen] = React60__default.useState(defaultOpen);
2011
- const [primaryLoading, setPrimaryLoading] = React60__default.useState(false);
2012
+ const [internalOpen, setInternalOpen] = React61__default.useState(defaultOpen);
2013
+ const [primaryLoading, setPrimaryLoading] = React61__default.useState(false);
2012
2014
  const isControlled = open !== void 0;
2013
2015
  const currentOpen = isControlled ? open : internalOpen;
2014
2016
  const setOpen = (nextOpen) => {
@@ -2290,7 +2292,7 @@ function useDialog(store) {
2290
2292
  description: options.description,
2291
2293
  size: options.size || "sm",
2292
2294
  className: options.className,
2293
- render: ({ dialog, zIndex, confirm, cancel, onOpenChange }) => React60__default.createElement(NDeleteDialog, {
2295
+ render: ({ dialog, zIndex, confirm, cancel, onOpenChange }) => React61__default.createElement(NDeleteDialog, {
2294
2296
  itemName: options.itemName,
2295
2297
  itemType: options.itemType,
2296
2298
  icon: options.icon,
@@ -2406,77 +2408,6 @@ function Checkbox({ className, ...props }) {
2406
2408
  }
2407
2409
  );
2408
2410
  }
2409
-
2410
- // src/components/Badge/status.ts
2411
- var NAJM_STATUS_COLORS = {
2412
- active: "success",
2413
- approved: "success",
2414
- completed: "success",
2415
- confirmed: "success",
2416
- delivered: "success",
2417
- paid: "success",
2418
- published: "success",
2419
- succeeded: "success",
2420
- validated: "success",
2421
- verified: "success",
2422
- in_preparation: "warning",
2423
- in_progress: "warning",
2424
- out_for_delivery: "warning",
2425
- pending: "warning",
2426
- pending_email_verification: "warning",
2427
- pending_review: "warning",
2428
- processing: "warning",
2429
- submitted: "warning",
2430
- paused: "info",
2431
- purchased: "info",
2432
- scheduled: "info",
2433
- archived: "neutral",
2434
- cancelled: "neutral",
2435
- canceled: "neutral",
2436
- closed: "neutral",
2437
- draft: "neutral",
2438
- inactive: "neutral",
2439
- stopped: "neutral",
2440
- unknown: "neutral",
2441
- blocked: "destructive",
2442
- expired: "destructive",
2443
- failed: "destructive",
2444
- refunded: "destructive",
2445
- rejected: "destructive",
2446
- suspended: "destructive"
2447
- };
2448
- var NAJM_COLOR_TEXT_CLASSES = {
2449
- primary: "text-primary",
2450
- secondary: "text-secondary-foreground",
2451
- accent: "text-accent-foreground",
2452
- neutral: "text-muted-foreground",
2453
- info: "text-info",
2454
- success: "text-success",
2455
- warning: "text-warning",
2456
- destructive: "text-destructive"
2457
- };
2458
- function normalizeStatus(status) {
2459
- return status.trim().toLowerCase().replace(/[\s-]+/g, "_");
2460
- }
2461
- function lookup(map, status, normalized) {
2462
- if (!map) return void 0;
2463
- return map[status] ?? map[normalized];
2464
- }
2465
- function findStatusColor(status, statusMap) {
2466
- if (!status) return void 0;
2467
- const normalized = normalizeStatus(status);
2468
- return lookup(statusMap, status, normalized) ?? lookup(NAJM_STATUS_COLORS, status, normalized);
2469
- }
2470
- function resolveStatusColor(status, statusMap, fallback = "neutral") {
2471
- return findStatusColor(status, statusMap) ?? fallback;
2472
- }
2473
- function colorTextClass(color) {
2474
- return NAJM_COLOR_TEXT_CLASSES[color] ?? "text-foreground";
2475
- }
2476
- function statusTextClass(status, statusMap, fallback) {
2477
- const color = findStatusColor(status, statusMap) ?? fallback;
2478
- return color ? colorTextClass(color) : "";
2479
- }
2480
2411
  var badgeVariants = cva(
2481
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",
2482
2413
  {
@@ -2586,29 +2517,37 @@ function Badge({
2586
2517
  }) {
2587
2518
  const Comp = asChild ? Slot : "span";
2588
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);
2589
2528
  const aliased = resolveVariantAlias(
2590
2529
  recipe?.variants,
2591
2530
  variant ?? recipe?.defaultVariant ?? "default"
2592
2531
  );
2593
2532
  const effVariant = variant ?? aliased.variant ?? recipe?.defaultVariant;
2594
- const recipeRadius = shape === void 0 ? resolveRadiusValue(recipe?.radius) : void 0;
2533
+ const recipeRadius = effectiveShape === void 0 ? resolveRadiusValue(recipe?.radius) : void 0;
2595
2534
  const recipeStyle = recipeRadius ? { borderRadius: recipeRadius, ...style } : style;
2596
- const resolvedColor = status ? resolveStatusColor(status, statusMap, color ?? "neutral") : color ?? "primary";
2597
- 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);
2598
2537
  const content = typeof children !== "string" && children ? children : resolvedLabel ?? children;
2599
- const resolvedIcon = icon ?? (resolvedColor ? iconMap?.[resolvedColor] : void 0);
2600
- const iconNode = renderIcon(showIcon ? resolvedIcon : icon);
2601
- 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";
2602
2541
  if (isMinimal) {
2603
2542
  const textColor = colorTextClass(resolvedColor);
2604
- const sizeClass = SIZE_TEXT_MAP[size ?? "md"] ?? "text-sm";
2543
+ const sizeClass = SIZE_TEXT_MAP[effectiveSize ?? "md"] ?? "text-sm";
2605
2544
  return /* @__PURE__ */ jsxs(
2606
2545
  Comp,
2607
2546
  {
2608
2547
  "data-slot": "badge",
2609
2548
  className: cn(
2610
2549
  "inline-flex items-center gap-1.5 font-medium bg-transparent border-0",
2611
- look === "text" ? "px-0" : void 0,
2550
+ effectiveLook === "text" ? "px-0" : void 0,
2612
2551
  textColor,
2613
2552
  sizeClass,
2614
2553
  className
@@ -2623,7 +2562,12 @@ function Badge({
2623
2562
  }
2624
2563
  );
2625
2564
  }
2626
- 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 });
2627
2571
  return /* @__PURE__ */ jsxs(Comp, { "data-slot": "badge", className: cn(classes, aliased.style?.className, className), style: recipeStyle, ...props, children: [
2628
2572
  iconPosition === "left" && iconNode,
2629
2573
  content,
@@ -2642,8 +2586,8 @@ function resolveIcon(icon) {
2642
2586
  }
2643
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 }) => {
2644
2588
  const [open, setOpen] = useState(false);
2645
- const triggerRef = React60__default.useRef(null);
2646
- const pointerDismissedRef = React60__default.useRef(false);
2589
+ const triggerRef = React61__default.useRef(null);
2590
+ const pointerDismissedRef = React61__default.useRef(false);
2647
2591
  const shouldDisplayIcon = Boolean(icon) && showIcon && value.length === 0;
2648
2592
  const iconProps = getIconColorProps(iconColor, "h-4 w-4");
2649
2593
  const handleSelect = (itemValue) => {
@@ -2759,7 +2703,7 @@ function SelectScrollDownButton({ className, ...props }) {
2759
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" }) });
2760
2704
  }
2761
2705
  function SelectContent({ className, children, position = "popper", style, ...props }) {
2762
- const container = React60.useContext(NajmThemeContainerCtx);
2706
+ const container = React61.useContext(NajmThemeContainerCtx);
2763
2707
  const recipe = useNajmComponentStyle("select");
2764
2708
  const contentSlot = recipe?.slots?.content;
2765
2709
  const borderWidth = contentSlot?.borderWidth ?? recipe?.borderWidth;
@@ -2842,9 +2786,9 @@ var SelectInput = ({ placeholder = "", ariaLabel, value, onChange, icon, showIco
2842
2786
  (item) => typeof item === "string" ? item === value : item.value === value
2843
2787
  );
2844
2788
  const displayLabel = typeof found === "string" ? found : found?.label ?? value;
2845
- const [open, setOpen] = React60__default.useState(false);
2846
- const triggerRef = React60__default.useRef(null);
2847
- 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);
2848
2792
  return /* @__PURE__ */ jsxs("div", { className: cn("group relative", className), children: [
2849
2793
  /* @__PURE__ */ jsxs(
2850
2794
  BaseInput,
@@ -3712,7 +3656,7 @@ function CollapsibleSection({
3712
3656
  children,
3713
3657
  disabled
3714
3658
  }) {
3715
- const [open, setOpen] = React60.useState(true);
3659
+ const [open, setOpen] = React61.useState(true);
3716
3660
  const titleText = typeof title === "string" || typeof title === "number" ? String(title) : "Section";
3717
3661
  return /* @__PURE__ */ jsxs(
3718
3662
  Collapsible,
@@ -4030,7 +3974,7 @@ function TokenGroupSection({
4030
3974
  disabled,
4031
3975
  labels
4032
3976
  }) {
4033
- const [open, setOpen] = React60.useState(groupId === "surface" || groupId === "brand");
3977
+ const [open, setOpen] = React61.useState(groupId === "surface" || groupId === "brand");
4034
3978
  const labelText = typeof label === "string" || typeof label === "number" ? String(label) : "Group";
4035
3979
  return /* @__PURE__ */ jsxs(
4036
3980
  Collapsible,
@@ -4362,7 +4306,7 @@ function normalizeCode(value, numeric, length) {
4362
4306
  const normalized = numeric ? value.replace(/\D/g, "") : value.replace(/\s/g, "");
4363
4307
  return normalized.slice(0, length);
4364
4308
  }
4365
- var OtpInput = React60__default.forwardRef(
4309
+ var OtpInput = React61__default.forwardRef(
4366
4310
  ({
4367
4311
  value,
4368
4312
  onChange,
@@ -4544,8 +4488,8 @@ var TextAreaInput = ({ value, onChange, placeholder = "", className = "", varian
4544
4488
  };
4545
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 }) => {
4546
4490
  const [open, setOpen] = useState(false);
4547
- const triggerRef = React60__default.useRef(null);
4548
- const pointerDismissedRef = React60__default.useRef(false);
4491
+ const triggerRef = React61__default.useRef(null);
4492
+ const pointerDismissedRef = React61__default.useRef(false);
4549
4493
  const [query, setQuery] = useState("");
4550
4494
  const normalizedItems = items.map((item) => typeof item === "string" ? { value: item, label: item } : item);
4551
4495
  const selectedItem = normalizedItems.find((item) => item.value === value);
@@ -5932,7 +5876,7 @@ function DropdownMenuSubContent({ className, children, style, ...props }) {
5932
5876
  );
5933
5877
  }
5934
5878
  function DropdownMenuContent({ className, children, sideOffset = 4, style, ...props }) {
5935
- const container = React60.useContext(NajmThemeContainerCtx);
5879
+ const container = React61.useContext(NajmThemeContainerCtx);
5936
5880
  const surface = useDropdownSurfaceRecipe("content");
5937
5881
  const { hostRef, viewportRef } = useNajmScrollViewport();
5938
5882
  useNajmPortalLayerStyles();
@@ -6336,8 +6280,8 @@ function NSlider({
6336
6280
  return Array.isArray(v) ? [...v] : [v];
6337
6281
  };
6338
6282
  const initialRadix = toRadix(controlledValue ?? defaultValue);
6339
- const [internalValues, setInternalValues] = React60.useState(initialRadix);
6340
- const [active, setActive] = React60.useState(null);
6283
+ const [internalValues, setInternalValues] = React61.useState(initialRadix);
6284
+ const [active, setActive] = React61.useState(null);
6341
6285
  const currentValues = controlledValue !== void 0 ? toRadix(controlledValue) : internalValues;
6342
6286
  const handleRadix = (arr) => {
6343
6287
  setInternalValues(arr);
@@ -6494,13 +6438,13 @@ function NThemePresets({
6494
6438
  disabled = false,
6495
6439
  className
6496
6440
  }) {
6497
- const [saveOpen, setSaveOpen] = React60.useState(false);
6498
- const [name, setName] = React60.useState("");
6499
- const [pendingDelete, setPendingDelete] = React60.useState(
6441
+ const [saveOpen, setSaveOpen] = React61.useState(false);
6442
+ const [name, setName] = React61.useState("");
6443
+ const [pendingDelete, setPendingDelete] = React61.useState(
6500
6444
  null
6501
6445
  );
6502
- const [busy, setBusy] = React60.useState(false);
6503
- const rows = React60.useMemo(
6446
+ const [busy, setBusy] = React61.useState(false);
6447
+ const rows = React61.useMemo(
6504
6448
  () => [
6505
6449
  ...savedDesign ? [
6506
6450
  {
@@ -6752,12 +6696,12 @@ function NThemeCustomizer({
6752
6696
  }) {
6753
6697
  const inheritedMode = useNajmThemeMode();
6754
6698
  const resolvedPreviewMode = previewMode ?? inheritedMode ?? value.theme.mode ?? "light";
6755
- const visibleTabs = React60.useMemo(() => buildTabs(tabs), [tabs]);
6699
+ const visibleTabs = React61.useMemo(() => buildTabs(tabs), [tabs]);
6756
6700
  const firstTab = visibleTabs[0] ?? "theme";
6757
- const [activeTab, setActiveTab] = React60.useState(TAB_VALUE[firstTab]);
6758
- const [fileError, setFileError] = React60.useState(false);
6759
- const fileInputRef = React60.useRef(null);
6760
- 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(() => {
6761
6705
  setActiveTab(TAB_VALUE[firstTab]);
6762
6706
  }, [firstTab]);
6763
6707
  const themeLabel = resolveLabel("themeTab", labels);
@@ -6769,7 +6713,7 @@ function NThemeCustomizer({
6769
6713
  const invalidThemeFileLabel = resolveLabel("invalidThemeFile", labels);
6770
6714
  const defaultOptionLabel = resolveLabel("defaultOption", labels);
6771
6715
  const colorSwatchFallbackLabel = resolveLabel("colorSwatchFallback", labels);
6772
- const tokenLabels = React60.useMemo(() => {
6716
+ const tokenLabels = React61.useMemo(() => {
6773
6717
  const out = {};
6774
6718
  const knownTokens = [
6775
6719
  "background",
@@ -7573,7 +7517,7 @@ function Alert({
7573
7517
  );
7574
7518
  }
7575
7519
  var NAlert = Alert;
7576
- var NativeSelect = React60.forwardRef(
7520
+ var NativeSelect = React61.forwardRef(
7577
7521
  ({ className, options, placeholder, value, ...props }, ref) => {
7578
7522
  const hasValue = value !== void 0 && value !== "";
7579
7523
  return /* @__PURE__ */ jsxs("div", { className: "relative", children: [
@@ -7626,10 +7570,20 @@ function ScrollArea({ className, children, ...props }) {
7626
7570
  }
7627
7571
  ) });
7628
7572
  }
7629
- function NImage({ src, fallback, alt = "", ...rest }) {
7630
- const [failed, setFailed] = useState(null);
7631
- const resolved = failed === src && fallback ? fallback : src;
7632
- 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
+ );
7633
7587
  }
7634
7588
  var avatarVariants = cva(
7635
7589
  "relative flex shrink-0 overflow-hidden",
@@ -7721,7 +7675,7 @@ function Avatar({
7721
7675
  ...props
7722
7676
  }) {
7723
7677
  const hasShortcut = src !== void 0 || fallback !== void 0;
7724
- const hasChildren = React60.Children.count(children) > 0;
7678
+ const hasChildren = React61.Children.count(children) > 0;
7725
7679
  return /* @__PURE__ */ jsxs(
7726
7680
  AvatarPrimitive.Root,
7727
7681
  {
@@ -7815,9 +7769,9 @@ function AvatarGroup({ ring = true, className, children, ...props }) {
7815
7769
  "data-slot": "avatar-group",
7816
7770
  className: cn("flex -space-x-2", className),
7817
7771
  ...props,
7818
- children: ring ? React60.Children.map(children, (child) => {
7819
- if (React60.isValidElement(child) && child.type === Avatar) {
7820
- 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 });
7821
7775
  }
7822
7776
  return child;
7823
7777
  }) : children
@@ -7884,7 +7838,7 @@ function Swap({
7884
7838
  className,
7885
7839
  ...props
7886
7840
  }) {
7887
- const [internalChecked, setInternalChecked] = React60.useState(defaultChecked);
7841
+ const [internalChecked, setInternalChecked] = React61.useState(defaultChecked);
7888
7842
  const isControlled = controlledChecked !== void 0 || controlledState !== void 0;
7889
7843
  const currentState = getDerivedState(
7890
7844
  isControlled ? controlledChecked ?? false : internalChecked,
@@ -7892,7 +7846,7 @@ function Swap({
7892
7846
  );
7893
7847
  const dataState = currentState === "indeterminate" ? "indeterminate" : currentState ? "on" : "off";
7894
7848
  const ariaPressed = currentState === "indeterminate" ? "mixed" : currentState;
7895
- const handleClick = React60.useCallback((event) => {
7849
+ const handleClick = React61.useCallback((event) => {
7896
7850
  onClick?.(event);
7897
7851
  if (event.defaultPrevented) return;
7898
7852
  if (disabled) return;
@@ -8017,7 +7971,7 @@ var toneClasses = {
8017
7971
  ring: "border-primary/30"
8018
7972
  }
8019
7973
  };
8020
- var StatusPill = React60.forwardRef(
7974
+ var StatusPill = React61.forwardRef(
8021
7975
  ({ className, tone = "neutral", pulse = false, label, ...props }, ref) => {
8022
7976
  const c = toneClasses[tone];
8023
7977
  return /* @__PURE__ */ jsxs(
@@ -8076,20 +8030,20 @@ function Toaster({ toastOptions, ...props }) {
8076
8030
  );
8077
8031
  }
8078
8032
  var Form = FormProvider;
8079
- var FormFieldContext = React60.createContext({});
8033
+ var FormFieldContext = React61.createContext({});
8080
8034
  var FormField = ({ ...props }) => /* @__PURE__ */ jsx(FormFieldContext.Provider, { value: { name: props.name }, children: /* @__PURE__ */ jsx(Controller, { ...props }) });
8081
8035
  var useFormField = () => {
8082
- const fieldContext = React60.useContext(FormFieldContext);
8083
- const itemContext = React60.useContext(FormItemContext);
8036
+ const fieldContext = React61.useContext(FormFieldContext);
8037
+ const itemContext = React61.useContext(FormItemContext);
8084
8038
  const { getFieldState, formState } = useFormContext();
8085
8039
  const fieldState = getFieldState(fieldContext.name, formState);
8086
8040
  if (!fieldContext) throw new Error("useFormField should be used within <FormField>");
8087
8041
  const { id } = itemContext;
8088
8042
  return { id, name: fieldContext.name, formItemId: `${id}-form-item`, formDescriptionId: `${id}-form-item-description`, formMessageId: `${id}-form-item-message`, ...fieldState };
8089
8043
  };
8090
- var FormItemContext = React60.createContext({});
8044
+ var FormItemContext = React61.createContext({});
8091
8045
  function FormItem({ className, ...props }) {
8092
- const id = React60.useId();
8046
+ const id = React61.useId();
8093
8047
  return /* @__PURE__ */ jsx(FormItemContext.Provider, { value: { id }, children: /* @__PURE__ */ jsx("div", { "data-slot": "form-item", className: cn("grid gap-2", className), ...props }) });
8094
8048
  }
8095
8049
  function FormLabel({ className, ...props }) {
@@ -8233,7 +8187,7 @@ function NErrorState({ title = "Something went wrong", message, onRetry, retryLa
8233
8187
  ] });
8234
8188
  }
8235
8189
  function NEmptyState({ title = "No data", description, icon, action, className }) {
8236
- 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;
8237
8191
  return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col items-center justify-center gap-3 py-12", className), children: [
8238
8192
  iconContent && /* @__PURE__ */ jsx("div", { className: "text-muted-foreground/50", children: iconContent }),
8239
8193
  /* @__PURE__ */ jsxs("div", { className: "text-center", children: [
@@ -8243,7 +8197,7 @@ function NEmptyState({ title = "No data", description, icon, action, className }
8243
8197
  action && /* @__PURE__ */ jsx("div", { className: "mt-2", children: action })
8244
8198
  ] });
8245
8199
  }
8246
- var NErrorBoundary = class extends React60__default.Component {
8200
+ var NErrorBoundary = class extends React61__default.Component {
8247
8201
  constructor(props) {
8248
8202
  super(props);
8249
8203
  this.state = { hasError: false, error: null };
@@ -8391,11 +8345,6 @@ function nameToColor(name) {
8391
8345
  function getInitials(name) {
8392
8346
  return name.split(" ").map((part) => part.charAt(0)).join("").toUpperCase().slice(0, 2);
8393
8347
  }
8394
- function withVersion(src, version) {
8395
- if (!version || src.startsWith("data:") || src.startsWith("blob:")) return src;
8396
- const separator = src.includes("?") ? "&" : "?";
8397
- return `${src}${separator}v=${encodeURIComponent(String(version))}`;
8398
- }
8399
8348
  function NAvatar({
8400
8349
  src,
8401
8350
  title,
@@ -8409,30 +8358,63 @@ function NAvatar({
8409
8358
  subtitle,
8410
8359
  meta,
8411
8360
  className,
8412
- classNames
8361
+ classNames,
8362
+ imageProps
8413
8363
  }) {
8414
8364
  const label = title || fallback || "";
8415
8365
  const imageVersion = srcVersion ?? version;
8416
- const resolvedSrc = resolveAvatarSrc(src, void 0);
8417
- 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);
8418
8371
  const { bg, text } = nameToColor(label);
8419
8372
  const hasText = Boolean(title || subtitle || meta);
8420
8373
  const fallbackText = fallback && !title ? fallback : label ? getInitials(label) : "?";
8421
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;
8422
8389
  return /* @__PURE__ */ jsxs("div", { className: cn("flex items-center gap-3", classNames?.root, className), children: [
8423
8390
  /* @__PURE__ */ jsxs(
8424
8391
  Avatar,
8425
8392
  {
8426
- 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),
8427
8394
  children: [
8428
- imageSrc && /* @__PURE__ */ jsx(
8429
- AvatarImage,
8395
+ showImage && /* @__PURE__ */ jsx(
8396
+ "img",
8430
8397
  {
8431
- src: imageSrc,
8398
+ ...restImageProps,
8399
+ ref: imageRef,
8400
+ "data-slot": "avatar-image",
8401
+ src: chain.src,
8432
8402
  alt: alt || label,
8433
- 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
+ }
8434
8413
  }
8435
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.
8436
8418
  /* @__PURE__ */ jsx(
8437
8419
  AvatarFallback,
8438
8420
  {
@@ -8553,8 +8535,8 @@ function NCard({
8553
8535
  let footerClassName;
8554
8536
  let mediaSlot = null;
8555
8537
  const mainChildren = [];
8556
- React60__default.Children.forEach(children, (child) => {
8557
- if (!React60__default.isValidElement(child)) {
8538
+ React61__default.Children.forEach(children, (child) => {
8539
+ if (!React61__default.isValidElement(child)) {
8558
8540
  mainChildren.push(child);
8559
8541
  return;
8560
8542
  }
@@ -8730,7 +8712,7 @@ function truncateByCharacters(text, maxCharacters, suffix = "...") {
8730
8712
  const str = String(text);
8731
8713
  return str.length <= maxCharacters ? str : str.slice(0, maxCharacters) + suffix;
8732
8714
  }
8733
- var CardDensityContext = React60__default.createContext("default");
8715
+ var CardDensityContext = React61__default.createContext("default");
8734
8716
  function NCardInfo({
8735
8717
  icon: Icon2,
8736
8718
  label,
@@ -8743,7 +8725,7 @@ function NCardInfo({
8743
8725
  className,
8744
8726
  ...props
8745
8727
  }) {
8746
- const inheritedDensity = React60__default.useContext(CardDensityContext);
8728
+ const inheritedDensity = React61__default.useContext(CardDensityContext);
8747
8729
  const resolvedDensity = density ?? inheritedDensity;
8748
8730
  const isTruncated = typeof value === "string" && value.length > maxChars;
8749
8731
  const displayValue = isTruncated ? truncateByCharacters(value, maxChars) : value;
@@ -9992,7 +9974,7 @@ function NContextMenu({ x, y, items, onAction, onClose, className }) {
9992
9974
  children: items.map((item) => {
9993
9975
  const Icon2 = item.icon;
9994
9976
  const hasSub = !!item.submenu?.length;
9995
- return /* @__PURE__ */ jsxs(React60__default.Fragment, { children: [
9977
+ return /* @__PURE__ */ jsxs(React61__default.Fragment, { children: [
9996
9978
  item.separatorBefore && /* @__PURE__ */ jsx("div", { className: "my-1 border-t border-border/60" }),
9997
9979
  /* @__PURE__ */ jsxs(
9998
9980
  "div",
@@ -10464,19 +10446,19 @@ function Combobox({
10464
10446
  allowFreeText = false,
10465
10447
  disabled = false
10466
10448
  }) {
10467
- const [open, setOpen] = React60.useState(false);
10468
- const [query, setQuery] = React60.useState("");
10469
- const [highlight, setHighlight] = React60.useState(0);
10470
- const wrapperRef = React60.useRef(null);
10471
- const inputRef = React60.useRef(null);
10472
- 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(() => {
10473
10455
  const q = query.trim().toLowerCase();
10474
10456
  if (!q) return options;
10475
10457
  return options.filter(
10476
10458
  (opt) => opt.label.toLowerCase().includes(q) || opt.value.toLowerCase().includes(q)
10477
10459
  );
10478
10460
  }, [options, query]);
10479
- React60.useEffect(() => {
10461
+ React61.useEffect(() => {
10480
10462
  if (!open) return;
10481
10463
  const onClick = (e) => {
10482
10464
  if (wrapperRef.current && !wrapperRef.current.contains(e.target)) {
@@ -10487,7 +10469,7 @@ function Combobox({
10487
10469
  document.addEventListener("mousedown", onClick);
10488
10470
  return () => document.removeEventListener("mousedown", onClick);
10489
10471
  }, [open]);
10490
- React60.useEffect(() => {
10472
+ React61.useEffect(() => {
10491
10473
  if (open) {
10492
10474
  setHighlight(0);
10493
10475
  requestAnimationFrame(() => inputRef.current?.focus());
@@ -10495,7 +10477,7 @@ function Combobox({
10495
10477
  setQuery("");
10496
10478
  }
10497
10479
  }, [open]);
10498
- const selectedLabel = React60.useMemo(() => {
10480
+ const selectedLabel = React61.useMemo(() => {
10499
10481
  const match = options.find((o) => o.value === value);
10500
10482
  return match?.label ?? value;
10501
10483
  }, [options, value]);
@@ -11869,8 +11851,8 @@ function useTable(effectiveViewModeOverride) {
11869
11851
  ...effectiveColumns,
11870
11852
  {
11871
11853
  id: "actions",
11872
- header: () => isMenuActions ? null : React60__default.createElement("div", { className: "flex w-full justify-start text-left" }, "Actions"),
11873
- 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 }),
11874
11856
  enableSorting: false,
11875
11857
  enableHiding: false
11876
11858
  }
@@ -12134,10 +12116,10 @@ function EditableCell({ cell, onCellEdit }) {
12134
12116
  const columnId = cell.column.id;
12135
12117
  const editor = meta.editor || "text";
12136
12118
  const initial = cell.getValue();
12137
- const [editing, setEditing] = React60__default.useState(false);
12138
- const [value, setValue] = React60__default.useState(initial);
12139
- const [saving, setSaving] = React60__default.useState(false);
12140
- 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(() => {
12141
12123
  if (!editing) setValue(initial);
12142
12124
  }, [initial, editing]);
12143
12125
  const commit = async (next) => {
@@ -12308,7 +12290,7 @@ function NTableContent({ effectiveMode }) {
12308
12290
  const isExpanded = canExpand && row.getIsExpanded();
12309
12291
  const totalCols = row.getVisibleCells().length + (showCheckbox ? 1 : 0) + (hasExpansion ? 1 : 0);
12310
12292
  const rowClassName = getRowClassName?.(row.original);
12311
- return /* @__PURE__ */ jsxs(React60__default.Fragment, { children: [
12293
+ return /* @__PURE__ */ jsxs(React61__default.Fragment, { children: [
12312
12294
  /* @__PURE__ */ jsxs(
12313
12295
  TableRow,
12314
12296
  {
@@ -12567,7 +12549,7 @@ function NTableCardSkeleton({ surface }) {
12567
12549
  }
12568
12550
  function NTableLoadingSkeleton({ rows }) {
12569
12551
  const rawColumns = useTableStore.use.columns();
12570
- const responsiveColumns = React60__default.useMemo(() => filterResponsiveColumns(rawColumns), [rawColumns]);
12552
+ const responsiveColumns = React61__default.useMemo(() => filterResponsiveColumns(rawColumns), [rawColumns]);
12571
12553
  const columns = responsiveColumns;
12572
12554
  const showCheckbox = useTableStore.use.showCheckbox();
12573
12555
  const headerClassName = useTableStore.use.headerClassName();
@@ -12690,19 +12672,19 @@ function useCardContinuation({
12690
12672
  rowCount,
12691
12673
  viewportRef
12692
12674
  }) {
12693
- const [internalPending, setInternalPending] = React60__default.useState(false);
12694
- const [internalError, setInternalError] = React60__default.useState(null);
12695
- const [announcement, setAnnouncement] = React60__default.useState("");
12696
- const [viewportReady, setViewportReady] = React60__default.useState(false);
12697
- const pendingRef = React60__default.useRef(false);
12698
- const previousRowCountRef = React60__default.useRef(rowCount);
12699
- 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);
12700
12682
  configRef.current = config;
12701
12683
  const enabled = Boolean(config);
12702
12684
  const pending = Boolean(config?.loadingMore || internalPending);
12703
12685
  const error = config?.loadMoreError ?? internalError;
12704
12686
  const hasNextPage = Boolean(config?.hasNextPage);
12705
- const load = React60__default.useCallback(async () => {
12687
+ const load = React61__default.useCallback(async () => {
12706
12688
  const current = configRef.current;
12707
12689
  if (!current) return;
12708
12690
  if (pendingRef.current || current.loadingMore || !current.hasNextPage) return;
@@ -12727,13 +12709,13 @@ function useCardContinuation({
12727
12709
  load,
12728
12710
  { rootMargin: config?.rootMargin ?? DEFAULT_ROOT_MARGIN }
12729
12711
  );
12730
- React60__default.useLayoutEffect(() => {
12712
+ React61__default.useLayoutEffect(() => {
12731
12713
  const node = viewportRef.current ?? null;
12732
12714
  scrollContainerRef.current = node;
12733
12715
  const ready = Boolean(node);
12734
12716
  setViewportReady((value) => value === ready ? value : ready);
12735
12717
  });
12736
- React60__default.useEffect(() => {
12718
+ React61__default.useEffect(() => {
12737
12719
  const previous = previousRowCountRef.current;
12738
12720
  previousRowCountRef.current = rowCount;
12739
12721
  if (!configRef.current) return;
@@ -12743,10 +12725,10 @@ function useCardContinuation({
12743
12725
  configRef.current.itemsLoadedLabel?.(appended) ?? `${appended} more ${appended === 1 ? "item" : "items"} loaded.`
12744
12726
  );
12745
12727
  }, [rowCount]);
12746
- React60__default.useEffect(() => {
12728
+ React61__default.useEffect(() => {
12747
12729
  if (!pending) doneLoading();
12748
12730
  }, [pending, doneLoading]);
12749
- React60__default.useEffect(() => {
12731
+ React61__default.useEffect(() => {
12750
12732
  if (!enabled || !hasNextPage || error) return;
12751
12733
  return observe();
12752
12734
  }, [enabled, hasNextPage, error, observe, viewportReady, rowCount]);
@@ -12800,7 +12782,7 @@ function NTableCards({ effectiveMode }) {
12800
12782
  const cardPagination = useTableStore.use.cardPagination();
12801
12783
  const cardColumnCount = useTableStore.use.cardColumnCount();
12802
12784
  const surface = useTableSurfaceAppearance(bordered, borderColor);
12803
- const viewportRef = React60__default.useRef(null);
12785
+ const viewportRef = React61__default.useRef(null);
12804
12786
  const continuationConfig = cardPagination.mode === "infinite" ? cardPagination : null;
12805
12787
  const continuation = useCardContinuation({
12806
12788
  config: continuationConfig,
@@ -13021,17 +13003,17 @@ function CardLoadMorePagination({
13021
13003
  bordered,
13022
13004
  className
13023
13005
  }) {
13024
- const [internalPending, setInternalPending] = React60__default.useState(false);
13025
- const [internalError, setInternalError] = React60__default.useState(null);
13026
- const [announcement, setAnnouncement] = React60__default.useState("");
13027
- const buttonRef = React60__default.useRef(null);
13028
- const pendingRef = React60__default.useRef(false);
13029
- const restoreFocusRef = React60__default.useRef(false);
13030
- const previousRowCountRef = React60__default.useRef(rowCount);
13031
- 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();
13032
13014
  const pending = Boolean(config.loadingMore || internalPending);
13033
13015
  const error = config.loadMoreError ?? internalError;
13034
- React60__default.useEffect(() => {
13016
+ React61__default.useEffect(() => {
13035
13017
  const previous = previousRowCountRef.current;
13036
13018
  if (rowCount > previous) {
13037
13019
  const appended = rowCount - previous;
@@ -13041,7 +13023,7 @@ function CardLoadMorePagination({
13041
13023
  }
13042
13024
  previousRowCountRef.current = rowCount;
13043
13025
  }, [config.itemsLoadedLabel, rowCount]);
13044
- React60__default.useEffect(() => {
13026
+ React61__default.useEffect(() => {
13045
13027
  if (pending || !restoreFocusRef.current) return;
13046
13028
  restoreFocusRef.current = false;
13047
13029
  const frame = requestAnimationFrame(() => buttonRef.current?.focus());
@@ -13111,9 +13093,9 @@ function CardLoadMorePagination({
13111
13093
  var navButtonClass = "h-8 w-8 p-0 text-foreground disabled:text-muted-foreground disabled:opacity-70";
13112
13094
  var chevronClass = "h-4 w-4 rtl:-scale-x-100";
13113
13095
  function useLowerBoundPageCountWarning(manualPagination, pageCount, pagination) {
13114
- const previous = React60__default.useRef(null);
13115
- const warned = React60__default.useRef(false);
13116
- React60__default.useEffect(() => {
13096
+ const previous = React61__default.useRef(null);
13097
+ const warned = React61__default.useRef(false);
13098
+ React61__default.useEffect(() => {
13117
13099
  if (typeof console === "undefined") return;
13118
13100
  if (typeof process !== "undefined" && process.env?.NODE_ENV === "production") return;
13119
13101
  if (!manualPagination || pageCount === void 0 || !pagination) {
@@ -15003,7 +14985,7 @@ function NNavbar({
15003
14985
  (userMenuActions.length > 0 || onLogout) && /* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
15004
14986
  userMenuActions.map((action) => {
15005
14987
  const ActionIcon = action.icon;
15006
- return /* @__PURE__ */ jsxs(React60__default.Fragment, { children: [
14988
+ return /* @__PURE__ */ jsxs(React61__default.Fragment, { children: [
15007
14989
  action.separator && /* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
15008
14990
  /* @__PURE__ */ jsxs(DropdownMenuItem, { onClick: action.onClick, className: "cursor-pointer", children: [
15009
14991
  ActionIcon && /* @__PURE__ */ jsx(ActionIcon, { className: "h-4 w-4 mr-2" }),
@@ -15273,4 +15255,4 @@ function NGridItem({
15273
15255
  return /* @__PURE__ */ jsx("div", { className: itemClassName, ...props, children });
15274
15256
  }
15275
15257
 
15276
- 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 };