najm-kit 2.11.9 → 2.11.11

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,6 +1,19 @@
1
- # Changelog
2
-
3
- ## 2.11.9 - 2026-08-30
1
+ # Changelog
2
+
3
+ ## 2.11.10 - 2026-09-03
4
+
5
+ - Fixed the selected numbered `NTable` pagination button inheriting the regular
6
+ foreground colour over its filled primary style. The active page now keeps
7
+ the primary button foreground token, which is white in the light theme.
8
+ - Fixed focused invalid inputs combining a destructive border with the normal
9
+ theme focus colour. `BaseInput` now keeps the visible keyboard-focus ring but
10
+ colours it from the destructive token for both directly focused composite
11
+ controls and wrappers whose child has `:focus-visible`.
12
+ - Made the desktop and mobile sidebar use logical inline edges, spacing, border
13
+ utilities, chevrons, and drag direction so the complete rail behaves
14
+ correctly in both LTR and RTL layouts.
15
+
16
+ ## 2.11.9 - 2026-08-30
4
17
 
5
18
  - Fixed card grids that paginate client-side rendering their entire dataset on
6
19
  one page. `useTable` pinned an uncontrolled paged card list to `data.length`,
@@ -1,9 +1,9 @@
1
1
  'use client';
2
- import { FormDevToolsProvider, NBrandingStateProvider, NajmFormatProvider } from '../chunk-A7BKZZJ4.mjs';
3
- export { NEmptyState, NErrorState, NForbiddenState, NLoadingState, NNotFoundState } from '../chunk-A7BKZZJ4.mjs';
2
+ import { FormDevToolsProvider, NBrandingStateProvider, NajmFormatProvider } from '../chunk-W2HMBUZ4.mjs';
3
+ export { NEmptyState, NErrorState, NForbiddenState, NLoadingState, NNotFoundState } from '../chunk-W2HMBUZ4.mjs';
4
4
  import { NajmNextUIProvider } from '../chunk-T6RL7TSQ.mjs';
5
5
  import '../chunk-6UDJNTJ6.mjs';
6
- import '../chunk-ONE7GLIH.mjs';
6
+ import '../chunk-M5VGBZ7R.mjs';
7
7
  import '../chunk-LK3SMYUP.mjs';
8
8
  import '../chunk-JABLSOQN.mjs';
9
9
  import '../chunk-TFHWLE7N.mjs';
@@ -86,21 +86,27 @@ var SURFACE_BORDER_CLASSES = {
86
86
  top: "najm-border-t border-border",
87
87
  right: "najm-border-r border-border",
88
88
  bottom: "najm-border-b border-border",
89
- left: "najm-border-l border-border"
89
+ left: "najm-border-l border-border",
90
+ start: "najm-border-s border-border",
91
+ end: "najm-border-e border-border"
90
92
  };
91
93
  var SIDEBAR_BORDER_CLASSES = {
92
94
  all: "najm-border border-sidebar-border",
93
95
  top: "najm-border-t border-sidebar-border",
94
96
  right: "najm-border-r border-sidebar-border",
95
97
  bottom: "najm-border-b border-sidebar-border",
96
- left: "najm-border-l border-sidebar-border"
98
+ left: "najm-border-l border-sidebar-border",
99
+ start: "najm-border-s border-sidebar-border",
100
+ end: "najm-border-e border-sidebar-border"
97
101
  };
98
102
  var BORDER_RESET_CLASSES = {
99
103
  all: "border-0",
100
104
  top: "border-t-0",
101
105
  right: "border-r-0",
102
106
  bottom: "border-b-0",
103
- left: "border-l-0"
107
+ left: "border-l-0",
108
+ start: "border-s-0",
109
+ end: "border-e-0"
104
110
  };
