@tetrascience-npm/tetrascience-react-ui 1.0.0-beta.136.1 → 1.0.0-beta.137.1
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/components/ai/context.d.ts +4 -4
- package/dist/components/composed/AppShellSimple/AppShellSimple.cjs +2 -0
- package/dist/components/composed/AppShellSimple/AppShellSimple.cjs.map +1 -0
- package/dist/components/composed/AppShellSimple/AppShellSimple.d.ts +49 -0
- package/dist/components/composed/AppShellSimple/AppShellSimple.js +204 -0
- package/dist/components/composed/AppShellSimple/AppShellSimple.js.map +1 -0
- package/dist/components/composed/AppShellSimple/index.d.ts +2 -0
- package/dist/components/composed/DataAppShell/DataAppShell.cjs +1 -1
- package/dist/components/composed/DataAppShell/DataAppShell.cjs.map +1 -1
- package/dist/components/composed/DataAppShell/DataAppShell.js +86 -93
- package/dist/components/composed/DataAppShell/DataAppShell.js.map +1 -1
- package/dist/components/composed/DataAppShell/PrimaryNav.cjs +1 -1
- package/dist/components/composed/DataAppShell/PrimaryNav.cjs.map +1 -1
- package/dist/components/composed/DataAppShell/PrimaryNav.js +106 -92
- package/dist/components/composed/DataAppShell/PrimaryNav.js.map +1 -1
- package/dist/components/ui/badge.d.ts +1 -1
- package/dist/components/ui/button.d.ts +2 -2
- package/dist/components/ui/input-group.d.ts +1 -1
- package/dist/components/ui/item.d.ts +2 -2
- package/dist/components/ui/tabs.d.ts +1 -1
- package/dist/composed/AppShellSimple.cjs +2 -0
- package/dist/composed/AppShellSimple.cjs.map +1 -0
- package/dist/composed/AppShellSimple.js +5 -0
- package/dist/composed/AppShellSimple.js.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.css +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +712 -710
- package/dist/index.js.map +1 -1
- package/dist/index.tailwind.css +1 -1
- package/package.json +1 -1
|
@@ -30,11 +30,11 @@ export declare const ContextContentBody: ({ children, className, ...props }: Con
|
|
|
30
30
|
export type ContextContentFooterProps = ComponentProps<"div">;
|
|
31
31
|
export declare const ContextContentFooter: ({ children, className, ...props }: ContextContentFooterProps) => import("react/jsx-runtime").JSX.Element;
|
|
32
32
|
export type ContextInputUsageProps = ComponentProps<"div">;
|
|
33
|
-
export declare const ContextInputUsage: ({ className, children, ...props }: ContextInputUsageProps) => string | number | bigint | true | Iterable<import('react').ReactNode> | Promise<string | number | bigint | boolean | import('react').ReactPortal | import('react').ReactElement<unknown, string | import('react').JSXElementConstructor<any>> | Iterable<import('react').ReactNode> | null | undefined> |
|
|
33
|
+
export declare const ContextInputUsage: ({ className, children, ...props }: ContextInputUsageProps) => string | number | bigint | true | import("react/jsx-runtime").JSX.Element | Iterable<import('react').ReactNode> | Promise<string | number | bigint | boolean | import('react').ReactPortal | import('react').ReactElement<unknown, string | import('react').JSXElementConstructor<any>> | Iterable<import('react').ReactNode> | null | undefined> | null;
|
|
34
34
|
export type ContextOutputUsageProps = ComponentProps<"div">;
|
|
35
|
-
export declare const ContextOutputUsage: ({ className, children, ...props }: ContextOutputUsageProps) => string | number | bigint | true | Iterable<import('react').ReactNode> | Promise<string | number | bigint | boolean | import('react').ReactPortal | import('react').ReactElement<unknown, string | import('react').JSXElementConstructor<any>> | Iterable<import('react').ReactNode> | null | undefined> |
|
|
35
|
+
export declare const ContextOutputUsage: ({ className, children, ...props }: ContextOutputUsageProps) => string | number | bigint | true | import("react/jsx-runtime").JSX.Element | Iterable<import('react').ReactNode> | Promise<string | number | bigint | boolean | import('react').ReactPortal | import('react').ReactElement<unknown, string | import('react').JSXElementConstructor<any>> | Iterable<import('react').ReactNode> | null | undefined> | null;
|
|
36
36
|
export type ContextReasoningUsageProps = ComponentProps<"div">;
|
|
37
|
-
export declare const ContextReasoningUsage: ({ className, children, ...props }: ContextReasoningUsageProps) => string | number | bigint | true | Iterable<import('react').ReactNode> | Promise<string | number | bigint | boolean | import('react').ReactPortal | import('react').ReactElement<unknown, string | import('react').JSXElementConstructor<any>> | Iterable<import('react').ReactNode> | null | undefined> |
|
|
37
|
+
export declare const ContextReasoningUsage: ({ className, children, ...props }: ContextReasoningUsageProps) => string | number | bigint | true | import("react/jsx-runtime").JSX.Element | Iterable<import('react').ReactNode> | Promise<string | number | bigint | boolean | import('react').ReactPortal | import('react').ReactElement<unknown, string | import('react').JSXElementConstructor<any>> | Iterable<import('react').ReactNode> | null | undefined> | null;
|
|
38
38
|
export type ContextCacheUsageProps = ComponentProps<"div">;
|
|
39
|
-
export declare const ContextCacheUsage: ({ className, children, ...props }: ContextCacheUsageProps) => string | number | bigint | true | Iterable<import('react').ReactNode> | Promise<string | number | bigint | boolean | import('react').ReactPortal | import('react').ReactElement<unknown, string | import('react').JSXElementConstructor<any>> | Iterable<import('react').ReactNode> | null | undefined> |
|
|
39
|
+
export declare const ContextCacheUsage: ({ className, children, ...props }: ContextCacheUsageProps) => string | number | bigint | true | import("react/jsx-runtime").JSX.Element | Iterable<import('react').ReactNode> | Promise<string | number | bigint | boolean | import('react').ReactPortal | import('react').ReactElement<unknown, string | import('react').JSXElementConstructor<any>> | Iterable<import('react').ReactNode> | null | undefined> | null;
|
|
40
40
|
export {};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("react/jsx-runtime"),F=require("lucide-react"),W=require("react"),K=require("../DataAppShell/PrimaryNav.cjs"),U=require("../TopBar/TopBar.cjs"),l=require("../../../ui/breadcrumb.cjs"),$=require("../../../ui/button.cjs"),x=require("../../../ui/tooltip.cjs"),w=require("../../../lib/utils.cjs");function G(n){const e=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(n){for(const t in n)if(t!=="default"){const i=Object.getOwnPropertyDescriptor(n,t);Object.defineProperty(e,t,i.get?i:{enumerable:!0,get:()=>n[t]})}}return e.default=n,Object.freeze(e)}const c=G(W),f=["sidebar","rail","hidden"],u=f.length-1,d=n=>n>=u?-1:1,R=n=>Math.max(0,f.indexOf(n)),y=48,_=220,X=(y+_)/2,Y=y/2,D={sidebar:_,rail:y,hidden:0};function J(n){const e=n>=X?0:n>=Y?1:u;return{index:e,dir:d(e)}}function Q({index:n,dir:e}){const t=n+e;if(t<0||t>u){const i=e*-1;return{index:n+i,dir:i}}return{index:t,dir:e}}function Z(n,e){switch(f[e]){case"sidebar":return"Expand navigation to labels";case"hidden":return"Hide navigation";default:return e>n?"Collapse navigation to icons":"Expand navigation to icons"}}const ee=[];function re({items:n}){return r.jsx(l.Breadcrumb,{className:"min-w-0",children:r.jsx(l.BreadcrumbList,{className:"flex-nowrap min-w-0",children:n.map((e,t)=>{const i=t===n.length-1,h=!i&&(!!e.href||!!e.onClick);return r.jsxs(c.Fragment,{children:[t>0&&r.jsx(l.BreadcrumbSeparator,{className:"shrink-0",children:"/"}),r.jsx(l.BreadcrumbItem,{className:i?"min-w-0":"shrink-0",children:i?r.jsx(l.BreadcrumbPage,{className:"truncate font-medium",children:e.label}):h&&e.href?r.jsx(l.BreadcrumbLink,{href:e.href,className:"whitespace-nowrap text-primary",children:e.label}):h&&e.onClick?r.jsx(l.BreadcrumbLink,{asChild:!0,className:"whitespace-nowrap text-primary",children:r.jsx("button",{type:"button",className:"cursor-pointer",onClick:e.onClick,children:e.label})}):r.jsx("span",{className:"whitespace-nowrap",children:e.label})})]},`${e.label}-${t}`)})})})}function ne({label:n,onCycle:e}){return r.jsx(x.TooltipProvider,{children:r.jsxs(x.Tooltip,{children:[r.jsx(x.TooltipTrigger,{asChild:!0,children:r.jsx($.Button,{"data-slot":"app-shell-simple-nav-toggle",variant:"ghost",size:"icon","aria-label":n,className:"-ml-1 shrink-0 text-muted-foreground hover:bg-sidebar-accent/60 hover:text-foreground active:translate-y-0",onClick:e,children:r.jsx(F.PanelLeft,{className:"size-4"})})}),r.jsx(x.TooltipContent,{side:"bottom",children:n})]})})}function ae({showNav:n=!0,navGroups:e=ee,activeKey:t,onSelect:i,breadcrumbs:h,headerActions:B,userMenu:I,defaultNav:L="sidebar",nav:v,onNavChange:S,children:O}){const[g,q]=c.useState(()=>{const a=R(v??L);return{index:a,dir:d(a)}}),s=v===void 0?g.index:R(v),z=g.index===s?g.dir:d(s),o=f[s],p=c.useCallback(a=>{q(a),a.index!==s&&S?.(f[a.index])},[s,S]),T=Q({index:s,dir:z}),H=()=>p(T),E=Z(s,T.index),C=c.useId(),P=c.useRef(null),[j,m]=c.useState(!1),M=a=>p(J(a-(P.current?.getBoundingClientRect().left??0))),k=a=>{const b=Math.min(u,Math.max(0,s+a));b!==s&&p({index:b,dir:d(b)})},V=a=>{const A={ArrowLeft:()=>k(1),ArrowRight:()=>k(-1),Home:()=>p({index:0,dir:d(0)}),End:()=>p({index:u,dir:d(u)})}[a.key];A&&(a.preventDefault(),A())},N=o==="hidden";return r.jsxs("div",{"data-slot":"app-shell-simple","data-nav-state":o,className:w.cn("grid h-screen w-full overflow-hidden [grid-template-rows:auto_minmax(0,1fr)]",n?"[grid-template-columns:auto_minmax(0,1fr)] [grid-template-areas:'top_top'_'nav_body']":"[grid-template-columns:minmax(0,1fr)] [grid-template-areas:'top'_'body']",j&&"select-none cursor-col-resize"),children:[r.jsx("div",{className:"[grid-area:top] min-w-0",children:r.jsx(U.TopBar,{left:r.jsxs(r.Fragment,{children:[n&&r.jsx(ne,{label:E,onCycle:H}),r.jsx(re,{items:h})]}),right:B})}),n&&r.jsxs("div",{ref:P,id:C,"data-slot":"app-shell-simple-nav","data-nav-state":o,className:w.cn("[grid-area:nav] relative min-h-0 flex flex-col shrink-0 bg-sidebar h-full transition-[width] duration-200",N?"overflow-hidden":"border-r border-sidebar-border"),style:{width:D[o]},children:[r.jsx("div",{"data-slot":"app-shell-simple-nav-content",className:"h-full w-full overflow-hidden",inert:N,children:r.jsx(K.DataAppShellPrimaryNav,{variant:o==="rail"?"rail":"sidebar","aria-label":"Application navigation",navGroups:e,activeKey:t,onSelect:i,user:I,className:"h-full w-full"})}),r.jsx("div",{role:"separator",tabIndex:0,"aria-orientation":"vertical","aria-label":"Resize navigation","aria-controls":C,"aria-valuemin":0,"aria-valuemax":_,"aria-valuenow":D[o],"aria-valuetext":o,onKeyDown:V,onPointerDown:a=>{a.preventDefault(),a.currentTarget.setPointerCapture(a.pointerId),m(!0)},onPointerMove:a=>{if(j){if(a.buttons===0){m(!1);return}M(a.clientX)}},onPointerUp:()=>m(!1),onPointerCancel:()=>m(!1),onLostPointerCapture:()=>m(!1),className:w.cn("absolute top-0 right-0 z-10 h-full translate-x-1/2 cursor-col-resize transition-colors hover:bg-primary/40 focus-visible:outline-none focus-visible:bg-primary/60 focus-visible:ring-2 focus-visible:ring-ring",N?"w-3":"w-1.5",j&&"bg-primary/60")})]}),r.jsx("main",{"data-slot":"app-shell-simple-content",className:"[grid-area:body] min-h-0 min-w-0 overflow-auto bg-background",children:O})]})}exports.AppShellSimple=ae;
|
|
2
|
+
//# sourceMappingURL=AppShellSimple.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AppShellSimple.cjs","sources":["../../../../src/components/composed/AppShellSimple/AppShellSimple.tsx"],"sourcesContent":["/**\n * AppShellSimple (SW-2410) — a Data App Shell stripped down to just two zones:\n * a full-width **top bar** and a three-state **side nav**. For apps that don't\n * need the full `DataAppShell` (no secondary nav, right panel, horizontal nav\n * variant, or mobile Sheet).\n *\n * - The side-nav control **lives in the top bar** (far left, above the nav).\n * It ping-pongs the nav through three states — labels ↔ icons ↔ hidden —\n * and dragging the nav's right border snaps between the same three.\n * - The **breadcrumb is the top bar name** — it sits right after the toggle.\n *\n * Composes existing kit primitives (`TopBar`, `DataAppShellPrimaryNav`,\n * `Breadcrumb`, `Button`, `Tooltip`).\n */\nimport { PanelLeft } from \"lucide-react\";\nimport * as React from \"react\";\n\nimport {\n DataAppShellPrimaryNav,\n type NavGroup,\n type NavPage,\n} from \"@/components/composed/DataAppShell\";\nimport { TopBar } from \"@/components/composed/TopBar\";\nimport {\n Breadcrumb,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from \"@/components/ui/breadcrumb\";\nimport { Button } from \"@/components/ui/button\";\nimport {\n Tooltip,\n TooltipContent,\n TooltipProvider,\n TooltipTrigger,\n} from \"@/components/ui/tooltip\";\nimport { cn } from \"@/lib/utils\";\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface AppShellSimpleCrumb {\n /** Display label */\n label: string;\n /** If set, the crumb renders as a link */\n href?: string;\n /** Click handler when there's no `href` */\n onClick?: () => void;\n}\n\n/**\n * The side nav has three states. The top-bar toggle ping-pongs between them,\n * and dragging the nav's right border snaps between them:\n * - `sidebar` — full panel with icon + label rows\n * - `rail` — icon-only rail\n * - `hidden` — no side nav; only the top bar + content\n */\nexport type AppShellSimpleNavState = \"sidebar\" | \"rail\" | \"hidden\";\n\n/**\n * Where the nav sits in the ping-pong: which state (`index` into `NAV_ORDER`)\n * and which way the next toggle click moves (`dir`, reversing at either end).\n */\ntype NavCursor = { index: number; dir: 1 | -1 };\n\n// Ping-pong order (does not wrap): labels ↔ icons ↔ hidden.\nconst NAV_ORDER: AppShellSimpleNavState[] = [\"sidebar\", \"rail\", \"hidden\"];\nconst LAST_NAV = NAV_ORDER.length - 1;\n\n// Single source of truth for the direction convention: point inward from the\n// ends so the next toggle keeps the ping-pong moving (middle defaults forward).\nconst dirFor = (index: number): 1 | -1 => (index >= LAST_NAV ? -1 : 1);\n\nconst indexOfNav = (state: AppShellSimpleNavState) => Math.max(0, NAV_ORDER.indexOf(state));\n\n// Fixed widths per state — the border drag snaps between these; it never sets\n// an in-between width.\nconst RAIL_WIDTH = 48;\nconst SIDEBAR_WIDTH = 220;\n// Snap thresholds: midpoints between the fixed widths.\nconst RAIL_SNAP = (RAIL_WIDTH + SIDEBAR_WIDTH) / 2;\nconst HIDE_SNAP = RAIL_WIDTH / 2;\n\nconst NAV_WIDTH: Record<AppShellSimpleNavState, number> = {\n sidebar: SIDEBAR_WIDTH,\n rail: RAIL_WIDTH,\n hidden: 0,\n};\n\n/** Map a dragged pixel width to the nearest nav state. */\nfunction snapNav(width: number): NavCursor {\n const index = width >= RAIL_SNAP ? 0 : width >= HIDE_SNAP ? 1 : LAST_NAV;\n return { index, dir: dirFor(index) };\n}\n\n/** Next cursor in the ping-pong, reversing direction at either end. */\nfunction nextNav({ index, dir }: NavCursor): NavCursor {\n const forward = index + dir;\n if (forward < 0 || forward > LAST_NAV) {\n const reversed = (dir * -1) as 1 | -1;\n return { index: index + reversed, dir: reversed };\n }\n return { index: forward, dir };\n}\n\n/**\n * Label for the toggle, describing the transition the next click performs.\n * `rail` is reachable from both directions, so it can't be keyed on the\n * destination alone — arriving from `hidden` is an expand, not a collapse.\n */\nfunction navToggleLabel(from: number, to: number): string {\n switch (NAV_ORDER[to]) {\n case \"sidebar\":\n return \"Expand navigation to labels\";\n case \"hidden\":\n return \"Hide navigation\";\n default:\n return to > from ? \"Collapse navigation to icons\" : \"Expand navigation to icons\";\n }\n}\n\nexport interface AppShellSimpleProps {\n /**\n * Whether the app has a side nav at all (default `true`). When `false`, the\n * shell renders as a top bar + full-width body: no nav zone, and no top-bar\n * toggle. This is the app-level switch — distinct from the runtime `hidden`\n * nav state, which the end user can toggle back open. `navGroups` is ignored\n * when `showNav` is `false`.\n */\n showNav?: boolean;\n /** Nav groups rendered in the side nav (ignored when `showNav` is `false`) */\n navGroups?: NavGroup[];\n /** Controlled active page id — takes precedence over per-page `isActive` */\n activeKey?: string;\n /** Called with the selected page id after the page's own `onClick` */\n onSelect?: (key: string, page: NavPage) => void;\n /** Breadcrumb trail — the top bar name */\n breadcrumbs: AppShellSimpleCrumb[];\n /** Right-side top bar actions (e.g. notifications, user menu) */\n headerActions?: React.ReactNode;\n /** Bottom-of-nav user slot */\n userMenu?: React.ReactNode;\n /** Uncontrolled initial nav state (default `sidebar`) */\n defaultNav?: AppShellSimpleNavState;\n /** Controlled nav state — pair with `onNavChange`; overrides `defaultNav` */\n nav?: AppShellSimpleNavState;\n /** Fired whenever the nav state changes (toggle, drag, or keyboard resize) */\n onNavChange?: (nav: AppShellSimpleNavState) => void;\n /** Main content */\n children: React.ReactNode;\n}\n\nconst EMPTY_NAV_GROUPS: NavGroup[] = [];\n\n// =============================================================================\n// Breadcrumb trail — the top bar name\n// =============================================================================\n\nfunction ShellBreadcrumb({ items }: { items: AppShellSimpleCrumb[] }) {\n return (\n <Breadcrumb className=\"min-w-0\">\n <BreadcrumbList className=\"flex-nowrap min-w-0\">\n {items.map((item, index) => {\n const isLast = index === items.length - 1;\n const isClickable = !isLast && (!!item.href || !!item.onClick);\n return (\n <React.Fragment key={`${item.label}-${index}`}>\n {index > 0 && <BreadcrumbSeparator className=\"shrink-0\">/</BreadcrumbSeparator>}\n <BreadcrumbItem className={isLast ? \"min-w-0\" : \"shrink-0\"}>\n {isLast ? (\n <BreadcrumbPage className=\"truncate font-medium\">{item.label}</BreadcrumbPage>\n ) : isClickable && item.href ? (\n <BreadcrumbLink href={item.href} className=\"whitespace-nowrap text-primary\">\n {item.label}\n </BreadcrumbLink>\n ) : isClickable && item.onClick ? (\n <BreadcrumbLink asChild className=\"whitespace-nowrap text-primary\">\n <button type=\"button\" className=\"cursor-pointer\" onClick={item.onClick}>\n {item.label}\n </button>\n </BreadcrumbLink>\n ) : (\n <span className=\"whitespace-nowrap\">{item.label}</span>\n )}\n </BreadcrumbItem>\n </React.Fragment>\n );\n })}\n </BreadcrumbList>\n </Breadcrumb>\n );\n}\n\n// =============================================================================\n// Top-bar side-nav toggle — the collapse/expand control (SW-2410).\n// =============================================================================\n\nfunction SideNavToggle({ label, onCycle }: { label: string; onCycle: () => void }) {\n return (\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n data-slot=\"app-shell-simple-nav-toggle\"\n variant=\"ghost\"\n size=\"icon\"\n aria-label={label}\n // size-8 (32px) so the hover highlight box matches the nav icon box;\n // -ml-1 centers the icon on the nav's 24px gutter (TopBar has px-3);\n // hover uses sidebar-accent (not the ghost default accent) to match the\n // nav-row hover on the shared sidebar surface; no press inset.\n className=\"-ml-1 shrink-0 text-muted-foreground hover:bg-sidebar-accent/60 hover:text-foreground active:translate-y-0\"\n onClick={onCycle}\n >\n <PanelLeft className=\"size-4\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent side=\"bottom\">{label}</TooltipContent>\n </Tooltip>\n </TooltipProvider>\n );\n}\n\n// =============================================================================\n// AppShellSimple — two zones: full-width top bar + collapsible side nav\n// =============================================================================\n\nexport function AppShellSimple({\n showNav = true,\n navGroups = EMPTY_NAV_GROUPS,\n activeKey,\n onSelect,\n breadcrumbs,\n headerActions,\n userMenu,\n defaultNav = \"sidebar\",\n nav: navProp,\n onNavChange,\n children,\n}: AppShellSimpleProps) {\n // The cursor is always local: `index` is only authoritative while\n // uncontrolled, but `dir` (which way the ping-pong is travelling) has no\n // prop equivalent and is tracked here in both modes.\n const [cursor, setCursor] = React.useState<NavCursor>(() => {\n const index = indexOfNav(navProp ?? defaultNav);\n return { index, dir: dirFor(index) };\n });\n\n const index = navProp === undefined ? cursor.index : indexOfNav(navProp);\n // A controlled index moved by the parent invalidates our stored direction.\n const dir = cursor.index === index ? cursor.dir : dirFor(index);\n const navState = NAV_ORDER[index];\n\n const applyNav = React.useCallback(\n (next: NavCursor) => {\n setCursor(next);\n if (next.index !== index) onNavChange?.(NAV_ORDER[next.index]);\n },\n [index, onNavChange]\n );\n\n const nextCursor = nextNav({ index, dir });\n const cycleNav = () => applyNav(nextCursor);\n // Label describes the transition the next click performs.\n const nextLabel = navToggleLabel(index, nextCursor.index);\n\n // Drag the border to snap between the three states (widest → slimmest:\n // icon + text → icon rail → fully closed). Pointer capture keeps the drag\n // scoped to the handle — no window listeners to leak.\n //\n // The nav zone stays mounted at `width: 0` in the `hidden` state rather than\n // unmounting: unmounting mid-drag destroyed the element holding pointer\n // capture, so `pointerup` never came back and `resizing` stuck on. Keeping it\n // mounted also makes the handle draggable back out of `hidden`.\n const navId = React.useId();\n const navRef = React.useRef<HTMLDivElement>(null);\n const [resizing, setResizing] = React.useState(false);\n const snapToPointer = (clientX: number) =>\n applyNav(snapNav(clientX - (navRef.current?.getBoundingClientRect().left ?? 0)));\n\n const stepNav = (delta: 1 | -1) => {\n const target = Math.min(LAST_NAV, Math.max(0, index + delta));\n if (target !== index) applyNav({ index: target, dir: dirFor(target) });\n };\n\n const onHandleKeyDown = (e: React.KeyboardEvent) => {\n // ← narrower · → wider, matching the on-screen direction of the drag\n // (the arrow moves the nav's right border the same way).\n const move: Record<string, () => void> = {\n ArrowLeft: () => stepNav(1),\n ArrowRight: () => stepNav(-1),\n Home: () => applyNav({ index: 0, dir: dirFor(0) }),\n End: () => applyNav({ index: LAST_NAV, dir: dirFor(LAST_NAV) }),\n };\n const action = move[e.key];\n if (!action) return;\n e.preventDefault();\n action();\n };\n\n const isHidden = navState === \"hidden\";\n\n return (\n <div\n data-slot=\"app-shell-simple\"\n data-nav-state={navState}\n className={cn(\n \"grid h-screen w-full overflow-hidden [grid-template-rows:auto_minmax(0,1fr)]\",\n showNav\n ? \"[grid-template-columns:auto_minmax(0,1fr)] [grid-template-areas:'top_top'_'nav_body']\"\n : \"[grid-template-columns:minmax(0,1fr)] [grid-template-areas:'top'_'body']\",\n resizing && \"select-none cursor-col-resize\"\n )}\n >\n {/* Top bar */}\n <div className=\"[grid-area:top] min-w-0\">\n <TopBar\n left={\n <>\n {showNav && <SideNavToggle label={nextLabel} onCycle={cycleNav} />}\n <ShellBreadcrumb items={breadcrumbs} />\n </>\n }\n right={headerActions}\n />\n </div>\n\n {/* Side nav — sidebar (labels), rail (icons), or collapsed to zero width\n when hidden; the toggle ping-pongs and the border drag snaps between\n states. Omitted entirely when the app opts out (`showNav={false}`). */}\n {showNav && (\n <div\n ref={navRef}\n id={navId}\n data-slot=\"app-shell-simple-nav\"\n data-nav-state={navState}\n className={cn(\n \"[grid-area:nav] relative min-h-0 flex flex-col shrink-0 bg-sidebar h-full transition-[width] duration-200\",\n isHidden ? \"overflow-hidden\" : \"border-r border-sidebar-border\"\n )}\n style={{ width: NAV_WIDTH[navState] }}\n >\n {/* `inert` keeps the collapsed nav out of the tab order and the\n accessibility tree while it stays mounted for the drag handle. */}\n <div\n data-slot=\"app-shell-simple-nav-content\"\n className=\"h-full w-full overflow-hidden\"\n inert={isHidden}\n >\n <DataAppShellPrimaryNav\n variant={navState === \"rail\" ? \"rail\" : \"sidebar\"}\n aria-label=\"Application navigation\"\n navGroups={navGroups}\n activeKey={activeKey}\n onSelect={onSelect}\n user={userMenu}\n className=\"h-full w-full\"\n />\n </div>\n {/* Drag handle on the right border — snaps between the nav states.\n Also a keyboard-operable window splitter (arrows / Home / End). */}\n <div\n role=\"separator\"\n tabIndex={0}\n aria-orientation=\"vertical\"\n aria-label=\"Resize navigation\"\n aria-controls={navId}\n aria-valuemin={0}\n aria-valuemax={SIDEBAR_WIDTH}\n aria-valuenow={NAV_WIDTH[navState]}\n aria-valuetext={navState}\n onKeyDown={onHandleKeyDown}\n onPointerDown={(e) => {\n e.preventDefault();\n e.currentTarget.setPointerCapture(e.pointerId);\n setResizing(true);\n }}\n onPointerMove={(e) => {\n if (!resizing) return;\n // Defensive: a lost capture can strand `resizing` on, which would\n // otherwise turn a plain hover into a resize.\n if (e.buttons === 0) {\n setResizing(false);\n return;\n }\n snapToPointer(e.clientX);\n }}\n onPointerUp={() => setResizing(false)}\n onPointerCancel={() => setResizing(false)}\n onLostPointerCapture={() => setResizing(false)}\n className={cn(\n \"absolute top-0 right-0 z-10 h-full translate-x-1/2 cursor-col-resize transition-colors hover:bg-primary/40 focus-visible:outline-none focus-visible:bg-primary/60 focus-visible:ring-2 focus-visible:ring-ring\",\n isHidden ? \"w-3\" : \"w-1.5\",\n resizing && \"bg-primary/60\"\n )}\n />\n </div>\n )}\n\n {/* Body */}\n <main\n data-slot=\"app-shell-simple-content\"\n className=\"[grid-area:body] min-h-0 min-w-0 overflow-auto bg-background\"\n >\n {children}\n </main>\n </div>\n );\n}\n"],"names":["NAV_ORDER","LAST_NAV","dirFor","index","indexOfNav","state","RAIL_WIDTH","SIDEBAR_WIDTH","RAIL_SNAP","HIDE_SNAP","NAV_WIDTH","snapNav","width","nextNav","dir","forward","reversed","navToggleLabel","from","to","EMPTY_NAV_GROUPS","ShellBreadcrumb","items","jsx","Breadcrumb","BreadcrumbList","item","isLast","isClickable","jsxs","React","BreadcrumbSeparator","BreadcrumbItem","BreadcrumbPage","BreadcrumbLink","SideNavToggle","label","onCycle","TooltipProvider","Tooltip","TooltipTrigger","Button","PanelLeft","TooltipContent","AppShellSimple","showNav","navGroups","activeKey","onSelect","breadcrumbs","headerActions","userMenu","defaultNav","navProp","onNavChange","children","cursor","setCursor","navState","applyNav","next","nextCursor","cycleNav","nextLabel","navId","navRef","resizing","setResizing","snapToPointer","clientX","stepNav","delta","target","onHandleKeyDown","e","action","isHidden","cn","TopBar","Fragment","DataAppShellPrimaryNav"],"mappings":"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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { NavGroup, NavPage } from '../DataAppShell';
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
export interface AppShellSimpleCrumb {
|
|
4
|
+
/** Display label */
|
|
5
|
+
label: string;
|
|
6
|
+
/** If set, the crumb renders as a link */
|
|
7
|
+
href?: string;
|
|
8
|
+
/** Click handler when there's no `href` */
|
|
9
|
+
onClick?: () => void;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* The side nav has three states. The top-bar toggle ping-pongs between them,
|
|
13
|
+
* and dragging the nav's right border snaps between them:
|
|
14
|
+
* - `sidebar` — full panel with icon + label rows
|
|
15
|
+
* - `rail` — icon-only rail
|
|
16
|
+
* - `hidden` — no side nav; only the top bar + content
|
|
17
|
+
*/
|
|
18
|
+
export type AppShellSimpleNavState = "sidebar" | "rail" | "hidden";
|
|
19
|
+
export interface AppShellSimpleProps {
|
|
20
|
+
/**
|
|
21
|
+
* Whether the app has a side nav at all (default `true`). When `false`, the
|
|
22
|
+
* shell renders as a top bar + full-width body: no nav zone, and no top-bar
|
|
23
|
+
* toggle. This is the app-level switch — distinct from the runtime `hidden`
|
|
24
|
+
* nav state, which the end user can toggle back open. `navGroups` is ignored
|
|
25
|
+
* when `showNav` is `false`.
|
|
26
|
+
*/
|
|
27
|
+
showNav?: boolean;
|
|
28
|
+
/** Nav groups rendered in the side nav (ignored when `showNav` is `false`) */
|
|
29
|
+
navGroups?: NavGroup[];
|
|
30
|
+
/** Controlled active page id — takes precedence over per-page `isActive` */
|
|
31
|
+
activeKey?: string;
|
|
32
|
+
/** Called with the selected page id after the page's own `onClick` */
|
|
33
|
+
onSelect?: (key: string, page: NavPage) => void;
|
|
34
|
+
/** Breadcrumb trail — the top bar name */
|
|
35
|
+
breadcrumbs: AppShellSimpleCrumb[];
|
|
36
|
+
/** Right-side top bar actions (e.g. notifications, user menu) */
|
|
37
|
+
headerActions?: React.ReactNode;
|
|
38
|
+
/** Bottom-of-nav user slot */
|
|
39
|
+
userMenu?: React.ReactNode;
|
|
40
|
+
/** Uncontrolled initial nav state (default `sidebar`) */
|
|
41
|
+
defaultNav?: AppShellSimpleNavState;
|
|
42
|
+
/** Controlled nav state — pair with `onNavChange`; overrides `defaultNav` */
|
|
43
|
+
nav?: AppShellSimpleNavState;
|
|
44
|
+
/** Fired whenever the nav state changes (toggle, drag, or keyboard resize) */
|
|
45
|
+
onNavChange?: (nav: AppShellSimpleNavState) => void;
|
|
46
|
+
/** Main content */
|
|
47
|
+
children: React.ReactNode;
|
|
48
|
+
}
|
|
49
|
+
export declare function AppShellSimple({ showNav, navGroups, activeKey, onSelect, breadcrumbs, headerActions, userMenu, defaultNav, nav: navProp, onNavChange, children, }: AppShellSimpleProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
import { jsxs as p, jsx as r, Fragment as j } from "react/jsx-runtime";
|
|
2
|
+
import { PanelLeft as K } from "lucide-react";
|
|
3
|
+
import * as s from "react";
|
|
4
|
+
import { DataAppShellPrimaryNav as U } from "../DataAppShell/PrimaryNav.js";
|
|
5
|
+
import { TopBar as $ } from "../TopBar/TopBar.js";
|
|
6
|
+
import { Breadcrumb as G, BreadcrumbList as X, BreadcrumbSeparator as Y, BreadcrumbItem as q, BreadcrumbPage as J, BreadcrumbLink as R } from "../../../ui/breadcrumb.js";
|
|
7
|
+
import { Button as Q } from "../../../ui/button.js";
|
|
8
|
+
import { TooltipProvider as Z, Tooltip as ee, TooltipTrigger as re, TooltipContent as ae } from "../../../ui/tooltip.js";
|
|
9
|
+
import { cn as N } from "../../../lib/utils.js";
|
|
10
|
+
const f = ["sidebar", "rail", "hidden"], d = f.length - 1, c = (a) => a >= d ? -1 : 1, D = (a) => Math.max(0, f.indexOf(a)), y = 48, C = 220, ne = (y + C) / 2, te = y / 2, I = {
|
|
11
|
+
sidebar: C,
|
|
12
|
+
rail: y,
|
|
13
|
+
hidden: 0
|
|
14
|
+
};
|
|
15
|
+
function ie(a) {
|
|
16
|
+
const e = a >= ne ? 0 : a >= te ? 1 : d;
|
|
17
|
+
return { index: e, dir: c(e) };
|
|
18
|
+
}
|
|
19
|
+
function oe({ index: a, dir: e }) {
|
|
20
|
+
const t = a + e;
|
|
21
|
+
if (t < 0 || t > d) {
|
|
22
|
+
const o = e * -1;
|
|
23
|
+
return { index: a + o, dir: o };
|
|
24
|
+
}
|
|
25
|
+
return { index: t, dir: e };
|
|
26
|
+
}
|
|
27
|
+
function le(a, e) {
|
|
28
|
+
switch (f[e]) {
|
|
29
|
+
case "sidebar":
|
|
30
|
+
return "Expand navigation to labels";
|
|
31
|
+
case "hidden":
|
|
32
|
+
return "Hide navigation";
|
|
33
|
+
default:
|
|
34
|
+
return e > a ? "Collapse navigation to icons" : "Expand navigation to icons";
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
const se = [];
|
|
38
|
+
function ce({ items: a }) {
|
|
39
|
+
return /* @__PURE__ */ r(G, { className: "min-w-0", children: /* @__PURE__ */ r(X, { className: "flex-nowrap min-w-0", children: a.map((e, t) => {
|
|
40
|
+
const o = t === a.length - 1, h = !o && (!!e.href || !!e.onClick);
|
|
41
|
+
return /* @__PURE__ */ p(s.Fragment, { children: [
|
|
42
|
+
t > 0 && /* @__PURE__ */ r(Y, { className: "shrink-0", children: "/" }),
|
|
43
|
+
/* @__PURE__ */ r(q, { className: o ? "min-w-0" : "shrink-0", children: o ? /* @__PURE__ */ r(J, { className: "truncate font-medium", children: e.label }) : h && e.href ? /* @__PURE__ */ r(R, { href: e.href, className: "whitespace-nowrap text-primary", children: e.label }) : h && e.onClick ? /* @__PURE__ */ r(R, { asChild: !0, className: "whitespace-nowrap text-primary", children: /* @__PURE__ */ r("button", { type: "button", className: "cursor-pointer", onClick: e.onClick, children: e.label }) }) : /* @__PURE__ */ r("span", { className: "whitespace-nowrap", children: e.label }) })
|
|
44
|
+
] }, `${e.label}-${t}`);
|
|
45
|
+
}) }) });
|
|
46
|
+
}
|
|
47
|
+
function de({ label: a, onCycle: e }) {
|
|
48
|
+
return /* @__PURE__ */ r(Z, { children: /* @__PURE__ */ p(ee, { children: [
|
|
49
|
+
/* @__PURE__ */ r(re, { asChild: !0, children: /* @__PURE__ */ r(
|
|
50
|
+
Q,
|
|
51
|
+
{
|
|
52
|
+
"data-slot": "app-shell-simple-nav-toggle",
|
|
53
|
+
variant: "ghost",
|
|
54
|
+
size: "icon",
|
|
55
|
+
"aria-label": a,
|
|
56
|
+
className: "-ml-1 shrink-0 text-muted-foreground hover:bg-sidebar-accent/60 hover:text-foreground active:translate-y-0",
|
|
57
|
+
onClick: e,
|
|
58
|
+
children: /* @__PURE__ */ r(K, { className: "size-4" })
|
|
59
|
+
}
|
|
60
|
+
) }),
|
|
61
|
+
/* @__PURE__ */ r(ae, { side: "bottom", children: a })
|
|
62
|
+
] }) });
|
|
63
|
+
}
|
|
64
|
+
function xe({
|
|
65
|
+
showNav: a = !0,
|
|
66
|
+
navGroups: e = se,
|
|
67
|
+
activeKey: t,
|
|
68
|
+
onSelect: o,
|
|
69
|
+
breadcrumbs: h,
|
|
70
|
+
headerActions: B,
|
|
71
|
+
userMenu: L,
|
|
72
|
+
defaultNav: z = "sidebar",
|
|
73
|
+
nav: b,
|
|
74
|
+
onNavChange: A,
|
|
75
|
+
children: H
|
|
76
|
+
}) {
|
|
77
|
+
const [g, E] = s.useState(() => {
|
|
78
|
+
const n = D(b ?? z);
|
|
79
|
+
return { index: n, dir: c(n) };
|
|
80
|
+
}), i = b === void 0 ? g.index : D(b), M = g.index === i ? g.dir : c(i), l = f[i], u = s.useCallback(
|
|
81
|
+
(n) => {
|
|
82
|
+
E(n), n.index !== i && A?.(f[n.index]);
|
|
83
|
+
},
|
|
84
|
+
[i, A]
|
|
85
|
+
), T = oe({ index: i, dir: M }), O = () => u(T), V = le(i, T.index), _ = s.useId(), k = s.useRef(null), [x, m] = s.useState(!1), F = (n) => u(ie(n - (k.current?.getBoundingClientRect().left ?? 0))), S = (n) => {
|
|
86
|
+
const v = Math.min(d, Math.max(0, i + n));
|
|
87
|
+
v !== i && u({ index: v, dir: c(v) });
|
|
88
|
+
}, W = (n) => {
|
|
89
|
+
const P = {
|
|
90
|
+
ArrowLeft: () => S(1),
|
|
91
|
+
ArrowRight: () => S(-1),
|
|
92
|
+
Home: () => u({ index: 0, dir: c(0) }),
|
|
93
|
+
End: () => u({ index: d, dir: c(d) })
|
|
94
|
+
}[n.key];
|
|
95
|
+
P && (n.preventDefault(), P());
|
|
96
|
+
}, w = l === "hidden";
|
|
97
|
+
return /* @__PURE__ */ p(
|
|
98
|
+
"div",
|
|
99
|
+
{
|
|
100
|
+
"data-slot": "app-shell-simple",
|
|
101
|
+
"data-nav-state": l,
|
|
102
|
+
className: N(
|
|
103
|
+
"grid h-screen w-full overflow-hidden [grid-template-rows:auto_minmax(0,1fr)]",
|
|
104
|
+
a ? "[grid-template-columns:auto_minmax(0,1fr)] [grid-template-areas:'top_top'_'nav_body']" : "[grid-template-columns:minmax(0,1fr)] [grid-template-areas:'top'_'body']",
|
|
105
|
+
x && "select-none cursor-col-resize"
|
|
106
|
+
),
|
|
107
|
+
children: [
|
|
108
|
+
/* @__PURE__ */ r("div", { className: "[grid-area:top] min-w-0", children: /* @__PURE__ */ r(
|
|
109
|
+
$,
|
|
110
|
+
{
|
|
111
|
+
left: /* @__PURE__ */ p(j, { children: [
|
|
112
|
+
a && /* @__PURE__ */ r(de, { label: V, onCycle: O }),
|
|
113
|
+
/* @__PURE__ */ r(ce, { items: h })
|
|
114
|
+
] }),
|
|
115
|
+
right: B
|
|
116
|
+
}
|
|
117
|
+
) }),
|
|
118
|
+
a && /* @__PURE__ */ p(
|
|
119
|
+
"div",
|
|
120
|
+
{
|
|
121
|
+
ref: k,
|
|
122
|
+
id: _,
|
|
123
|
+
"data-slot": "app-shell-simple-nav",
|
|
124
|
+
"data-nav-state": l,
|
|
125
|
+
className: N(
|
|
126
|
+
"[grid-area:nav] relative min-h-0 flex flex-col shrink-0 bg-sidebar h-full transition-[width] duration-200",
|
|
127
|
+
w ? "overflow-hidden" : "border-r border-sidebar-border"
|
|
128
|
+
),
|
|
129
|
+
style: { width: I[l] },
|
|
130
|
+
children: [
|
|
131
|
+
/* @__PURE__ */ r(
|
|
132
|
+
"div",
|
|
133
|
+
{
|
|
134
|
+
"data-slot": "app-shell-simple-nav-content",
|
|
135
|
+
className: "h-full w-full overflow-hidden",
|
|
136
|
+
inert: w,
|
|
137
|
+
children: /* @__PURE__ */ r(
|
|
138
|
+
U,
|
|
139
|
+
{
|
|
140
|
+
variant: l === "rail" ? "rail" : "sidebar",
|
|
141
|
+
"aria-label": "Application navigation",
|
|
142
|
+
navGroups: e,
|
|
143
|
+
activeKey: t,
|
|
144
|
+
onSelect: o,
|
|
145
|
+
user: L,
|
|
146
|
+
className: "h-full w-full"
|
|
147
|
+
}
|
|
148
|
+
)
|
|
149
|
+
}
|
|
150
|
+
),
|
|
151
|
+
/* @__PURE__ */ r(
|
|
152
|
+
"div",
|
|
153
|
+
{
|
|
154
|
+
role: "separator",
|
|
155
|
+
tabIndex: 0,
|
|
156
|
+
"aria-orientation": "vertical",
|
|
157
|
+
"aria-label": "Resize navigation",
|
|
158
|
+
"aria-controls": _,
|
|
159
|
+
"aria-valuemin": 0,
|
|
160
|
+
"aria-valuemax": C,
|
|
161
|
+
"aria-valuenow": I[l],
|
|
162
|
+
"aria-valuetext": l,
|
|
163
|
+
onKeyDown: W,
|
|
164
|
+
onPointerDown: (n) => {
|
|
165
|
+
n.preventDefault(), n.currentTarget.setPointerCapture(n.pointerId), m(!0);
|
|
166
|
+
},
|
|
167
|
+
onPointerMove: (n) => {
|
|
168
|
+
if (x) {
|
|
169
|
+
if (n.buttons === 0) {
|
|
170
|
+
m(!1);
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
F(n.clientX);
|
|
174
|
+
}
|
|
175
|
+
},
|
|
176
|
+
onPointerUp: () => m(!1),
|
|
177
|
+
onPointerCancel: () => m(!1),
|
|
178
|
+
onLostPointerCapture: () => m(!1),
|
|
179
|
+
className: N(
|
|
180
|
+
"absolute top-0 right-0 z-10 h-full translate-x-1/2 cursor-col-resize transition-colors hover:bg-primary/40 focus-visible:outline-none focus-visible:bg-primary/60 focus-visible:ring-2 focus-visible:ring-ring",
|
|
181
|
+
w ? "w-3" : "w-1.5",
|
|
182
|
+
x && "bg-primary/60"
|
|
183
|
+
)
|
|
184
|
+
}
|
|
185
|
+
)
|
|
186
|
+
]
|
|
187
|
+
}
|
|
188
|
+
),
|
|
189
|
+
/* @__PURE__ */ r(
|
|
190
|
+
"main",
|
|
191
|
+
{
|
|
192
|
+
"data-slot": "app-shell-simple-content",
|
|
193
|
+
className: "[grid-area:body] min-h-0 min-w-0 overflow-auto bg-background",
|
|
194
|
+
children: H
|
|
195
|
+
}
|
|
196
|
+
)
|
|
197
|
+
]
|
|
198
|
+
}
|
|
199
|
+
);
|
|
200
|
+
}
|
|
201
|
+
export {
|
|
202
|
+
xe as AppShellSimple
|
|
203
|
+
};
|
|
204
|
+
//# sourceMappingURL=AppShellSimple.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AppShellSimple.js","sources":["../../../../src/components/composed/AppShellSimple/AppShellSimple.tsx"],"sourcesContent":["/**\n * AppShellSimple (SW-2410) — a Data App Shell stripped down to just two zones:\n * a full-width **top bar** and a three-state **side nav**. For apps that don't\n * need the full `DataAppShell` (no secondary nav, right panel, horizontal nav\n * variant, or mobile Sheet).\n *\n * - The side-nav control **lives in the top bar** (far left, above the nav).\n * It ping-pongs the nav through three states — labels ↔ icons ↔ hidden —\n * and dragging the nav's right border snaps between the same three.\n * - The **breadcrumb is the top bar name** — it sits right after the toggle.\n *\n * Composes existing kit primitives (`TopBar`, `DataAppShellPrimaryNav`,\n * `Breadcrumb`, `Button`, `Tooltip`).\n */\nimport { PanelLeft } from \"lucide-react\";\nimport * as React from \"react\";\n\nimport {\n DataAppShellPrimaryNav,\n type NavGroup,\n type NavPage,\n} from \"@/components/composed/DataAppShell\";\nimport { TopBar } from \"@/components/composed/TopBar\";\nimport {\n Breadcrumb,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from \"@/components/ui/breadcrumb\";\nimport { Button } from \"@/components/ui/button\";\nimport {\n Tooltip,\n TooltipContent,\n TooltipProvider,\n TooltipTrigger,\n} from \"@/components/ui/tooltip\";\nimport { cn } from \"@/lib/utils\";\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface AppShellSimpleCrumb {\n /** Display label */\n label: string;\n /** If set, the crumb renders as a link */\n href?: string;\n /** Click handler when there's no `href` */\n onClick?: () => void;\n}\n\n/**\n * The side nav has three states. The top-bar toggle ping-pongs between them,\n * and dragging the nav's right border snaps between them:\n * - `sidebar` — full panel with icon + label rows\n * - `rail` — icon-only rail\n * - `hidden` — no side nav; only the top bar + content\n */\nexport type AppShellSimpleNavState = \"sidebar\" | \"rail\" | \"hidden\";\n\n/**\n * Where the nav sits in the ping-pong: which state (`index` into `NAV_ORDER`)\n * and which way the next toggle click moves (`dir`, reversing at either end).\n */\ntype NavCursor = { index: number; dir: 1 | -1 };\n\n// Ping-pong order (does not wrap): labels ↔ icons ↔ hidden.\nconst NAV_ORDER: AppShellSimpleNavState[] = [\"sidebar\", \"rail\", \"hidden\"];\nconst LAST_NAV = NAV_ORDER.length - 1;\n\n// Single source of truth for the direction convention: point inward from the\n// ends so the next toggle keeps the ping-pong moving (middle defaults forward).\nconst dirFor = (index: number): 1 | -1 => (index >= LAST_NAV ? -1 : 1);\n\nconst indexOfNav = (state: AppShellSimpleNavState) => Math.max(0, NAV_ORDER.indexOf(state));\n\n// Fixed widths per state — the border drag snaps between these; it never sets\n// an in-between width.\nconst RAIL_WIDTH = 48;\nconst SIDEBAR_WIDTH = 220;\n// Snap thresholds: midpoints between the fixed widths.\nconst RAIL_SNAP = (RAIL_WIDTH + SIDEBAR_WIDTH) / 2;\nconst HIDE_SNAP = RAIL_WIDTH / 2;\n\nconst NAV_WIDTH: Record<AppShellSimpleNavState, number> = {\n sidebar: SIDEBAR_WIDTH,\n rail: RAIL_WIDTH,\n hidden: 0,\n};\n\n/** Map a dragged pixel width to the nearest nav state. */\nfunction snapNav(width: number): NavCursor {\n const index = width >= RAIL_SNAP ? 0 : width >= HIDE_SNAP ? 1 : LAST_NAV;\n return { index, dir: dirFor(index) };\n}\n\n/** Next cursor in the ping-pong, reversing direction at either end. */\nfunction nextNav({ index, dir }: NavCursor): NavCursor {\n const forward = index + dir;\n if (forward < 0 || forward > LAST_NAV) {\n const reversed = (dir * -1) as 1 | -1;\n return { index: index + reversed, dir: reversed };\n }\n return { index: forward, dir };\n}\n\n/**\n * Label for the toggle, describing the transition the next click performs.\n * `rail` is reachable from both directions, so it can't be keyed on the\n * destination alone — arriving from `hidden` is an expand, not a collapse.\n */\nfunction navToggleLabel(from: number, to: number): string {\n switch (NAV_ORDER[to]) {\n case \"sidebar\":\n return \"Expand navigation to labels\";\n case \"hidden\":\n return \"Hide navigation\";\n default:\n return to > from ? \"Collapse navigation to icons\" : \"Expand navigation to icons\";\n }\n}\n\nexport interface AppShellSimpleProps {\n /**\n * Whether the app has a side nav at all (default `true`). When `false`, the\n * shell renders as a top bar + full-width body: no nav zone, and no top-bar\n * toggle. This is the app-level switch — distinct from the runtime `hidden`\n * nav state, which the end user can toggle back open. `navGroups` is ignored\n * when `showNav` is `false`.\n */\n showNav?: boolean;\n /** Nav groups rendered in the side nav (ignored when `showNav` is `false`) */\n navGroups?: NavGroup[];\n /** Controlled active page id — takes precedence over per-page `isActive` */\n activeKey?: string;\n /** Called with the selected page id after the page's own `onClick` */\n onSelect?: (key: string, page: NavPage) => void;\n /** Breadcrumb trail — the top bar name */\n breadcrumbs: AppShellSimpleCrumb[];\n /** Right-side top bar actions (e.g. notifications, user menu) */\n headerActions?: React.ReactNode;\n /** Bottom-of-nav user slot */\n userMenu?: React.ReactNode;\n /** Uncontrolled initial nav state (default `sidebar`) */\n defaultNav?: AppShellSimpleNavState;\n /** Controlled nav state — pair with `onNavChange`; overrides `defaultNav` */\n nav?: AppShellSimpleNavState;\n /** Fired whenever the nav state changes (toggle, drag, or keyboard resize) */\n onNavChange?: (nav: AppShellSimpleNavState) => void;\n /** Main content */\n children: React.ReactNode;\n}\n\nconst EMPTY_NAV_GROUPS: NavGroup[] = [];\n\n// =============================================================================\n// Breadcrumb trail — the top bar name\n// =============================================================================\n\nfunction ShellBreadcrumb({ items }: { items: AppShellSimpleCrumb[] }) {\n return (\n <Breadcrumb className=\"min-w-0\">\n <BreadcrumbList className=\"flex-nowrap min-w-0\">\n {items.map((item, index) => {\n const isLast = index === items.length - 1;\n const isClickable = !isLast && (!!item.href || !!item.onClick);\n return (\n <React.Fragment key={`${item.label}-${index}`}>\n {index > 0 && <BreadcrumbSeparator className=\"shrink-0\">/</BreadcrumbSeparator>}\n <BreadcrumbItem className={isLast ? \"min-w-0\" : \"shrink-0\"}>\n {isLast ? (\n <BreadcrumbPage className=\"truncate font-medium\">{item.label}</BreadcrumbPage>\n ) : isClickable && item.href ? (\n <BreadcrumbLink href={item.href} className=\"whitespace-nowrap text-primary\">\n {item.label}\n </BreadcrumbLink>\n ) : isClickable && item.onClick ? (\n <BreadcrumbLink asChild className=\"whitespace-nowrap text-primary\">\n <button type=\"button\" className=\"cursor-pointer\" onClick={item.onClick}>\n {item.label}\n </button>\n </BreadcrumbLink>\n ) : (\n <span className=\"whitespace-nowrap\">{item.label}</span>\n )}\n </BreadcrumbItem>\n </React.Fragment>\n );\n })}\n </BreadcrumbList>\n </Breadcrumb>\n );\n}\n\n// =============================================================================\n// Top-bar side-nav toggle — the collapse/expand control (SW-2410).\n// =============================================================================\n\nfunction SideNavToggle({ label, onCycle }: { label: string; onCycle: () => void }) {\n return (\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n data-slot=\"app-shell-simple-nav-toggle\"\n variant=\"ghost\"\n size=\"icon\"\n aria-label={label}\n // size-8 (32px) so the hover highlight box matches the nav icon box;\n // -ml-1 centers the icon on the nav's 24px gutter (TopBar has px-3);\n // hover uses sidebar-accent (not the ghost default accent) to match the\n // nav-row hover on the shared sidebar surface; no press inset.\n className=\"-ml-1 shrink-0 text-muted-foreground hover:bg-sidebar-accent/60 hover:text-foreground active:translate-y-0\"\n onClick={onCycle}\n >\n <PanelLeft className=\"size-4\" />\n </Button>\n </TooltipTrigger>\n <TooltipContent side=\"bottom\">{label}</TooltipContent>\n </Tooltip>\n </TooltipProvider>\n );\n}\n\n// =============================================================================\n// AppShellSimple — two zones: full-width top bar + collapsible side nav\n// =============================================================================\n\nexport function AppShellSimple({\n showNav = true,\n navGroups = EMPTY_NAV_GROUPS,\n activeKey,\n onSelect,\n breadcrumbs,\n headerActions,\n userMenu,\n defaultNav = \"sidebar\",\n nav: navProp,\n onNavChange,\n children,\n}: AppShellSimpleProps) {\n // The cursor is always local: `index` is only authoritative while\n // uncontrolled, but `dir` (which way the ping-pong is travelling) has no\n // prop equivalent and is tracked here in both modes.\n const [cursor, setCursor] = React.useState<NavCursor>(() => {\n const index = indexOfNav(navProp ?? defaultNav);\n return { index, dir: dirFor(index) };\n });\n\n const index = navProp === undefined ? cursor.index : indexOfNav(navProp);\n // A controlled index moved by the parent invalidates our stored direction.\n const dir = cursor.index === index ? cursor.dir : dirFor(index);\n const navState = NAV_ORDER[index];\n\n const applyNav = React.useCallback(\n (next: NavCursor) => {\n setCursor(next);\n if (next.index !== index) onNavChange?.(NAV_ORDER[next.index]);\n },\n [index, onNavChange]\n );\n\n const nextCursor = nextNav({ index, dir });\n const cycleNav = () => applyNav(nextCursor);\n // Label describes the transition the next click performs.\n const nextLabel = navToggleLabel(index, nextCursor.index);\n\n // Drag the border to snap between the three states (widest → slimmest:\n // icon + text → icon rail → fully closed). Pointer capture keeps the drag\n // scoped to the handle — no window listeners to leak.\n //\n // The nav zone stays mounted at `width: 0` in the `hidden` state rather than\n // unmounting: unmounting mid-drag destroyed the element holding pointer\n // capture, so `pointerup` never came back and `resizing` stuck on. Keeping it\n // mounted also makes the handle draggable back out of `hidden`.\n const navId = React.useId();\n const navRef = React.useRef<HTMLDivElement>(null);\n const [resizing, setResizing] = React.useState(false);\n const snapToPointer = (clientX: number) =>\n applyNav(snapNav(clientX - (navRef.current?.getBoundingClientRect().left ?? 0)));\n\n const stepNav = (delta: 1 | -1) => {\n const target = Math.min(LAST_NAV, Math.max(0, index + delta));\n if (target !== index) applyNav({ index: target, dir: dirFor(target) });\n };\n\n const onHandleKeyDown = (e: React.KeyboardEvent) => {\n // ← narrower · → wider, matching the on-screen direction of the drag\n // (the arrow moves the nav's right border the same way).\n const move: Record<string, () => void> = {\n ArrowLeft: () => stepNav(1),\n ArrowRight: () => stepNav(-1),\n Home: () => applyNav({ index: 0, dir: dirFor(0) }),\n End: () => applyNav({ index: LAST_NAV, dir: dirFor(LAST_NAV) }),\n };\n const action = move[e.key];\n if (!action) return;\n e.preventDefault();\n action();\n };\n\n const isHidden = navState === \"hidden\";\n\n return (\n <div\n data-slot=\"app-shell-simple\"\n data-nav-state={navState}\n className={cn(\n \"grid h-screen w-full overflow-hidden [grid-template-rows:auto_minmax(0,1fr)]\",\n showNav\n ? \"[grid-template-columns:auto_minmax(0,1fr)] [grid-template-areas:'top_top'_'nav_body']\"\n : \"[grid-template-columns:minmax(0,1fr)] [grid-template-areas:'top'_'body']\",\n resizing && \"select-none cursor-col-resize\"\n )}\n >\n {/* Top bar */}\n <div className=\"[grid-area:top] min-w-0\">\n <TopBar\n left={\n <>\n {showNav && <SideNavToggle label={nextLabel} onCycle={cycleNav} />}\n <ShellBreadcrumb items={breadcrumbs} />\n </>\n }\n right={headerActions}\n />\n </div>\n\n {/* Side nav — sidebar (labels), rail (icons), or collapsed to zero width\n when hidden; the toggle ping-pongs and the border drag snaps between\n states. Omitted entirely when the app opts out (`showNav={false}`). */}\n {showNav && (\n <div\n ref={navRef}\n id={navId}\n data-slot=\"app-shell-simple-nav\"\n data-nav-state={navState}\n className={cn(\n \"[grid-area:nav] relative min-h-0 flex flex-col shrink-0 bg-sidebar h-full transition-[width] duration-200\",\n isHidden ? \"overflow-hidden\" : \"border-r border-sidebar-border\"\n )}\n style={{ width: NAV_WIDTH[navState] }}\n >\n {/* `inert` keeps the collapsed nav out of the tab order and the\n accessibility tree while it stays mounted for the drag handle. */}\n <div\n data-slot=\"app-shell-simple-nav-content\"\n className=\"h-full w-full overflow-hidden\"\n inert={isHidden}\n >\n <DataAppShellPrimaryNav\n variant={navState === \"rail\" ? \"rail\" : \"sidebar\"}\n aria-label=\"Application navigation\"\n navGroups={navGroups}\n activeKey={activeKey}\n onSelect={onSelect}\n user={userMenu}\n className=\"h-full w-full\"\n />\n </div>\n {/* Drag handle on the right border — snaps between the nav states.\n Also a keyboard-operable window splitter (arrows / Home / End). */}\n <div\n role=\"separator\"\n tabIndex={0}\n aria-orientation=\"vertical\"\n aria-label=\"Resize navigation\"\n aria-controls={navId}\n aria-valuemin={0}\n aria-valuemax={SIDEBAR_WIDTH}\n aria-valuenow={NAV_WIDTH[navState]}\n aria-valuetext={navState}\n onKeyDown={onHandleKeyDown}\n onPointerDown={(e) => {\n e.preventDefault();\n e.currentTarget.setPointerCapture(e.pointerId);\n setResizing(true);\n }}\n onPointerMove={(e) => {\n if (!resizing) return;\n // Defensive: a lost capture can strand `resizing` on, which would\n // otherwise turn a plain hover into a resize.\n if (e.buttons === 0) {\n setResizing(false);\n return;\n }\n snapToPointer(e.clientX);\n }}\n onPointerUp={() => setResizing(false)}\n onPointerCancel={() => setResizing(false)}\n onLostPointerCapture={() => setResizing(false)}\n className={cn(\n \"absolute top-0 right-0 z-10 h-full translate-x-1/2 cursor-col-resize transition-colors hover:bg-primary/40 focus-visible:outline-none focus-visible:bg-primary/60 focus-visible:ring-2 focus-visible:ring-ring\",\n isHidden ? \"w-3\" : \"w-1.5\",\n resizing && \"bg-primary/60\"\n )}\n />\n </div>\n )}\n\n {/* Body */}\n <main\n data-slot=\"app-shell-simple-content\"\n className=\"[grid-area:body] min-h-0 min-w-0 overflow-auto bg-background\"\n >\n {children}\n </main>\n </div>\n );\n}\n"],"names":["NAV_ORDER","LAST_NAV","dirFor","index","indexOfNav","state","RAIL_WIDTH","SIDEBAR_WIDTH","RAIL_SNAP","HIDE_SNAP","NAV_WIDTH","snapNav","width","nextNav","dir","forward","reversed","navToggleLabel","from","to","EMPTY_NAV_GROUPS","ShellBreadcrumb","items","jsx","Breadcrumb","BreadcrumbList","item","isLast","isClickable","jsxs","React","BreadcrumbSeparator","BreadcrumbItem","BreadcrumbPage","BreadcrumbLink","SideNavToggle","label","onCycle","TooltipProvider","Tooltip","TooltipTrigger","Button","PanelLeft","TooltipContent","AppShellSimple","showNav","navGroups","activeKey","onSelect","breadcrumbs","headerActions","userMenu","defaultNav","navProp","onNavChange","children","cursor","setCursor","navState","applyNav","next","nextCursor","cycleNav","nextLabel","navId","navRef","resizing","setResizing","snapToPointer","clientX","stepNav","delta","target","onHandleKeyDown","e","action","isHidden","cn","TopBar","Fragment","DataAppShellPrimaryNav"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),_=require("lucide-react"),re=require("react"),
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),_=require("lucide-react"),re=require("react"),L=require("./CollapseButton.cjs"),S=require("./PrimaryNav.cjs"),se=require("./ShellContext.cjs"),te=require("../../../composed/tdp-link.cjs"),ne=require("../TopBar/TopBar.cjs"),f=require("../../../ui/breadcrumb.cjs"),E=require("../../../ui/button.cjs"),h=require("../../../ui/dropdown-menu.cjs"),j=require("../../../ui/sheet.cjs"),I=require("../../../lib/utils.cjs");function le(r){const a=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(r){for(const s in r)if(s!=="default"){const t=Object.getOwnPropertyDescriptor(r,s);Object.defineProperty(a,s,t.get?t:{enumerable:!0,get:()=>r[s]})}}return a.default=r,Object.freeze(a)}const u=le(re);function v({appName:r,appFullName:a,appIcon:s,version:t,onAppNameClick:n,backToPlatformPath:l,onBackToPlatform:p,compact:o,menuSide:c="right"}){const d=e.jsx("span",{className:"flex items-center justify-center rounded-lg bg-sidebar-accent border border-sidebar-border font-bold text-foreground shrink-0 size-8 text-[10px]",children:s??r});return e.jsxs(h.DropdownMenu,{modal:!1,children:[e.jsx(h.DropdownMenuTrigger,{asChild:!0,children:e.jsxs("button",{type:"button",className:I.cn("cursor-pointer bg-transparent border-none p-0",!o&&"flex items-center w-full text-left"),children:[o?d:e.jsx("span",{className:"flex w-12 shrink-0 justify-center",children:d}),!o&&e.jsx("span",{className:"text-sm font-semibold text-foreground truncate leading-snug",children:a??r})]})}),e.jsxs(h.DropdownMenuContent,{side:c,align:"start",className:"min-w-[220px]",children:[e.jsxs(h.DropdownMenuItem,{className:"gap-3 px-3 py-2.5",onSelect:()=>n?.(),children:[e.jsx("div",{className:"w-8 h-8 rounded-lg bg-sidebar-accent border border-sidebar-border flex items-center justify-center shrink-0",children:e.jsx("span",{className:"text-[10px] font-bold text-foreground",children:s??r})}),e.jsxs("div",{className:"flex flex-col min-w-0",children:[e.jsx("span",{className:"text-sm font-semibold text-foreground truncate",children:a??r}),t&&e.jsx("span",{className:"text-[10px] text-muted-foreground/70 font-mono leading-none mt-0.5",children:t})]})]}),e.jsx(h.DropdownMenuSeparator,{}),e.jsx(h.DropdownMenuItem,{className:"gap-2.5 p-0",asChild:!0,children:l?e.jsxs(te.TDPLink,{path:l,navigationOptions:{newTab:!1},className:"flex items-center gap-2.5 w-full px-2 py-1.5 !no-underline hover:!no-underline",children:[e.jsx(_.ArrowLeft,{className:"w-4 h-4 text-muted-foreground"}),"Back to TDP Platform"]}):e.jsxs("button",{type:"button",className:"flex items-center gap-2.5 w-full px-2 py-1.5 bg-transparent border-none cursor-pointer",onClick:p,children:[e.jsx(_.ArrowLeft,{className:"w-4 h-4 text-muted-foreground"}),"Back to TDP Platform"]})})]})]})}function G({appName:r,appFullName:a,appIcon:s,version:t,navGroups:n,onAppNameClick:l,backToPlatformPath:p,onBackToPlatform:o,userMenu:c,compact:d,onAfterNavClick:x}){return e.jsx(S.DataAppShellPrimaryNav,{variant:d?"rail":"sidebar","aria-label":"Application navigation",navGroups:n,onSelect:()=>x?.(),header:e.jsx(v,{appName:r,appFullName:a,appIcon:s,version:t,onAppNameClick:l,backToPlatformPath:p,onBackToPlatform:o,compact:d}),user:c,className:"h-full w-full"})}function ie(r){return e.jsx("div",{"data-slot":"data-app-sidebar-rail",className:"hidden md:flex w-12 flex-col shrink-0 bg-sidebar border-r border-sidebar-border h-full z-50",children:e.jsx(G,{compact:!0,...r})})}function oe({collapsed:r,onCollapsedChange:a,...s}){const{appName:t,appFullName:n,appIcon:l,version:p,onAppNameClick:o,backToPlatformPath:c,onBackToPlatform:d}=s,x={appName:t,appFullName:n,appIcon:l,version:p,onAppNameClick:o,backToPlatformPath:c,onBackToPlatform:d};return r?e.jsx("div",{"data-slot":"data-app-sidebar-rail","data-collapsed":"true",className:"hidden md:flex w-12 flex-col shrink-0 bg-sidebar border-r border-sidebar-border h-full z-50",children:e.jsx(S.DataAppShellPrimaryNav,{variant:"rail","aria-label":"Application navigation",navGroups:s.navGroups,header:e.jsxs("div",{className:"flex flex-col items-center gap-2",children:[e.jsx(v,{...x,compact:!0}),e.jsx(L.ShellCollapseButton,{direction:"right",label:"Expand navigation",onClick:()=>a(!1)})]}),user:s.userMenu,className:"h-full w-full"})}):e.jsx("div",{"data-slot":"data-app-sidebar","data-collapsed":"false",className:"hidden md:flex w-[220px] flex-col shrink-0 bg-sidebar border-r border-sidebar-border h-full z-50",children:e.jsx(S.DataAppShellPrimaryNav,{variant:"sidebar","aria-label":"Application navigation",navGroups:s.navGroups,header:e.jsxs("div",{className:"flex items-center gap-2 w-full min-w-0",children:[e.jsx("div",{className:"flex-1 min-w-0",children:e.jsx(v,{...x,compact:!1})}),e.jsx(L.ShellCollapseButton,{direction:"left",label:"Collapse navigation",onClick:()=>a(!0)})]}),user:s.userMenu,className:"h-full w-full"})})}function de({items:r}){return e.jsx(f.Breadcrumb,{className:"min-w-0",children:e.jsx(f.BreadcrumbList,{className:"flex-nowrap min-w-0",children:r.map((a,s)=>{const t=s===r.length-1,n=!t&&(!!a.href||!!a.onClick),l=t?"min-w-0":"shrink-0";return e.jsxs(u.Fragment,{children:[s>0&&e.jsx(f.BreadcrumbSeparator,{className:"shrink-0",children:"/"}),e.jsx(f.BreadcrumbItem,{className:l,children:t?e.jsx(f.BreadcrumbPage,{className:"truncate",children:a.label}):n&&a.href?e.jsx(f.BreadcrumbLink,{href:a.href,className:"whitespace-nowrap",children:a.label}):n&&a.onClick?e.jsx("button",{type:"button",className:"text-sm text-primary hover:underline cursor-pointer bg-transparent border-none p-0 font-normal whitespace-nowrap",onClick:a.onClick,children:a.label}):e.jsx("span",{className:"text-sm text-muted-foreground whitespace-nowrap",children:a.label})})]},`${a.label}-${s}`)})})})}function ce({breadcrumbs:r=[],headerLeft:a,headerCenter:s,headerActions:t,mobileTrigger:n}){return e.jsx(ne.TopBar,{"data-slot":"data-app-top-nav",left:e.jsxs(e.Fragment,{children:[n&&e.jsx("div",{className:"shrink-0",children:n}),e.jsx(de,{items:r}),a!=null&&e.jsx("div",{className:"shrink-0",children:a})]}),center:s,right:t})}function ue({appName:r,appFullName:a,appIcon:s,version:t,navGroups:n,onAppNameClick:l,backToPlatformPath:p,onBackToPlatform:o,userMenu:c,breadcrumbs:d=[],headerLeft:x,headerCenter:H,headerActions:F,navVariant:b="vertical",primaryNav:$="rail",sidebarPanel:y,secondaryBar:T,rightPanel:J,showNavRail:K=!0,showTopBar:Q=!0,collapsed:g,defaultCollapsed:U=!1,onCollapsedChange:w,hideNavOnCollapse:C=!1,autoCollapse:A="(max-width: 1023px)",children:W,className:X}){const[Y,R]=u.useState(!1),[Z,D]=u.useState(U),m=g??Z,O=u.useRef(m);O.current=m;const N=u.useRef(!1),B=u.useCallback(i=>{N.current=!1,g===void 0&&D(i),w?.(i)},[g,w]),M=u.useRef(i=>{});M.current=i=>{i&&!O.current?(g===void 0&&D(!0),w?.(!0),N.current=!0):!i&&N.current&&(N.current=!1,g===void 0&&D(!1),w?.(!1))},u.useEffect(()=>{if(A===!1||b!=="vertical")return;const i=window.matchMedia(A);M.current(i.matches);const z=ae=>M.current(ae.matches);return i.addEventListener("change",z),()=>i.removeEventListener("change",z)},[A,b]);const k={appName:r,appFullName:a,appIcon:s,version:t,navGroups:n,onAppNameClick:l,backToPlatformPath:p,onBackToPlatform:o,userMenu:c},q=b==="vertical",P=q&&$==="sidebar",V=!K||C&&m&&!P,ee=q?"grid h-screen w-full overflow-hidden [grid-template-columns:auto_auto_minmax(0,1fr)] [grid-template-rows:auto_auto_minmax(0,1fr)] [grid-template-areas:'nav_top_top'_'nav_sub_sub'_'nav_side_body']":"grid h-screen w-full overflow-hidden [grid-template-columns:auto_minmax(0,1fr)] [grid-template-rows:auto_auto_auto_minmax(0,1fr)] [grid-template-areas:'pnav_pnav'_'top_top'_'sub_sub'_'side_body']";return e.jsx(se.DataAppShellProvider,{value:{navVariant:b,collapsed:m,setCollapsed:B,hideNavOnCollapse:C},children:e.jsx(j.Sheet,{open:Y,onOpenChange:R,children:e.jsxs("div",{"data-slot":"data-app-shell","data-nav-variant":b,"data-collapsed":m||void 0,className:I.cn(ee,X),children:[!V&&(q?e.jsx("div",{className:"[grid-area:nav] min-h-0",children:P?e.jsx(oe,{collapsed:m,onCollapsedChange:B,...k}):e.jsx(ie,{...k})}):e.jsx("div",{className:"[grid-area:pnav] hidden md:block border-b border-sidebar-border bg-sidebar px-3 py-1.5",children:e.jsx(S.DataAppShellPrimaryNav,{variant:"top","aria-label":"Application navigation",navGroups:n,header:e.jsx(v,{...k,compact:!0,menuSide:"bottom"}),user:c})})),C&&m&&!y&&e.jsx(E.Button,{"data-slot":"data-app-shell-expand-fab",variant:"outline",size:"icon-sm","aria-label":"Expand navigation",className:"absolute left-2 top-2 z-50 shadow-elevation-2",onClick:()=>B(!1),children:e.jsx(_.ChevronRight,{className:"w-4 h-4"})}),e.jsxs(j.SheetContent,{side:"left",showCloseButton:!1,className:"p-0 bg-sidebar border-r border-sidebar-border data-[side=left]:w-[220px] data-[side=left]:sm:w-[220px] data-[side=left]:sm:max-w-[220px] flex flex-col",children:[e.jsx(j.SheetTitle,{className:"sr-only",children:"Navigation"}),e.jsx(j.SheetDescription,{className:"sr-only",children:"Application navigation menu"}),e.jsx(G,{compact:!1,onAfterNavClick:()=>R(!1),...k})]}),y&&e.jsx("div",{className:"[grid-area:side] min-h-0 flex",children:y}),Q&&e.jsx("div",{className:"[grid-area:top] min-w-0",children:e.jsx(ce,{breadcrumbs:d,headerLeft:x,headerCenter:H,headerActions:F,mobileTrigger:e.jsx(j.SheetTrigger,{asChild:!0,children:e.jsx(E.Button,{variant:"ghost",size:"icon","aria-label":"Open navigation menu",className:"md:hidden w-7 h-7 shrink-0 text-muted-foreground",children:e.jsx(_.Menu,{className:"w-4 h-4"})})})})}),T&&e.jsx("div",{className:"[grid-area:sub] min-w-0",children:T}),e.jsxs("div",{className:"[grid-area:body] relative flex min-h-0 min-w-0 overflow-hidden",children:[e.jsx("main",{"data-slot":"data-app-shell-content",className:"flex-1 min-w-0 overflow-auto bg-background",children:W}),J]})]})})})}exports.AppHeaderMenu=v;exports.DataAppShell=ue;
|
|
2
2
|
//# sourceMappingURL=DataAppShell.cjs.map
|