najm-kit 2.11.5 → 2.11.7

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/CHANGELOG.md CHANGED
@@ -1,44 +1,69 @@
1
- # Changelog
2
-
3
- ## 2.11.5 - 2026-08-14
4
-
5
- - Fixed numbered lists staying on an invalid final page after a deletion or
6
- another mutation reduced the server total. Paged lists now clamp before
7
- slicing their row buffer, render the previous valid page immediately, and
8
- reconcile the controlled pagination state without showing a false empty
9
- state. A genuinely empty result still remains on page one.
10
- - Fixed panel feedback states stretching their icon, copy, and action across
11
- separate grid rows in tall table and dialog bodies. Panel content now stays
12
- together in one centered vertical stack with consistent spacing.
13
-
14
- ## 2.11.4 - 2026-08-12
15
-
16
- - Fixed server-paginated card grids briefly rendering at a placeholder-derived
17
- page size before correcting to the real card height. Card mode now waits for
18
- real rows and publishes the measured fit before their first paint; fixed-row
19
- table sizing remains immediate during loading.
20
-
21
- ## 2.11.3 - 2026-08-12
22
-
23
- - Fixed `NTable` replacing or clipping an explicit Rows/page choice when
24
- `dynamicHeight` was enabled. Automatic fit sizing still owns the initial page
25
- size; after the reader chooses a value, the table preserves it and scrolls
26
- its bounded body when the requested rows exceed the measured fit.
27
-
28
- ## 2.11.2 - 2026-08-11
29
-
30
- - Fixed `PasswordInput` forwarding native input attributes such as generated
31
- form IDs and ARIA metadata to the actual `<input>`, restoring programmatic
32
- label association for assistive technology and browser automation.
33
-
34
- ## 2.11.1 - 2026-08-11
35
-
36
- - Fixed `NajmThemeProvider` precedence so an explicit runtime `mode` overrides
37
- a preset stored in the design config. An explicit `preset` prop still wins,
38
- allowing deliberately fixed-preset subtrees without producing mixed light
39
- and dark application surfaces.
40
-
41
- ## 2.11.0 - 2026-08-10
1
+ # Changelog
2
+
3
+ ## 2.11.7 - 2026-08-17
4
+
5
+ - Fixed date, combobox, and multiselect `FormInput` controls reaching the
6
+ accessibility tree with no accessible name. These types render their trigger
7
+ as a styled `div`, so the `<label for>` that `FormControl` wires up pointed at
8
+ a non-labelable element and named nothing: screen readers announced an unnamed
9
+ control, and `getByRole(..., { name })` could not resolve one. The form label
10
+ now becomes the trigger's `aria-label`, and `DateInput` and `ComboboxInput`
11
+ accept an explicit `ariaLabel` to override it. `select` keeps naming itself
12
+ from `ariaLabel || placeholder`; renaming it would break consumers that select
13
+ it by placeholder today.
14
+ - Fixed `DateInput` rendering its popover trigger as a `div`. Radix only merges
15
+ trigger props onto the child, so the control had no role, no tab stop, and no
16
+ keyboard activation it was unreachable without a mouse. It is now a real
17
+ `<button type="button">`, which also keeps it from submitting the surrounding
18
+ form when the calendar opens.
19
+
20
+ ## 2.11.6 - 2026-08-15
21
+
22
+ - Fixed `FormInput` dropping React Hook Form's native field binding for text,
23
+ number, password, textarea, and time controls. These controls now forward
24
+ their field name, composed blur handler, and focus ref to the actual native
25
+ element, preserving browser form semantics, touched-state tracking, and
26
+ programmatic focus without changing composite-control contracts.
27
+
28
+ ## 2.11.5 - 2026-08-14
29
+
30
+ - Fixed numbered lists staying on an invalid final page after a deletion or
31
+ another mutation reduced the server total. Paged lists now clamp before
32
+ slicing their row buffer, render the previous valid page immediately, and
33
+ reconcile the controlled pagination state without showing a false empty
34
+ state. A genuinely empty result still remains on page one.
35
+ - Fixed panel feedback states stretching their icon, copy, and action across
36
+ separate grid rows in tall table and dialog bodies. Panel content now stays
37
+ together in one centered vertical stack with consistent spacing.
38
+
39
+ ## 2.11.4 - 2026-08-12
40
+
41
+ - Fixed server-paginated card grids briefly rendering at a placeholder-derived
42
+ page size before correcting to the real card height. Card mode now waits for
43
+ real rows and publishes the measured fit before their first paint; fixed-row
44
+ table sizing remains immediate during loading.
45
+
46
+ ## 2.11.3 - 2026-08-12
47
+
48
+ - Fixed `NTable` replacing or clipping an explicit Rows/page choice when
49
+ `dynamicHeight` was enabled. Automatic fit sizing still owns the initial page
50
+ size; after the reader chooses a value, the table preserves it and scrolls
51
+ its bounded body when the requested rows exceed the measured fit.
52
+
53
+ ## 2.11.2 - 2026-08-11
54
+
55
+ - Fixed `PasswordInput` forwarding native input attributes such as generated
56
+ form IDs and ARIA metadata to the actual `<input>`, restoring programmatic
57
+ label association for assistive technology and browser automation.
58
+
59
+ ## 2.11.1 - 2026-08-11
60
+
61
+ - Fixed `NajmThemeProvider` precedence so an explicit runtime `mode` overrides
62
+ a preset stored in the design config. An explicit `preset` prop still wins,
63
+ allowing deliberately fixed-preset subtrees without producing mixed light
64
+ and dark application surfaces.
65
+
66
+ ## 2.11.0 - 2026-08-10
42
67
 
43
68
  - Gave every keyboard-focusable primitive a visible focus ring, from one shared
44
69
  source: `focusRingClasses` and `focusRingWithinClasses`, exported from the
package/README.md CHANGED
@@ -725,14 +725,14 @@ keyboard focus always reveals the action. Applications still decide which menu
725
725
  items exist through `menu`, `onView`, `onEdit`, and `onDelete`; visibility does
726
726
  not grant an action or replace server authorization.
727
727
 
728
- When `dynamicHeight` is enabled, table and card loading skeletons measure the
729
- available body. Table rows use the same header/row geometry as dynamic page
730
- sizing, while cards measure the active grid columns, card height, and gap. The
731
- loading surface also follows the loaded `bordered`, design recipe, radius,
732
- border color, shadow, and `classNames.content`/`classNames.cards` contract.
733
- The measured fit owns the initial page size. Once a reader explicitly chooses
734
- Rows/page, `NTable` preserves that choice and scrolls the bounded table body
735
- when the requested rows exceed the available height.
728
+ When `dynamicHeight` is enabled, table and card loading skeletons measure the
729
+ available body. Table rows use the same header/row geometry as dynamic page
730
+ sizing, while cards measure the active grid columns, card height, and gap. The
731
+ loading surface also follows the loaded `bordered`, design recipe, radius,
732
+ border color, shadow, and `classNames.content`/`classNames.cards` contract.
733
+ The measured fit owns the initial page size. Once a reader explicitly chooses
734
+ Rows/page, `NTable` preserves that choice and scrolls the bounded table body
735
+ when the requested rows exceed the available height.
736
736
 
737
737
  Use `cardPagination` to choose pagination presentation whenever the effective
738
738
  rendered mode is cards:
package/dist/index.d.ts CHANGED
@@ -535,9 +535,9 @@ declare namespace NIndicator {
535
535
  }
536
536
  declare const Indicator: typeof NIndicator;
537
537
 
538
- declare function Input({ className, type, ...props }: React$1.ComponentProps<"input">): react_jsx_runtime.JSX.Element;
538
+ declare const Input: React$1.ForwardRefExoticComponent<Omit<React$1.DetailedHTMLProps<React$1.InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>, "ref"> & React$1.RefAttributes<HTMLInputElement>>;
539
539
 
540
- declare function Textarea({ className, ...props }: React$1.ComponentProps<"textarea">): react_jsx_runtime.JSX.Element;
540
+ declare const Textarea: React$1.ForwardRefExoticComponent<Omit<React$1.DetailedHTMLProps<React$1.TextareaHTMLAttributes<HTMLTextAreaElement>, HTMLTextAreaElement>, "ref"> & React$1.RefAttributes<HTMLTextAreaElement>>;
541
541
 
542
542
  declare function Label({ className, ...props }: React$1.ComponentProps<typeof LabelPrimitive.Root>): react_jsx_runtime.JSX.Element;
543
543
 
@@ -2184,19 +2184,14 @@ interface SelectItemType {
2184
2184
  className?: string;
2185
2185
  }>;
2186
2186
  }