105
111
  function surfaceBorderClasses(bordered = true, side = "all") {
106
112
  return bordered === false ? BORDER_RESET_CLASSES[side] : SURFACE_BORDER_CLASSES[side];
@@ -1,5 +1,5 @@
1
1
  import { useResolvedFeedbackLabels, useNajmPreferencesContext } from './chunk-6UDJNTJ6.mjs';
2
- import { Button } from './chunk-ONE7GLIH.mjs';
2
+ import { Button } from './chunk-M5VGBZ7R.mjs';
3
3
  import { useNajmDesign, cn } from './chunk-LK3SMYUP.mjs';
4
4
  import { humanizeToken, DEFAULT_PLACEHOLDER, formatRelativeTime, formatTime, formatDateTime, formatDate, formatPercent, formatNumber, formatCurrency } from './chunk-JABLSOQN.mjs';
5
5
  import * as React3 from 'react';
package/dist/index.d.ts CHANGED
@@ -316,7 +316,7 @@ interface NajmDesignProviderProps {
316
316
  */
317
317
  declare function NajmDesignProvider({ config, mode, className, children, }: NajmDesignProviderProps): react_jsx_runtime.JSX.Element;
318
318
 
319
- type NajmBorderSide = 'all' | 'top' | 'right' | 'bottom' | 'left';
319
+ type NajmBorderSide = 'all' | 'top' | 'right' | 'bottom' | 'left' | 'start' | 'end';
320
320
  /**
321
321
  * Border utility for structural surfaces (cards, tables, dividers, side rails).
322
322
  * `bordered === false` returns a per-side reset so primitives that already
@@ -558,7 +558,7 @@ type DialogPadding = "none" | "sm" | "md" | "lg";
558
558
  interface DialogContentProps extends React$1.ComponentProps<typeof DialogPrimitive.Content> {
559
559
  /** Controls the padding of the dialog surface. `none` also collapses the header/body/footer gap. Defaults to `sm` on mobile, `md` on desktop. */
560
560
  padding?: DialogPadding;
561
- /** Hides the built-in top-right close (X). Use when the content provides its own close control (e.g. inside a page header). */
561
+ /** Hides the built-in close (X) in the top inline-end corner. Use when the content provides its own close control (e.g. inside a page header). */
562
562
  hideClose?: boolean;
563
563
  }
564
564
  declare function DialogContent({ className, children, padding, hideClose, onOpenAutoFocus, onCloseAutoFocus, ...props }: DialogContentProps): react_jsx_runtime.JSX.Element;
package/dist/index.mjs CHANGED
@@ -1,13 +1,13 @@
1
1
  import { resolveAvatarSrc } from './chunk-BEGOH366.mjs';
2
2
  export { isPlaceholderAvatar, resolveAvatarSrc } from './chunk-BEGOH366.mjs';
3
- import { NLoadingState, NErrorState, NEmptyState, useResolvedFormDevTools, useNBranding } from './chunk-A7BKZZJ4.mjs';
4
- export { FormDevToolsProvider, NBrandingProvider, NBrandingStateProvider, NEmptyState, NErrorState, NForbiddenState, NLoadingState, NNotFoundState, NPageLayout, NSpinner, NajmFormatProvider, buildFormFill, normalizeBranding, useNBranding, useNBrandingEditor, useNajmFormat, useNajmFormatContext } from './chunk-A7BKZZJ4.mjs';
3
+ import { NLoadingState, NErrorState, NEmptyState, useResolvedFormDevTools, useNBranding } from './chunk-W2HMBUZ4.mjs';
4
+ export { FormDevToolsProvider, NBrandingProvider, NBrandingStateProvider, NEmptyState, NErrorState, NForbiddenState, NLoadingState, NNotFoundState, NPageLayout, NSpinner, NajmFormatProvider, buildFormFill, normalizeBranding, useNBranding, useNBrandingEditor, useNajmFormat, useNajmFormatContext } from './chunk-W2HMBUZ4.mjs';
5
5
  import { normalizeImageSources, useImageChain, useNBadgeDefaults, mergeBadgeMaps, resolveStatusColor, resolveBadgeStatusLabel, colorTextClass, useResolvedPaginationLabels } from './chunk-6UDJNTJ6.mjs';
6
6
  export { DEFAULT_PAGINATION_KEY_PREFIX, DEFAULT_TIME_ZONE, EMPTY_DESIGN, NAJM_COLOR_TEXT_CLASSES, NAJM_STATUS_COLORS, NTableDefaultsProvider, NajmDesignEditorProvider, NajmPreferencesProvider, NajmUIProvider, buildPaginationLabels, colorTextClass, findStatusColor, normalizeStatusToken, resolveStatusColor, statusTextClass, useNTableDefaults, useNajmDesignEditor, useNajmPreferencesContext, useNajmTheme, useNajmTimeZone } from './chunk-6UDJNTJ6.mjs';
7
7
  import { NajmScroll, useNajmScrollViewport, useTableStore, TableStoreContext, NTableJson } from './chunk-5JVFMOLI.mjs';
8
8
  export { NTableJson, NajmScroll, TableStoreContext, useTableStore } from './chunk-5JVFMOLI.mjs';
9
- import { inputBorderClasses, Button, NIcon, surfaceBorderClasses, buttonVariants, NButton, sidebarBorderClasses } from './chunk-ONE7GLIH.mjs';
10
- export { Button, NButton, NIcon, buttonVariants, inputBorderClasses, sidebarBorderClasses, surfaceBorderClasses } from './chunk-ONE7GLIH.mjs';
9
+ import { inputBorderClasses, Button, NIcon, surfaceBorderClasses, buttonVariants, NButton, sidebarBorderClasses } from './chunk-M5VGBZ7R.mjs';
10
+ export { Button, NButton, NIcon, buttonVariants, inputBorderClasses, sidebarBorderClasses, surfaceBorderClasses } from './chunk-M5VGBZ7R.mjs';
11
11
  import { useNajmComponentStyle, cn, NajmThemeContainerCtx, useNajmThemeMode, useNajmDesign, composePreset } from './chunk-LK3SMYUP.mjs';
12
12
  export { NajmDesignProvider, NajmThemeProvider, cn, composePreset, resolvePreset, useNajmAppearance, useNajmComponentStyle, useNajmDesign, useNajmThemeMode } from './chunk-LK3SMYUP.mjs';
13
13
  export { DEFAULT_CARD_BREAKPOINT, DEFAULT_CARD_PAGINATION_KEY_PREFIX, buildCardPaginationLabels, createCardPagination, useCardViewport, useDesktopTableMode, useMediaQuery } from './chunk-OUS7OYVA.mjs';
@@ -453,6 +453,7 @@ var inputVariants = cva(
453
453
  }
454
454
  );
