najm-kit 2.11.8 → 2.11.10

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,4 +1,36 @@
1
- # Changelog
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
17
+
18
+ - Fixed card grids that paginate client-side rendering their entire dataset on
19
+ one page. `useTable` pinned an uncontrolled paged card list to `data.length`,
20
+ a branch that predates the container measurement added in 2.2.0 and was never
21
+ reconciled with it: `calculatedCardPageSize` was measured and published, but
22
+ only ever applied to a server-paginated grid. A 500-row list rendered 500
23
+ cards on page one, reported a single page, and showed 500 as the current
24
+ Rows/page value. The measured size is now applied to an uncontrolled card grid
25
+ too, through the guards that already keep a server-paginated one stable —
26
+ geometry bucketing, the per-container report budget, and the deferral until
27
+ real cards have been measured. That loop is a property of the measurement
28
+ rather than of fetching: page size decides which cards render, and rendered
29
+ cards are what card height is measured from. Rendering every supplied row
30
+ stays the behavior wherever there is nothing to measure against, so
31
+ `dynamicHeight={false}` and a container that has not yet reported a layout are
32
+ unchanged, and a controlled `pagination` prop or an explicit Rows/page choice
33
+ still wins.
2
34
 
3
35
  ## 2.11.8 - 2026-08-28
4
36
 
@@ -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
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
@@ -12207,15 +12209,17 @@ function useTable(effectiveViewModeOverride) {
12207
12209
  useLayoutEffect(() => {
12208
12210
  if (manualPagination || isPaginationControlled || isPageSizeUserSelected) return;
12209
12211
  if (dynamicHeight && renderedMode === "table") table.setPageSize(calculatedPageSize);
12210
- if (viewMode === "cards" && cardPagination.mode === "paged") {
12212
+ const cardsAreUnmeasured = !dynamicHeight || !hasMeasuredLayout;
12213
+ if (viewMode === "cards" && cardPagination.mode === "paged" && cardsAreUnmeasured) {
12211
12214
  table.setPageSize(data.length || 9999);
12212
12215
  }
12213
- }, [calculatedPageSize, dynamicHeight, renderedMode, viewMode, cardPagination.mode, table, data.length, manualPagination, isPaginationControlled, isPageSizeUserSelected]);
12216
+ }, [calculatedPageSize, dynamicHeight, hasMeasuredLayout, renderedMode, viewMode, cardPagination.mode, table, data.length, manualPagination, isPaginationControlled, isPageSizeUserSelected]);
12214
12217
  const dynamicPageSizeTarget = renderedMode === "cards" ? calculatedCardPageSize : calculatedPageSize;
12215
12218
  const geometryKey = `${Math.round(measuredBodyWidth / GEOMETRY_BUCKET_PX)}x${Math.round(measuredBodyHeight / GEOMETRY_BUCKET_PX)}`;
12216
12219
  const reportedGeometryRef = useRef(null);
12217
12220
  useLayoutEffect(() => {
12218
- if (!manualPagination || !dynamicHeight || isPageSizeUserSelected) return;
12221
+ if (!dynamicHeight || isPageSizeUserSelected) return;
12222
+ if (!manualPagination && (isPaginationControlled || renderedMode !== "cards")) return;
12219
12223
  if (cardPagination.mode !== "paged") return;
12220
12224
  if (!hasMeasuredLayout || measuredBodyHeight <= 0) return;
12221
12225
  if (!dynamicPageSizeTarget || dynamicPageSizeTarget < 1) return;
@@ -12237,6 +12241,7 @@ function useTable(effectiveViewModeOverride) {
12237
12241
  return () => clearTimeout(timer);
12238
12242
  }, [
12239
12243
  manualPagination,
12244
+ isPaginationControlled,
12240
12245
  dynamicHeight,
12241
12246
  isPageSizeUserSelected,
12242
12247
  cardPagination.mode,
@@ -13348,7 +13353,7 @@ function CardLoadMorePagination({
13348
13353
  }
13349
13354
  );
13350
13355
  }
13351
- 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";
13352
13357
  var chevronClass = "h-4 w-4 rtl:-scale-x-100";
13353
13358
  function useLowerBoundPageCountWarning(manualPagination, pageCount, pagination) {
13354
13359
  const previous = React66__default.useRef(null);
@@ -14527,7 +14532,7 @@ function NSidebarBrand({ logo, collapsed, linkComponent: Link, className }) {
14527
14532
  ] }) : null
14528
14533
  ] });
14529
14534
  const wrapper = cn(
14530
- "flex min-w-0 items-center gap-2.5 text-left",
14535
+ "flex min-w-0 items-center gap-2.5 text-start",
14531
14536
  !collapsed && !showText && !isChip && "mx-auto"
14532
14537
  );
14533
14538
  const interactive = "cursor-pointer transition-opacity hover:opacity-80";
@@ -14563,9 +14568,9 @@ function NSidebarItem({
14563
14568
  if (childActive) setOpen(true);
14564
14569
  }, [childActive]);
14565
14570
  const baseClasses = cn(
14566
- "flex items-center gap-3 w-full rounded-md text-sm px-2 font-medium transition-colors h-8 text-left",
14567
- depth > 0 && "pl-7",
14568
- 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))]",
14569
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",
14570
14575
  classNames?.sidebarItem
14571
14576
  );
