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 +66 -41
- package/README.md +8 -8
- package/dist/index.d.ts +13 -17
- package/dist/index.mjs +172 -150
- package/dist/theme.css +5 -5
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,44 +1,69 @@
|
|
|
1
|
-
# Changelog
|
|
2
|
-
|
|
3
|
-
## 2.11.
|
|
4
|
-
|
|
5
|
-
- Fixed
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
## 2.11.
|
|
29
|
-
|
|
30
|
-
- Fixed
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
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
|
|
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
|
|
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.
|
|
2457
|
+
declare const TextInput: React__default.ForwardRefExoticComponent<TextInputProps & React__default.RefAttributes<HTMLInputElement>>;
|
|
2462
2458
|
|
|
2463
|
-
declare const NumberInput: React__default.
|
|
2459
|
+
declare const NumberInput: React__default.ForwardRefExoticComponent<NumberInputProps & React__default.RefAttributes<HTMLInputElement>>;
|
|
2464
2460
|
|
|
2465
|
-
declare const PasswordInput: React__default.
|
|
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.
|
|
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.
|
|
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
|
|
21
|
-
import
|
|
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,
|
|
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
|
-
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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] =
|
|
1145
|
-
|
|
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 =
|
|
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 =
|
|
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
|
|
1316
|
+
return React66__default.isValidElement(child) && child.type === slot;
|
|
1317
1317
|
}
|
|
1318
1318
|
function getSlotElements(children, slot) {
|
|
1319
|
-
const matches =
|
|
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
|
-
|
|
1733
|
-
if (!
|
|
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] =
|
|
1807
|
-
const [contentOwnsActions, setContentOwnsActions] =
|
|
1808
|
-
const contentElementRef =
|
|
1809
|
-
const handleContentElementRef =
|
|
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
|
-
|
|
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] =
|
|
2068
|
-
const [primaryLoading, setPrimaryLoading] =
|
|
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 }) =>
|
|
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 =
|
|
2645
|
-
const pointerDismissedRef =
|
|
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 =
|
|
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] =
|
|
2845
|
-
const triggerRef =
|
|
2846
|
-
const pointerDismissedRef =
|
|
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
|
-
|
|
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] =
|
|
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] =
|
|
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
|
-
|
|
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
|
-
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
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 =
|
|
4549
|
-
const pointerDismissedRef =
|
|
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("
|
|
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 =
|
|
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] =
|
|
6341
|
-
const [active, setActive] =
|
|
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] =
|
|
6499
|
-
const [name, setName] =
|
|
6500
|
-
const [pendingDelete, setPendingDelete] =
|
|
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] =
|
|
6504
|
-
const rows =
|
|
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 =
|
|
6767
|
+
const visibleTabs = React66.useMemo(() => buildTabs(tabs), [tabs]);
|
|
6757
6768
|
const firstTab = visibleTabs[0] ?? "theme";
|
|
6758
|
-
const [activeTab, setActiveTab] =
|
|
6759
|
-
const [fileError, setFileError] =
|
|
6760
|
-
const fileInputRef =
|
|
6761
|
-
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 ?
|
|
7830
|
-
if (
|
|
7831
|
-
return
|
|
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] =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
8094
|
-
const itemContext =
|
|
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 =
|
|
8112
|
+
var FormItemContext = React66.createContext({});
|
|
8102
8113
|
function FormItem({ className, ...props }) {
|
|
8103
|
-
const id =
|
|
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
|
|
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 =
|
|
8340
|
+
const imageRef = React66__default.useRef(null);
|
|
8330
8341
|
const { markLoaded } = chain;
|
|
8331
|
-
|
|
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
|
-
|
|
8487
|
-
if (!
|
|
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 =
|
|
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 =
|
|
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(
|
|
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] =
|
|
10357
|
-
const revertTimer =
|
|
10358
|
-
const mountedRef =
|
|
10359
|
-
const requestTokenRef =
|
|
10360
|
-
|
|
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 =
|
|
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 =
|
|
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] =
|
|
10616
|
-
const [query, setQuery] =
|
|
10617
|
-
const [highlight, setHighlight] =
|
|
10618
|
-
const wrapperRef =
|
|
10619
|
-
const inputRef =
|
|
10620
|
-
const filtered =
|
|
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
|
-
|
|
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
|
-
|
|
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 =
|
|
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 :
|
|
12043
|
-
cell: ({ row }) =>
|
|
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] =
|
|
12307
|
-
const [value, setValue] =
|
|
12308
|
-
const [saving, setSaving] =
|
|
12309
|
-
|
|
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(
|
|
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 =
|
|
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] =
|
|
12866
|
-
const [internalError, setInternalError] =
|
|
12867
|
-
const [announcement, setAnnouncement] =
|
|
12868
|
-
const [viewportReady, setViewportReady] =
|
|
12869
|
-
const pendingRef =
|
|
12870
|
-
const previousRowCountRef =
|
|
12871
|
-
const configRef =
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
12940
|
+
React66__default.useEffect(() => {
|
|
12919
12941
|
if (!pending) doneLoading();
|
|
12920
12942
|
}, [pending, doneLoading]);
|
|
12921
|
-
|
|
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 =
|
|
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] =
|
|
13197
|
-
const [internalError, setInternalError] =
|
|
13198
|
-
const [announcement, setAnnouncement] =
|
|
13199
|
-
const buttonRef =
|
|
13200
|
-
const pendingRef =
|
|
13201
|
-
const restoreFocusRef =
|
|
13202
|
-
const previousRowCountRef =
|
|
13203
|
-
const errorId =
|
|
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
|
-
|
|
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
|
-
|
|
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 =
|
|
13287
|
-
const warned =
|
|
13288
|
-
|
|
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(
|
|
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.
|