455
455
  var ERROR_BORDER = "border !border-red-600";
456
+ var ERROR_FOCUS_RING = "focus-visible:ring-destructive/20 has-[:focus-visible]:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:has-[:focus-visible]:ring-destructive/40";
456
457
  var FOCUS_INTERACTIVE_BASE = "border focus-within:border-primary";
457
458
  var HOVER_INTERACTIVE_BASE = "hover:border-primary";
458
459
  var STATIC_BASE = "border";
@@ -492,6 +493,7 @@ var BaseInput = React66__default.forwardRef(
492
493
  // fields and the multi-select trigger came out of the acceptance walk
493
494
  // as tab stops with no visible indicator at all.
494
495
  !isGhost && focusRingWithinClasses,
496
+ !isGhost && isError && ERROR_FOCUS_RING,
495
497
  !isGhost && borderClass,
496
498
  !isGhost && colorClass,
497
499
  className
@@ -1002,7 +1004,7 @@ function SheetContent({ className, portalClassName, side, children, ...props })
1002
1004
  ...props,
1003
1005
  children: [
1004
1006
  children,
1005
- /* @__PURE__ */ jsxs(SheetPrimitive.Close, { className: "ring-offset-background focus:ring-ring data-[state=open]:bg-secondary absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none", children: [
1007
+ /* @__PURE__ */ jsxs(SheetPrimitive.Close, { className: "ring-offset-background focus:ring-ring data-[state=open]:bg-secondary absolute top-4 end-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none", children: [
1006
1008
  /* @__PURE__ */ jsx(X, { className: "size-4" }),
1007
1009
  /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Close" })
1008
1010
  ] })
@@ -1199,7 +1201,7 @@ function DialogContent({
1199
1201
  ...props,
1200
1202
  children: [
1201
1203
  children,
1202
- !hideClose && /* @__PURE__ */ jsxs(SheetPrimitive.Close, { className: "ring-offset-background cursor-pointer focus:ring-ring absolute top-4 right-4 rounded-xs text-muted-foreground hover:text-foreground transition-colors focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", children: [
1204
+ !hideClose && /* @__PURE__ */ jsxs(SheetPrimitive.Close, { className: "ring-offset-background cursor-pointer focus:ring-ring absolute top-4 end-4 rounded-xs text-muted-foreground hover:text-foreground transition-colors focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", children: [
1203
1205
  /* @__PURE__ */ jsx(XIcon, {}),
1204
1206
  /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Close" })
1205
1207
  ] })
@@ -1209,7 +1211,7 @@ function DialogContent({
1209
1211
  ] }) });
1210
1212
  }
1211
1213
  function DialogHeader({ className, ...props }) {
1212
- return /* @__PURE__ */ jsx("div", { "data-slot": "dialog-header", className: cn("flex flex-col gap-2 text-center sm:text-left", className), ...props });
1214
+ return /* @__PURE__ */ jsx("div", { "data-slot": "dialog-header", className: cn("flex flex-col gap-2 text-center sm:text-start", className), ...props });
1213
1215
  }
1214
1216
  function DialogFooter({ className, ...props }) {
1215
1217
  return /* @__PURE__ */ jsx("div", { "data-slot": "dialog-footer", className: cn("flex flex-col-reverse gap-2 sm:flex-row sm:justify-end", className), ...props });
@@ -1880,7 +1882,7 @@ function DialogChrome({
1880
1882
  DialogHeader,
1881
1883
  {
1882
1884
  className: cn(
1883
- "flex-row items-center justify-between gap-3 border-b border-border bg-secondary text-left text-secondary-foreground",
1885
+ "flex-row items-center justify-between gap-3 border-b border-border bg-secondary text-start text-secondary-foreground",
1884
1886
  windowHeaderSpacing[resolvedPadding],
1885
1887
  headerClassName
1886
1888
  ),
@@ -2279,7 +2281,7 @@ function NDeleteDialog({
2279
2281
  {
2280
2282
  className: cn(
2281
2283
  "h-auto max-w-[380px] gap-0 rounded-[18px] border border-border bg-card p-6 pt-8 shadow-2xl dark:border-0 dark:bg-[#222b38]",
2282
- "[&>button]:right-4 [&>button]:top-4 [&>button]:flex [&>button]:size-6 [&>button]:items-center [&>button]:justify-center",
2284
+ "[&>button]:end-4 [&>button]:top-4 [&>button]:flex [&>button]:size-6 [&>button]:items-center [&>button]:justify-center",
2283
2285
  "[&>button]:rounded-full [&>button]:bg-muted [&>button]:text-muted-foreground [&>button]:opacity-100 [&>button]:ring-offset-0",
2284
2286
  "[&>button]:hover:bg-secondary [&>button]:hover:text-foreground dark:[&>button]:bg-[#4d5a6d] dark:[&>button]:text-white dark:[&>button]:hover:bg-[#647186] dark:[&>button]:hover:text-white",
2285
2287
  className
@@ -13351,7 +13353,7 @@ function CardLoadMorePagination({
13351
13353
  }
13352
13354
  );
13353
13355
  }
13354
- var navButtonClass = "h-8 w-8 p-0 text-foreground disabled:text-muted-foreground disabled:opacity-70";
13356
+ var navButtonClass = "h-8 w-8 p-0 disabled:text-muted-foreground disabled:opacity-70";
13355
13357
  var chevronClass = "h-4 w-4 rtl:-scale-x-100";
13356
13358
  function useLowerBoundPageCountWarning(manualPagination, pageCount, pagination) {
13357
13359
  const previous = React66__default.useRef(null);
@@ -14437,7 +14439,7 @@ function NSmartPasteDialog({
14437
14439
  onClick: handleMerge,
14438
14440
  disabled: !preview || preview.newCount === 0,
14439
14441
  children: [
14440
- /* @__PURE__ */ jsx(Merge, { className: "h-3.5 w-3.5 mr-1.5" }),
14442
+ /* @__PURE__ */ jsx(Merge, { className: "h-3.5 w-3.5 me-1.5" }),
14441
14443
  preview ? `Merge ${preview.newCount} ${itemLabel}${preview.newCount !== 1 ? "s" : ""}` : "Merge"
14442
14444
  ]
14443
14445
  }
@@ -14530,7 +14532,7 @@ function NSidebarBrand({ logo, collapsed, linkComponent: Link, className }) {
14530
14532
  ] }) : null
14531
14533
  ] });
14532
14534
  const wrapper = cn(
14533
- "flex min-w-0 items-center gap-2.5 text-left",
14535
+ "flex min-w-0 items-center gap-2.5 text-start",
14534
14536
  !collapsed && !showText && !isChip && "mx-auto"
14535
14537
  );
14536
14538
  const interactive = "cursor-pointer transition-opacity hover:opacity-80";
@@ -14566,9 +14568,9 @@ function NSidebarItem({
14566
14568
  if (childActive) setOpen(true);
14567
14569
  }, [childActive]);
14568
14570
  const baseClasses = cn(
14569
- "flex items-center gap-3 w-full rounded-md text-sm px-2 font-medium transition-colors h-8 text-left",
14570
- depth > 0 && "pl-7",
14571
- collapsed && "pl-[calc((var(--rail,4rem)-var(--sidebar-edge-width,0px))/2-var(--spacing,0.25rem)-var(--spacing,0.25rem)-var(--spacing,0.25rem)-var(--spacing,0.25rem)-var(--spacing,0.25rem)-var(--spacing,0.25rem))]",
14571
+ "flex items-center gap-3 w-full rounded-md text-sm px-2 font-medium transition-colors h-8 text-start",
14572
+ depth > 0 && "ps-7",
14573
+ collapsed && "ps-[calc((var(--rail,4rem)-var(--sidebar-edge-width,0px))/2-var(--spacing,0.25rem)-var(--spacing,0.25rem)-var(--spacing,0.25rem)-var(--spacing,0.25rem)-var(--spacing,0.25rem)-var(--spacing,0.25rem))]",
14572
14574
  item.disabled ? "opacity-50 cursor-not-allowed" : active ? "cursor-pointer bg-sidebar-primary text-sidebar-primary-foreground" : "cursor-pointer text-sidebar-foreground/70 hover:bg-sidebar-accent hover:text-sidebar-accent-foreground",
14573
14575
  classNames?.sidebarItem
14574
14576
  );
@@ -14587,7 +14589,7 @@ function NSidebarItem({
14587
14589
  Icon2 && /* @__PURE__ */ jsx(Icon2, { className: "h-4 w-4 shrink-0" }),
14588
14590
  !collapsed && /* @__PURE__ */ jsxs(Fragment, { children: [
14589
14591
  /* @__PURE__ */ jsx("span", { className: "flex-1 truncate", children: item.label }),
14590
- item.badge && /* @__PURE__ */ jsx("span", { className: "shrink-0 ml-auto", children: item.badge }),
14592
+ item.badge && /* @__PURE__ */ jsx("span", { className: "shrink-0 ms-auto", children: item.badge }),
14591
14593
  hasChildren && /* @__PURE__ */ jsx(
14592
14594
  ChevronDown,
14593
14595
  {
@@ -14717,7 +14719,7 @@ function DefaultFooter({
14717
14719
  collapsed = false
14718
14720
  }) {
14719
14721
  if (!onSettings && !onLogout) return null;
14720
- const itemClass = "flex h-8 w-full cursor-pointer items-center gap-3 rounded-md px-2 text-left text-sm font-medium text-sidebar-foreground/70 hover:bg-sidebar-accent hover:text-sidebar-accent-foreground transition-colors";
14722
+ const itemClass = "flex h-8 w-full cursor-pointer items-center gap-3 rounded-md px-2 text-start text-sm font-medium text-sidebar-foreground/70 hover:bg-sidebar-accent hover:text-sidebar-accent-foreground transition-colors";
14721
14723
  return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-0.5", children: [
14722
14724
  onSettings && /* @__PURE__ */ jsxs("button", { type: "button", onClick: onSettings, className: itemClass, "aria-label": settingsLabel, title: settingsLabel, children: [
14723
14725
  /* @__PURE__ */ jsx(Settings, { className: "h-4 w-4 shrink-0" }),
@@ -14758,12 +14760,12 @@ function NSidebarFooter({
14758
14760
  onClick: onToggleCollapsed,
14759
14761
  className: cn(
14760
14762
  "flex items-center w-full cursor-pointer rounded-md text-sm font-medium transition-colors h-8 text-sidebar-foreground/70 hover:bg-sidebar-accent hover:text-sidebar-accent-foreground",
14761
- "gap-3 px-2 text-left"
14763
+ "gap-3 px-2 text-start"
14762
14764
  ),
14763
14765
  "aria-label": collapsed ? expandLabel : collapseLabel,
14764
14766
  title: collapsed ? expandLabel : collapseLabel,
14765
14767
  children: [
14766
- /* @__PURE__ */ jsx(CollapseIcon, { className: "h-4 w-4 shrink-0" }),
14768
+ /* @__PURE__ */ jsx(CollapseIcon, { className: "h-4 w-4 shrink-0 rtl:-scale-x-100" }),
14767
14769
  !collapsed && /* @__PURE__ */ jsx("span", { className: "flex-1 truncate", children: collapseLabel })
14768
14770
  ]
14769
14771
  }
@@ -14791,7 +14793,7 @@ function NSidebarMobile({
14791
14793
  type: "button",
14792
14794
  onClick: onOpen,
14793
14795
  className: cn(
14794
- "fixed top-3 left-3 z-50 p-2 rounded-lg bg-sidebar najm-border border-sidebar-border shadow-md text-sidebar-foreground hover:text-sidebar-accent-foreground hover:bg-sidebar-accent transition-colors",
14796
+ "fixed top-3 start-3 z-50 p-2 rounded-lg bg-sidebar najm-border border-sidebar-border shadow-md text-sidebar-foreground hover:text-sidebar-accent-foreground hover:bg-sidebar-accent transition-colors",
14795
14797
  mobileClass,
14796
14798
  hamburgerClassName,
14797
14799
  open && "hidden"
@@ -14813,10 +14815,10 @@ function NSidebarMobile({
14813
14815
  {
14814
14816
  "data-bordered": bordered === false ? "false" : bordered ? "true" : void 0,
14815
14817
  className: cn(
14816
- "fixed inset-y-0 left-0 z-50 bg-sidebar text-sidebar-foreground flex flex-col transition-transform duration-200",
14817
- sidebarBorderClasses(bordered, "right"),
14818
+ "fixed inset-y-0 start-0 z-50 bg-sidebar text-sidebar-foreground flex flex-col transition-transform duration-200",
14819
+ sidebarBorderClasses(bordered, "end"),
14818
14820
  mobileClass,
14819
- open ? "translate-x-0" : "-translate-x-full"
14821
+ open ? "translate-x-0" : "-translate-x-full rtl:translate-x-full"
14820
14822
  ),
14821
14823
  style: { width },
14822
14824
  children: [
@@ -14825,7 +14827,7 @@ function NSidebarMobile({
14825
14827
  {
14826
14828
  type: "button",
14827
14829
  onClick: onClose,
14828
- className: "absolute top-3 right-3 z-10 p-1 rounded-md hover:bg-sidebar-accent text-sidebar-foreground/70",
14830
+ className: "absolute top-3 end-3 z-10 p-1 rounded-md hover:bg-sidebar-accent text-sidebar-foreground/70",
14829
14831
  "aria-label": closeLabel,
14830
14832
  children: /* @__PURE__ */ jsx(X, { className: "h-4 w-4" })
14831
14833
  }
@@ -14982,13 +14984,14 @@ function NSidebar({
14982
14984
  }, [collapsed, setCollapsedState]);
14983
14985
  const handleRailPointerDown = useCallback((e) => {
14984
14986
  if (e.button !== 0) return;
14987
+ const inlineSign = getComputedStyle(e.currentTarget).direction === "rtl" ? -1 : 1;
14985
14988
  const startX = e.clientX;
14986
14989
  const startCollapsed = collapsed;
14987
14990
  const threshold = 24;
14988
14991
  let resolved = false;
14989
14992
  setRailDragging(true);
14990
14993
  const onMove = (ev) => {
14991
- const dx = ev.clientX - startX;
14994
+ const dx = (ev.clientX - startX) * inlineSign;
14992
14995
  if (!resolved && !startCollapsed && dx < -threshold) {
14993
14996
  resolved = true;
14994
14997
  suppressRailClickRef.current = true;
@@ -15137,7 +15140,7 @@ function NSidebar({
15137
15140
  className: cn(
15138
15141
  "relative z-10 flex flex-col h-full bg-sidebar text-sidebar-foreground transition-all duration-200 shrink-0",
15139
15142
  desktopClass,
15140
- sidebarBorderClasses(bordered, "right"),
15143
+ sidebarBorderClasses(bordered, "end"),
15141
15144
  classNames?.sidebar,
15142
15145
  className
15143
15146
  ),
@@ -15145,7 +15148,7 @@ function NSidebar({
15145
15148
  width: desktopCollapsed ? collapsedWidth : expandedWidth,
15146
15149
  ["--rail"]: railVar,
15147
15150
  ["--sidebar-edge-width"]: sidebarEdgeWidth,
15148
- ...bordered !== false && recipe?.borderWidth ? { borderRightWidth: recipe.borderWidth } : {}
15151
+ ...bordered !== false && recipe?.borderWidth ? { borderInlineEndWidth: recipe.borderWidth } : {}
15149
15152
  },
15150
15153
  children: [
15151
15154
  sidebarInner,
@@ -15158,9 +15161,9 @@ function NSidebar({
15158
15161
  "data-dragging": railDragging ? "true" : void 0,
15159
15162
  onPointerDown: handleRailPointerDown,
15160
15163
  onClick: handleRailClick,
15161
- className: "group/rail absolute inset-y-0 right-0 z-20 flex w-3 translate-x-1/2 cursor-ew-resize touch-none select-none items-center justify-center border-0 bg-transparent p-0",
15164
+ className: "group/rail absolute inset-y-0 end-0 z-20 flex w-3 translate-x-1/2 rtl:-translate-x-1/2 cursor-ew-resize touch-none select-none items-center justify-center border-0 bg-transparent p-0",
15162
15165
  children: [
15163
- /* @__PURE__ */ jsx("span", { className: "absolute inset-y-0 right-1/2 w-0.5 translate-x-1/2 bg-sidebar-ring opacity-0 transition-opacity duration-150 group-hover/rail:opacity-100 group-data-[dragging=true]/rail:opacity-100" }),
15166
+ /* @__PURE__ */ jsx("span", { className: "absolute inset-y-0 end-1/2 w-0.5 translate-x-1/2 rtl:-translate-x-1/2 bg-sidebar-ring opacity-0 transition-opacity duration-150 group-hover/rail:opacity-100 group-data-[dragging=true]/rail:opacity-100" }),
15164
15167
  /* @__PURE__ */ jsx("span", { className: "relative h-9 w-1 rounded-full bg-sidebar-border transition-all duration-150 group-hover/rail:h-12 group-hover/rail:bg-sidebar-ring group-data-[dragging=true]/rail:bg-sidebar-ring" })
15165
15168
  ]
15166
15169
  }
@@ -15172,8 +15175,8 @@ function NSidebar({
15172
15175
  onClick: handleToggleCollapsed,
15173
15176
  "aria-label": collapsed ? expandLabel : collapseLabel,
15174
15177
  title: collapsed ? expandLabel : collapseLabel,
15175
- className: "absolute right-0 top-7 z-20 flex size-6 -translate-y-1/2 translate-x-1/2 cursor-pointer items-center justify-center rounded-full border border-sidebar-border bg-sidebar text-sidebar-foreground shadow-sm transition-colors hover:bg-sidebar-accent hover:text-sidebar-accent-foreground",
15176
- children: desktopCollapsed ? /* @__PURE__ */ jsx(ChevronRight, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ jsx(ChevronLeft, { className: "h-3.5 w-3.5" })
15178
+ className: "absolute end-0 top-7 z-20 flex size-6 -translate-y-1/2 translate-x-1/2 rtl:-translate-x-1/2 cursor-pointer items-center justify-center rounded-full border border-sidebar-border bg-sidebar text-sidebar-foreground shadow-sm transition-colors hover:bg-sidebar-accent hover:text-sidebar-accent-foreground",
15179
+ children: desktopCollapsed ? /* @__PURE__ */ jsx(ChevronRight, { className: "h-3.5 w-3.5 rtl:-scale-x-100" }) : /* @__PURE__ */ jsx(ChevronLeft, { className: "h-3.5 w-3.5 rtl:-scale-x-100" })
15177
15180
  }
15178
15181
  )
15179
15182
  ]
package/dist/json.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  export { NTableJson } from './chunk-5JVFMOLI.mjs';
2
- import { Button } from './chunk-ONE7GLIH.mjs';
2
+ import { Button } from './chunk-M5VGBZ7R.mjs';
3
3
  import { cn } from './chunk-LK3SMYUP.mjs';
4
4
  import './chunk-TFHWLE7N.mjs';
5
5
  import { useMemo, useRef, useCallback } from 'react';
package/dist/theme.css CHANGED
@@ -26,7 +26,7 @@
26
26
  @source inline("{sm,md,lg,xl,2xl}:table-cell");
27
27
  @source inline("border-{black,white}");
28
28
  @source inline("border-{gray,slate,zinc,neutral,stone,red,orange,amber,yellow,green,teal,blue,indigo,purple}{,-600}");
29
- @source inline("najm-border najm-border-t najm-border-r najm-border-b najm-border-l");
29
+ @source inline("najm-border najm-border-t najm-border-r najm-border-b najm-border-l najm-border-s najm-border-e");
30
30
 
31
31
  /* NGrid / NGridItem build column and span classes dynamically. */
32
32
  @source inline("grid-cols-{1,2,3,4,5,6,7,8,9,10,11,12}");
@@ -281,6 +281,16 @@ input:autofill {
281
281
  border-left-width: var(--border-width);
282
282
  }
283
283
 
284
+ .najm-border-s {
285
+ border-inline-start-style: solid;
286
+ border-inline-start-width: var(--border-width);
287
+ }
288
+
289
+ .najm-border-e {
290
+ border-inline-end-style: solid;
291
+ border-inline-end-width: var(--border-width);
292
+ }
293
+
284
294
  [data-radix-popper-content-wrapper] {
285
295
  z-index: 10000 !important;
286
296
  }
@@ -307,10 +317,10 @@ input:autofill {
307
317
  overflow-x: auto;
308
318
  scrollbar-width: none;
309
319
  }
310
- .najm-overlay-scroll-x::-webkit-scrollbar {
311
- display: none;
312
- }
313
-
320
+ .najm-overlay-scroll-x::-webkit-scrollbar {
321
+ display: none;
322
+ }
323
+
314
324
  /* Responsive table actions stay discoverable on touch and tablet layouts.
315
325
  Fine-pointer desktops may keep the quieter hover/focus reveal treatment. */
316
326
  .ntable-card-action {
@@ -367,7 +377,7 @@ input:autofill {
367
377
  .nimage-input-compact-overlay:focus-visible {
368
378
  opacity: 1;
369
379
  }
370
- }
380
+ }
371
381
 
372
382
  /* OverlayScrollbars theme used by the <NajmScroll> component — a thin,
373
383
  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.9",
3
+ "version": "2.11.11",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "description": "Reusable React UI component package for Najm framework",