najm-kit 2.1.8 → 2.1.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/dist/index.d.ts CHANGED
@@ -489,6 +489,10 @@ interface NPageHeaderProps {
489
489
  top?: ReactNode;
490
490
  /** Must match the paired NSidebar breakpoint so its hamburger has reserved space. */
491
491
  mobileBreakpoint?: NPageHeaderBreakpoint;
492
+ /** Renders the mobile sidebar trigger inside the header's leading column. */
493
+ onSidebarOpen?: () => void;
494
+ sidebarTriggerLabel?: string;
495
+ sidebarTriggerClassName?: string;
492
496
  search?: InputHTMLAttributes<HTMLInputElement> & {
493
497
  placeholder?: string;
494
498
  ref?: Ref<HTMLInputElement>;
@@ -516,7 +520,7 @@ declare function NPageHeaderTop({ children, className }: PageHeaderSlotProps): r
516
520
  declare namespace NPageHeaderTop {
517
521
  var displayName: string;
518
522
  }
519
- declare function NPageHeader({ icon: Icon, title, subtitle, actions, compactActions, filters, top, mobileBreakpoint, search, children, className, headerClassName, card, bordered, }: NPageHeaderProps): react_jsx_runtime.JSX.Element;
523
+ declare function NPageHeader({ icon: Icon, title, subtitle, actions, compactActions, filters, top, mobileBreakpoint, onSidebarOpen, sidebarTriggerLabel, sidebarTriggerClassName, search, children, className, headerClassName, card, bordered, }: NPageHeaderProps): react_jsx_runtime.JSX.Element;
520
524
 
521
525
  type DialogActionMode = "auto" | "dialog" | "content";
522
526
  type DialogVariant = "default" | "window";
@@ -3236,6 +3240,11 @@ interface SidebarProps {
3236
3240
  className?: string;
3237
3241
  classNames?: NAppShellClassNames;
3238
3242
  mobileBreakpoint?: 'sm' | 'md' | 'lg';
3243
+ /**
3244
+ * Automatically use the collapsed desktop rail within one Tailwind
3245
+ * breakpoint band. For example, `lg` collapses from 1024px through 1279px.
3246
+ */
3247
+ autoCollapseAt?: 'sm' | 'md' | 'lg' | 'xl';
3239
3248
  mobileOpen?: boolean;
3240
3249
  defaultMobileOpen?: boolean;
3241
3250
  onMobileOpenChange?: (open: boolean) => void;
@@ -3245,6 +3254,10 @@ interface SidebarProps {
3245
3254
  collapseLabel?: string;
3246
3255
  expandLabel?: string;
3247
3256
  hamburgerClassName?: string;
3257
+ /**
3258
+ * Opts into the legacy fixed standalone trigger. Prefer controlling
3259
+ * `mobileOpen` from an NPageHeader via its `onSidebarOpen` prop.
3260
+ */
3248
3261
  showHamburgerButton?: boolean;
3249
3262
  logoIcon?: ComponentType<{
3250
3263
  className?: string;
@@ -3349,7 +3362,7 @@ declare function NSidebarFooter({ children, onSettings, settingsLabel, onLogout,
3349
3362
 
3350
3363
  declare function NSidebarMobile({ open, onOpen, onClose, mobileBreakpoint, width, hamburgerLabel, closeLabel, hamburgerClassName, showHamburgerButton, children, bordered, }: NSidebarMobileProps): react_jsx_runtime.JSX.Element;
3351
3364
 
3352
- declare function NSidebar({ logo, navItems, activePath, isActive, onNavigate, linkComponent, collapsed: collapsedProp, defaultCollapsed, onCollapsedChange, showCollapseButton, collapseButtonPosition, showSectionLabels, showSectionIcons, showSectionSeparators, bordered, footer, className, classNames, mobileBreakpoint, mobileOpen: mobileOpenProp, defaultMobileOpen, onMobileOpenChange, closeOnNavigate, hamburgerLabel, closeLabel, collapseLabel, expandLabel, hamburgerClassName, showHamburgerButton, logoIcon, logoTitle, logoSubtitle, onLogoClick, onSettings, settingsLabel, onLogout, logoutLabel, widths, }: SidebarProps): react_jsx_runtime.JSX.Element;
3365
+ declare function NSidebar({ logo, navItems, activePath, isActive, onNavigate, linkComponent, collapsed: collapsedProp, defaultCollapsed, onCollapsedChange, showCollapseButton, collapseButtonPosition, showSectionLabels, showSectionIcons, showSectionSeparators, bordered, footer, className, classNames, mobileBreakpoint, autoCollapseAt, mobileOpen: mobileOpenProp, defaultMobileOpen, onMobileOpenChange, closeOnNavigate, hamburgerLabel, closeLabel, collapseLabel, expandLabel, hamburgerClassName, showHamburgerButton, logoIcon, logoTitle, logoSubtitle, onLogoClick, onSettings, settingsLabel, onLogout, logoutLabel, widths, }: SidebarProps): react_jsx_runtime.JSX.Element;
3353
3366
 
3354
3367
  declare function NSidebarItem({ item, activePath, isActive, onNavigate, linkComponent: LinkComponent, collapsed, depth, classNames, }: SidebarItemProps): react_jsx_runtime.JSX.Element;
3355
3368
 
package/dist/index.mjs CHANGED
@@ -3,7 +3,7 @@ import React__default, { createContext, useContext, useCallback, useEffect, useS
3
3
  import { Slot } from '@radix-ui/react-slot';
4
4
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
5
5
  import * as LucideIcons from 'lucide-react';
6
- import { ChevronDown, AlertTriangle, RefreshCw, LoaderCircleIcon, X, XIcon, Search, ChevronRightIcon, CheckIcon, CircleIcon, ChevronDownIcon, ChevronUpIcon, ChevronLeftIcon, SearchIcon, Table as Table$1, FileJson, ChevronRight, CheckSquare, FilePlus, FolderPlus, Trash2, Share2, Move, ClipboardPaste, Copy, Scissors, Pencil, Download, Eye, ArrowUpDown, Loader2, ChevronUp, Folder, EyeOff, ChevronsUpDown, Check, Calendar as Calendar$1, FileUp, UploadCloud, CheckCircle2, AlertCircle, Star, Globe, Clock, Upload, Plus, MoreVertical, Edit, ChevronsLeft, ChevronLeft, ChevronsRight, Merge, PanelLeftOpen, PanelLeftClose, Menu, LogOut, Image, ArrowUp, ArrowDown, LoaderPinwheelIcon, LoaderIcon, ArrowUpRight, ArrowDownRight, SlidersHorizontal, Columns3, Settings, SearchX, Inbox, List, LayoutGrid, Code, FolderOpen } from 'lucide-react';
6
+ import { ChevronDown, AlertTriangle, RefreshCw, LoaderCircleIcon, X, XIcon, Menu, Search, ChevronRightIcon, CheckIcon, CircleIcon, ChevronDownIcon, ChevronUpIcon, ChevronLeftIcon, SearchIcon, Table as Table$1, FileJson, ChevronRight, CheckSquare, FilePlus, FolderPlus, Trash2, Share2, Move, ClipboardPaste, Copy, Scissors, Pencil, Download, Eye, ArrowUpDown, Loader2, ChevronUp, Folder, EyeOff, ChevronsUpDown, Check, Calendar as Calendar$1, FileUp, UploadCloud, CheckCircle2, AlertCircle, Star, Globe, Clock, Upload, Plus, MoreVertical, Edit, ChevronsLeft, ChevronLeft, ChevronsRight, Merge, PanelLeftOpen, PanelLeftClose, LogOut, Image, ArrowUp, ArrowDown, LoaderPinwheelIcon, LoaderIcon, ArrowUpRight, ArrowDownRight, SlidersHorizontal, Columns3, Settings, SearchX, Inbox, List, LayoutGrid, Code, FolderOpen } from 'lucide-react';
7
7
  import { cva } from 'class-variance-authority';
8
8
  import { clsx } from 'clsx';
9
9
  import { twMerge } from 'tailwind-merge';
@@ -2002,21 +2002,30 @@ var responsiveClasses = {
2002
2002
  identity: "sm:col-start-auto sm:row-start-auto sm:justify-self-auto",
2003
2003
  controls: "sm:col-start-auto sm:row-start-auto sm:justify-self-auto",
2004
2004
  fullActions: "sm:flex",
2005
- compactActions: "sm:hidden"
2005
+ compactActions: "sm:hidden",
2006
+ sidebarTrigger: "sm:hidden",
2007
+ icon: "sm:flex",
2008
+ subtitle: "sm:block"
2006
2009
  },
2007
2010
  md: {
2008
2011
  main: "md:flex md:justify-between md:px-5",
2009
2012
  identity: "md:col-start-auto md:row-start-auto md:justify-self-auto",
2010
2013
  controls: "md:col-start-auto md:row-start-auto md:justify-self-auto",
2011
2014
  fullActions: "md:flex",
2012
- compactActions: "md:hidden"
2015
+ compactActions: "md:hidden",
2016
+ sidebarTrigger: "md:hidden",
2017
+ icon: "md:flex",
2018
+ subtitle: "md:block"
2013
2019
  },
2014
2020
  lg: {
2015
2021
  main: "lg:flex lg:justify-between lg:px-5",
2016
2022
  identity: "lg:col-start-auto lg:row-start-auto lg:justify-self-auto",
2017
2023
  controls: "lg:col-start-auto lg:row-start-auto lg:justify-self-auto",
2018
2024
  fullActions: "lg:flex",
2019
- compactActions: "lg:hidden"
2025
+ compactActions: "lg:hidden",
2026
+ sidebarTrigger: "lg:hidden",
2027
+ icon: "lg:flex",
2028
+ subtitle: "lg:block"
2020
2029
  }
2021
2030
  };
2022
2031
  function NPageHeader({
@@ -2028,6 +2037,9 @@ function NPageHeader({
2028
2037
  filters,
2029
2038
  top,
2030
2039
  mobileBreakpoint = "md",
2040
+ onSidebarOpen,
2041
+ sidebarTriggerLabel = "Open sidebar",
2042
+ sidebarTriggerClassName,
2031
2043
  search,
2032
2044
  children,
2033
2045
  className,
@@ -2081,6 +2093,23 @@ function NPageHeader({
2081
2093
  headerClassName
2082
2094
  ),
2083
2095
  children: [
2096
+ onSidebarOpen && /* @__PURE__ */ jsx(
2097
+ Button,
2098
+ {
2099
+ type: "button",
2100
+ variant: "ghost",
2101
+ size: "icon",
2102
+ onClick: onSidebarOpen,
2103
+ "aria-label": sidebarTriggerLabel,
2104
+ "data-slot": "page-header-sidebar-trigger",
2105
+ className: cn(
2106
+ "col-start-1 row-start-1 justify-self-start",
2107
+ breakpointClasses.sidebarTrigger,
2108
+ sidebarTriggerClassName
2109
+ ),
2110
+ children: /* @__PURE__ */ jsx(Menu, { className: "h-5 w-5" })
2111
+ }
2112
+ ),
2084
2113
  /* @__PURE__ */ jsxs(
2085
2114
  "div",
2086
2115
  {
@@ -2090,10 +2119,10 @@ function NPageHeader({
2090
2119
  breakpointClasses.identity
2091
2120
  ),
2092
2121
  children: [
2093
- /* @__PURE__ */ jsx("div", { className: "flex h-8 w-8 shrink-0 rounded-lg bg-primary/10 items-center justify-center", children: /* @__PURE__ */ jsx(Icon2, { className: "h-4 w-4 text-primary" }) }),
2122
+ /* @__PURE__ */ jsx("div", { className: cn("hidden h-8 w-8 shrink-0 rounded-lg bg-primary/10 items-center justify-center", breakpointClasses.icon), children: /* @__PURE__ */ jsx(Icon2, { className: "h-4 w-4 text-primary" }) }),
2094
2123
  /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
2095
2124
  /* @__PURE__ */ jsx("h2", { className: "truncate text-sm font-semibold text-foreground", children: title }),
2096
- subtitle && /* @__PURE__ */ jsx("p", { className: "truncate text-xs leading-relaxed text-muted-foreground sm:text-sm sm:leading-normal", children: subtitle })
2125
+ subtitle && /* @__PURE__ */ jsx("p", { className: cn("hidden truncate text-xs leading-relaxed text-muted-foreground sm:text-sm sm:leading-normal", breakpointClasses.subtitle), children: subtitle })
2097
2126
  ] })
2098
2127
  ]
2099
2128
  }
@@ -11000,6 +11029,27 @@ function buildGroups(items) {
11000
11029
  }
11001
11030
  return groups;
11002
11031
  }
11032
+ var autoCollapseQueries = {
11033
+ sm: "(min-width: 640px) and (max-width: 767.98px)",
11034
+ md: "(min-width: 768px) and (max-width: 1023.98px)",
11035
+ lg: "(min-width: 1024px) and (max-width: 1279.98px)",
11036
+ xl: "(min-width: 1280px) and (max-width: 1535.98px)"
11037
+ };
11038
+ function useAutoCollapsed(breakpoint) {
11039
+ const [matches, setMatches] = useState(false);
11040
+ useEffect(() => {
11041
+ if (!breakpoint || typeof window === "undefined") {
11042
+ setMatches(false);
11043
+ return;
11044
+ }
11045
+ const mediaQuery = window.matchMedia(autoCollapseQueries[breakpoint]);
11046
+ const update = () => setMatches(mediaQuery.matches);
11047
+ update();
11048
+ mediaQuery.addEventListener?.("change", update);
11049
+ return () => mediaQuery.removeEventListener?.("change", update);
11050
+ }, [breakpoint]);
11051
+ return matches;
11052
+ }
11003
11053
  function NSidebar({
11004
11054
  logo,
11005
11055
  navItems = [],
@@ -11020,6 +11070,7 @@ function NSidebar({
11020
11070
  className,
11021
11071
  classNames,
11022
11072
  mobileBreakpoint = "md",
11073
+ autoCollapseAt,
11023
11074
  mobileOpen: mobileOpenProp,
11024
11075
  defaultMobileOpen = false,
11025
11076
  onMobileOpenChange,
@@ -11029,7 +11080,7 @@ function NSidebar({
11029
11080
  collapseLabel = "Collapse",
11030
11081
  expandLabel = "Expand",
11031
11082
  hamburgerClassName,
11032
- showHamburgerButton = true,
11083
+ showHamburgerButton = false,
11033
11084
  logoIcon,
11034
11085
  logoTitle,
11035
11086
  logoSubtitle,
@@ -11046,6 +11097,8 @@ function NSidebar({
11046
11097
  const isControlled = mobileOpenProp !== void 0;
11047
11098
  const mobileOpen = isControlled ? mobileOpenProp : _mobileOpen;
11048
11099
  const collapsed = collapsedProp ?? _collapsed;
11100
+ const autoCollapsed = useAutoCollapsed(autoCollapseAt);
11101
+ const desktopCollapsed = collapsed || autoCollapsed;
11049
11102
  const setMobileOpen = (open) => {
11050
11103
  if (!isControlled) _setMobileOpen(open);
11051
11104
  onMobileOpenChange?.(open);
@@ -11106,21 +11159,23 @@ function NSidebar({
11106
11159
  const mobileWidth = widths?.mobile ?? expandedWidth;
11107
11160
  const railVar = typeof collapsedWidth === "number" ? `${collapsedWidth}px` : collapsedWidth;
11108
11161
  const sidebarEdgeWidth = bordered === false ? "0px" : recipe?.borderWidth ?? "var(--border-width, 1px)";
11109
- const showEdgeCollapse = showCollapseButton && collapseButtonPosition === "edge";
11110
- const showRailCollapse = showCollapseButton && collapseButtonPosition === "rail";
11162
+ const showEdgeCollapse = showCollapseButton && collapseButtonPosition === "edge" && !autoCollapsed;
11163
+ const showRailCollapse = showCollapseButton && collapseButtonPosition === "rail" && !autoCollapsed;
11111
11164
  const effectiveShowSectionLabels = showSectionLabels ?? recipe?.showSectionLabels ?? true;
11112
11165
  const effectiveShowSectionSeparators = showSectionSeparators ?? recipe?.showSectionSeparators ?? false;
11113
11166
  const contentSlot = recipe?.slots?.content;
11114
11167
  const contentStyle = contentSlot?.paddingTop ? { paddingTop: contentSlot.paddingTop } : void 0;
11115
- const defaultLogoContent = logoIcon || logoTitle || logoSubtitle ? /* @__PURE__ */ jsx(NSidebarLogo, { icon: logoIcon, title: logoTitle, subtitle: logoSubtitle, onClick: onLogoClick, collapsed }) : null;
11116
- const headerContent = logo ?? defaultLogoContent;
11168
+ const desktopDefaultLogoContent = logoIcon || logoTitle || logoSubtitle ? /* @__PURE__ */ jsx(NSidebarLogo, { icon: logoIcon, title: logoTitle, subtitle: logoSubtitle, onClick: onLogoClick, collapsed: desktopCollapsed }) : null;
11169
+ const mobileDefaultLogoContent = logoIcon || logoTitle || logoSubtitle ? /* @__PURE__ */ jsx(NSidebarLogo, { icon: logoIcon, title: logoTitle, subtitle: logoSubtitle, onClick: onLogoClick, collapsed: false }) : null;
11170
+ const desktopHeaderContent = logo ?? desktopDefaultLogoContent;
11171
+ const mobileHeaderContent = logo ?? mobileDefaultLogoContent;
11117
11172
  const contentProps = {
11118
11173
  groups,
11119
11174
  activePath,
11120
11175
  isActive,
11121
11176
  onNavigate: handleNavigate,
11122
11177
  linkComponent,
11123
- collapsed,
11178
+ collapsed: desktopCollapsed,
11124
11179
  showSectionLabels: effectiveShowSectionLabels,
11125
11180
  showSectionIcons,
11126
11181
  showSectionSeparators: effectiveShowSectionSeparators,
@@ -11133,22 +11188,22 @@ function NSidebar({
11133
11188
  settingsLabel,
11134
11189
  onLogout,
11135
11190
  logoutLabel,
11136
- showCollapseButton: showCollapseButton && collapseButtonPosition === "footer",
11137
- collapsed,
11191
+ showCollapseButton: showCollapseButton && collapseButtonPosition === "footer" && !autoCollapsed,
11192
+ collapsed: desktopCollapsed,
11138
11193
  onToggleCollapsed: handleToggleCollapsed,
11139
11194
  collapseLabel,
11140
11195
  expandLabel,
11141
11196
  classNames
11142
11197
  };
11143
11198
  const sidebarInner = /* @__PURE__ */ jsxs(Fragment, { children: [
11144
- headerContent && /* @__PURE__ */ jsx(NSidebarHeader, { collapsed, classNames, children: headerContent }),
11199
+ desktopHeaderContent && /* @__PURE__ */ jsx(NSidebarHeader, { collapsed: desktopCollapsed, classNames, children: desktopHeaderContent }),
11145
11200
  /* @__PURE__ */ jsx(NSidebarContent, { ...contentProps }),
11146
11201
  /* @__PURE__ */ jsx(NSidebarFooter, { ...footerProps })
11147
11202
  ] });
11148
11203
  const mobileInner = /* @__PURE__ */ jsxs(Fragment, { children: [
11149
- headerContent && /* @__PURE__ */ jsx(NSidebarHeader, { collapsed, classNames, children: headerContent }),
11150
- /* @__PURE__ */ jsx(NSidebarContent, { ...contentProps }),
11151
- /* @__PURE__ */ jsx(NSidebarFooter, { ...footerProps, isMobile: true })
11204
+ mobileHeaderContent && /* @__PURE__ */ jsx(NSidebarHeader, { collapsed: false, classNames, children: mobileHeaderContent }),
11205
+ /* @__PURE__ */ jsx(NSidebarContent, { ...contentProps, collapsed: false }),
11206
+ /* @__PURE__ */ jsx(NSidebarFooter, { ...footerProps, collapsed: false, isMobile: true })
11152
11207
  ] });
11153
11208
  return /* @__PURE__ */ jsxs(Fragment, { children: [
11154
11209
  /* @__PURE__ */ jsx(
@@ -11171,6 +11226,8 @@ function NSidebar({
11171
11226
  "aside",
11172
11227
  {
11173
11228
  "data-bordered": bordered === false ? "false" : bordered ? "true" : void 0,
11229
+ "data-collapsed": desktopCollapsed ? "true" : "false",
11230
+ "data-auto-collapsed": autoCollapsed ? "true" : void 0,
11174
11231
  className: cn(
11175
11232
  "relative z-10 flex flex-col h-full bg-sidebar text-sidebar-foreground transition-all duration-200",
11176
11233
  desktopClass,
@@ -11179,7 +11236,7 @@ function NSidebar({
11179
11236
  className
11180
11237
  ),
11181
11238
  style: {
11182
- width: collapsed ? collapsedWidth : expandedWidth,
11239
+ width: desktopCollapsed ? collapsedWidth : expandedWidth,
11183
11240
  ["--rail"]: railVar,
11184
11241
  ["--sidebar-edge-width"]: sidebarEdgeWidth,
11185
11242
  ...bordered !== false && recipe?.borderWidth ? { borderRightWidth: recipe.borderWidth } : {}
@@ -11190,8 +11247,8 @@ function NSidebar({
11190
11247
  "button",
11191
11248
  {
11192
11249
  type: "button",
11193
- "aria-label": collapsed ? expandLabel : collapseLabel,
11194
- title: collapsed ? expandLabel : collapseLabel,
11250
+ "aria-label": desktopCollapsed ? expandLabel : collapseLabel,
11251
+ title: desktopCollapsed ? expandLabel : collapseLabel,
11195
11252
  "data-dragging": railDragging ? "true" : void 0,
11196
11253
  onPointerDown: handleRailPointerDown,
11197
11254
  onClick: handleRailClick,
@@ -11210,7 +11267,7 @@ function NSidebar({
11210
11267
  "aria-label": collapsed ? expandLabel : collapseLabel,
11211
11268
  title: collapsed ? expandLabel : collapseLabel,
11212
11269
  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",
11213
- children: collapsed ? /* @__PURE__ */ jsx(ChevronRight, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ jsx(ChevronLeft, { className: "h-3.5 w-3.5" })
11270
+ children: desktopCollapsed ? /* @__PURE__ */ jsx(ChevronRight, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ jsx(ChevronLeft, { className: "h-3.5 w-3.5" })
11214
11271
  }
11215
11272
  )
11216
11273
  ]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "najm-kit",
3
- "version": "2.1.8",
3
+ "version": "2.1.10",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "description": "Reusable React UI component package for Najm framework",