2187
- interface TextInputProps extends BaseProps {
2187
+ interface TextInputProps extends BaseProps, Omit<InputHTMLAttributes<HTMLInputElement>, "className" | "onChange" | "placeholder" | "type" | "value"> {
2188
2188
  value: string;
2189
2189
  onChange: (value: string) => void;
2190
2190
  placeholder?: string;
2191
2191
  icon?: InputIcon;
2192
2192
  showIcon?: boolean;
2193
- disabled?: boolean;
2194
- onKeyDown?: (e: React.KeyboardEvent<HTMLInputElement>) => void;
2195
- onKeyUp?: (e: React.KeyboardEvent<HTMLInputElement>) => void;
2196
- onBlur?: (e: React.FocusEvent<HTMLInputElement>) => void;
2197
- onFocus?: (e: React.FocusEvent<HTMLInputElement>) => void;
2198
2193
  }
2199
- interface NumberInputProps extends BaseProps {
2194
+ interface NumberInputProps extends BaseProps, Omit<InputHTMLAttributes<HTMLInputElement>, "className" | "onChange" | "placeholder" | "type" | "value"> {
2200
2195
  value: string | number;
2201
2196
  onChange: (value: number) => void;
2202
2197
  placeholder?: string;
@@ -2210,7 +2205,7 @@ interface PasswordInputProps extends BaseProps, Omit<InputHTMLAttributes<HTMLInp
2210
2205
  icon?: InputIcon;
2211
2206
  showIcon?: boolean;
2212
2207
  }
2213
- interface TextAreaInputProps extends BaseProps {
2208
+ interface TextAreaInputProps extends BaseProps, Omit<React.TextareaHTMLAttributes<HTMLTextAreaElement>, "className" | "onChange" | "placeholder" | "value"> {
2214
2209
  value: string;
2215
2210
  onChange: (value: string) => void;
2216
2211
  placeholder?: string;
@@ -2243,6 +2238,7 @@ interface ComboboxInputProps extends BaseProps {
2243
2238
  showIcon?: boolean;
2244
2239
  disabled?: boolean;
2245
2240
  allowFreeText?: boolean;
2241
+ ariaLabel?: string;
2246
2242
  }
2247
2243
  interface MultiSelectInputProps extends BaseProps {
2248
2244
  value: string[];
@@ -2299,6 +2295,7 @@ interface DateInputProps extends BaseProps {
2299
2295
  placeholder?: string;
2300
2296
  icon?: InputIcon;
2301
2297
  showIcon?: boolean;
2298
+ ariaLabel?: string;
2302
2299
  }
2303
2300
  interface StarRatingInputProps extends BaseProps {
2304
2301
  value: number;
@@ -2320,7 +2317,7 @@ interface ColorPickerInputProps extends ColorArrayInputProps {
2320
2317
  output?: ColorFormat | "preserve";
2321
2318
  hideSwatches?: boolean;
2322
2319
  }
2323
- interface TimeInputProps extends BaseProps {
2320
+ interface TimeInputProps extends BaseProps, Omit<InputHTMLAttributes<HTMLInputElement>, "className" | "onChange" | "placeholder" | "type" | "value"> {
2324
2321
  value?: string;
2325
2322
  onChange: (value: string) => void;
2326
2323
  placeholder?: string;
@@ -2328,7 +2325,6 @@ interface TimeInputProps extends BaseProps {
2328
2325
  showIcon?: boolean;
2329
2326
  format24?: boolean;
2330
2327
  showSeconds?: boolean;
2331
- disabled?: boolean;
2332
2328
  }
2333
2329
  interface TimeZoneInputProps extends Omit<ComboboxInputProps, "items"> {
2334
2330
  items?: SelectItemType[];
@@ -2458,16 +2454,16 @@ interface BaseInputProps extends React__default.HTMLAttributes<HTMLDivElement> {
2458
2454
  }
2459
2455
  declare const BaseInput: React__default.ForwardRefExoticComponent<BaseInputProps & React__default.RefAttributes<HTMLDivElement>>;
2460
2456
 
2461
- declare const TextInput: React__default.FC<TextInputProps>;
2457
+ declare const TextInput: React__default.ForwardRefExoticComponent<TextInputProps & React__default.RefAttributes<HTMLInputElement>>;
2462
2458
 
2463
- declare const NumberInput: React__default.FC<NumberInputProps>;
2459
+ declare const NumberInput: React__default.ForwardRefExoticComponent<NumberInputProps & React__default.RefAttributes<HTMLInputElement>>;
2464
2460
 
2465
- declare const PasswordInput: React__default.FC<PasswordInputProps>;
2461
+ declare const PasswordInput: React__default.ForwardRefExoticComponent<PasswordInputProps & React__default.RefAttributes<HTMLInputElement>>;
2466
2462
 
2467
2463
  /** Accessible, controlled one-time-code input with keyboard and paste support. */
2468
2464
  declare const OtpInput: React__default.ForwardRefExoticComponent<OtpInputProps & React__default.RefAttributes<HTMLInputElement>>;
2469
2465
 
2470
- declare const TextAreaInput: React__default.FC<TextAreaInputProps>;
2466
+ declare const TextAreaInput: React__default.ForwardRefExoticComponent<TextAreaInputProps & React__default.RefAttributes<HTMLTextAreaElement>>;
2471
2467
 
2472
2468
  declare const SelectInput: React__default.FC<SelectInputProps>;
2473
2469
 
@@ -2540,7 +2536,7 @@ declare function PhoneInput({ value, onChange, defaultCountry, placeholder, disa
2540
2536
  bordered?: boolean;
2541
2537
  }): react_jsx_runtime.JSX.Element;
2542
2538
 
2543
- declare const TimeInput: React__default.FC<TimeInputProps>;
2539
+ declare const TimeInput: React__default.ForwardRefExoticComponent<TimeInputProps & React__default.RefAttributes<HTMLInputElement>>;
2544
2540
 
2545
2541
  declare const TimeZoneInput: React__default.FC<TimeZoneInputProps>;
2546
2542
 
package/dist/index.mjs CHANGED
@@ -17,11 +17,11 @@ export { DEFAULT_PLACEHOLDER, formatCurrency, formatDate, formatDateTime, format
17
17
  export { DEFAULT_MAX_PAGE_SIZE, DEFAULT_PAGE_SIZE, cleanQuery, createOffsetPagination, fetchOffsetPage, getPageIndex } from './chunk-2NX2VKS2.mjs';
18
18
  import { resolveRadiusValue, resolveVariantAlias, parseNajmDesignConfig } from './chunk-TFHWLE7N.mjs';
19
19
  export { NAJM_COMPONENT_NAMES, RADIUS_VALUE_MAP, defineNajmDesignConfig, defineNajmThemeConfig, parseNajmDesignConfig, parseNajmThemeConfig, resolveRadiusValue, resolveVariantAlias, stringifyNajmDesignConfig, stringifyNajmThemeConfig } from './chunk-TFHWLE7N.mjs';
20
- import * as React61 from 'react';
21
- import React61__default, { createContext, useRef, useMemo, useState, useEffect, useContext, useCallback, useLayoutEffect, isValidElement } from 'react';
20
+ import * as React66 from 'react';
21
+ import React66__default, { createContext, useState, useRef, useMemo, useEffect, useContext, useCallback, useLayoutEffect, isValidElement } from 'react';
22
22
  import * as TabsPrimitive from '@radix-ui/react-tabs';
23
23
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
24
- import { ChevronDown, AlertTriangle, RefreshCw, X, XIcon, Menu, Search, SearchIcon, CheckIcon, ChevronUp, ChevronDownIcon, ChevronUpIcon, Eye, EyeOff, ChevronsUpDown, Check, CircleIcon, ChevronLeftIcon, ChevronRightIcon, Calendar as Calendar$1, FileUp, Folder, UploadCloud, CheckCircle2, AlertCircle, Camera, Star, Globe, Clock, Trash2, Plus, Upload, Download, RotateCcw, Table as Table$1, FileJson, ChevronRight, ArrowUpDown, Loader2, Copy, MoreVertical, Edit, ChevronsLeft, ChevronLeft, ChevronsRight, Pencil, Merge, PanelLeftOpen, PanelLeftClose, LogOut, Image, ArrowUp, ArrowDown, CheckSquare, FilePlus, FolderPlus, Share2, Move, ClipboardPaste, Scissors, ArrowUpRight, ArrowDownRight, SlidersHorizontal, Columns3, Settings, Filter, SearchX, Inbox, List, LayoutGrid, Code, FolderOpen } from 'lucide-react';
24
+ import { Eye, EyeOff, Clock, ChevronDown, AlertTriangle, RefreshCw, X, XIcon, Menu, Search, SearchIcon, CheckIcon, ChevronUp, ChevronDownIcon, ChevronUpIcon, ChevronsUpDown, Check, CircleIcon, ChevronLeftIcon, ChevronRightIcon, Calendar as Calendar$1, FileUp, Folder, UploadCloud, CheckCircle2, AlertCircle, Camera, Star, Globe, Trash2, Plus, Upload, Download, RotateCcw, Table as Table$1, FileJson, ChevronRight, ArrowUpDown, Loader2, Copy, MoreVertical, Edit, ChevronsLeft, ChevronLeft, ChevronsRight, Pencil, Merge, PanelLeftOpen, PanelLeftClose, LogOut, Image, ArrowUp, ArrowDown, CheckSquare, FilePlus, FolderPlus, Share2, Move, ClipboardPaste, Scissors, ArrowUpRight, ArrowDownRight, SlidersHorizontal, Columns3, Settings, Filter, SearchX, Inbox, List, LayoutGrid, Code, FolderOpen } from 'lucide-react';
25
25
  import * as TooltipPrimitive from '@radix-ui/react-tooltip';
26
26
  import { cva } from 'class-variance-authority';
27
27
  import { HexColorPicker } from 'react-colorful';
@@ -275,7 +275,7 @@ function NTabs({
275
275
  }
276
276
  var PORTAL_LAYER_STYLE_ID = "najm-kit-portal-layer-styles";
277
277
  function useNajmPortalLayerStyles() {
278
- React61.useInsertionEffect(() => {
278
+ React66.useInsertionEffect(() => {
279
279
  if (typeof document === "undefined") return;
280
280
  if (document.getElementById(PORTAL_LAYER_STYLE_ID)) return;
281
281
  const style = document.createElement("style");
@@ -306,7 +306,7 @@ var tooltipContentVariants = cva(
306
306
  }
307
307
  );
308
308
  function TooltipContent({ className, sideOffset = 4, variant, children, ...props }) {
309
- const container = React61.useContext(NajmThemeContainerCtx);
309
+ const container = React66.useContext(NajmThemeContainerCtx);
310
310
  useNajmPortalLayerStyles();
311
311
  return /* @__PURE__ */ jsx(TooltipPrimitive.Portal, { container: container ?? void 0, children: /* @__PURE__ */ jsx(
312
312
  TooltipPrimitive.Content,
@@ -456,7 +456,7 @@ var ERROR_BORDER = "border !border-red-600";
456
456
  var FOCUS_INTERACTIVE_BASE = "border focus-within:border-primary";
457
457
  var HOVER_INTERACTIVE_BASE = "hover:border-primary";
458
458
  var STATIC_BASE = "border";
459
- var BaseInput = React61__default.forwardRef(
459
+ var BaseInput = React66__default.forwardRef(
460
460
  ({ children, variant = "default", status = "default", bordered, borderColor, className, style, disabled = false, onHover, onClick, hasIcon, ...rest }, ref) => {
461
461
  const recipe = useNajmComponentStyle("input");
462
462
  const isGhost = variant === "ghost";
@@ -515,7 +515,7 @@ function PopoverAnchor({ ...props }) {
515
515
  return /* @__PURE__ */ jsx(PopoverPrimitive.Anchor, { "data-slot": "popover-anchor", ...props });
516
516
  }
517
517
  function PopoverContent({ className, align = "center", sideOffset = 4, ...props }) {
518
- const container = React61.useContext(NajmThemeContainerCtx);
518
+ const container = React66.useContext(NajmThemeContainerCtx);
519
519
  useNajmPortalLayerStyles();
520
520
  return /* @__PURE__ */ jsx(PopoverPrimitive.Portal, { container: container ?? void 0, children: /* @__PURE__ */ jsx(
521
521
  PopoverPrimitive.Content,
@@ -624,7 +624,7 @@ function SwatchesColorPicker({
624
624
  hideSwatches = false
625
625
  }) {
626
626
  const inputRef = useRef(null);
627
- const themeContainer = React61__default.useContext(NajmThemeContainerCtx);
627
+ const themeContainer = React66__default.useContext(NajmThemeContainerCtx);
628
628
  const resolvedValue = resolvePickerColor(value, themeContainer);
629
629
  return /* @__PURE__ */ jsxs(
630
630
  BaseInput,
@@ -694,7 +694,7 @@ function PopoverColorPicker({
694
694
  formats = DEFAULT_FORMATS,
695
695
  output = "preserve"
696
696
  }) {
697
- const themeContainer = React61__default.useContext(NajmThemeContainerCtx);
697
+ const themeContainer = React66__default.useContext(NajmThemeContainerCtx);
698
698
  const resolvedValue = resolvePickerColor(value, themeContainer);
699
699
  const initialFormat = formats.includes(detectFormat(resolvedValue)) ? detectFormat(resolvedValue) : formats[0] ?? "hex";
700
700
  const [activeFormat, setActiveFormat] = useState(initialFormat);
@@ -961,7 +961,7 @@ function SheetClose({ ...props }) {
961
961
  return /* @__PURE__ */ jsx(SheetPrimitive.Close, { "data-slot": "sheet-close", ...props });
962
962
  }
963
963
  function SheetPortal({ ...props }) {
964
- const container = React61.useContext(NajmThemeContainerCtx);
964
+ const container = React66.useContext(NajmThemeContainerCtx);
965
965
  return /* @__PURE__ */ jsx(SheetPrimitive.Portal, { "data-slot": "sheet-portal", container: container ?? void 0, ...props });
966
966
  }
967
967
  function SheetOverlay({ className, ...props }) {
@@ -1110,7 +1110,7 @@ function DialogTrigger({ ...props }) {
1110
1110
  return /* @__PURE__ */ jsx(SheetPrimitive.Trigger, { "data-slot": "dialog-trigger", ...props });
1111
1111
  }
1112
1112
  function DialogPortal({ ...props }) {
1113
- const container = React61.useContext(NajmThemeContainerCtx);
1113
+ const container = React66.useContext(NajmThemeContainerCtx);
1114
1114
  return /* @__PURE__ */ jsx(SheetPrimitive.Portal, { "data-slot": "dialog-portal", container: container ?? void 0, ...props });
1115
1115
  }
1116
1116
  function DialogClose({ ...props }) {
@@ -1141,8 +1141,8 @@ function getDefaultPadding() {
1141
1141
  return window.matchMedia(MOBILE_PADDING_QUERY).matches ? "sm" : "md";
1142
1142
  }
1143
1143
  function useResponsivePadding(value) {
1144
- const [resolved, setResolved] = React61.useState(() => value ?? getDefaultPadding());
1145
- React61.useEffect(() => {
1144
+ const [resolved, setResolved] = React66.useState(() => value ?? getDefaultPadding());
1145
+ React66.useEffect(() => {
1146
1146
  if (value) {
1147
1147
  setResolved(value);
1148
1148
  return;
@@ -1167,7 +1167,7 @@ function DialogContent({
1167
1167
  }) {
1168
1168
  const resolvedPadding = useResponsivePadding(padding);
1169
1169
  const portalClassName = useNPortalScope();
1170
- const openerRef = React61.useRef(null);
1170
+ const openerRef = React66.useRef(null);
1171
1171
  return /* @__PURE__ */ jsx(DialogPortal, { "data-slot": "dialog-portal", children: /* @__PURE__ */ jsxs("div", { className: portalClassName, children: [
1172
1172
  /* @__PURE__ */ jsx(DialogOverlay, {}),
1173
1173
  /* @__PURE__ */ jsxs(
@@ -1231,7 +1231,7 @@ var sizeClasses2 = {
1231
1231
  md: "h-8 w-8",
1232
1232
  lg: "h-10 w-10"
1233
1233
  };
1234
- var IconButton = React61.forwardRef(
1234
+ var IconButton = React66.forwardRef(
1235
1235
  ({
1236
1236
  className,
1237
1237
  variant = "ghost",
@@ -1313,10 +1313,10 @@ function NPageHeaderTop({ children, className }) {
1313
1313
  }
1314
1314
  NPageHeaderTop.displayName = "NPageHeaderTop";
1315
1315
  function isPageHeaderSlot(child, slot) {
1316
- return React61__default.isValidElement(child) && child.type === slot;
1316
+ return React66__default.isValidElement(child) && child.type === slot;
1317
1317
  }
1318
1318
  function getSlotElements(children, slot) {
1319
- const matches = React61__default.Children.toArray(children).filter((child) => isPageHeaderSlot(child, slot));
1319
+ const matches = React66__default.Children.toArray(children).filter((child) => isPageHeaderSlot(child, slot));
1320
1320
  return matches.length > 0 ? matches : void 0;
1321
1321
  }
1322
1322
  var responsiveClasses = {
@@ -1729,8 +1729,8 @@ function NDialogSecondaryButton(_props) {
1729
1729
  function parseDirectDialogSlots(children) {
1730
1730
  const body = [];
1731
1731
  const parsed = {};
1732
- React61__default.Children.forEach(children, (child) => {
1733
- if (!React61__default.isValidElement(child)) {
1732
+ React66__default.Children.forEach(children, (child) => {
1733
+ if (!React66__default.isValidElement(child)) {
1734
1734
  body.push(child);
1735
1735
  return;
1736
1736
  }
@@ -1803,15 +1803,15 @@ var dialogVariants = cva(
1803
1803
  );
1804
1804
  var CONTENT_ACTIONS_SELECTOR = '[data-najm-dialog-actions="content"], [data-najm-wizard-form="true"]';
1805
1805
  function useContentOwnsActions() {
1806
- const [contentElement, setContentElement] = React61__default.useState(null);
1807
- const [contentOwnsActions, setContentOwnsActions] = React61__default.useState(false);
1808
- const contentElementRef = React61__default.useRef(null);
1809
- const handleContentElementRef = React61__default.useCallback((node) => {
1806
+ const [contentElement, setContentElement] = React66__default.useState(null);
1807
+ const [contentOwnsActions, setContentOwnsActions] = React66__default.useState(false);
1808
+ const contentElementRef = React66__default.useRef(null);
1809
+ const handleContentElementRef = React66__default.useCallback((node) => {
1810
1810
  if (contentElementRef.current === node) return;
1811
1811
  contentElementRef.current = node;
1812
1812
  setContentElement(node);
1813
1813
  }, []);
1814
- React61__default.useLayoutEffect(() => {
1814
+ React66__default.useLayoutEffect(() => {
1815
1815
  if (!contentElement) {
1816
1816
  setContentOwnsActions((current) => current ? false : current);
1817
1817
  return;
@@ -2064,8 +2064,8 @@ function NDirectDialog({
2064
2064
  const resolvedHeaderClassName = cn(slots.header?.className, headerClassName);
2065
2065
  const resolvedTitleClassName = cn(slots.header?.titleClassName, titleClassName);
2066
2066
  const resolvedDescriptionClassName = cn(slots.description?.className, descriptionClassName);
2067
- const [internalOpen, setInternalOpen] = React61__default.useState(defaultOpen);
2068
- const [primaryLoading, setPrimaryLoading] = React61__default.useState(false);
2067
+ const [internalOpen, setInternalOpen] = React66__default.useState(defaultOpen);
2068
+ const [primaryLoading, setPrimaryLoading] = React66__default.useState(false);
2069
2069
  const isControlled = open !== void 0;
2070
2070
  const currentOpen = isControlled ? open : internalOpen;
2071
2071
  const setOpen = (nextOpen) => {
@@ -2347,7 +2347,7 @@ function useDialog(store) {
2347
2347
  description: options.description,
2348
2348
  size: options.size || "sm",
2349
2349
  className: options.className,
2350
- render: ({ dialog, zIndex, confirm, cancel, onOpenChange }) => React61__default.createElement(NDeleteDialog, {
2350
+ render: ({ dialog, zIndex, confirm, cancel, onOpenChange }) => React66__default.createElement(NDeleteDialog, {
2351
2351
  itemName: options.itemName,
2352
2352
  itemType: options.itemType,
2353
2353
  icon: options.icon,
@@ -2641,8 +2641,8 @@ function resolveIcon(icon) {
2641
2641
  }
2642
2642
  var MultiSelectInput = ({ ariaLabel, placeholder = "Select items...", value = [], onChange, icon, showIcon = true, iconColor, items, className = "", variant = "default", status = "default", bordered, borderColor, disabled = false, searchPlaceholder = "Search...", emptyMessage = "No items found.", maxDisplay = 3, showSearch = true }) => {
2643
2643
  const [open, setOpen] = useState(false);
2644
- const triggerRef = React61__default.useRef(null);
2645
- const pointerDismissedRef = React61__default.useRef(false);
2644
+ const triggerRef = React66__default.useRef(null);
2645
+ const pointerDismissedRef = React66__default.useRef(false);
2646
2646
  const shouldDisplayIcon = Boolean(icon) && showIcon && value.length === 0;
2647
2647
  const iconProps = getIconColorProps(iconColor, "h-4 w-4");
2648
2648
  const handleSelect = (itemValue) => {
@@ -2758,7 +2758,7 @@ function SelectScrollDownButton({ className, ...props }) {
2758
2758
  return /* @__PURE__ */ jsx(SelectPrimitive.ScrollDownButton, { "data-slot": "select-scroll-down-button", className: cn("flex cursor-default items-center justify-center py-1", className), ...props, children: /* @__PURE__ */ jsx(ChevronDownIcon, { className: "size-4" }) });
2759
2759
  }
2760
2760
  function SelectContent({ className, children, position = "popper", style, ...props }) {
2761
- const container = React61.useContext(NajmThemeContainerCtx);
2761
+ const container = React66.useContext(NajmThemeContainerCtx);
2762
2762
  const recipe = useNajmComponentStyle("select");
2763
2763
  const contentSlot = recipe?.slots?.content;
2764
2764
  const borderWidth = contentSlot?.borderWidth ?? recipe?.borderWidth;
@@ -2841,9 +2841,9 @@ var SelectInput = ({ placeholder = "", ariaLabel, value, onChange, icon, showIco
2841
2841
  (item) => typeof item === "string" ? item === value : item.value === value
2842
2842
  );
2843
2843
  const displayLabel = typeof found === "string" ? found : found?.label ?? value;
2844
- const [open, setOpen] = React61__default.useState(false);
2845
- const triggerRef = React61__default.useRef(null);
2846
- const pointerDismissedRef = React61__default.useRef(false);
2844
+ const [open, setOpen] = React66__default.useState(false);
2845
+ const triggerRef = React66__default.useRef(null);
2846
+ const pointerDismissedRef = React66__default.useRef(false);
2847
2847
  return /* @__PURE__ */ jsxs("div", { className: cn("group relative", className), children: [
2848
2848
  /* @__PURE__ */ jsxs(
2849
2849
  BaseInput,
@@ -2901,10 +2901,11 @@ var SelectInput = ({ placeholder = "", ariaLabel, value, onChange, icon, showIco
2901
2901
  )
2902
2902
  ] });
2903
2903
  };
2904
- function Input({ className, type, ...props }) {
2904
+ var Input = React66.forwardRef(function Input2({ className, type, ...props }, ref) {
2905
2905
  return /* @__PURE__ */ jsx(
2906
2906
  "input",
2907
2907
  {
2908
+ ref,
2908
2909
  type,
2909
2910
  "data-slot": "input",
2910
2911
  className: cn(
@@ -2916,7 +2917,7 @@ function Input({ className, type, ...props }) {
2916
2917
  ...props
2917
2918
  }
2918
2919
  );
2919
- }
2920
+ });
2920
2921
  var TRACK = {
2921
2922
  xs: "h-3 w-5",
2922
2923
  sm: "h-4 w-7",
@@ -3711,7 +3712,7 @@ function CollapsibleSection({
3711
3712
  children,
3712
3713
  disabled
3713
3714
  }) {
3714
- const [open, setOpen] = React61.useState(true);
3715
+ const [open, setOpen] = React66.useState(true);
3715
3716
  const titleText = typeof title === "string" || typeof title === "number" ? String(title) : "Section";
3716
3717
  return /* @__PURE__ */ jsxs(
3717
3718
  Collapsible,
@@ -4030,7 +4031,7 @@ function TokenGroupSection({
4030
4031
  disabled,
4031
4032
  labels
4032
4033
  }) {
4033
- const [open, setOpen] = React61.useState(groupId === "surface" || groupId === "brand");
4034
+ const [open, setOpen] = React66.useState(groupId === "surface" || groupId === "brand");
4034
4035
  const labelText = typeof label === "string" || typeof label === "number" ? String(label) : "Group";
4035
4036
  return /* @__PURE__ */ jsxs(
4036
4037
  Collapsible,
@@ -4333,37 +4334,40 @@ function Label2({ className, ...props }) {
4333
4334
  }
4334
4335
  );
4335
4336
  }
4336
- var TextInput = ({ value, onChange, placeholder = "", icon, showIcon = true, iconColor, className = "", variant = "default", status = "default", bordered, borderColor, disabled = false, ...props }) => {
4337
+ var TextInput = React66__default.forwardRef(({ value, onChange, placeholder = "", icon, showIcon = true, iconColor, className = "", variant = "default", status = "default", bordered, borderColor, disabled = false, ...props }, ref) => {
4337
4338
  const shouldDisplayIcon = Boolean(icon) && showIcon;
4338
4339
  const iconProps = getIconColorProps(iconColor, "h-4 w-4");
4339
4340
  return /* @__PURE__ */ jsxs(BaseInput, { variant, status, bordered, borderColor, className: cn("gap-2", className), disabled, children: [
4340
4341
  shouldDisplayIcon && /* @__PURE__ */ jsx("span", { className: iconProps.className, style: iconProps.style, children: resolveIcon(icon) }),
4341
- /* @__PURE__ */ jsx(Input, { placeholder, value, onChange: (ev) => onChange(ev.target.value), className: "p-0 border-0 shadow-none bg-transparent dark:bg-transparent focus-visible:ring-0 focus-visible:ring-transparent focus-visible:ring-offset-0 text-foreground placeholder:text-muted-foreground", disabled, ...props })
4342
+ /* @__PURE__ */ jsx(Input, { ref, placeholder, value, onChange: (ev) => onChange(ev.target.value), className: "p-0 border-0 shadow-none bg-transparent dark:bg-transparent focus-visible:ring-0 focus-visible:ring-transparent focus-visible:ring-offset-0 text-foreground placeholder:text-muted-foreground", disabled, ...props })
4342
4343
  ] });
4343
- };
4344
- var NumberInput = ({ value, onChange, placeholder = "", icon, showIcon = true, iconColor, className = "", variant = "default", status = "default", bordered, borderColor }) => {
4344
+ });
4345
+ TextInput.displayName = "TextInput";
4346
+ var NumberInput = React66__default.forwardRef(({ value, onChange, placeholder = "", icon, showIcon = true, iconColor, className = "", variant = "default", status = "default", bordered, borderColor, disabled = false, ...props }, ref) => {
4345
4347
  const shouldDisplayIcon = Boolean(icon) && showIcon;
4346
4348
  const iconProps = getIconColorProps(iconColor, "h-4 w-4");
4347
4349
  return /* @__PURE__ */ jsxs(BaseInput, { variant, status, bordered, borderColor, className: cn("gap-2", className), children: [
4348
4350
  shouldDisplayIcon && /* @__PURE__ */ jsx("span", { className: iconProps.className, style: iconProps.style, children: resolveIcon(icon) }),
4349
- /* @__PURE__ */ jsx(Input, { type: "number", placeholder, value: value ?? "", onChange: (ev) => onChange(Number(ev.target.value)), className: "p-0 border-0 shadow-none bg-transparent dark:bg-transparent focus-visible:ring-0 focus-visible:ring-transparent focus-visible:ring-offset-0 text-foreground placeholder:text-muted-foreground" })
4351
+ /* @__PURE__ */ jsx(Input, { ref, type: "number", placeholder, value: value ?? "", onChange: (ev) => onChange(Number(ev.target.value)), className: "p-0 border-0 shadow-none bg-transparent dark:bg-transparent focus-visible:ring-0 focus-visible:ring-transparent focus-visible:ring-offset-0 text-foreground placeholder:text-muted-foreground", disabled, ...props })
4350
4352
  ] });
4351
- };
4352
- var PasswordInput = ({ value, onChange, placeholder = "", icon, showIcon = true, iconColor, className = "", variant = "default", status = "default", bordered, borderColor, disabled = false, ...props }) => {
4353
+ });
4354
+ NumberInput.displayName = "NumberInput";
4355
+ var PasswordInput = React66__default.forwardRef(({ value, onChange, placeholder = "", icon, showIcon = true, iconColor, className = "", variant = "default", status = "default", bordered, borderColor, disabled = false, ...props }, ref) => {
4353
4356
  const [showPassword, setShowPassword] = useState(false);
4354
4357
  const shouldDisplayIcon = Boolean(icon) && showIcon;
4355
4358
  const iconProps = getIconColorProps(iconColor, "h-4 w-4");
4356
4359
  return /* @__PURE__ */ jsxs(BaseInput, { variant, status, bordered, borderColor, className: cn("gap-2", className), disabled, children: [
4357
4360
  shouldDisplayIcon && /* @__PURE__ */ jsx("span", { className: iconProps.className, style: iconProps.style, children: resolveIcon(icon) }),
4358
- /* @__PURE__ */ jsx(Input, { type: showPassword ? "text" : "password", placeholder, value, onChange: (ev) => onChange(ev.target.value), className: "p-0 border-0 shadow-none bg-transparent dark:bg-transparent focus-visible:ring-0 focus-visible:ring-transparent focus-visible:ring-offset-0 text-foreground placeholder:text-muted-foreground", disabled, ...props }),
4361
+ /* @__PURE__ */ jsx(Input, { ref, type: showPassword ? "text" : "password", placeholder, value, onChange: (ev) => onChange(ev.target.value), className: "p-0 border-0 shadow-none bg-transparent dark:bg-transparent focus-visible:ring-0 focus-visible:ring-transparent focus-visible:ring-offset-0 text-foreground placeholder:text-muted-foreground", disabled, ...props }),
4359
4362
  showPassword ? /* @__PURE__ */ jsx(Eye, { className: "absolute right-2 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground cursor-pointer", onClick: () => setShowPassword(false) }) : /* @__PURE__ */ jsx(EyeOff, { className: "absolute right-2 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground cursor-pointer", onClick: () => setShowPassword(true) })
4360
4363
  ] });
4361
- };
4364
+ });
4365
+ PasswordInput.displayName = "PasswordInput";
4362
4366
  function normalizeCode(value, numeric, length) {
4363
4367
  const normalized = numeric ? value.replace(/\D/g, "") : value.replace(/\s/g, "");
4364
4368
  return normalized.slice(0, length);
4365
4369
  }
4366
- var OtpInput = React61__default.forwardRef(
4370
+ var OtpInput = React66__default.forwardRef(
4367
4371
  ({
4368
4372
  value,
4369
4373
  onChange,
@@ -4502,10 +4506,11 @@ var OtpInput = React61__default.forwardRef(
4502
4506
  }
4503
4507
  );
4504
4508
  OtpInput.displayName = "OtpInput";
4505
- function Textarea({ className, ...props }) {
4509
+ var Textarea = React66.forwardRef(function Textarea2({ className, ...props }, ref) {
4506
4510
  return /* @__PURE__ */ jsx(
4507
4511
  "textarea",
4508
4512
  {
4513
+ ref,
4509
4514
  "data-slot": "textarea",
4510
4515
  className: cn(
4511
4516
  "border-input placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 flex field-sizing-content min-h-16 w-full rounded-md border bg-transparent px-3 py-2 text-base text-foreground shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
@@ -4514,11 +4519,11 @@ function Textarea({ className, ...props }) {
4514
4519
  ...props
4515
4520
  }
4516
4521
  );
4517
- }
4522
+ });
4518
4523
  var DEFAULT_ROWS = 3;
4519
4524
  var MIN_ROWS = 2;
4520
4525
  var REM_PER_ROW = 1.5;
4521
- var TextAreaInput = ({ value, onChange, placeholder = "", className = "", variant = "default", status = "default", bordered, borderColor, rows }) => {
4526
+ var TextAreaInput = React66__default.forwardRef(({ value, onChange, placeholder = "", className = "", variant = "default", status = "default", bordered, borderColor, iconColor: _iconColor, rows, ...props }, ref) => {
4522
4527
  const visibleRows = Math.max(rows ?? DEFAULT_ROWS, MIN_ROWS);
4523
4528
  const textareaMinHeight = `${visibleRows * REM_PER_ROW}rem`;
4524
4529
  return /* @__PURE__ */ jsx(
@@ -4532,21 +4537,24 @@ var TextAreaInput = ({ value, onChange, placeholder = "", className = "", varian
4532
4537
  children: /* @__PURE__ */ jsx(
4533
4538
  Textarea,
4534
4539
  {
4540
+ ref,
4535
4541
  rows: visibleRows,
4536
4542
  placeholder,
4537
4543
  value,
4538
4544
  onChange: (ev) => onChange(ev.target.value),
4539
4545
  style: { minHeight: textareaMinHeight },
4540
- className: "h-auto min-h-0 resize-y border-0 bg-transparent p-0 text-foreground placeholder:text-muted-foreground shadow-none focus-visible:border-transparent focus-visible:ring-0 focus-visible:ring-transparent focus-visible:ring-offset-0 dark:bg-transparent"
4546
+ className: "h-auto min-h-0 resize-y border-0 bg-transparent p-0 text-foreground placeholder:text-muted-foreground shadow-none focus-visible:border-transparent focus-visible:ring-0 focus-visible:ring-transparent focus-visible:ring-offset-0 dark:bg-transparent",
4547
+ ...props
4541
4548
  }
4542
4549
  )
4543
4550
  }
4544
4551
  );
4545
- };
4546
- var ComboboxInput = ({ placeholder = "Select...", searchPlaceholder = "Search...", emptyMessage = "No results found.", loading = false, loadingMessage = "Loading...", onSearchChange, shouldFilter = true, value, onChange, icon, showIcon = true, iconColor, items = [], className = "", variant = "default", status = "default", bordered, borderColor, disabled = false, allowFreeText = false }) => {
4552
+ });
4553
+ TextAreaInput.displayName = "TextAreaInput";
4554
+ 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, ariaLabel }) => {
4547
4555
  const [open, setOpen] = useState(false);
4548
- const triggerRef = React61__default.useRef(null);
4549
- const pointerDismissedRef = React61__default.useRef(false);
4556
+ const triggerRef = React66__default.useRef(null);
4557
+ const pointerDismissedRef = React66__default.useRef(false);
4550
4558
  const [query, setQuery] = useState("");
4551
4559
  const normalizedItems = items.map((item) => typeof item === "string" ? { value: item, label: item } : item);
4552
4560
  const selectedItem = normalizedItems.find((item) => item.value === value);
@@ -4582,6 +4590,7 @@ var ComboboxInput = ({ placeholder = "Select...", searchPlaceholder = "Search...
4582
4590
  bordered,
4583
4591
  borderColor,
4584
4592
  role: "combobox",
4593
+ "aria-label": ariaLabel,
4585
4594
  tabIndex: disabled ? -1 : 0,
4586
4595
  "aria-expanded": open,
4587
4596
  className: cn(
@@ -4774,13 +4783,13 @@ function Calendar(props) {
4774
4783
  }
4775
4784
  );
4776
4785
  }
4777
- var DateInput = ({ value, onChange, placeholder = "Pick a date", className = "", icon, showIcon = true, iconColor, variant = "default", status = "default", bordered, borderColor }) => {
4786
+ var DateInput = ({ value, onChange, placeholder = "Pick a date", className = "", icon, showIcon = true, iconColor, variant = "default", status = "default", bordered, borderColor, ariaLabel }) => {
4778
4787
  const iconProps = getIconColorProps(iconColor, "h-4 w-4");
4779
4788
  const toDateString = (date) => date ? format(date, "yyyy-MM-dd") : void 0;
4780
4789
  const toDate = (val) => typeof val === "string" ? parseISO(val) : val;
4781
4790
  return /* @__PURE__ */ jsxs(BaseInput, { variant, status, bordered, borderColor, className, children: [
4782
4791
  /* @__PURE__ */ jsxs(Popover, { children: [
4783
- /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx("div", { className: "w-full flex items-center cursor-pointer gap-2 justify-start text-left font-normal", children: /* @__PURE__ */ jsx(Label2, { className: cn("cursor-pointer", value ? "text-foreground" : "text-muted-foreground"), children: value ? format(toDate(value), "PPP") : placeholder }) }) }),
4792
+ /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx("button", { type: "button", "aria-label": ariaLabel, className: "w-full flex items-center cursor-pointer gap-2 justify-start text-left font-normal bg-transparent border-0 p-0 outline-none", children: /* @__PURE__ */ jsx("span", { className: cn("cursor-pointer", value ? "text-foreground" : "text-muted-foreground"), children: value ? format(toDate(value), "PPP") : placeholder }) }) }),
4784
4793
  /* @__PURE__ */ jsx(PopoverContent, { className: "w-auto p-0", align: "start", children: /* @__PURE__ */ jsx(Calendar, { mode: "single", selected: toDate(value), onSelect: (date) => onChange(toDateString(date)), captionLayout: "dropdown" }) })
4785
4794
  ] }),
4786
4795
  !icon && showIcon && /* @__PURE__ */ jsx(Calendar$1, { className: iconProps.className, style: iconProps.style })
@@ -5933,7 +5942,7 @@ function DropdownMenuSubContent({ className, children, style, ...props }) {
5933
5942
  );
5934
5943
  }
5935
5944
  function DropdownMenuContent({ className, children, sideOffset = 4, style, ...props }) {
5936
- const container = React61.useContext(NajmThemeContainerCtx);
5945
+ const container = React66.useContext(NajmThemeContainerCtx);
5937
5946
  const surface = useDropdownSurfaceRecipe("content");
5938
5947
  const { hostRef, viewportRef } = useNajmScrollViewport();
5939
5948
  useNajmPortalLayerStyles();
@@ -6138,7 +6147,7 @@ function PhoneInput({
6138
6147
  }
6139
6148
  ) });
6140
6149
  }
6141
- var TimeInput = ({ value = "", onChange, placeholder = "", icon, showIcon = true, iconColor, className = "", variant = "default", status = "default", bordered, borderColor, format24 = true, showSeconds = false, disabled = false }) => {
6150
+ var TimeInput = React66__default.forwardRef(({ value = "", onChange, placeholder = "", icon, showIcon = true, iconColor, className = "", variant = "default", status = "default", bordered, borderColor, format24 = true, showSeconds = false, disabled = false, onBlur, ...props }, ref) => {
6142
6151
  const [inputValue, setInputValue] = useState(value);
6143
6152
  const [isValid, setIsValid] = useState(true);
6144
6153
  useEffect(() => {
@@ -6172,7 +6181,7 @@ var TimeInput = ({ value = "", onChange, placeholder = "", icon, showIcon = true
6172
6181
  if (valid || formatted === "") onChange(formatted);
6173
6182
  }
6174
6183
  };
6175
- const handleBlur = () => {
6184
+ const handleBlur = (event) => {
6176
6185
  if (inputValue) {
6177
6186
  let completed = inputValue;
6178
6187
  if (completed.length === 1) completed = "0" + completed + ":00";
@@ -6183,16 +6192,18 @@ var TimeInput = ({ value = "", onChange, placeholder = "", icon, showIcon = true
6183
6192
  onChange(completed);
6184
6193
  }
6185
6194
  }
6195
+ onBlur?.(event);
6186
6196
  };
6187
6197
  const iconProps = getIconColorProps(iconColor, "h-4 w-4");
6188
6198
  const currentStatus = !isValid ? "error" : status;
6189
6199
  return /* @__PURE__ */ jsxs(BaseInput, { variant, status: currentStatus, bordered, borderColor, className: cn("gap-2", className), children: [
6190
6200
  showIcon && (icon ? /* @__PURE__ */ jsx("span", { className: iconProps.className, style: iconProps.style, children: resolveIcon(icon) }) : /* @__PURE__ */ jsx(Clock, { className: iconProps.className, style: iconProps.style })),
6191
- /* @__PURE__ */ jsx(Input, { type: "text", placeholder: placeholder || (showSeconds ? "HH:MM:SS" : "HH:MM"), value: inputValue, onChange: (e) => handleInputChange(e.target.value), onKeyDown: (e) => {
6201
+ /* @__PURE__ */ jsx(Input, { ref, type: "text", placeholder: placeholder || (showSeconds ? "HH:MM:SS" : "HH:MM"), value: inputValue, onChange: (e) => handleInputChange(e.target.value), onKeyDown: (e) => {
6192
6202
  if (!/\d/.test(e.key) && !["Backspace", "Delete", "ArrowLeft", "ArrowRight", "Tab"].includes(e.key)) e.preventDefault();
6193
- }, onBlur: handleBlur, disabled, className: cn("p-0 border-0 shadow-none bg-transparent dark:bg-transparent focus-visible:ring-0 placeholder:text-muted-foreground", !isValid ? "text-red-500" : "text-foreground") })
6203
+ }, onBlur: handleBlur, disabled, className: cn("p-0 border-0 shadow-none bg-transparent dark:bg-transparent focus-visible:ring-0 placeholder:text-muted-foreground", !isValid ? "text-red-500" : "text-foreground"), ...props })
6194
6204
  ] });
6195
- };
6205
+ });
6206
+ TimeInput.displayName = "TimeInput";
6196
6207
  var timeZoneValues = [
6197
6208
  "UTC",
6198
6209
  "Atlantic/Azores",
@@ -6337,8 +6348,8 @@ function NSlider({
6337
6348
  return Array.isArray(v) ? [...v] : [v];
6338
6349
  };
6339
6350
  const initialRadix = toRadix(controlledValue ?? defaultValue);
6340
- const [internalValues, setInternalValues] = React61.useState(initialRadix);
6341
- const [active, setActive] = React61.useState(null);
6351
+ const [internalValues, setInternalValues] = React66.useState(initialRadix);
6352
+ const [active, setActive] = React66.useState(null);
6342
6353
  const currentValues = controlledValue !== void 0 ? toRadix(controlledValue) : internalValues;
6343
6354
  const handleRadix = (arr) => {
6344
6355
  setInternalValues(arr);
@@ -6495,13 +6506,13 @@ function NThemePresets({
6495
6506
  disabled = false,
6496
6507
  className
6497
6508
  }) {
6498
- const [saveOpen, setSaveOpen] = React61.useState(false);
6499
- const [name, setName] = React61.useState("");
6500
- const [pendingDelete, setPendingDelete] = React61.useState(
6509
+ const [saveOpen, setSaveOpen] = React66.useState(false);
6510
+ const [name, setName] = React66.useState("");
6511
+ const [pendingDelete, setPendingDelete] = React66.useState(
6501
6512
  null
6502
6513
  );
6503
- const [busy, setBusy] = React61.useState(false);
6504
- const rows = React61.useMemo(
6514
+ const [busy, setBusy] = React66.useState(false);
6515
+ const rows = React66.useMemo(
6505
6516
  () => [
6506
6517
  ...savedDesign ? [
6507
6518
  {
@@ -6753,12 +6764,12 @@ function NThemeCustomizer({
6753
6764
  }) {
6754
6765
  const inheritedMode = useNajmThemeMode();
6755
6766
  const resolvedPreviewMode = previewMode ?? inheritedMode ?? value.theme.mode ?? "light";
6756
- const visibleTabs = React61.useMemo(() => buildTabs(tabs), [tabs]);
6767
+ const visibleTabs = React66.useMemo(() => buildTabs(tabs), [tabs]);
6757
6768
  const firstTab = visibleTabs[0] ?? "theme";
6758
- const [activeTab, setActiveTab] = React61.useState(TAB_VALUE[firstTab]);
6759
- const [fileError, setFileError] = React61.useState(false);
6760
- const fileInputRef = React61.useRef(null);
6761
- React61.useEffect(() => {
6769
+ const [activeTab, setActiveTab] = React66.useState(TAB_VALUE[firstTab]);
6770
+ const [fileError, setFileError] = React66.useState(false);
6771
+ const fileInputRef = React66.useRef(null);
6772
+ React66.useEffect(() => {
6762
6773
  setActiveTab(TAB_VALUE[firstTab]);
6763
6774
  }, [firstTab]);
6764
6775
  const themeLabel = resolveLabel("themeTab", labels);
@@ -6770,7 +6781,7 @@ function NThemeCustomizer({
6770
6781
  const invalidThemeFileLabel = resolveLabel("invalidThemeFile", labels);
6771
6782
  const defaultOptionLabel = resolveLabel("defaultOption", labels);
6772
6783
  const colorSwatchFallbackLabel = resolveLabel("colorSwatchFallback", labels);
6773
- const tokenLabels = React61.useMemo(() => {
6784
+ const tokenLabels = React66.useMemo(() => {
6774
6785
  const out = {};
6775
6786
  const knownTokens = [
6776
6787
  "background",
@@ -7574,7 +7585,7 @@ function Alert({
7574
7585
  );
7575
7586
  }
7576
7587
  var NAlert = Alert;
7577
- var NativeSelect = React61.forwardRef(
7588
+ var NativeSelect = React66.forwardRef(
7578
7589
  ({ className, options, placeholder, value, ...props }, ref) => {
7579
7590
  const hasValue = value !== void 0 && value !== "";
7580
7591
  return /* @__PURE__ */ jsxs("div", { className: "relative", children: [
@@ -7732,7 +7743,7 @@ function Avatar({
7732
7743
  ...props
7733
7744
  }) {
7734
7745
  const hasShortcut = src !== void 0 || fallback !== void 0;
7735
- const hasChildren = React61.Children.count(children) > 0;
7746
+ const hasChildren = React66.Children.count(children) > 0;
7736
7747
  return /* @__PURE__ */ jsxs(
7737
7748
  AvatarPrimitive.Root,
7738
7749
  {
@@ -7826,9 +7837,9 @@ function AvatarGroup({ ring = true, className, children, ...props }) {
7826
7837
  "data-slot": "avatar-group",
7827
7838
  className: cn("flex -space-x-2", className),
7828
7839
  ...props,
7829
- children: ring ? React61.Children.map(children, (child) => {
7830
- if (React61.isValidElement(child) && child.type === Avatar) {
7831
- return React61.cloneElement(child, { ring: true, ...child.props });
7840
+ children: ring ? React66.Children.map(children, (child) => {
7841
+ if (React66.isValidElement(child) && child.type === Avatar) {
7842
+ return React66.cloneElement(child, { ring: true, ...child.props });
7832
7843
  }
7833
7844
  return child;
7834
7845
  }) : children
@@ -7895,7 +7906,7 @@ function Swap({
7895
7906
  className,
7896
7907
  ...props
7897
7908
  }) {
7898
- const [internalChecked, setInternalChecked] = React61.useState(defaultChecked);
7909
+ const [internalChecked, setInternalChecked] = React66.useState(defaultChecked);
7899
7910
  const isControlled = controlledChecked !== void 0 || controlledState !== void 0;
7900
7911
  const currentState = getDerivedState(
7901
7912
  isControlled ? controlledChecked ?? false : internalChecked,
@@ -7903,7 +7914,7 @@ function Swap({
7903
7914
  );
7904
7915
  const dataState = currentState === "indeterminate" ? "indeterminate" : currentState ? "on" : "off";
7905
7916
  const ariaPressed = currentState === "indeterminate" ? "mixed" : currentState;
7906
- const handleClick = React61.useCallback((event) => {
7917
+ const handleClick = React66.useCallback((event) => {
7907
7918
  onClick?.(event);
7908
7919
  if (event.defaultPrevented) return;
7909
7920
  if (disabled) return;
@@ -8028,7 +8039,7 @@ var toneClasses = {
8028
8039
  ring: "border-primary/30"
8029
8040
  }
8030
8041
  };
8031
- var StatusPill = React61.forwardRef(
8042
+ var StatusPill = React66.forwardRef(
8032
8043
  ({ className, tone = "neutral", pulse = false, label, ...props }, ref) => {
8033
8044
  const c = toneClasses[tone];
8034
8045
  return /* @__PURE__ */ jsxs(
@@ -8087,20 +8098,20 @@ function Toaster({ toastOptions, ...props }) {
8087
8098
  );
8088
8099
  }
8089
8100
  var Form = FormProvider;
8090
- var FormFieldContext = React61.createContext({});
8101
+ var FormFieldContext = React66.createContext({});
8091
8102
  var FormField = ({ ...props }) => /* @__PURE__ */ jsx(FormFieldContext.Provider, { value: { name: props.name }, children: /* @__PURE__ */ jsx(Controller, { ...props }) });
8092
8103
  var useFormField = () => {
8093
- const fieldContext = React61.useContext(FormFieldContext);
8094
- const itemContext = React61.useContext(FormItemContext);
8104
+ const fieldContext = React66.useContext(FormFieldContext);
8105
+ const itemContext = React66.useContext(FormItemContext);
8095
8106
  const { getFieldState, formState } = useFormContext();
8096
8107
  const fieldState = getFieldState(fieldContext.name, formState);
8097
8108
  if (!fieldContext) throw new Error("useFormField should be used within <FormField>");
8098
8109
  const { id } = itemContext;
8099
8110
  return { id, name: fieldContext.name, formItemId: `${id}-form-item`, formDescriptionId: `${id}-form-item-description`, formMessageId: `${id}-form-item-message`, ...fieldState };
8100
8111
  };
8101
- var FormItemContext = React61.createContext({});
8112
+ var FormItemContext = React66.createContext({});
8102
8113
  function FormItem({ className, ...props }) {
8103
- const id = React61.useId();
8114
+ const id = React66.useId();
8104
8115
  return /* @__PURE__ */ jsx(FormItemContext.Provider, { value: { id }, children: /* @__PURE__ */ jsx("div", { "data-slot": "form-item", className: cn("grid gap-2", className), ...props }) });
8105
8116
  }
8106
8117
  function FormLabel({ className, ...props }) {
@@ -8145,7 +8156,7 @@ function TableCell({ className, ...props }) {
8145
8156
  function TableCaption({ className, ...props }) {
8146
8157
  return /* @__PURE__ */ jsx("caption", { "data-slot": "table-caption", className: cn("text-muted-foreground mt-4 text-sm", className), ...props });
8147
8158
  }
8148
- var NErrorBoundary = class extends React61__default.Component {
8159
+ var NErrorBoundary = class extends React66__default.Component {
8149
8160
  constructor(props) {
8150
8161
  super(props);
8151
8162
  this.state = { hasError: false, error: null };
@@ -8326,9 +8337,9 @@ function NAvatar({
8326
8337
  loading: imageLoading,
8327
8338
  ...restImageProps
8328
8339
  } = imageProps ?? {};
8329
- const imageRef = React61__default.useRef(null);
8340
+ const imageRef = React66__default.useRef(null);
8330
8341
  const { markLoaded } = chain;
8331
- React61__default.useEffect(() => {
8342
+ React66__default.useEffect(() => {
8332
8343
  const element = imageRef.current;
8333
8344
  if (element?.complete && element.naturalWidth > 0) markLoaded();
8334
8345
  }, [chain.src, markLoaded]);
@@ -8483,8 +8494,8 @@ function NCard({
8483
8494
  let footerClassName;
8484
8495
  let mediaSlot = null;
8485
8496
  const mainChildren = [];
8486
- React61__default.Children.forEach(children, (child) => {
8487
- if (!React61__default.isValidElement(child)) {
8497
+ React66__default.Children.forEach(children, (child) => {
8498
+ if (!React66__default.isValidElement(child)) {
8488
8499
  mainChildren.push(child);
8489
8500
  return;
8490
8501
  }
@@ -8660,7 +8671,7 @@ function truncateByCharacters(text, maxCharacters, suffix = "...") {
8660
8671
  const str = String(text);
8661
8672
  return str.length <= maxCharacters ? str : str.slice(0, maxCharacters) + suffix;
8662
8673
  }
8663
- var CardDensityContext = React61__default.createContext("default");
8674
+ var CardDensityContext = React66__default.createContext("default");
8664
8675
  function NCardInfo({
8665
8676
  icon: Icon2,
8666
8677
  label,
@@ -8673,7 +8684,7 @@ function NCardInfo({
8673
8684
  className,
8674
8685
  ...props
8675
8686
  }) {
8676
- const inheritedDensity = React61__default.useContext(CardDensityContext);
8687
+ const inheritedDensity = React66__default.useContext(CardDensityContext);
8677
8688
  const resolvedDensity = density ?? inheritedDensity;
8678
8689
  const isTruncated = typeof value === "string" && value.length > maxChars;
8679
8690
  const displayValue = isTruncated ? truncateByCharacters(value, maxChars) : value;
@@ -9922,7 +9933,7 @@ function NContextMenu({ x, y, items, onAction, onClose, className }) {
9922
9933
  children: items.map((item) => {
9923
9934
  const Icon2 = item.icon;
9924
9935
  const hasSub = !!item.submenu?.length;
9925
- return /* @__PURE__ */ jsxs(React61__default.Fragment, { children: [
9936
+ return /* @__PURE__ */ jsxs(React66__default.Fragment, { children: [
9926
9937
  item.separatorBefore && /* @__PURE__ */ jsx("div", { className: "my-1 border-t border-border/60" }),
9927
9938
  /* @__PURE__ */ jsxs(
9928
9939
  "div",
@@ -10353,11 +10364,11 @@ function NCredentialsCard({
10353
10364
  className,
10354
10365
  classNames
10355
10366
  }) {
10356
- const [status, setStatus] = React61.useState("idle");
10357
- const revertTimer = React61.useRef(null);
10358
- const mountedRef = React61.useRef(true);
10359
- const requestTokenRef = React61.useRef(0);
10360
- React61.useEffect(() => {
10367
+ const [status, setStatus] = React66.useState("idle");
10368
+ const revertTimer = React66.useRef(null);
10369
+ const mountedRef = React66.useRef(true);
10370
+ const requestTokenRef = React66.useRef(0);
10371
+ React66.useEffect(() => {
10361
10372
  mountedRef.current = true;
10362
10373
  return () => {
10363
10374
  mountedRef.current = false;
@@ -10365,14 +10376,14 @@ function NCredentialsCard({
10365
10376
  revertTimer.current = null;
10366
10377
  };
10367
10378
  }, []);
10368
- const scheduleRevert = React61.useCallback(() => {
10379
+ const scheduleRevert = React66.useCallback(() => {
10369
10380
  if (revertTimer.current) clearTimeout(revertTimer.current);
10370
10381
  revertTimer.current = setTimeout(() => {
10371
10382
  revertTimer.current = null;
10372
10383
  if (mountedRef.current) setStatus("idle");
10373
10384
  }, REVERT_MS);
10374
10385
  }, []);
10375
- const handleCopy = React61.useCallback(() => {
10386
+ const handleCopy = React66.useCallback(() => {
10376
10387
  if (status === "pending") return;
10377
10388
  if (revertTimer.current) {
10378
10389
  clearTimeout(revertTimer.current);
@@ -10612,19 +10623,19 @@ function Combobox({
10612
10623
  allowFreeText = false,
10613
10624
  disabled = false
10614
10625
  }) {
10615
- const [open, setOpen] = React61.useState(false);
10616
- const [query, setQuery] = React61.useState("");
10617
- const [highlight, setHighlight] = React61.useState(0);
10618
- const wrapperRef = React61.useRef(null);
10619
- const inputRef = React61.useRef(null);
10620
- const filtered = React61.useMemo(() => {
10626
+ const [open, setOpen] = React66.useState(false);
10627
+ const [query, setQuery] = React66.useState("");
10628
+ const [highlight, setHighlight] = React66.useState(0);
10629
+ const wrapperRef = React66.useRef(null);
10630
+ const inputRef = React66.useRef(null);
10631
+ const filtered = React66.useMemo(() => {
10621
10632
  const q = query.trim().toLowerCase();
10622
10633
  if (!q) return options;
10623
10634
  return options.filter(
10624
10635
  (opt) => opt.label.toLowerCase().includes(q) || opt.value.toLowerCase().includes(q)
10625
10636
  );
10626
10637
  }, [options, query]);
10627
- React61.useEffect(() => {
10638
+ React66.useEffect(() => {
10628
10639
  if (!open) return;
10629
10640
  const onClick = (e) => {
10630
10641
  if (wrapperRef.current && !wrapperRef.current.contains(e.target)) {
@@ -10635,7 +10646,7 @@ function Combobox({
10635
10646
  document.addEventListener("mousedown", onClick);
10636
10647
  return () => document.removeEventListener("mousedown", onClick);
10637
10648
  }, [open]);
10638
- React61.useEffect(() => {
10649
+ React66.useEffect(() => {
10639
10650
  if (open) {
10640
10651
  setHighlight(0);
10641
10652
  requestAnimationFrame(() => inputRef.current?.focus());
@@ -10643,7 +10654,7 @@ function Combobox({
10643
10654
  setQuery("");
10644
10655
  }
10645
10656
  }, [open]);
10646
- const selectedLabel = React61.useMemo(() => {
10657
+ const selectedLabel = React66.useMemo(() => {
10647
10658
  const match = options.find((o) => o.value === value);
10648
10659
  return match?.label ?? value;
10649
10660
  }, [options, value]);
@@ -10868,10 +10879,12 @@ var Inputs = {
10868
10879
  time: TimeInput,
10869
10880
  slider: SliderInput
10870
10881
  };
10882
+ var nativeFieldTypes = /* @__PURE__ */ new Set(["text", "number", "password", "textarea", "time"]);
10883
+ var labelNamedCompositeTypes = /* @__PURE__ */ new Set(["date", "combobox", "multiselect"]);
10871
10884
  var FormInput = ({ name, type, formLabel, formDescription, required = false, disabled = false, readOnly = false, hidden = false, icon, iconColor, classNames, background, ...rest }) => {
10872
10885
  const InputComponent = Inputs[type];
10873
10886
  const { control } = useFormContext();
10874
- const { className, onChange: consumerOnChange, ...inputRest } = rest;
10887
+ const { className, onChange: consumerOnChange, onBlur: consumerOnBlur, ...inputRest } = rest;
10875
10888
  const prefix = usePrefix();
10876
10889
  const preset = useVariantPreset();
10877
10890
  const contextBordered = useBordered();
@@ -10886,6 +10899,7 @@ var FormInput = ({ name, type, formLabel, formDescription, required = false, dis
10886
10899
  };
10887
10900
  const presetInput = type === "textarea" ? preset.input?.replace(/\bh-\d+\b/g, "").trim() : preset.input;
10888
10901
  const isFillAvatar = type === "avatar" && inputRest.fill === true;
10902
+ const compositeAriaLabel = labelNamedCompositeTypes.has(type) && typeof formLabel === "string" ? { ariaLabel: inputRest.ariaLabel ?? formLabel } : {};
10889
10903
  const slot = {
10890
10904
  item: cn(
10891
10905
  preset.item,
@@ -10904,13 +10918,21 @@ var FormInput = ({ name, type, formLabel, formDescription, required = false, dis
10904
10918
  field.onChange(val);
10905
10919
  consumerOnChange?.(val);
10906
10920
  };
10921
+ const nativeFieldBinding = nativeFieldTypes.has(type) ? {
10922
+ name: field.name,
10923
+ onBlur: (event) => {
10924
+ field.onBlur();
10925
+ consumerOnBlur?.(event);
10926
+ },
10927
+ ref: field.ref
10928
+ } : {};
10907
10929
  return /* @__PURE__ */ jsxs(FormItem, { className: slot.item, children: [
10908
10930
  formLabel && /* @__PURE__ */ jsxs(FormLabel, { className: slot.label, children: [
10909
10931
  icon && /* @__PURE__ */ jsx(NIcon, { icon, size: 16, className: "shrink-0 text-muted-foreground" }),
10910
10932
  formLabel,
10911
10933
  required && !disabled && !readOnly && /* @__PURE__ */ jsx("span", { className: "text-destructive ml-1", children: "*" })
10912
10934
  ] }),
10913
- /* @__PURE__ */ jsx(FormControl, { children: /* @__PURE__ */ jsx(InputComponent, { value: field.value ?? getDefaultValue(), onChange: handleChange, status: hasError && !isHidden ? "error" : "default", bordered: contextBordered, icon: formLabel ? void 0 : icon, iconColor: formLabel ? void 0 : iconColor, disabled, readOnly, ...inputRest, className: slot.input }) }),
10935
+ /* @__PURE__ */ jsx(FormControl, { children: /* @__PURE__ */ jsx(InputComponent, { value: field.value ?? getDefaultValue(), onChange: handleChange, status: hasError && !isHidden ? "error" : "default", bordered: contextBordered, icon: formLabel ? void 0 : icon, iconColor: formLabel ? void 0 : iconColor, disabled, readOnly, ...inputRest, ...compositeAriaLabel, ...nativeFieldBinding, className: slot.input }) }),
10914
10936
  !hasError && !disabled && !readOnly && formDescription && /* @__PURE__ */ jsx(FormDescription, { className: slot.description, children: formDescription }),
10915
10937
  !isHidden && /* @__PURE__ */ jsx(FormMessage, { className: slot.error })
10916
10938
  ] });
@@ -12039,8 +12061,8 @@ function useTable(effectiveViewModeOverride) {
12039
12061
  ...effectiveColumns,
12040
12062
  {
12041
12063
  id: "actions",
12042
- header: () => isMenuActions ? null : React61__default.createElement("div", { className: "flex w-full justify-start text-left" }, "Actions"),
12043
- cell: ({ row }) => React61__default.createElement(TableActionCell, { row, onView, onEdit, onDelete, openRowMenu, menuButton, bordered }),
12064
+ header: () => isMenuActions ? null : React66__default.createElement("div", { className: "flex w-full justify-start text-left" }, "Actions"),
12065
+ cell: ({ row }) => React66__default.createElement(TableActionCell, { row, onView, onEdit, onDelete, openRowMenu, menuButton, bordered }),
12044
12066
  enableSorting: false,
12045
12067
  enableHiding: false
12046
12068
  }
@@ -12303,10 +12325,10 @@ function EditableCell({ cell, onCellEdit }) {
12303
12325
  const columnId = cell.column.id;
12304
12326
  const editor = meta.editor || "text";
12305
12327
  const initial = cell.getValue();
12306
- const [editing, setEditing] = React61__default.useState(false);
12307
- const [value, setValue] = React61__default.useState(initial);
12308
- const [saving, setSaving] = React61__default.useState(false);
12309
- React61__default.useEffect(() => {
12328
+ const [editing, setEditing] = React66__default.useState(false);
12329
+ const [value, setValue] = React66__default.useState(initial);
12330
+ const [saving, setSaving] = React66__default.useState(false);
12331
+ React66__default.useEffect(() => {
12310
12332
  if (!editing) setValue(initial);
12311
12333
  }, [initial, editing]);
12312
12334
  const commit = async (next) => {
@@ -12480,7 +12502,7 @@ function NTableContent({ effectiveMode }) {
12480
12502
  const isExpanded = canExpand && row.getIsExpanded();
12481
12503
  const totalCols = row.getVisibleCells().length + (showCheckbox ? 1 : 0) + (hasExpansion ? 1 : 0);
12482
12504
  const rowClassName = getRowClassName?.(row.original);
12483
- return /* @__PURE__ */ jsxs(React61__default.Fragment, { children: [
12505
+ return /* @__PURE__ */ jsxs(React66__default.Fragment, { children: [
12484
12506
  /* @__PURE__ */ jsxs(
12485
12507
  TableRow,
12486
12508
  {
@@ -12739,7 +12761,7 @@ function NTableCardSkeleton({ surface }) {
12739
12761
  }
12740
12762
  function NTableLoadingSkeleton({ rows }) {
12741
12763
  const rawColumns = useTableStore.use.columns();
12742
- const responsiveColumns = React61__default.useMemo(() => filterResponsiveColumns(rawColumns), [rawColumns]);
12764
+ const responsiveColumns = React66__default.useMemo(() => filterResponsiveColumns(rawColumns), [rawColumns]);
12743
12765
  const columns = responsiveColumns;
12744
12766
  const showCheckbox = useTableStore.use.showCheckbox();
12745
12767
  const headerClassName = useTableStore.use.headerClassName();
@@ -12862,19 +12884,19 @@ function useCardContinuation({
12862
12884
  rowCount,
12863
12885
  viewportRef
12864
12886
  }) {
12865
- const [internalPending, setInternalPending] = React61__default.useState(false);
12866
- const [internalError, setInternalError] = React61__default.useState(null);
12867
- const [announcement, setAnnouncement] = React61__default.useState("");
12868
- const [viewportReady, setViewportReady] = React61__default.useState(false);
12869
- const pendingRef = React61__default.useRef(false);
12870
- const previousRowCountRef = React61__default.useRef(rowCount);
12871
- const configRef = React61__default.useRef(config);
12887
+ const [internalPending, setInternalPending] = React66__default.useState(false);
12888
+ const [internalError, setInternalError] = React66__default.useState(null);
12889
+ const [announcement, setAnnouncement] = React66__default.useState("");
12890
+ const [viewportReady, setViewportReady] = React66__default.useState(false);
12891
+ const pendingRef = React66__default.useRef(false);
12892
+ const previousRowCountRef = React66__default.useRef(rowCount);
12893
+ const configRef = React66__default.useRef(config);
12872
12894
  configRef.current = config;
12873
12895
  const enabled = Boolean(config);
12874
12896
  const pending = Boolean(config?.loadingMore || internalPending);
12875
12897
  const error = config?.loadMoreError ?? internalError;
12876
12898
  const hasNextPage = Boolean(config?.hasNextPage);
12877
- const load = React61__default.useCallback(async () => {
12899
+ const load = React66__default.useCallback(async () => {
12878
12900
  const current = configRef.current;
12879
12901
  if (!current) return;
12880
12902
  if (pendingRef.current || current.loadingMore || !current.hasNextPage) return;
@@ -12899,13 +12921,13 @@ function useCardContinuation({
12899
12921
  load,
12900
12922
  { rootMargin: config?.rootMargin ?? DEFAULT_ROOT_MARGIN }
12901
12923
  );
12902
- React61__default.useLayoutEffect(() => {
12924
+ React66__default.useLayoutEffect(() => {
12903
12925
  const node = viewportRef.current ?? null;
12904
12926
  scrollContainerRef.current = node;
12905
12927
  const ready = Boolean(node);
12906
12928
  setViewportReady((value) => value === ready ? value : ready);
12907
12929
  });
12908
- React61__default.useEffect(() => {
12930
+ React66__default.useEffect(() => {
12909
12931
  const previous = previousRowCountRef.current;
12910
12932
  previousRowCountRef.current = rowCount;
12911
12933
  if (!configRef.current) return;
@@ -12915,10 +12937,10 @@ function useCardContinuation({
12915
12937
  configRef.current.itemsLoadedLabel?.(appended) ?? `${appended} more ${appended === 1 ? "item" : "items"} loaded.`
12916
12938
  );
12917
12939
  }, [rowCount]);
12918
- React61__default.useEffect(() => {
12940
+ React66__default.useEffect(() => {
12919
12941
  if (!pending) doneLoading();
12920
12942
  }, [pending, doneLoading]);
12921
- React61__default.useEffect(() => {
12943
+ React66__default.useEffect(() => {
12922
12944
  if (!enabled || !hasNextPage || error) return;
12923
12945
  return observe();
12924
12946
  }, [enabled, hasNextPage, error, observe, viewportReady, rowCount]);
@@ -12972,7 +12994,7 @@ function NTableCards({ effectiveMode }) {
12972
12994
  const cardPagination = useTableStore.use.cardPagination();
12973
12995
  const cardColumnCount = useTableStore.use.cardColumnCount();
12974
12996
  const surface = useTableSurfaceAppearance(bordered, borderColor);
12975
- const viewportRef = React61__default.useRef(null);
12997
+ const viewportRef = React66__default.useRef(null);
12976
12998
  const continuationConfig = cardPagination.mode === "infinite" ? cardPagination : null;
12977
12999
  const continuation = useCardContinuation({
12978
13000
  config: continuationConfig,
@@ -13193,17 +13215,17 @@ function CardLoadMorePagination({
13193
13215
  bordered,
13194
13216
  className
13195
13217
  }) {
13196
- const [internalPending, setInternalPending] = React61__default.useState(false);
13197
- const [internalError, setInternalError] = React61__default.useState(null);
13198
- const [announcement, setAnnouncement] = React61__default.useState("");
13199
- const buttonRef = React61__default.useRef(null);
13200
- const pendingRef = React61__default.useRef(false);
13201
- const restoreFocusRef = React61__default.useRef(false);
13202
- const previousRowCountRef = React61__default.useRef(rowCount);
13203
- const errorId = React61__default.useId();
13218
+ const [internalPending, setInternalPending] = React66__default.useState(false);
13219
+ const [internalError, setInternalError] = React66__default.useState(null);
13220
+ const [announcement, setAnnouncement] = React66__default.useState("");
13221
+ const buttonRef = React66__default.useRef(null);
13222
+ const pendingRef = React66__default.useRef(false);
13223
+ const restoreFocusRef = React66__default.useRef(false);
13224
+ const previousRowCountRef = React66__default.useRef(rowCount);
13225
+ const errorId = React66__default.useId();
13204
13226
  const pending = Boolean(config.loadingMore || internalPending);
13205
13227
  const error = config.loadMoreError ?? internalError;
13206
- React61__default.useEffect(() => {
13228
+ React66__default.useEffect(() => {
13207
13229
  const previous = previousRowCountRef.current;
13208
13230
  if (rowCount > previous) {
13209
13231
  const appended = rowCount - previous;
@@ -13213,7 +13235,7 @@ function CardLoadMorePagination({
13213
13235
  }
13214
13236
  previousRowCountRef.current = rowCount;
13215
13237
  }, [config.itemsLoadedLabel, rowCount]);
13216
- React61__default.useEffect(() => {
13238
+ React66__default.useEffect(() => {
13217
13239
  if (pending || !restoreFocusRef.current) return;
13218
13240
  restoreFocusRef.current = false;
13219
13241
  const frame = requestAnimationFrame(() => buttonRef.current?.focus());
@@ -13283,9 +13305,9 @@ function CardLoadMorePagination({
13283
13305
  var navButtonClass = "h-8 w-8 p-0 text-foreground disabled:text-muted-foreground disabled:opacity-70";
13284
13306
  var chevronClass = "h-4 w-4 rtl:-scale-x-100";
13285
13307
  function useLowerBoundPageCountWarning(manualPagination, pageCount, pagination) {
13286
- const previous = React61__default.useRef(null);
13287
- const warned = React61__default.useRef(false);
13288
- React61__default.useEffect(() => {
13308
+ const previous = React66__default.useRef(null);
13309
+ const warned = React66__default.useRef(false);
13310
+ React66__default.useEffect(() => {
13289
13311
  if (typeof console === "undefined") return;
13290
13312
  if (typeof process !== "undefined" && process.env?.NODE_ENV === "production") return;
13291
13313
  if (!manualPagination || pageCount === void 0 || !pagination) {
@@ -15176,7 +15198,7 @@ function NNavbar({
15176
15198
  (userMenuActions.length > 0 || onLogout) && /* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
15177
15199
  userMenuActions.map((action) => {
15178
15200
  const ActionIcon = action.icon;
15179
- return /* @__PURE__ */ jsxs(React61__default.Fragment, { children: [
15201
+ return /* @__PURE__ */ jsxs(React66__default.Fragment, { children: [
15180
15202
  action.separator && /* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
15181
15203
  /* @__PURE__ */ jsxs(DropdownMenuItem, { onClick: action.onClick, className: "cursor-pointer", children: [
15182
15204
  ActionIcon && /* @__PURE__ */ jsx(ActionIcon, { className: "h-4 w-4 mr-2" }),
package/dist/theme.css CHANGED
@@ -307,10 +307,10 @@ input:autofill {
307
307
  overflow-x: auto;
308
308
  scrollbar-width: none;
309
309
  }
310
- .najm-overlay-scroll-x::-webkit-scrollbar {
311
- display: none;
312
- }
313
-
310
+ .najm-overlay-scroll-x::-webkit-scrollbar {
311
+ display: none;
312
+ }
313
+
314
314
  /* Responsive table actions stay discoverable on touch and tablet layouts.
315
315
  Fine-pointer desktops may keep the quieter hover/focus reveal treatment. */
316
316
  .ntable-card-action {
@@ -367,7 +367,7 @@ input:autofill {
367
367
  .nimage-input-compact-overlay:focus-visible {
368
368
  opacity: 1;
369
369
  }
370
- }
370
+ }
371
371
 
372
372
  /* OverlayScrollbars theme used by the <NajmScroll> component — a thin,
373
373
  translucent slate bar that floats over content with no reserved space.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "najm-kit",
3
- "version": "2.11.5",
3
+ "version": "2.11.7",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "description": "Reusable React UI component package for Najm framework",