"use client" /** * Central outline-tree chrome — mirrors shadcn/ui **Sidebar** file-tree structure * (`SidebarMenu` → `SidebarMenuItem` + `Collapsible` → `SidebarMenuSub` → rows) without * coupling to `useSidebar`. * * - **`guideLayout="inset"`** — same rhythm as `SidebarMenuSub` (`ps-6` left guide, full width). * - **`guideLayout="chevronRail"`** — vertical guide on `.group/collapsible::before` * at chevron center (`--outline-tree-guide-x`); child rows use minimal left indent. * * @see packages/ui/src/components/ui/sidebar.tsx — `SidebarMenuSub`, `SidebarMenuSubItem` */ import * as React from "react" import { CollapsibleContent } from "../ui/collapsible" import { cn } from "../../lib/utils" export type OutlineTreeSurface = "sidebar" | "panel" export type OutlineTreeGuideLayout = "inset" | "chevronRail" const outlineTreeSubInsetClass: Record = { sidebar: "flex w-full min-w-0 list-none flex-col gap-1 border-s border-sidebar-border py-[var(--exxat-spacing-1)] pe-0 ps-[var(--exxat-spacing-6)]", panel: "flex w-full min-w-0 list-none flex-col gap-1 border-s border-border/60 py-[var(--exxat-spacing-1)] pe-0 ps-[var(--exxat-spacing-6)]", } const outlineTreeSubChevronRailClass: Record = { sidebar: "flex min-w-0 flex-1 list-none flex-col gap-1 py-[var(--exxat-spacing-1)] pe-0 ps-0", panel: "flex min-w-0 flex-1 list-none flex-col gap-1 py-[var(--exxat-spacing-1)] pe-0 ps-0", } /** Pull row content onto the guide line — matches `SidebarMenuSubButton` horizontal nudge (inset layout only). */ export const OUTLINE_TREE_SUB_ROW_SHIFT_CLASS = "-translate-x-px rtl:translate-x-px" /** `CollapsibleContent` row: spacer width = `px-2` (8px) + half of `size-8` chevron (16px) → guide under chevron center. */ export const OUTLINE_TREE_COLLAPSIBLE_CONTENT_RAIL_CLASS = "flex min-w-0 w-full" /** Spacer column — keep in sync with folder row `px-2` + `size-8` chevron. */ export const OUTLINE_TREE_CHEVRON_GUIDE_SPACER_CLASS = "w-6 shrink-0" /** Row indent for outline-tree depth — flat sub-lists, +12px per level on the row only. */ export function outlineTreeRowIndentStyle(depth: number): React.CSSProperties { return { "--outline-tree-depth": depth, paddingInlineStart: `calc(var(--outline-tree-row-padding-x) + ${depth} * var(--outline-tree-depth-step))`, } as React.CSSProperties } /** Guide-line anchor depth for the parent `OutlineTreeMenuItem` / root `
  • `. */ export function outlineTreeBranchDepthStyle(depth: number): React.CSSProperties { return { "--outline-tree-depth": depth } as React.CSSProperties } /** `CollapsibleContent` wrapper — vertical guide is on `.group/collapsible::before`. */ export function OutlineTreeCollapsibleContentRail({ className, children, ...props }: React.ComponentProps) { return ( {children} ) } /** Nested list under a folder — vertical guide + indent. */ export function OutlineTreeSub({ surface = "panel", guideLayout = "inset", className, ...props }: React.ComponentProps<"ul"> & { surface?: OutlineTreeSurface guideLayout?: OutlineTreeGuideLayout }) { return (
      ) } /** Root or nested branch list — matches `SidebarMenu` spacing. */ export function OutlineTreeMenu({ className, ...props }: React.ComponentProps<"ul">) { return (
        ) } /** Expandable folder row wrapper — matches `SidebarMenuItem`. */ export function OutlineTreeMenuItem({ className, ...props }: React.ComponentProps<"li">) { return (
      • ) } /** Leaf / nested row inside `OutlineTreeSub` — matches `SidebarMenuSubItem`. */ export function OutlineTreeSubItem({ className, ...props }: React.ComponentProps<"li">) { return (
      • ) } export interface OutlineTreeLeafButtonProps extends React.ComponentProps<"button"> { surface?: OutlineTreeSurface isActive?: boolean /** Inset `OutlineTreeSub` only — nudge like `SidebarMenuSubButton`. Ignored when parent uses `chevronRail`. */ subGuideAlign?: boolean } /** Selectable leaf row (file / terminal row) — `SidebarMenuSubButton`–aligned rhythm. */ export function OutlineTreeLeafButton({ surface = "panel", isActive = false, subGuideAlign = false, className, ...props }: OutlineTreeLeafButtonProps) { return (