@@ -14584,7 +14589,7 @@ function NSidebarItem({
14584
14589
  Icon2 && /* @__PURE__ */ jsx(Icon2, { className: "h-4 w-4 shrink-0" }),
14585
14590
  !collapsed && /* @__PURE__ */ jsxs(Fragment, { children: [
14586
14591
  /* @__PURE__ */ jsx("span", { className: "flex-1 truncate", children: item.label }),
14587
- 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 }),
14588
14593
  hasChildren && /* @__PURE__ */ jsx(
14589
14594
  ChevronDown,
14590
14595
  {
@@ -14714,7 +14719,7 @@ function DefaultFooter({
14714
14719
  collapsed = false
14715
14720
  }) {
14716
14721
  if (!onSettings && !onLogout) return null;
14717
- 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";
14718
14723
  return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-0.5", children: [
14719
14724
  onSettings && /* @__PURE__ */ jsxs("button", { type: "button", onClick: onSettings, className: itemClass, "aria-label": settingsLabel, title: settingsLabel, children: [
14720
14725
  /* @__PURE__ */ jsx(Settings, { className: "h-4 w-4 shrink-0" }),
@@ -14755,12 +14760,12 @@ function NSidebarFooter({
14755
14760
  onClick: onToggleCollapsed,
14756
14761
  className: cn(
14757
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",
14758
- "gap-3 px-2 text-left"
14763
+ "gap-3 px-2 text-start"
14759
14764
  ),
14760
14765
  "aria-label": collapsed ? expandLabel : collapseLabel,
14761
14766
  title: collapsed ? expandLabel : collapseLabel,
14762
14767
  children: [
14763
- /* @__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" }),
14764
14769
  !collapsed && /* @__PURE__ */ jsx("span", { className: "flex-1 truncate", children: collapseLabel })
14765
14770
  ]
14766
14771
  }
@@ -14788,7 +14793,7 @@ function NSidebarMobile({
14788
14793
  type: "button",
14789
14794
  onClick: onOpen,
14790
14795
  className: cn(
14791
- "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",
14792
14797
  mobileClass,
14793
14798
  hamburgerClassName,
14794
14799
  open && "hidden"
@@ -14810,10 +14815,10 @@ function NSidebarMobile({
14810
14815
  {
14811
14816
  "data-bordered": bordered === false ? "false" : bordered ? "true" : void 0,
14812
14817
  className: cn(
14813
- "fixed inset-y-0 left-0 z-50 bg-sidebar text-sidebar-foreground flex flex-col transition-transform duration-200",
14814
- 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"),
14815
14820
  mobileClass,
14816
- open ? "translate-x-0" : "-translate-x-full"
14821
+ open ? "translate-x-0" : "-translate-x-full rtl:translate-x-full"
14817
14822
  ),
14818
14823
  style: { width },
14819
14824
  children: [
@@ -14822,7 +14827,7 @@ function NSidebarMobile({
14822
14827
  {
14823
14828
  type: "button",
14824
14829
  onClick: onClose,
14825
- 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",
14826
14831
  "aria-label": closeLabel,
14827
14832
  children: /* @__PURE__ */ jsx(X, { className: "h-4 w-4" })
14828
14833
  }
@@ -14979,13 +14984,14 @@ function NSidebar({
14979
14984
  }, [collapsed, setCollapsedState]);
14980
14985
  const handleRailPointerDown = useCallback((e) => {
14981
14986
  if (e.button !== 0) return;
14987
+ const inlineSign = getComputedStyle(e.currentTarget).direction === "rtl" ? -1 : 1;
14982
14988
  const startX = e.clientX;
14983
14989
  const startCollapsed = collapsed;
14984
14990
  const threshold = 24;
14985
14991
  let resolved = false;
14986
14992
  setRailDragging(true);
14987
14993
  const onMove = (ev) => {
14988
- const dx = ev.clientX - startX;
14994
+ const dx = (ev.clientX - startX) * inlineSign;
14989
14995
  if (!resolved && !startCollapsed && dx < -threshold) {
14990
14996
  resolved = true;
14991
14997
  suppressRailClickRef.current = true;
@@ -15134,7 +15140,7 @@ function NSidebar({
15134
15140
  className: cn(
15135
15141
  "relative z-10 flex flex-col h-full bg-sidebar text-sidebar-foreground transition-all duration-200 shrink-0",
15136
15142
  desktopClass,
15137
- sidebarBorderClasses(bordered, "right"),
15143
+ sidebarBorderClasses(bordered, "end"),
15138
15144
  classNames?.sidebar,
15139
15145
  className
15140
15146
  ),
@@ -15142,7 +15148,7 @@ function NSidebar({
15142
15148
  width: desktopCollapsed ? collapsedWidth : expandedWidth,
15143
15149
  ["--rail"]: railVar,
15144
15150
  ["--sidebar-edge-width"]: sidebarEdgeWidth,
15145
- ...bordered !== false && recipe?.borderWidth ? { borderRightWidth: recipe.borderWidth } : {}
15151
+ ...bordered !== false && recipe?.borderWidth ? { borderInlineEndWidth: recipe.borderWidth } : {}
15146
15152
  },
15147
15153
  children: [
15148
15154
  sidebarInner,
@@ -15155,9 +15161,9 @@ function NSidebar({
15155
15161
  "data-dragging": railDragging ? "true" : void 0,
15156
15162
  onPointerDown: handleRailPointerDown,
15157
15163
  onClick: handleRailClick,
15158
- 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",
15159
15165
  children: [
15160
- /* @__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" }),
15161
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" })
15162
15168
  ]
15163
15169
  }
@@ -15169,8 +15175,8 @@ function NSidebar({
15169
15175
  onClick: handleToggleCollapsed,
15170
15176
  "aria-label": collapsed ? expandLabel : collapseLabel,
15171
15177
  title: collapsed ? expandLabel : collapseLabel,
15172
- 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",
15173
- 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" })
15174
15180
  }
15175
15181
  )
15176
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.8",
3
+ "version": "2.11.10",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "description": "Reusable React UI component package for Najm framework",