@particle-academy/react-fancy 5.18.0 → 5.19.0

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.
@@ -178,6 +178,7 @@ function SidebarRoot({
178
178
  defaultCollapsed = false,
179
179
  onCollapsedChange,
180
180
  collapseMode = "icons",
181
+ embedded = false,
181
182
  className
182
183
  }) {
183
184
  const [collapsed, setCollapsed] = useControllableState(
@@ -190,9 +191,17 @@ function SidebarRoot({
190
191
  {
191
192
  "data-react-fancy-sidebar": "",
192
193
  "data-collapsed": collapsed || void 0,
194
+ "data-embedded": embedded || void 0,
193
195
  className: cn(
194
- "flex flex-col gap-0.5 border-r border-zinc-200 bg-white transition-[width] duration-200 dark:border-zinc-700 dark:bg-zinc-900",
195
- collapsed ? "w-16" : "w-60",
196
+ "flex flex-col gap-0.5 transition-[width] duration-200",
197
+ // The app-shell chrome. Correct for the rail this is usually used as,
198
+ // and actively wrong inside a container that already draws its own —
199
+ // a 240px rail in a 300px card puts its right border 240px in, which
200
+ // reads as a stray line slicing the panel rather than an edge.
201
+ !embedded && "border-r border-zinc-200 bg-white dark:border-zinc-700 dark:bg-zinc-900",
202
+ // Collapsed is a fixed icon rail either way; only the expanded width
203
+ // defers to the container.
204
+ collapsed ? "w-16" : embedded ? "w-full" : "w-60",
196
205
  className
197
206
  ),
198
207
  children
@@ -207,5 +216,5 @@ var Sidebar = Object.assign(SidebarRoot, {
207
216
  });
208
217
 
209
218
  export { Sidebar, useSidebar };
210
- //# sourceMappingURL=chunk-N7WQ53US.js.map
211
- //# sourceMappingURL=chunk-N7WQ53US.js.map
219
+ //# sourceMappingURL=chunk-4CM2VMLR.js.map
220
+ //# sourceMappingURL=chunk-4CM2VMLR.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/Sidebar/Sidebar.context.ts","../src/components/Sidebar/SidebarItem.tsx","../src/components/Sidebar/SidebarGroup.tsx","../src/components/Sidebar/SidebarSubmenu.tsx","../src/components/Sidebar/SidebarToggle.tsx","../src/components/Sidebar/Sidebar.tsx"],"names":["jsxs","jsx","getLetters"],"mappings":";;;;;;AAGO,IAAM,cAAA,GAAiB,cAA0C,IAAI,CAAA;AAErE,SAAS,UAAA,GAAkC;AAChD,EAAA,MAAM,GAAA,GAAM,WAAW,cAAc,CAAA;AACrC,EAAA,IAAI,CAAC,GAAA,EAAK;AACR,IAAA,MAAM,IAAI,MAAM,sDAAsD,CAAA;AAAA,EACxE;AACA,EAAA,OAAO,GAAA;AACT;ACLA,SAAS,WAAW,QAAA,EAAmC;AACrD,EAAA,IAAI,OAAO,QAAA,KAAa,QAAA,SAAiB,QAAA,CAAS,KAAA,CAAM,GAAG,CAAC,CAAA;AAC5D,EAAA,OAAO,KAAA;AACT;AAEO,SAAS,WAAA,CAAY;AAAA,EAC1B,QAAA;AAAA,EACA,IAAA;AAAA,EACA,EAAA,EAAI,EAAA;AAAA,EACJ,IAAA;AAAA,EACA,MAAA,GAAS,KAAA;AAAA,EACT,QAAA,GAAW,KAAA;AAAA,EACX,KAAA;AAAA,EACA,OAAA;AAAA,EACA,SAAA;AAAA,EACA,GAAG;AACL,CAAA,EAAqB;AACnB,EAAA,MAAM,EAAE,SAAA,EAAW,YAAA,EAAa,GAAI,UAAA,EAAW;AAM/C,EAAA,MAAM,MAAA,GAAS,OAAA,CAAQ,IAAA,IAAQ,EAAE,CAAA;AACjC,EAAA,MAAM,GAAA,GAAM,MAAA,GAAW,EAAA,IAAM,GAAA,GAAuB,QAAA;AACpD,EAAA,MAAM,QAAA,GAAW,MAAA,GACb,EAAE,GAAI,OAAO,EAAE,IAAA,EAAK,GAAI,IAAK,OAAA,EAAQ,GACrC,EAAE,IAAA,EAAM,UAAmB,OAAA,EAAQ;AAEvC,EAAA,MAAM,YAAA,GAAe,SAAA,IAAa,YAAA,KAAiB,OAAA,IAAW,IAAA;AAC9D,EAAA,MAAM,cAAc,SAAA,KAAc,YAAA,KAAiB,SAAA,IAAc,YAAA,KAAiB,WAAW,CAAC,IAAA,CAAA;AAE9F,EAAA,MAAM,KAAA,GAAQ,OAAO,QAAA,KAAa,QAAA,GAAW,QAAA,GAAW,MAAA;AAExD,EAAA,uBACE,IAAA;AAAA,IAAC,GAAA;AAAA,IAAA;AAAA,MACE,GAAG,QAAA;AAAA,MACH,GAAG,IAAA;AAAA,MACJ,+BAAA,EAA8B,EAAA;AAAA,MAC9B,eAAa,MAAA,IAAU,MAAA;AAAA,MACvB,cAAA,EAAc,SAAS,MAAA,GAAS,MAAA;AAAA,MAChC,iBAAe,QAAA,IAAY,MAAA;AAAA,MAC3B,KAAA,EAAO,YAAY,KAAA,GAAQ,MAAA;AAAA,MAC3B,SAAA,EAAW,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAOT,2EAAA;AAAA,QACA,+DAAA;AAAA,QACA,YAAY,0BAAA,GAA6B,iBAAA;AAAA,QACzC,SACI,+DAAA,GACA,0HAAA;AAAA,QACJ,QAAA,IAAY,gCAAA;AAAA,QACZ;AAAA,OACF;AAAA,MAEC,QAAA,EAAA;AAAA,QAAA,YAAA,oBACC,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,mDAAA,EAAqD,QAAA,EAAA,IAAA,EAAK,CAAA;AAAA,QAE3E,+BACC,GAAA,CAAC,MAAA,EAAA,EAAK,WAAU,iCAAA,EAAmC,QAAA,EAAA,UAAA,CAAW,QAAQ,CAAA,EAAE,CAAA;AAAA,QAEzE,CAAC,6BACA,IAAA,CAAA,QAAA,EAAA,EACG,QAAA,EAAA;AAAA,UAAA,IAAA,oBAAQ,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,mDAAA,EAAqD,QAAA,EAAA,IAAA,EAAK,CAAA;AAAA,0BAYnF,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,mCAAA,EAAqC,QAAA,EAAS,CAAA;AAAA,UAC7D,KAAA,oBAAS,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,YAAY,QAAA,EAAA,KAAA,EAAM;AAAA,SAAA,EAC9C;AAAA;AAAA;AAAA,GAEJ;AAEJ;AAEA,WAAA,CAAY,WAAA,GAAc,aAAA;AC1FnB,SAAS,YAAA,CAAa,EAAE,QAAA,EAAU,KAAA,EAAO,WAAU,EAAsB;AAC9E,EAAA,MAAM,EAAE,SAAA,EAAU,GAAI,UAAA,EAAW;AAEjC,EAAA,uBACEA,KAAC,KAAA,EAAA,EAAI,gCAAA,EAA+B,IAAG,SAAA,EAAW,EAAA,CAAG,MAAA,EAAQ,SAAS,CAAA,EACnE,QAAA,EAAA;AAAA,IAAA,KAAA,IAAS,CAAC,SAAA,oBACTC,IAAC,GAAA,EAAA,EAAE,SAAA,EAAU,6FACV,QAAA,EAAA,KAAA,EACH,CAAA;AAAA,IAED,SAAS,SAAA,oBACRA,GAAAA,CAAC,KAAA,EAAA,EAAI,WAAU,oDAAA,EAAqD,CAAA;AAAA,IAErE;AAAA,GAAA,EACH,CAAA;AAEJ;AAEA,YAAA,CAAa,WAAA,GAAc,cAAA;ACf3B,SAASC,YAAW,KAAA,EAAuB;AACzC,EAAA,OAAO,KAAA,CAAM,KAAA,CAAM,CAAA,EAAG,CAAC,CAAA;AACzB;AAEO,SAAS,cAAA,CAAe;AAAA,EAC7B,QAAA;AAAA,EACA,KAAA;AAAA,EACA,IAAA;AAAA,EACA,WAAA,GAAc,KAAA;AAAA,EACd;AACF,CAAA,EAAwB;AACtB,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAI,SAAS,WAAW,CAAA;AAC5C,EAAA,MAAM,EAAE,SAAA,EAAW,YAAA,EAAa,GAAI,UAAA,EAAW;AAE/C,EAAA,MAAM,YAAA,GAAe,SAAA,IAAa,YAAA,KAAiB,OAAA,IAAW,IAAA;AAC9D,EAAA,MAAM,cAAc,SAAA,KAAc,YAAA,KAAiB,SAAA,IAAc,YAAA,KAAiB,WAAW,CAAC,IAAA,CAAA;AAG9F,EAAA,IAAI,SAAA,EAAW;AACb,IAAA,uBACEF,IAAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,kCAAA,EAAiC,EAAA;AAAA,QACjC,KAAA,EAAO,KAAA;AAAA,QACP,SAAA,EAAW,EAAA;AAAA,UACT,6FAAA;AAAA,UACA,oDAAA;AAAA,UACA,uEAAA;AAAA,UACA;AAAA,SACF;AAAA,QAEC,QAAA,EAAA;AAAA,UAAA,YAAA,oBACCC,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,qDAAqD,QAAA,EAAA,IAAA,EAAK,CAAA;AAAA,UAE3E,WAAA,oBACCA,GAAAA,CAAC,MAAA,EAAA,EAAK,WAAU,iCAAA,EAAmC,QAAA,EAAAC,WAAAA,CAAW,KAAK,CAAA,EAAE;AAAA;AAAA;AAAA,KAEzE;AAAA,EAEJ;AAEA,EAAA,uBACEF,IAAAA,CAAC,KAAA,EAAA,EAAI,kCAAA,EAAiC,IAAG,SAAA,EACvC,QAAA,EAAA;AAAA,oBAAAA,IAAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAK,QAAA;AAAA,QACL,SAAS,MAAM,OAAA,CAAQ,CAAC,CAAA,KAAM,CAAC,CAAC,CAAA;AAAA,QAChC,SAAA,EAAW,EAAA;AAAA,UACT,2FAAA;AAAA,UACA,oDAAA;AAAA,UACA;AAAA,SACF;AAAA,QAEC,QAAA,EAAA;AAAA,UAAA,IAAA,oBAAQC,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,qDAAqD,QAAA,EAAA,IAAA,EAAK,CAAA;AAAA,0BACnFA,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,oBAAoB,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,0BAC1CA,GAAAA;AAAA,YAAC,WAAA;AAAA,YAAA;AAAA,cACC,SAAA,EAAW,EAAA;AAAA,gBACT,0DAAA;AAAA,gBACA,IAAA,IAAQ;AAAA;AACV;AAAA;AACF;AAAA;AAAA,KACF;AAAA,oBACAA,GAAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,SAAA,EAAW,EAAA;AAAA,UACT,mDAAA;AAAA,UACA,OAAO,iBAAA,GAAoB;AAAA,SAC7B;AAAA,QAEA,QAAA,kBAAAA,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,iBAAA,EACb,QAAA,kBAAAA,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,8DAAA,EACZ,QAAA,EACH,CAAA,EACF;AAAA;AAAA;AACF,GAAA,EACF,CAAA;AAEJ;AAEA,cAAA,CAAe,WAAA,GAAc,gBAAA;AC9EtB,SAAS,aAAA,CAAc,EAAE,SAAA,EAAU,EAAuB;AAC/D,EAAA,MAAM,EAAE,SAAA,EAAW,YAAA,EAAa,GAAI,UAAA,EAAW;AAE/C,EAAA,uBACEA,GAAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MACC,IAAA,EAAK,QAAA;AAAA,MACL,iCAAA,EAAgC,EAAA;AAAA,MAChC,OAAA,EAAS,MAAM,YAAA,CAAa,CAAC,SAAS,CAAA;AAAA,MACtC,KAAA,EAAO,YAAY,gBAAA,GAAmB,kBAAA;AAAA,MACtC,SAAA,EAAW,EAAA;AAAA,QACT,mFAAA;AAAA,QACA,uFAAA;AAAA,QACA;AAAA,OACF;AAAA,MAEC,QAAA,EAAA,SAAA,mBACCA,GAAAA,CAAC,aAAA,EAAA,EAAc,SAAA,EAAU,SAAA,EAAU,CAAA,mBAEnCA,GAAAA,CAAC,cAAA,EAAA,EAAe,SAAA,EAAU,SAAA,EAAU;AAAA;AAAA,GAExC;AAEJ;AAEA,aAAA,CAAc,WAAA,GAAc,eAAA;ACpB5B,SAAS,WAAA,CAAY;AAAA,EACnB,QAAA;AAAA,EACA,SAAA,EAAW,mBAAA;AAAA,EACX,gBAAA,GAAmB,KAAA;AAAA,EACnB,iBAAA;AAAA,EACA,YAAA,GAAe,OAAA;AAAA,EACf,QAAA,GAAW,KAAA;AAAA,EACX;AACF,CAAA,EAAiB;AACf,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAI,oBAAA;AAAA,IAChC,mBAAA;AAAA,IACA,gBAAA;AAAA,IACA;AAAA,GACF;AAEA,EAAA,uBACEA,GAAAA,CAAC,cAAA,CAAe,QAAA,EAAf,EAAwB,KAAA,EAAO,EAAE,SAAA,EAAW,YAAA,EAAc,YAAA,EAAa,EACtE,QAAA,kBAAAA,GAAAA;AAAA,IAAC,OAAA;AAAA,IAAA;AAAA,MACC,0BAAA,EAAyB,EAAA;AAAA,MACzB,kBAAgB,SAAA,IAAa,MAAA;AAAA,MAC7B,iBAAe,QAAA,IAAY,MAAA;AAAA,MAC3B,SAAA,EAAW,EAAA;AAAA,QACT,uDAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAKA,CAAC,QAAA,IAAY,yEAAA;AAAA;AAAA;AAAA,QAGb,SAAA,GAAY,MAAA,GAAS,QAAA,GAAW,QAAA,GAAW,MAAA;AAAA,QAC3C;AAAA,OACF;AAAA,MAEC;AAAA;AAAA,GACH,EACF,CAAA;AAEJ;AAEO,IAAM,OAAA,GAAU,MAAA,CAAO,MAAA,CAAO,WAAA,EAAa;AAAA,EAChD,IAAA,EAAM,WAAA;AAAA,EACN,KAAA,EAAO,YAAA;AAAA,EACP,OAAA,EAAS,cAAA;AAAA,EACT,MAAA,EAAQ;AACV,CAAC","file":"chunk-4CM2VMLR.js","sourcesContent":["import { createContext, useContext } from \"react\";\nimport type { SidebarContextValue } from \"./Sidebar.types\";\n\nexport const SidebarContext = createContext<SidebarContextValue | null>(null);\n\nexport function useSidebar(): SidebarContextValue {\n const ctx = useContext(SidebarContext);\n if (!ctx) {\n throw new Error(\"useSidebar must be used within a <Sidebar> component\");\n }\n return ctx;\n}\n","import type { ElementType } from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { useSidebar } from \"./Sidebar.context\";\nimport type { SidebarItemProps } from \"./Sidebar.types\";\n\n/** Extract first 3 characters from a ReactNode if it's a string. */\nfunction getLetters(children: React.ReactNode): string {\n if (typeof children === \"string\") return children.slice(0, 3);\n return \"...\";\n}\n\nexport function SidebarItem({\n children,\n href,\n as: As,\n icon,\n active = false,\n disabled = false,\n badge,\n onClick,\n className,\n ...rest\n}: SidebarItemProps) {\n const { collapsed, collapseMode } = useSidebar();\n\n // Link mode engages on `href` OR `as` — a `to`-based router (TanStack Router,\n // React Router) passes no href, and would otherwise render a <button> that\n // navigates nowhere. `onClick` now rides along in link mode instead of being\n // dropped: an item that both navigates and closes a drawer is the common case.\n const isLink = Boolean(href || As);\n const Tag = isLink ? ((As ?? \"a\") as ElementType) : \"button\";\n const tagProps = isLink\n ? { ...(href ? { href } : {}), onClick }\n : { type: \"button\" as const, onClick };\n\n const showIconOnly = collapsed && collapseMode === \"icons\" && icon;\n const showLetters = collapsed && (collapseMode === \"letters\" || (collapseMode === \"icons\" && !icon));\n\n const title = typeof children === \"string\" ? children : undefined;\n\n return (\n <Tag\n {...tagProps}\n {...rest}\n data-react-fancy-sidebar-item=\"\"\n data-active={active || undefined}\n aria-current={active ? \"page\" : undefined}\n aria-disabled={disabled || undefined}\n title={collapsed ? title : undefined}\n className={cn(\n // `w-full` matters when the Tag is a <button>: form controls size to\n // FIT-CONTENT, not to their parent, so a long label made the item wider\n // than the sidebar and an ancestor clipped the overflow — which reads as\n // a label cut off mid-word rather than an ellipsis. Without this,\n // `min-w-0` on the label below can never engage, because the item is\n // never under width pressure in the first place.\n \"flex w-full items-center rounded-md text-sm font-medium transition-colors\",\n \"outline-none focus-visible:ring-2 focus-visible:ring-blue-500\",\n collapsed ? \"justify-center px-2 py-2\" : \"gap-2 px-3 py-2\",\n active\n ? \"bg-zinc-100 text-zinc-900 dark:bg-zinc-800 dark:text-zinc-100\"\n : \"text-zinc-600 hover:bg-zinc-50 hover:text-zinc-900 dark:text-zinc-400 dark:hover:bg-zinc-800/50 dark:hover:text-zinc-100\",\n disabled && \"pointer-events-none opacity-50\",\n className,\n )}\n >\n {showIconOnly && (\n <span className=\"flex h-5 w-5 shrink-0 items-center justify-center\">{icon}</span>\n )}\n {showLetters && (\n <span className=\"text-xs font-semibold uppercase\">{getLetters(children)}</span>\n )}\n {!collapsed && (\n <>\n {icon && <span className=\"flex h-5 w-5 shrink-0 items-center justify-center\">{icon}</span>}\n {/*\n `min-w-0` is load-bearing, not tidiness. A flex item defaults to\n `min-width: auto`, which resolves to its MIN-CONTENT width — so with\n `truncate` alone the span refuses to shrink below the full label,\n and the item grows wider than the sidebar instead of ellipsing.\n The overflow then gets clipped by an ancestor, which looks like a\n mid-word cut rather than a truncation.\n\n Only shows up with labels longer than the sidebar is wide, which is\n why it survived: short nav labels never trigger it.\n */}\n <span className=\"min-w-0 flex-1 truncate text-left\">{children}</span>\n {badge && <span className=\"shrink-0\">{badge}</span>}\n </>\n )}\n </Tag>\n );\n}\n\nSidebarItem.displayName = \"SidebarItem\";\n","import { cn } from \"../../utils/cn\";\nimport { useSidebar } from \"./Sidebar.context\";\nimport type { SidebarGroupProps } from \"./Sidebar.types\";\n\nexport function SidebarGroup({ children, label, className }: SidebarGroupProps) {\n const { collapsed } = useSidebar();\n\n return (\n <div data-react-fancy-sidebar-group=\"\" className={cn(\"py-1\", className)}>\n {label && !collapsed && (\n <p className=\"mb-1 px-3 text-xs font-semibold uppercase tracking-wider text-zinc-400 dark:text-zinc-500\">\n {label}\n </p>\n )}\n {label && collapsed && (\n <div className=\"mx-auto mb-1 h-px w-6 bg-zinc-200 dark:bg-zinc-700\" />\n )}\n {children}\n </div>\n );\n}\n\nSidebarGroup.displayName = \"SidebarGroup\";\n","import { useState } from \"react\";\nimport { ChevronDown } from \"lucide-react\";\nimport { cn } from \"../../utils/cn\";\nimport { useSidebar } from \"./Sidebar.context\";\nimport type { SidebarSubmenuProps } from \"./Sidebar.types\";\n\n/** Extract first 3 characters from a string. */\nfunction getLetters(label: string): string {\n return label.slice(0, 3);\n}\n\nexport function SidebarSubmenu({\n children,\n label,\n icon,\n defaultOpen = false,\n className,\n}: SidebarSubmenuProps) {\n const [open, setOpen] = useState(defaultOpen);\n const { collapsed, collapseMode } = useSidebar();\n\n const showIconOnly = collapsed && collapseMode === \"icons\" && icon;\n const showLetters = collapsed && (collapseMode === \"letters\" || (collapseMode === \"icons\" && !icon));\n\n // When collapsed, just show the icon/letters as a simple item (no expand)\n if (collapsed) {\n return (\n <div\n data-react-fancy-sidebar-submenu=\"\"\n title={label}\n className={cn(\n \"flex items-center justify-center rounded-md px-2 py-2 text-sm font-medium transition-colors\",\n \"text-zinc-600 hover:bg-zinc-50 hover:text-zinc-900\",\n \"dark:text-zinc-400 dark:hover:bg-zinc-800/50 dark:hover:text-zinc-100\",\n className,\n )}\n >\n {showIconOnly && (\n <span className=\"flex h-5 w-5 shrink-0 items-center justify-center\">{icon}</span>\n )}\n {showLetters && (\n <span className=\"text-xs font-semibold uppercase\">{getLetters(label)}</span>\n )}\n </div>\n );\n }\n\n return (\n <div data-react-fancy-sidebar-submenu=\"\" className={className}>\n <button\n type=\"button\"\n onClick={() => setOpen((v) => !v)}\n className={cn(\n \"flex w-full items-center gap-2 rounded-md px-3 py-2 text-sm font-medium transition-colors\",\n \"text-zinc-600 hover:bg-zinc-50 hover:text-zinc-900\",\n \"dark:text-zinc-400 dark:hover:bg-zinc-800/50 dark:hover:text-zinc-100\",\n )}\n >\n {icon && <span className=\"flex h-5 w-5 shrink-0 items-center justify-center\">{icon}</span>}\n <span className=\"flex-1 text-left\">{label}</span>\n <ChevronDown\n className={cn(\n \"h-3.5 w-3.5 opacity-60 transition-transform duration-200\",\n open && \"rotate-180\",\n )}\n />\n </button>\n <div\n className={cn(\n \"grid transition-[grid-template-rows] duration-200\",\n open ? \"grid-rows-[1fr]\" : \"grid-rows-[0fr]\",\n )}\n >\n <div className=\"overflow-hidden\">\n <div className=\"ml-4 border-l border-zinc-200 pl-2 pt-1 dark:border-zinc-700\">\n {children}\n </div>\n </div>\n </div>\n </div>\n );\n}\n\nSidebarSubmenu.displayName = \"SidebarSubmenu\";\n","import { PanelLeftClose, PanelLeftOpen } from \"lucide-react\";\nimport { cn } from \"../../utils/cn\";\nimport { useSidebar } from \"./Sidebar.context\";\nimport type { SidebarToggleProps } from \"./Sidebar.types\";\n\nexport function SidebarToggle({ className }: SidebarToggleProps) {\n const { collapsed, setCollapsed } = useSidebar();\n\n return (\n <button\n type=\"button\"\n data-react-fancy-sidebar-toggle=\"\"\n onClick={() => setCollapsed(!collapsed)}\n title={collapsed ? \"Expand sidebar\" : \"Collapse sidebar\"}\n className={cn(\n \"flex items-center justify-center rounded-md p-1.5 text-zinc-400 transition-colors\",\n \"hover:bg-zinc-100 hover:text-zinc-600 dark:hover:bg-zinc-800 dark:hover:text-zinc-300\",\n className,\n )}\n >\n {collapsed ? (\n <PanelLeftOpen className=\"h-4 w-4\" />\n ) : (\n <PanelLeftClose className=\"h-4 w-4\" />\n )}\n </button>\n );\n}\n\nSidebarToggle.displayName = \"SidebarToggle\";\n","import { cn } from \"../../utils/cn\";\nimport { useControllableState } from \"../../hooks\";\nimport { SidebarContext } from \"./Sidebar.context\";\nimport { SidebarItem } from \"./SidebarItem\";\nimport { SidebarGroup } from \"./SidebarGroup\";\nimport { SidebarSubmenu } from \"./SidebarSubmenu\";\nimport { SidebarToggle } from \"./SidebarToggle\";\nimport type { SidebarProps } from \"./Sidebar.types\";\n\nfunction SidebarRoot({\n children,\n collapsed: controlledCollapsed,\n defaultCollapsed = false,\n onCollapsedChange,\n collapseMode = \"icons\",\n embedded = false,\n className,\n}: SidebarProps) {\n const [collapsed, setCollapsed] = useControllableState(\n controlledCollapsed,\n defaultCollapsed,\n onCollapsedChange,\n );\n\n return (\n <SidebarContext.Provider value={{ collapsed, collapseMode, setCollapsed }}>\n <aside\n data-react-fancy-sidebar=\"\"\n data-collapsed={collapsed || undefined}\n data-embedded={embedded || undefined}\n className={cn(\n \"flex flex-col gap-0.5 transition-[width] duration-200\",\n // The app-shell chrome. Correct for the rail this is usually used as,\n // and actively wrong inside a container that already draws its own —\n // a 240px rail in a 300px card puts its right border 240px in, which\n // reads as a stray line slicing the panel rather than an edge.\n !embedded && \"border-r border-zinc-200 bg-white dark:border-zinc-700 dark:bg-zinc-900\",\n // Collapsed is a fixed icon rail either way; only the expanded width\n // defers to the container.\n collapsed ? \"w-16\" : embedded ? \"w-full\" : \"w-60\",\n className,\n )}\n >\n {children}\n </aside>\n </SidebarContext.Provider>\n );\n}\n\nexport const Sidebar = Object.assign(SidebarRoot, {\n Item: SidebarItem,\n Group: SidebarGroup,\n Submenu: SidebarSubmenu,\n Toggle: SidebarToggle,\n});\n"]}
@@ -180,6 +180,7 @@ function SidebarRoot({
180
180
  defaultCollapsed = false,
181
181
  onCollapsedChange,
182
182
  collapseMode = "icons",
183
+ embedded = false,
183
184
  className
184
185
  }) {
185
186
  const [collapsed, setCollapsed] = chunkOUOEQZHY_cjs.useControllableState(
@@ -192,9 +193,17 @@ function SidebarRoot({
192
193
  {
193
194
  "data-react-fancy-sidebar": "",
194
195
  "data-collapsed": collapsed || void 0,
196
+ "data-embedded": embedded || void 0,
195
197
  className: chunk3Z6ALUWP_cjs.cn(
196
- "flex flex-col gap-0.5 border-r border-zinc-200 bg-white transition-[width] duration-200 dark:border-zinc-700 dark:bg-zinc-900",
197
- collapsed ? "w-16" : "w-60",
198
+ "flex flex-col gap-0.5 transition-[width] duration-200",
199
+ // The app-shell chrome. Correct for the rail this is usually used as,
200
+ // and actively wrong inside a container that already draws its own —
201
+ // a 240px rail in a 300px card puts its right border 240px in, which
202
+ // reads as a stray line slicing the panel rather than an edge.
203
+ !embedded && "border-r border-zinc-200 bg-white dark:border-zinc-700 dark:bg-zinc-900",
204
+ // Collapsed is a fixed icon rail either way; only the expanded width
205
+ // defers to the container.
206
+ collapsed ? "w-16" : embedded ? "w-full" : "w-60",
198
207
  className
199
208
  ),
200
209
  children
@@ -210,5 +219,5 @@ var Sidebar = Object.assign(SidebarRoot, {
210
219
 
211
220
  exports.Sidebar = Sidebar;
212
221
  exports.useSidebar = useSidebar;
213
- //# sourceMappingURL=chunk-XBBEQLMY.cjs.map
214
- //# sourceMappingURL=chunk-XBBEQLMY.cjs.map
222
+ //# sourceMappingURL=chunk-M2S5GCXY.cjs.map
223
+ //# sourceMappingURL=chunk-M2S5GCXY.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/Sidebar/Sidebar.context.ts","../src/components/Sidebar/SidebarItem.tsx","../src/components/Sidebar/SidebarGroup.tsx","../src/components/Sidebar/SidebarSubmenu.tsx","../src/components/Sidebar/SidebarToggle.tsx","../src/components/Sidebar/Sidebar.tsx"],"names":["createContext","useContext","jsxs","cn","jsx","Fragment","getLetters","useState","ChevronDown","PanelLeftOpen","PanelLeftClose","useControllableState"],"mappings":"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","file":"chunk-M2S5GCXY.cjs","sourcesContent":["import { createContext, useContext } from \"react\";\nimport type { SidebarContextValue } from \"./Sidebar.types\";\n\nexport const SidebarContext = createContext<SidebarContextValue | null>(null);\n\nexport function useSidebar(): SidebarContextValue {\n const ctx = useContext(SidebarContext);\n if (!ctx) {\n throw new Error(\"useSidebar must be used within a <Sidebar> component\");\n }\n return ctx;\n}\n","import type { ElementType } from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { useSidebar } from \"./Sidebar.context\";\nimport type { SidebarItemProps } from \"./Sidebar.types\";\n\n/** Extract first 3 characters from a ReactNode if it's a string. */\nfunction getLetters(children: React.ReactNode): string {\n if (typeof children === \"string\") return children.slice(0, 3);\n return \"...\";\n}\n\nexport function SidebarItem({\n children,\n href,\n as: As,\n icon,\n active = false,\n disabled = false,\n badge,\n onClick,\n className,\n ...rest\n}: SidebarItemProps) {\n const { collapsed, collapseMode } = useSidebar();\n\n // Link mode engages on `href` OR `as` — a `to`-based router (TanStack Router,\n // React Router) passes no href, and would otherwise render a <button> that\n // navigates nowhere. `onClick` now rides along in link mode instead of being\n // dropped: an item that both navigates and closes a drawer is the common case.\n const isLink = Boolean(href || As);\n const Tag = isLink ? ((As ?? \"a\") as ElementType) : \"button\";\n const tagProps = isLink\n ? { ...(href ? { href } : {}), onClick }\n : { type: \"button\" as const, onClick };\n\n const showIconOnly = collapsed && collapseMode === \"icons\" && icon;\n const showLetters = collapsed && (collapseMode === \"letters\" || (collapseMode === \"icons\" && !icon));\n\n const title = typeof children === \"string\" ? children : undefined;\n\n return (\n <Tag\n {...tagProps}\n {...rest}\n data-react-fancy-sidebar-item=\"\"\n data-active={active || undefined}\n aria-current={active ? \"page\" : undefined}\n aria-disabled={disabled || undefined}\n title={collapsed ? title : undefined}\n className={cn(\n // `w-full` matters when the Tag is a <button>: form controls size to\n // FIT-CONTENT, not to their parent, so a long label made the item wider\n // than the sidebar and an ancestor clipped the overflow — which reads as\n // a label cut off mid-word rather than an ellipsis. Without this,\n // `min-w-0` on the label below can never engage, because the item is\n // never under width pressure in the first place.\n \"flex w-full items-center rounded-md text-sm font-medium transition-colors\",\n \"outline-none focus-visible:ring-2 focus-visible:ring-blue-500\",\n collapsed ? \"justify-center px-2 py-2\" : \"gap-2 px-3 py-2\",\n active\n ? \"bg-zinc-100 text-zinc-900 dark:bg-zinc-800 dark:text-zinc-100\"\n : \"text-zinc-600 hover:bg-zinc-50 hover:text-zinc-900 dark:text-zinc-400 dark:hover:bg-zinc-800/50 dark:hover:text-zinc-100\",\n disabled && \"pointer-events-none opacity-50\",\n className,\n )}\n >\n {showIconOnly && (\n <span className=\"flex h-5 w-5 shrink-0 items-center justify-center\">{icon}</span>\n )}\n {showLetters && (\n <span className=\"text-xs font-semibold uppercase\">{getLetters(children)}</span>\n )}\n {!collapsed && (\n <>\n {icon && <span className=\"flex h-5 w-5 shrink-0 items-center justify-center\">{icon}</span>}\n {/*\n `min-w-0` is load-bearing, not tidiness. A flex item defaults to\n `min-width: auto`, which resolves to its MIN-CONTENT width — so with\n `truncate` alone the span refuses to shrink below the full label,\n and the item grows wider than the sidebar instead of ellipsing.\n The overflow then gets clipped by an ancestor, which looks like a\n mid-word cut rather than a truncation.\n\n Only shows up with labels longer than the sidebar is wide, which is\n why it survived: short nav labels never trigger it.\n */}\n <span className=\"min-w-0 flex-1 truncate text-left\">{children}</span>\n {badge && <span className=\"shrink-0\">{badge}</span>}\n </>\n )}\n </Tag>\n );\n}\n\nSidebarItem.displayName = \"SidebarItem\";\n","import { cn } from \"../../utils/cn\";\nimport { useSidebar } from \"./Sidebar.context\";\nimport type { SidebarGroupProps } from \"./Sidebar.types\";\n\nexport function SidebarGroup({ children, label, className }: SidebarGroupProps) {\n const { collapsed } = useSidebar();\n\n return (\n <div data-react-fancy-sidebar-group=\"\" className={cn(\"py-1\", className)}>\n {label && !collapsed && (\n <p className=\"mb-1 px-3 text-xs font-semibold uppercase tracking-wider text-zinc-400 dark:text-zinc-500\">\n {label}\n </p>\n )}\n {label && collapsed && (\n <div className=\"mx-auto mb-1 h-px w-6 bg-zinc-200 dark:bg-zinc-700\" />\n )}\n {children}\n </div>\n );\n}\n\nSidebarGroup.displayName = \"SidebarGroup\";\n","import { useState } from \"react\";\nimport { ChevronDown } from \"lucide-react\";\nimport { cn } from \"../../utils/cn\";\nimport { useSidebar } from \"./Sidebar.context\";\nimport type { SidebarSubmenuProps } from \"./Sidebar.types\";\n\n/** Extract first 3 characters from a string. */\nfunction getLetters(label: string): string {\n return label.slice(0, 3);\n}\n\nexport function SidebarSubmenu({\n children,\n label,\n icon,\n defaultOpen = false,\n className,\n}: SidebarSubmenuProps) {\n const [open, setOpen] = useState(defaultOpen);\n const { collapsed, collapseMode } = useSidebar();\n\n const showIconOnly = collapsed && collapseMode === \"icons\" && icon;\n const showLetters = collapsed && (collapseMode === \"letters\" || (collapseMode === \"icons\" && !icon));\n\n // When collapsed, just show the icon/letters as a simple item (no expand)\n if (collapsed) {\n return (\n <div\n data-react-fancy-sidebar-submenu=\"\"\n title={label}\n className={cn(\n \"flex items-center justify-center rounded-md px-2 py-2 text-sm font-medium transition-colors\",\n \"text-zinc-600 hover:bg-zinc-50 hover:text-zinc-900\",\n \"dark:text-zinc-400 dark:hover:bg-zinc-800/50 dark:hover:text-zinc-100\",\n className,\n )}\n >\n {showIconOnly && (\n <span className=\"flex h-5 w-5 shrink-0 items-center justify-center\">{icon}</span>\n )}\n {showLetters && (\n <span className=\"text-xs font-semibold uppercase\">{getLetters(label)}</span>\n )}\n </div>\n );\n }\n\n return (\n <div data-react-fancy-sidebar-submenu=\"\" className={className}>\n <button\n type=\"button\"\n onClick={() => setOpen((v) => !v)}\n className={cn(\n \"flex w-full items-center gap-2 rounded-md px-3 py-2 text-sm font-medium transition-colors\",\n \"text-zinc-600 hover:bg-zinc-50 hover:text-zinc-900\",\n \"dark:text-zinc-400 dark:hover:bg-zinc-800/50 dark:hover:text-zinc-100\",\n )}\n >\n {icon && <span className=\"flex h-5 w-5 shrink-0 items-center justify-center\">{icon}</span>}\n <span className=\"flex-1 text-left\">{label}</span>\n <ChevronDown\n className={cn(\n \"h-3.5 w-3.5 opacity-60 transition-transform duration-200\",\n open && \"rotate-180\",\n )}\n />\n </button>\n <div\n className={cn(\n \"grid transition-[grid-template-rows] duration-200\",\n open ? \"grid-rows-[1fr]\" : \"grid-rows-[0fr]\",\n )}\n >\n <div className=\"overflow-hidden\">\n <div className=\"ml-4 border-l border-zinc-200 pl-2 pt-1 dark:border-zinc-700\">\n {children}\n </div>\n </div>\n </div>\n </div>\n );\n}\n\nSidebarSubmenu.displayName = \"SidebarSubmenu\";\n","import { PanelLeftClose, PanelLeftOpen } from \"lucide-react\";\nimport { cn } from \"../../utils/cn\";\nimport { useSidebar } from \"./Sidebar.context\";\nimport type { SidebarToggleProps } from \"./Sidebar.types\";\n\nexport function SidebarToggle({ className }: SidebarToggleProps) {\n const { collapsed, setCollapsed } = useSidebar();\n\n return (\n <button\n type=\"button\"\n data-react-fancy-sidebar-toggle=\"\"\n onClick={() => setCollapsed(!collapsed)}\n title={collapsed ? \"Expand sidebar\" : \"Collapse sidebar\"}\n className={cn(\n \"flex items-center justify-center rounded-md p-1.5 text-zinc-400 transition-colors\",\n \"hover:bg-zinc-100 hover:text-zinc-600 dark:hover:bg-zinc-800 dark:hover:text-zinc-300\",\n className,\n )}\n >\n {collapsed ? (\n <PanelLeftOpen className=\"h-4 w-4\" />\n ) : (\n <PanelLeftClose className=\"h-4 w-4\" />\n )}\n </button>\n );\n}\n\nSidebarToggle.displayName = \"SidebarToggle\";\n","import { cn } from \"../../utils/cn\";\nimport { useControllableState } from \"../../hooks\";\nimport { SidebarContext } from \"./Sidebar.context\";\nimport { SidebarItem } from \"./SidebarItem\";\nimport { SidebarGroup } from \"./SidebarGroup\";\nimport { SidebarSubmenu } from \"./SidebarSubmenu\";\nimport { SidebarToggle } from \"./SidebarToggle\";\nimport type { SidebarProps } from \"./Sidebar.types\";\n\nfunction SidebarRoot({\n children,\n collapsed: controlledCollapsed,\n defaultCollapsed = false,\n onCollapsedChange,\n collapseMode = \"icons\",\n embedded = false,\n className,\n}: SidebarProps) {\n const [collapsed, setCollapsed] = useControllableState(\n controlledCollapsed,\n defaultCollapsed,\n onCollapsedChange,\n );\n\n return (\n <SidebarContext.Provider value={{ collapsed, collapseMode, setCollapsed }}>\n <aside\n data-react-fancy-sidebar=\"\"\n data-collapsed={collapsed || undefined}\n data-embedded={embedded || undefined}\n className={cn(\n \"flex flex-col gap-0.5 transition-[width] duration-200\",\n // The app-shell chrome. Correct for the rail this is usually used as,\n // and actively wrong inside a container that already draws its own —\n // a 240px rail in a 300px card puts its right border 240px in, which\n // reads as a stray line slicing the panel rather than an edge.\n !embedded && \"border-r border-zinc-200 bg-white dark:border-zinc-700 dark:bg-zinc-900\",\n // Collapsed is a fixed icon rail either way; only the expanded width\n // defers to the container.\n collapsed ? \"w-16\" : embedded ? \"w-full\" : \"w-60\",\n className,\n )}\n >\n {children}\n </aside>\n </SidebarContext.Provider>\n );\n}\n\nexport const Sidebar = Object.assign(SidebarRoot, {\n Item: SidebarItem,\n Group: SidebarGroup,\n Submenu: SidebarSubmenu,\n Toggle: SidebarToggle,\n});\n"]}
package/dist/index.cjs CHANGED
@@ -17,7 +17,7 @@ require('./chunk-QGPMVFZJ.cjs');
17
17
  var chunkIGU5YXRV_cjs = require('./chunk-IGU5YXRV.cjs');
18
18
  var chunkWXADO5TS_cjs = require('./chunk-WXADO5TS.cjs');
19
19
  require('./chunk-HXLSEBAL.cjs');
20
- var chunkXBBEQLMY_cjs = require('./chunk-XBBEQLMY.cjs');
20
+ var chunkM2S5GCXY_cjs = require('./chunk-M2S5GCXY.cjs');
21
21
  var chunkANEX75DF_cjs = require('./chunk-ANEX75DF.cjs');
22
22
  var chunkGIDW3SUE_cjs = require('./chunk-GIDW3SUE.cjs');
23
23
  var chunk5LHG7HEY_cjs = require('./chunk-5LHG7HEY.cjs');
@@ -178,11 +178,11 @@ Object.defineProperty(exports, "RadioGroup", {
178
178
  });
179
179
  Object.defineProperty(exports, "Sidebar", {
180
180
  enumerable: true,
181
- get: function () { return chunkXBBEQLMY_cjs.Sidebar; }
181
+ get: function () { return chunkM2S5GCXY_cjs.Sidebar; }
182
182
  });
183
183
  Object.defineProperty(exports, "useSidebar", {
184
184
  enumerable: true,
185
- get: function () { return chunkXBBEQLMY_cjs.useSidebar; }
185
+ get: function () { return chunkM2S5GCXY_cjs.useSidebar; }
186
186
  });
187
187
  Object.defineProperty(exports, "Skeleton", {
188
188
  enumerable: true,
package/dist/index.js CHANGED
@@ -15,7 +15,7 @@ import './chunk-SHDSKHCC.js';
15
15
  export { MultiSwitch } from './chunk-ZT36VWIA.js';
16
16
  export { RadioGroup } from './chunk-JYKZKSZJ.js';
17
17
  import './chunk-GNHQVPZP.js';
18
- export { Sidebar, useSidebar } from './chunk-N7WQ53US.js';
18
+ export { Sidebar, useSidebar } from './chunk-4CM2VMLR.js';
19
19
  export { Skeleton } from './chunk-AGDW5ENV.js';
20
20
  export { Stat, StatBand } from './chunk-ESKVRRVA.js';
21
21
  export { StatList } from './chunk-3F66SAE7.js';
package/dist/sidebar.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var chunkXBBEQLMY_cjs = require('./chunk-XBBEQLMY.cjs');
3
+ var chunkM2S5GCXY_cjs = require('./chunk-M2S5GCXY.cjs');
4
4
  require('./chunk-G34OBTU3.cjs');
5
5
  require('./chunk-T6YELZPJ.cjs');
6
6
  require('./chunk-TXTRTTG7.cjs');
@@ -15,11 +15,11 @@ require('./chunk-3Z6ALUWP.cjs');
15
15
 
16
16
  Object.defineProperty(exports, "Sidebar", {
17
17
  enumerable: true,
18
- get: function () { return chunkXBBEQLMY_cjs.Sidebar; }
18
+ get: function () { return chunkM2S5GCXY_cjs.Sidebar; }
19
19
  });
20
20
  Object.defineProperty(exports, "useSidebar", {
21
21
  enumerable: true,
22
- get: function () { return chunkXBBEQLMY_cjs.useSidebar; }
22
+ get: function () { return chunkM2S5GCXY_cjs.useSidebar; }
23
23
  });
24
24
  //# sourceMappingURL=sidebar.cjs.map
25
25
  //# sourceMappingURL=sidebar.cjs.map
@@ -4,6 +4,20 @@ import { N as NavigableProps } from './types-8Sv0rCjw.cjs';
4
4
 
5
5
  type SidebarCollapseMode = "icons" | "letters";
6
6
  interface SidebarProps {
7
+ /**
8
+ * Render without the app-shell chrome — no right border, no background, and
9
+ * full width instead of the fixed `w-60`.
10
+ *
11
+ * For a sidebar living inside a container that already owns its surface: a
12
+ * card, a panel, a drawer. The defaults are right for the standalone rail and
13
+ * wrong here, and neutralising them from outside takes four `!important`
14
+ * utilities that every host has to rediscover and that rot when the base
15
+ * classes change.
16
+ *
17
+ * Chrome only — collapsing still works, and a collapsed rail keeps its fixed
18
+ * narrow width.
19
+ */
20
+ embedded?: boolean;
7
21
  children: ReactNode;
8
22
  collapsed?: boolean;
9
23
  defaultCollapsed?: boolean;
@@ -67,7 +81,7 @@ declare namespace SidebarToggle {
67
81
  var displayName: string;
68
82
  }
69
83
 
70
- declare function SidebarRoot({ children, collapsed: controlledCollapsed, defaultCollapsed, onCollapsedChange, collapseMode, className, }: SidebarProps): react.JSX.Element;
84
+ declare function SidebarRoot({ children, collapsed: controlledCollapsed, defaultCollapsed, onCollapsedChange, collapseMode, embedded, className, }: SidebarProps): react.JSX.Element;
71
85
  declare const Sidebar: typeof SidebarRoot & {
72
86
  Item: typeof SidebarItem;
73
87
  Group: typeof SidebarGroup;
package/dist/sidebar.d.ts CHANGED
@@ -4,6 +4,20 @@ import { N as NavigableProps } from './types-8Sv0rCjw.js';
4
4
 
5
5
  type SidebarCollapseMode = "icons" | "letters";
6
6
  interface SidebarProps {
7
+ /**
8
+ * Render without the app-shell chrome — no right border, no background, and
9
+ * full width instead of the fixed `w-60`.
10
+ *
11
+ * For a sidebar living inside a container that already owns its surface: a
12
+ * card, a panel, a drawer. The defaults are right for the standalone rail and
13
+ * wrong here, and neutralising them from outside takes four `!important`
14
+ * utilities that every host has to rediscover and that rot when the base
15
+ * classes change.
16
+ *
17
+ * Chrome only — collapsing still works, and a collapsed rail keeps its fixed
18
+ * narrow width.
19
+ */
20
+ embedded?: boolean;
7
21
  children: ReactNode;
8
22
  collapsed?: boolean;
9
23
  defaultCollapsed?: boolean;
@@ -67,7 +81,7 @@ declare namespace SidebarToggle {
67
81
  var displayName: string;
68
82
  }
69
83
 
70
- declare function SidebarRoot({ children, collapsed: controlledCollapsed, defaultCollapsed, onCollapsedChange, collapseMode, className, }: SidebarProps): react.JSX.Element;
84
+ declare function SidebarRoot({ children, collapsed: controlledCollapsed, defaultCollapsed, onCollapsedChange, collapseMode, embedded, className, }: SidebarProps): react.JSX.Element;
71
85
  declare const Sidebar: typeof SidebarRoot & {
72
86
  Item: typeof SidebarItem;
73
87
  Group: typeof SidebarGroup;
package/dist/sidebar.js CHANGED
@@ -1,4 +1,4 @@
1
- export { Sidebar, useSidebar } from './chunk-N7WQ53US.js';
1
+ export { Sidebar, useSidebar } from './chunk-4CM2VMLR.js';
2
2
  import './chunk-RNPFSVFN.js';
3
3
  import './chunk-CPY7NHXM.js';
4
4
  import './chunk-5U2DZ7AV.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@particle-academy/react-fancy",
3
- "version": "5.18.0",
3
+ "version": "5.19.0",
4
4
  "description": "React UI component library for Human+ UX \u2014 controlled, agent-bridgeable primitives",
5
5
  "repository": {
6
6
  "type": "git",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/Sidebar/Sidebar.context.ts","../src/components/Sidebar/SidebarItem.tsx","../src/components/Sidebar/SidebarGroup.tsx","../src/components/Sidebar/SidebarSubmenu.tsx","../src/components/Sidebar/SidebarToggle.tsx","../src/components/Sidebar/Sidebar.tsx"],"names":["jsxs","jsx","getLetters"],"mappings":"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","file":"chunk-N7WQ53US.js","sourcesContent":["import { createContext, useContext } from \"react\";\nimport type { SidebarContextValue } from \"./Sidebar.types\";\n\nexport const SidebarContext = createContext<SidebarContextValue | null>(null);\n\nexport function useSidebar(): SidebarContextValue {\n const ctx = useContext(SidebarContext);\n if (!ctx) {\n throw new Error(\"useSidebar must be used within a <Sidebar> component\");\n }\n return ctx;\n}\n","import type { ElementType } from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { useSidebar } from \"./Sidebar.context\";\nimport type { SidebarItemProps } from \"./Sidebar.types\";\n\n/** Extract first 3 characters from a ReactNode if it's a string. */\nfunction getLetters(children: React.ReactNode): string {\n if (typeof children === \"string\") return children.slice(0, 3);\n return \"...\";\n}\n\nexport function SidebarItem({\n children,\n href,\n as: As,\n icon,\n active = false,\n disabled = false,\n badge,\n onClick,\n className,\n ...rest\n}: SidebarItemProps) {\n const { collapsed, collapseMode } = useSidebar();\n\n // Link mode engages on `href` OR `as` — a `to`-based router (TanStack Router,\n // React Router) passes no href, and would otherwise render a <button> that\n // navigates nowhere. `onClick` now rides along in link mode instead of being\n // dropped: an item that both navigates and closes a drawer is the common case.\n const isLink = Boolean(href || As);\n const Tag = isLink ? ((As ?? \"a\") as ElementType) : \"button\";\n const tagProps = isLink\n ? { ...(href ? { href } : {}), onClick }\n : { type: \"button\" as const, onClick };\n\n const showIconOnly = collapsed && collapseMode === \"icons\" && icon;\n const showLetters = collapsed && (collapseMode === \"letters\" || (collapseMode === \"icons\" && !icon));\n\n const title = typeof children === \"string\" ? children : undefined;\n\n return (\n <Tag\n {...tagProps}\n {...rest}\n data-react-fancy-sidebar-item=\"\"\n data-active={active || undefined}\n aria-current={active ? \"page\" : undefined}\n aria-disabled={disabled || undefined}\n title={collapsed ? title : undefined}\n className={cn(\n // `w-full` matters when the Tag is a <button>: form controls size to\n // FIT-CONTENT, not to their parent, so a long label made the item wider\n // than the sidebar and an ancestor clipped the overflow — which reads as\n // a label cut off mid-word rather than an ellipsis. Without this,\n // `min-w-0` on the label below can never engage, because the item is\n // never under width pressure in the first place.\n \"flex w-full items-center rounded-md text-sm font-medium transition-colors\",\n \"outline-none focus-visible:ring-2 focus-visible:ring-blue-500\",\n collapsed ? \"justify-center px-2 py-2\" : \"gap-2 px-3 py-2\",\n active\n ? \"bg-zinc-100 text-zinc-900 dark:bg-zinc-800 dark:text-zinc-100\"\n : \"text-zinc-600 hover:bg-zinc-50 hover:text-zinc-900 dark:text-zinc-400 dark:hover:bg-zinc-800/50 dark:hover:text-zinc-100\",\n disabled && \"pointer-events-none opacity-50\",\n className,\n )}\n >\n {showIconOnly && (\n <span className=\"flex h-5 w-5 shrink-0 items-center justify-center\">{icon}</span>\n )}\n {showLetters && (\n <span className=\"text-xs font-semibold uppercase\">{getLetters(children)}</span>\n )}\n {!collapsed && (\n <>\n {icon && <span className=\"flex h-5 w-5 shrink-0 items-center justify-center\">{icon}</span>}\n {/*\n `min-w-0` is load-bearing, not tidiness. A flex item defaults to\n `min-width: auto`, which resolves to its MIN-CONTENT width — so with\n `truncate` alone the span refuses to shrink below the full label,\n and the item grows wider than the sidebar instead of ellipsing.\n The overflow then gets clipped by an ancestor, which looks like a\n mid-word cut rather than a truncation.\n\n Only shows up with labels longer than the sidebar is wide, which is\n why it survived: short nav labels never trigger it.\n */}\n <span className=\"min-w-0 flex-1 truncate text-left\">{children}</span>\n {badge && <span className=\"shrink-0\">{badge}</span>}\n </>\n )}\n </Tag>\n );\n}\n\nSidebarItem.displayName = \"SidebarItem\";\n","import { cn } from \"../../utils/cn\";\nimport { useSidebar } from \"./Sidebar.context\";\nimport type { SidebarGroupProps } from \"./Sidebar.types\";\n\nexport function SidebarGroup({ children, label, className }: SidebarGroupProps) {\n const { collapsed } = useSidebar();\n\n return (\n <div data-react-fancy-sidebar-group=\"\" className={cn(\"py-1\", className)}>\n {label && !collapsed && (\n <p className=\"mb-1 px-3 text-xs font-semibold uppercase tracking-wider text-zinc-400 dark:text-zinc-500\">\n {label}\n </p>\n )}\n {label && collapsed && (\n <div className=\"mx-auto mb-1 h-px w-6 bg-zinc-200 dark:bg-zinc-700\" />\n )}\n {children}\n </div>\n );\n}\n\nSidebarGroup.displayName = \"SidebarGroup\";\n","import { useState } from \"react\";\nimport { ChevronDown } from \"lucide-react\";\nimport { cn } from \"../../utils/cn\";\nimport { useSidebar } from \"./Sidebar.context\";\nimport type { SidebarSubmenuProps } from \"./Sidebar.types\";\n\n/** Extract first 3 characters from a string. */\nfunction getLetters(label: string): string {\n return label.slice(0, 3);\n}\n\nexport function SidebarSubmenu({\n children,\n label,\n icon,\n defaultOpen = false,\n className,\n}: SidebarSubmenuProps) {\n const [open, setOpen] = useState(defaultOpen);\n const { collapsed, collapseMode } = useSidebar();\n\n const showIconOnly = collapsed && collapseMode === \"icons\" && icon;\n const showLetters = collapsed && (collapseMode === \"letters\" || (collapseMode === \"icons\" && !icon));\n\n // When collapsed, just show the icon/letters as a simple item (no expand)\n if (collapsed) {\n return (\n <div\n data-react-fancy-sidebar-submenu=\"\"\n title={label}\n className={cn(\n \"flex items-center justify-center rounded-md px-2 py-2 text-sm font-medium transition-colors\",\n \"text-zinc-600 hover:bg-zinc-50 hover:text-zinc-900\",\n \"dark:text-zinc-400 dark:hover:bg-zinc-800/50 dark:hover:text-zinc-100\",\n className,\n )}\n >\n {showIconOnly && (\n <span className=\"flex h-5 w-5 shrink-0 items-center justify-center\">{icon}</span>\n )}\n {showLetters && (\n <span className=\"text-xs font-semibold uppercase\">{getLetters(label)}</span>\n )}\n </div>\n );\n }\n\n return (\n <div data-react-fancy-sidebar-submenu=\"\" className={className}>\n <button\n type=\"button\"\n onClick={() => setOpen((v) => !v)}\n className={cn(\n \"flex w-full items-center gap-2 rounded-md px-3 py-2 text-sm font-medium transition-colors\",\n \"text-zinc-600 hover:bg-zinc-50 hover:text-zinc-900\",\n \"dark:text-zinc-400 dark:hover:bg-zinc-800/50 dark:hover:text-zinc-100\",\n )}\n >\n {icon && <span className=\"flex h-5 w-5 shrink-0 items-center justify-center\">{icon}</span>}\n <span className=\"flex-1 text-left\">{label}</span>\n <ChevronDown\n className={cn(\n \"h-3.5 w-3.5 opacity-60 transition-transform duration-200\",\n open && \"rotate-180\",\n )}\n />\n </button>\n <div\n className={cn(\n \"grid transition-[grid-template-rows] duration-200\",\n open ? \"grid-rows-[1fr]\" : \"grid-rows-[0fr]\",\n )}\n >\n <div className=\"overflow-hidden\">\n <div className=\"ml-4 border-l border-zinc-200 pl-2 pt-1 dark:border-zinc-700\">\n {children}\n </div>\n </div>\n </div>\n </div>\n );\n}\n\nSidebarSubmenu.displayName = \"SidebarSubmenu\";\n","import { PanelLeftClose, PanelLeftOpen } from \"lucide-react\";\nimport { cn } from \"../../utils/cn\";\nimport { useSidebar } from \"./Sidebar.context\";\nimport type { SidebarToggleProps } from \"./Sidebar.types\";\n\nexport function SidebarToggle({ className }: SidebarToggleProps) {\n const { collapsed, setCollapsed } = useSidebar();\n\n return (\n <button\n type=\"button\"\n data-react-fancy-sidebar-toggle=\"\"\n onClick={() => setCollapsed(!collapsed)}\n title={collapsed ? \"Expand sidebar\" : \"Collapse sidebar\"}\n className={cn(\n \"flex items-center justify-center rounded-md p-1.5 text-zinc-400 transition-colors\",\n \"hover:bg-zinc-100 hover:text-zinc-600 dark:hover:bg-zinc-800 dark:hover:text-zinc-300\",\n className,\n )}\n >\n {collapsed ? (\n <PanelLeftOpen className=\"h-4 w-4\" />\n ) : (\n <PanelLeftClose className=\"h-4 w-4\" />\n )}\n </button>\n );\n}\n\nSidebarToggle.displayName = \"SidebarToggle\";\n","import { cn } from \"../../utils/cn\";\nimport { useControllableState } from \"../../hooks\";\nimport { SidebarContext } from \"./Sidebar.context\";\nimport { SidebarItem } from \"./SidebarItem\";\nimport { SidebarGroup } from \"./SidebarGroup\";\nimport { SidebarSubmenu } from \"./SidebarSubmenu\";\nimport { SidebarToggle } from \"./SidebarToggle\";\nimport type { SidebarProps } from \"./Sidebar.types\";\n\nfunction SidebarRoot({\n children,\n collapsed: controlledCollapsed,\n defaultCollapsed = false,\n onCollapsedChange,\n collapseMode = \"icons\",\n className,\n}: SidebarProps) {\n const [collapsed, setCollapsed] = useControllableState(\n controlledCollapsed,\n defaultCollapsed,\n onCollapsedChange,\n );\n\n return (\n <SidebarContext.Provider value={{ collapsed, collapseMode, setCollapsed }}>\n <aside\n data-react-fancy-sidebar=\"\"\n data-collapsed={collapsed || undefined}\n className={cn(\n \"flex flex-col gap-0.5 border-r border-zinc-200 bg-white transition-[width] duration-200 dark:border-zinc-700 dark:bg-zinc-900\",\n collapsed ? \"w-16\" : \"w-60\",\n className,\n )}\n >\n {children}\n </aside>\n </SidebarContext.Provider>\n );\n}\n\nexport const Sidebar = Object.assign(SidebarRoot, {\n Item: SidebarItem,\n Group: SidebarGroup,\n Submenu: SidebarSubmenu,\n Toggle: SidebarToggle,\n});\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/Sidebar/Sidebar.context.ts","../src/components/Sidebar/SidebarItem.tsx","../src/components/Sidebar/SidebarGroup.tsx","../src/components/Sidebar/SidebarSubmenu.tsx","../src/components/Sidebar/SidebarToggle.tsx","../src/components/Sidebar/Sidebar.tsx"],"names":["createContext","useContext","jsxs","cn","jsx","Fragment","getLetters","useState","ChevronDown","PanelLeftOpen","PanelLeftClose","useControllableState"],"mappings":"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","file":"chunk-XBBEQLMY.cjs","sourcesContent":["import { createContext, useContext } from \"react\";\nimport type { SidebarContextValue } from \"./Sidebar.types\";\n\nexport const SidebarContext = createContext<SidebarContextValue | null>(null);\n\nexport function useSidebar(): SidebarContextValue {\n const ctx = useContext(SidebarContext);\n if (!ctx) {\n throw new Error(\"useSidebar must be used within a <Sidebar> component\");\n }\n return ctx;\n}\n","import type { ElementType } from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { useSidebar } from \"./Sidebar.context\";\nimport type { SidebarItemProps } from \"./Sidebar.types\";\n\n/** Extract first 3 characters from a ReactNode if it's a string. */\nfunction getLetters(children: React.ReactNode): string {\n if (typeof children === \"string\") return children.slice(0, 3);\n return \"...\";\n}\n\nexport function SidebarItem({\n children,\n href,\n as: As,\n icon,\n active = false,\n disabled = false,\n badge,\n onClick,\n className,\n ...rest\n}: SidebarItemProps) {\n const { collapsed, collapseMode } = useSidebar();\n\n // Link mode engages on `href` OR `as` — a `to`-based router (TanStack Router,\n // React Router) passes no href, and would otherwise render a <button> that\n // navigates nowhere. `onClick` now rides along in link mode instead of being\n // dropped: an item that both navigates and closes a drawer is the common case.\n const isLink = Boolean(href || As);\n const Tag = isLink ? ((As ?? \"a\") as ElementType) : \"button\";\n const tagProps = isLink\n ? { ...(href ? { href } : {}), onClick }\n : { type: \"button\" as const, onClick };\n\n const showIconOnly = collapsed && collapseMode === \"icons\" && icon;\n const showLetters = collapsed && (collapseMode === \"letters\" || (collapseMode === \"icons\" && !icon));\n\n const title = typeof children === \"string\" ? children : undefined;\n\n return (\n <Tag\n {...tagProps}\n {...rest}\n data-react-fancy-sidebar-item=\"\"\n data-active={active || undefined}\n aria-current={active ? \"page\" : undefined}\n aria-disabled={disabled || undefined}\n title={collapsed ? title : undefined}\n className={cn(\n // `w-full` matters when the Tag is a <button>: form controls size to\n // FIT-CONTENT, not to their parent, so a long label made the item wider\n // than the sidebar and an ancestor clipped the overflow — which reads as\n // a label cut off mid-word rather than an ellipsis. Without this,\n // `min-w-0` on the label below can never engage, because the item is\n // never under width pressure in the first place.\n \"flex w-full items-center rounded-md text-sm font-medium transition-colors\",\n \"outline-none focus-visible:ring-2 focus-visible:ring-blue-500\",\n collapsed ? \"justify-center px-2 py-2\" : \"gap-2 px-3 py-2\",\n active\n ? \"bg-zinc-100 text-zinc-900 dark:bg-zinc-800 dark:text-zinc-100\"\n : \"text-zinc-600 hover:bg-zinc-50 hover:text-zinc-900 dark:text-zinc-400 dark:hover:bg-zinc-800/50 dark:hover:text-zinc-100\",\n disabled && \"pointer-events-none opacity-50\",\n className,\n )}\n >\n {showIconOnly && (\n <span className=\"flex h-5 w-5 shrink-0 items-center justify-center\">{icon}</span>\n )}\n {showLetters && (\n <span className=\"text-xs font-semibold uppercase\">{getLetters(children)}</span>\n )}\n {!collapsed && (\n <>\n {icon && <span className=\"flex h-5 w-5 shrink-0 items-center justify-center\">{icon}</span>}\n {/*\n `min-w-0` is load-bearing, not tidiness. A flex item defaults to\n `min-width: auto`, which resolves to its MIN-CONTENT width — so with\n `truncate` alone the span refuses to shrink below the full label,\n and the item grows wider than the sidebar instead of ellipsing.\n The overflow then gets clipped by an ancestor, which looks like a\n mid-word cut rather than a truncation.\n\n Only shows up with labels longer than the sidebar is wide, which is\n why it survived: short nav labels never trigger it.\n */}\n <span className=\"min-w-0 flex-1 truncate text-left\">{children}</span>\n {badge && <span className=\"shrink-0\">{badge}</span>}\n </>\n )}\n </Tag>\n );\n}\n\nSidebarItem.displayName = \"SidebarItem\";\n","import { cn } from \"../../utils/cn\";\nimport { useSidebar } from \"./Sidebar.context\";\nimport type { SidebarGroupProps } from \"./Sidebar.types\";\n\nexport function SidebarGroup({ children, label, className }: SidebarGroupProps) {\n const { collapsed } = useSidebar();\n\n return (\n <div data-react-fancy-sidebar-group=\"\" className={cn(\"py-1\", className)}>\n {label && !collapsed && (\n <p className=\"mb-1 px-3 text-xs font-semibold uppercase tracking-wider text-zinc-400 dark:text-zinc-500\">\n {label}\n </p>\n )}\n {label && collapsed && (\n <div className=\"mx-auto mb-1 h-px w-6 bg-zinc-200 dark:bg-zinc-700\" />\n )}\n {children}\n </div>\n );\n}\n\nSidebarGroup.displayName = \"SidebarGroup\";\n","import { useState } from \"react\";\nimport { ChevronDown } from \"lucide-react\";\nimport { cn } from \"../../utils/cn\";\nimport { useSidebar } from \"./Sidebar.context\";\nimport type { SidebarSubmenuProps } from \"./Sidebar.types\";\n\n/** Extract first 3 characters from a string. */\nfunction getLetters(label: string): string {\n return label.slice(0, 3);\n}\n\nexport function SidebarSubmenu({\n children,\n label,\n icon,\n defaultOpen = false,\n className,\n}: SidebarSubmenuProps) {\n const [open, setOpen] = useState(defaultOpen);\n const { collapsed, collapseMode } = useSidebar();\n\n const showIconOnly = collapsed && collapseMode === \"icons\" && icon;\n const showLetters = collapsed && (collapseMode === \"letters\" || (collapseMode === \"icons\" && !icon));\n\n // When collapsed, just show the icon/letters as a simple item (no expand)\n if (collapsed) {\n return (\n <div\n data-react-fancy-sidebar-submenu=\"\"\n title={label}\n className={cn(\n \"flex items-center justify-center rounded-md px-2 py-2 text-sm font-medium transition-colors\",\n \"text-zinc-600 hover:bg-zinc-50 hover:text-zinc-900\",\n \"dark:text-zinc-400 dark:hover:bg-zinc-800/50 dark:hover:text-zinc-100\",\n className,\n )}\n >\n {showIconOnly && (\n <span className=\"flex h-5 w-5 shrink-0 items-center justify-center\">{icon}</span>\n )}\n {showLetters && (\n <span className=\"text-xs font-semibold uppercase\">{getLetters(label)}</span>\n )}\n </div>\n );\n }\n\n return (\n <div data-react-fancy-sidebar-submenu=\"\" className={className}>\n <button\n type=\"button\"\n onClick={() => setOpen((v) => !v)}\n className={cn(\n \"flex w-full items-center gap-2 rounded-md px-3 py-2 text-sm font-medium transition-colors\",\n \"text-zinc-600 hover:bg-zinc-50 hover:text-zinc-900\",\n \"dark:text-zinc-400 dark:hover:bg-zinc-800/50 dark:hover:text-zinc-100\",\n )}\n >\n {icon && <span className=\"flex h-5 w-5 shrink-0 items-center justify-center\">{icon}</span>}\n <span className=\"flex-1 text-left\">{label}</span>\n <ChevronDown\n className={cn(\n \"h-3.5 w-3.5 opacity-60 transition-transform duration-200\",\n open && \"rotate-180\",\n )}\n />\n </button>\n <div\n className={cn(\n \"grid transition-[grid-template-rows] duration-200\",\n open ? \"grid-rows-[1fr]\" : \"grid-rows-[0fr]\",\n )}\n >\n <div className=\"overflow-hidden\">\n <div className=\"ml-4 border-l border-zinc-200 pl-2 pt-1 dark:border-zinc-700\">\n {children}\n </div>\n </div>\n </div>\n </div>\n );\n}\n\nSidebarSubmenu.displayName = \"SidebarSubmenu\";\n","import { PanelLeftClose, PanelLeftOpen } from \"lucide-react\";\nimport { cn } from \"../../utils/cn\";\nimport { useSidebar } from \"./Sidebar.context\";\nimport type { SidebarToggleProps } from \"./Sidebar.types\";\n\nexport function SidebarToggle({ className }: SidebarToggleProps) {\n const { collapsed, setCollapsed } = useSidebar();\n\n return (\n <button\n type=\"button\"\n data-react-fancy-sidebar-toggle=\"\"\n onClick={() => setCollapsed(!collapsed)}\n title={collapsed ? \"Expand sidebar\" : \"Collapse sidebar\"}\n className={cn(\n \"flex items-center justify-center rounded-md p-1.5 text-zinc-400 transition-colors\",\n \"hover:bg-zinc-100 hover:text-zinc-600 dark:hover:bg-zinc-800 dark:hover:text-zinc-300\",\n className,\n )}\n >\n {collapsed ? (\n <PanelLeftOpen className=\"h-4 w-4\" />\n ) : (\n <PanelLeftClose className=\"h-4 w-4\" />\n )}\n </button>\n );\n}\n\nSidebarToggle.displayName = \"SidebarToggle\";\n","import { cn } from \"../../utils/cn\";\nimport { useControllableState } from \"../../hooks\";\nimport { SidebarContext } from \"./Sidebar.context\";\nimport { SidebarItem } from \"./SidebarItem\";\nimport { SidebarGroup } from \"./SidebarGroup\";\nimport { SidebarSubmenu } from \"./SidebarSubmenu\";\nimport { SidebarToggle } from \"./SidebarToggle\";\nimport type { SidebarProps } from \"./Sidebar.types\";\n\nfunction SidebarRoot({\n children,\n collapsed: controlledCollapsed,\n defaultCollapsed = false,\n onCollapsedChange,\n collapseMode = \"icons\",\n className,\n}: SidebarProps) {\n const [collapsed, setCollapsed] = useControllableState(\n controlledCollapsed,\n defaultCollapsed,\n onCollapsedChange,\n );\n\n return (\n <SidebarContext.Provider value={{ collapsed, collapseMode, setCollapsed }}>\n <aside\n data-react-fancy-sidebar=\"\"\n data-collapsed={collapsed || undefined}\n className={cn(\n \"flex flex-col gap-0.5 border-r border-zinc-200 bg-white transition-[width] duration-200 dark:border-zinc-700 dark:bg-zinc-900\",\n collapsed ? \"w-16\" : \"w-60\",\n className,\n )}\n >\n {children}\n </aside>\n </SidebarContext.Provider>\n );\n}\n\nexport const Sidebar = Object.assign(SidebarRoot, {\n Item: SidebarItem,\n Group: SidebarGroup,\n Submenu: SidebarSubmenu,\n Toggle: SidebarToggle,\n});\n"]}