/** * AppShell — a chat-independent layout primitive modeled on the shadcn sidebar * (https://ui.shadcn.com/blocks). It owns the *layout + sidebar visibility*; * everything else is slots. The sidebar is binary — visible or hidden (no * collapse/icon-rail mode). Supports a left AND a right sidebar, each with its * own toggle and persisted state. * * Desktop: sidebars are inline flex columns (mounted only while open). * Mobile (< sm): sidebars become a focus-trapped off-canvas overlay + backdrop * that slides in from the relevant edge, with Escape-to-close, scroll-lock, and * focus restore. * * Renders the design-token stylesheet (`DesignTokenStyle`) so a standalone * `AppShell` mounted *outside* `` still resolves its `[var(--token)]` * utilities. Fully self-contained within `veryfront/ui`: uses the local `cn`, * `ui/button`, and `ui/tokens` — no imports back into `chat/`. * * @module react/components/ui/app-shell */ import * as React from "react"; import { type ButtonProps } from "./button.js"; /** Which edge a sidebar docks to. */ export type AppShellSide = "left" | "right"; interface AppShellContextValue { /** Viewport is below the `sm` breakpoint (< 640px). */ isMobile: boolean; /** Effective visibility of a side for the current viewport. */ isOpen: (side: AppShellSide) => boolean; /** Flip a side's visibility. */ toggle: (side: AppShellSide) => void; /** Set a side's visibility explicitly. */ setOpen: (side: AppShellSide, open: boolean) => void; /** Stable DOM id for a side's sidebar (for `aria-controls`). */ sidebarId: (side: AppShellSide) => string; } declare const useAppShell: () => AppShellContextValue; /** Access the enclosing {@link AppShell}'s state (external triggers, etc.). */ export { useAppShell }; /** Per-side visibility map. */ export interface AppShellOpenState { left?: boolean; right?: boolean; } /** Props accepted by {@link AppShell}. */ export interface AppShellProps extends React.HTMLAttributes { /** Controlled desktop visibility per side. Omit a side to leave it uncontrolled. */ open?: AppShellOpenState; /** Uncontrolled initial desktop visibility. Defaults: left `true`, right `false`. */ defaultOpen?: AppShellOpenState; /** Fires when a side is toggled (desktop). Receives the requested next value. */ onOpenChange?: (side: AppShellSide, open: boolean) => void; /** localStorage key prefix for persisting uncontrolled desktop visibility. */ storageKey?: string; /** Toggle the left sidebar with ⌘/Ctrl+B. Default `true`. */ keyboardShortcut?: boolean; ref?: React.Ref; } /** Root — provides sidebar state and the flex layout container. */ declare function AppShellRoot({ open, defaultOpen, onOpenChange, storageKey, keyboardShortcut, className, children, ref, ...props }: AppShellProps): React.ReactElement; declare namespace AppShellRoot { var displayName: string; } /** Props accepted by {@link AppShellSidebar}. */ export interface AppShellSidebarProps extends React.HTMLAttributes { /** Edge to dock to. Default `left`. */ side?: AppShellSide; /** Sidebar width in px (desktop column + mobile overlay panel). Default `240`. */ width?: number; } /** A dockable sidebar. Renders inline on desktop, as an overlay on mobile. */ declare function AppShellSidebar({ side, width, className, children, style, "aria-label": ariaLabel, ...props }: AppShellSidebarProps): React.ReactElement | null; declare namespace AppShellSidebar { var displayName: string; } /** Optional border-carrying section. */ interface BorderedProps extends React.HTMLAttributes { /** Draw a divider on the section's inner edge. Default `false`. */ border?: boolean; } /** Sidebar header slot — optional bottom border. */ declare function AppShellSidebarHeader({ border, className, ...props }: BorderedProps): React.ReactElement; declare namespace AppShellSidebarHeader { var displayName: string; } /** Sidebar scroll region — grows to fill and scrolls. */ declare function AppShellSidebarContent({ className, ...props }: React.HTMLAttributes): React.ReactElement; declare namespace AppShellSidebarContent { var displayName: string; } /** Sidebar footer slot — optional top border. */ declare function AppShellSidebarFooter({ border, className, ...props }: BorderedProps): React.ReactElement; declare namespace AppShellSidebarFooter { var displayName: string; } /** The main content column, between/beside the sidebars. */ declare function AppShellMain({ className, ...props }: React.HTMLAttributes): React.ReactElement; declare namespace AppShellMain { var displayName: string; } /** Props accepted by {@link AppShellHeader}. */ export interface AppShellHeaderProps extends React.HTMLAttributes { /** Draw a bottom divider. Default `false`. */ border?: boolean; } /** Optional top bar inside the main column — with or without a bottom border. */ declare function AppShellHeader({ border, className, ...props }: AppShellHeaderProps): React.ReactElement; declare namespace AppShellHeader { var displayName: string; } /** The main content region — grows to fill, host owns overflow. */ declare function AppShellContent({ className, ...props }: React.HTMLAttributes): React.ReactElement; declare namespace AppShellContent { var displayName: string; } /** Props accepted by {@link AppShellTrigger}. */ export interface AppShellTriggerProps extends ButtonProps { /** Which sidebar to toggle. Default `left`. */ side?: AppShellSide; /** Override the default panel icon (`PanelLeft` / `PanelRight`). */ icon?: React.ReactNode; } /** Toggle button — built on the shared `Button`, defaults its icon by `side`. */ declare function AppShellTrigger({ side, icon, variant, size, className, onClick, "aria-label": ariaLabel, ...props }: AppShellTriggerProps): React.ReactElement; declare namespace AppShellTrigger { var displayName: string; } /** * Compound AppShell. Compose: * * ```tsx * * * * * * * * * * * * * * ``` */ export declare const AppShell: typeof AppShellRoot & { Sidebar: typeof AppShellSidebar; SidebarHeader: typeof AppShellSidebarHeader; SidebarContent: typeof AppShellSidebarContent; SidebarFooter: typeof AppShellSidebarFooter; Main: typeof AppShellMain; Header: typeof AppShellHeader; Content: typeof AppShellContent; Trigger: typeof AppShellTrigger; }; //# sourceMappingURL=app-shell.d.ts.map