najm-kit 2.1.8 → 2.1.9

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,24 @@ 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"
2006
2007
  },
2007
2008
  md: {
2008
2009
  main: "md:flex md:justify-between md:px-5",
2009
2010
  identity: "md:col-start-auto md:row-start-auto md:justify-self-auto",
2010
2011
  controls: "md:col-start-auto md:row-start-auto md:justify-self-auto",
2011
2012
  fullActions: "md:flex",
2012
- compactActions: "md:hidden"
2013
+ compactActions: "md:hidden",
2014
+ sidebarTrigger: "md:hidden"
2013
2015
  },
2014
2016
  lg: {
2015
2017
  main: "lg:flex lg:justify-between lg:px-5",
2016
2018
  identity: "lg:col-start-auto lg:row-start-auto lg:justify-self-auto",
2017
2019
  controls: "lg:col-start-auto lg:row-start-auto lg:justify-self-auto",
2018
2020
  fullActions: "lg:flex",
2019
- compactActions: "lg:hidden"
2021
+ compactActions: "lg:hidden",
2022
+ sidebarTrigger: "lg:hidden"
2020
2023
  }
2021
2024
  };
2022
2025
  function NPageHeader({
@@ -2028,6 +2031,9 @@ function NPageHeader({
2028
2031
  filters,
2029
2032
  top,
2030
2033
  mobileBreakpoint = "md",
2034
+ onSidebarOpen,
2035
+ sidebarTriggerLabel = "Open sidebar",
2036
+ sidebarTriggerClassName,
2031
2037
  search,
2032
2038
  children,
2033
2039
  className,
@@ -2081,6 +2087,23 @@ function NPageHeader({
2081
2087
  headerClassName
2082
2088
  ),
2083
2089
  children: [
2090
+ onSidebarOpen && /* @__PURE__ */ jsx(
2091
+ Button,
2092
+ {
2093
+ type: "button",
2094
+ variant: "ghost",
2095
+ size: "icon",
2096
+ onClick: onSidebarOpen,
2097
+ "aria-label": sidebarTriggerLabel,
2098
+ "data-slot": "page-header-sidebar-trigger",
2099
+ className: cn(
2100
+ "col-start-1 row-start-1 justify-self-start",
2101
+ breakpointClasses.sidebarTrigger,
2102
+ sidebarTriggerClassName
2103
+ ),
2104
+ children: /* @__PURE__ */ jsx(Menu, { className: "h-5 w-5" })
2105
+ }
2106
+ ),
2084
2107
  /* @__PURE__ */ jsxs(
2085
2108
  "div",
2086
2109
  {
@@ -11000,6 +11023,27 @@ function buildGroups(items) {
11000
11023
  }
11001
11024
  return groups;
11002
11025
  }
11026
+ var autoCollapseQueries = {
11027
+ sm: "(min-width: 640px) and (max-width: 767.98px)",
11028
+ md: "(min-width: 768px) and (max-width: 1023.98px)",
11029
+ lg: "(min-width: 1024px) and (max-width: 1279.98px)",
11030
+ xl: "(min-width: 1280px) and (max-width: 1535.98px)"
11031
+ };
11032
+ function useAutoCollapsed(breakpoint) {
11033
+ const [matches, setMatches] = useState(false);
11034
+ useEffect(() => {
11035
+ if (!breakpoint || typeof window === "undefined") {
11036
+ setMatches(false);
11037
+ return;
11038
+ }
11039
+ const mediaQuery = window.matchMedia(autoCollapseQueries[breakpoint]);
11040
+ const update = () => setMatches(mediaQuery.matches);
11041
+ update();
11042
+ mediaQuery.addEventListener?.("change", update);
11043
+ return () => mediaQuery.removeEventListener?.("change", update);
11044
+ }, [breakpoint]);
11045
+ return matches;
11046
+ }
11003
11047
  function NSidebar({
11004
11048
  logo,
11005
11049
  navItems = [],
@@ -11020,6 +11064,7 @@ function NSidebar({
11020
11064
  className,
11021
11065
  classNames,
11022
11066
  mobileBreakpoint = "md",
11067
+ autoCollapseAt,
11023
11068
  mobileOpen: mobileOpenProp,
11024
11069
  defaultMobileOpen = false,
11025
11070
  onMobileOpenChange,
@@ -11029,7 +11074,7 @@ function NSidebar({
11029
11074
  collapseLabel = "Collapse",
11030
11075
  expandLabel = "Expand",
11031
11076
  hamburgerClassName,
11032
- showHamburgerButton = true,
11077
+ showHamburgerButton = false,
11033
11078
  logoIcon,
11034
11079
  logoTitle,
11035
11080
  logoSubtitle,
@@ -11046,6 +11091,8 @@ function NSidebar({
11046
11091
  const isControlled = mobileOpenProp !== void 0;
11047
11092
  const mobileOpen = isControlled ? mobileOpenProp : _mobileOpen;
11048
11093
  const collapsed = collapsedProp ?? _collapsed;
11094
+ const autoCollapsed = useAutoCollapsed(autoCollapseAt);
11095
+ const desktopCollapsed = collapsed || autoCollapsed;
11049
11096
  const setMobileOpen = (open) => {
11050
11097
  if (!isControlled) _setMobileOpen(open);
11051
11098
  onMobileOpenChange?.(open);
@@ -11106,21 +11153,23 @@ function NSidebar({
11106
11153
  const mobileWidth = widths?.mobile ?? expandedWidth;
11107
11154
  const railVar = typeof collapsedWidth === "number" ? `${collapsedWidth}px` : collapsedWidth;
11108
11155
  const sidebarEdgeWidth = bordered === false ? "0px" : recipe?.borderWidth ?? "var(--border-width, 1px)";
11109
- const showEdgeCollapse = showCollapseButton && collapseButtonPosition === "edge";
11110
- const showRailCollapse = showCollapseButton && collapseButtonPosition === "rail";
11156
+ const showEdgeCollapse = showCollapseButton && collapseButtonPosition === "edge" && !autoCollapsed;
11157
+ const showRailCollapse = showCollapseButton && collapseButtonPosition === "rail" && !autoCollapsed;
11111
11158
  const effectiveShowSectionLabels = showSectionLabels ?? recipe?.showSectionLabels ?? true;
11112
11159
  const effectiveShowSectionSeparators = showSectionSeparators ?? recipe?.showSectionSeparators ?? false;
11113
11160
  const contentSlot = recipe?.slots?.content;
11114
11161
  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;
11162
+ const desktopDefaultLogoContent = logoIcon || logoTitle || logoSubtitle ? /* @__PURE__ */ jsx(NSidebarLogo, { icon: logoIcon, title: logoTitle, subtitle: logoSubtitle, onClick: onLogoClick, collapsed: desktopCollapsed }) : null;
11163
+ const mobileDefaultLogoContent = logoIcon || logoTitle || logoSubtitle ? /* @__PURE__ */ jsx(NSidebarLogo, { icon: logoIcon, title: logoTitle, subtitle: logoSubtitle, onClick: onLogoClick, collapsed: false }) : null;
11164
+ const desktopHeaderContent = logo ?? desktopDefaultLogoContent;
11165
+ const mobileHeaderContent = logo ?? mobileDefaultLogoContent;
11117
11166
  const contentProps = {
11118
11167
  groups,
11119
11168
  activePath,
11120
11169
  isActive,
11121
11170
  onNavigate: handleNavigate,
11122
11171
  linkComponent,
11123
- collapsed,
11172
+ collapsed: desktopCollapsed,
11124
11173
  showSectionLabels: effectiveShowSectionLabels,
11125
11174
  showSectionIcons,
11126
11175
  showSectionSeparators: effectiveShowSectionSeparators,
@@ -11133,22 +11182,22 @@ function NSidebar({
11133
11182
  settingsLabel,
11134
11183
  onLogout,
11135
11184
  logoutLabel,
11136
- showCollapseButton: showCollapseButton && collapseButtonPosition === "footer",
11137
- collapsed,
11185
+ showCollapseButton: showCollapseButton && collapseButtonPosition === "footer" && !autoCollapsed,
11186
+ collapsed: desktopCollapsed,
11138
11187
  onToggleCollapsed: handleToggleCollapsed,
11139
11188
  collapseLabel,
11140
11189
  expandLabel,
11141
11190
  classNames
11142
11191
  };
11143
11192
  const sidebarInner = /* @__PURE__ */ jsxs(Fragment, { children: [
11144
- headerContent && /* @__PURE__ */ jsx(NSidebarHeader, { collapsed, classNames, children: headerContent }),
11193
+ desktopHeaderContent && /* @__PURE__ */ jsx(NSidebarHeader, { collapsed: desktopCollapsed, classNames, children: desktopHeaderContent }),
11145
11194
  /* @__PURE__ */ jsx(NSidebarContent, { ...contentProps }),
11146
11195
  /* @__PURE__ */ jsx(NSidebarFooter, { ...footerProps })
11147
11196
  ] });
11148
11197
  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 })
11198
+ mobileHeaderContent && /* @__PURE__ */ jsx(NSidebarHeader, { collapsed: false, classNames, children: mobileHeaderContent }),
11199
+ /* @__PURE__ */ jsx(NSidebarContent, { ...contentProps, collapsed: false }),
11200
+ /* @__PURE__ */ jsx(NSidebarFooter, { ...footerProps, collapsed: false, isMobile: true })
11152
11201
  ] });
11153
11202
  return /* @__PURE__ */ jsxs(Fragment, { children: [
11154
11203
  /* @__PURE__ */ jsx(
@@ -11171,6 +11220,8 @@ function NSidebar({
11171
11220
  "aside",
11172
11221
  {
11173
11222
  "data-bordered": bordered === false ? "false" : bordered ? "true" : void 0,
11223
+ "data-collapsed": desktopCollapsed ? "true" : "false",
11224
+ "data-auto-collapsed": autoCollapsed ? "true" : void 0,
11174
11225
  className: cn(
11175
11226
  "relative z-10 flex flex-col h-full bg-sidebar text-sidebar-foreground transition-all duration-200",
11176
11227
  desktopClass,
@@ -11179,7 +11230,7 @@ function NSidebar({
11179
11230
  className
11180
11231
  ),
11181
11232
  style: {
11182
- width: collapsed ? collapsedWidth : expandedWidth,
11233
+ width: desktopCollapsed ? collapsedWidth : expandedWidth,
11183
11234
  ["--rail"]: railVar,
11184
11235
  ["--sidebar-edge-width"]: sidebarEdgeWidth,
11185
11236
  ...bordered !== false && recipe?.borderWidth ? { borderRightWidth: recipe.borderWidth } : {}
@@ -11190,8 +11241,8 @@ function NSidebar({
11190
11241
  "button",
11191
11242
  {
11192
11243
  type: "button",
11193
- "aria-label": collapsed ? expandLabel : collapseLabel,
11194
- title: collapsed ? expandLabel : collapseLabel,
11244
+ "aria-label": desktopCollapsed ? expandLabel : collapseLabel,
11245
+ title: desktopCollapsed ? expandLabel : collapseLabel,
11195
11246
  "data-dragging": railDragging ? "true" : void 0,
11196
11247
  onPointerDown: handleRailPointerDown,
11197
11248
  onClick: handleRailClick,
@@ -11210,7 +11261,7 @@ function NSidebar({
11210
11261
  "aria-label": collapsed ? expandLabel : collapseLabel,
11211
11262
  title: collapsed ? expandLabel : collapseLabel,
11212
11263
  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" })
11264
+ children: desktopCollapsed ? /* @__PURE__ */ jsx(ChevronRight, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ jsx(ChevronLeft, { className: "h-3.5 w-3.5" })
11214
11265
  }
11215
11266
  )
11216
11267
  ]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "najm-kit",
3
- "version": "2.1.8",
3
+ "version": "2.1.9",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "description": "Reusable React UI component package for Najm framework",