{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "split-pane",
  "type": "registry:ui",
  "title": "SplitPane",
  "description": "Responsive two-column split layout with sticky aside, ratio presets, and mobile stacking.",
  "registryDependencies": [
    "https://ui.arpitbhayani.me/r/aui.json"
  ],
  "files": [
    {
      "path": "ui/split-pane.tsx",
      "content": "import * as React from \"react\";\nimport { cn } from \"@/lib/utils\";\n\nexport interface SplitPaneProps extends React.HTMLAttributes<HTMLDivElement> {\n  /** Optional content for the aside column. If provided, `children` becomes the main content. */\n  aside?: React.ReactNode;\n  /** Whether the first/aside column sticks while scrolling on desktop screens. Default true. */\n  stickyFirst?: boolean;\n  /** Alias for stickyFirst. */\n  stickyAside?: boolean;\n  /** Breakpoint at which columns stack vertically. Default \"lg\". */\n  stackBreakpoint?: \"md\" | \"lg\" | \"xl\";\n  /** Width ratio or grid template layout. Defaults to \"5/7\" (minmax(320px, 5fr) minmax(0, 7fr)). */\n  ratio?: \"5/7\" | \"1/1\" | \"1/2\" | \"2/1\" | \"1/3\" | \"3/1\" | string;\n  /** Minimum width for the aside column on large screens. Default \"320px\". */\n  minAside?: string | number;\n  /** Gap between columns. Default \"lg\" (1.5rem / 24px). */\n  gap?: \"sm\" | \"md\" | \"lg\" | \"xl\";\n}\n\nconst GAP_MAP = {\n  sm: \"gap-3\",\n  md: \"gap-4\",\n  lg: \"gap-6\",\n  xl: \"gap-8\",\n};\n\nexport interface SplitPaneAsideProps extends React.HTMLAttributes<HTMLElement> {\n  sticky?: boolean;\n}\n\nexport const SplitPaneAside = React.forwardRef<HTMLElement, SplitPaneAsideProps>(\n  ({ className, sticky, children, ...props }, ref) => {\n    return (\n      <aside\n        ref={ref}\n        className={cn(\n          \"flex flex-col gap-3 min-w-0 w-full\",\n          sticky && \"lg:sticky lg:top-4\",\n          className\n        )}\n        {...props}\n      >\n        {children}\n      </aside>\n    );\n  }\n);\nSplitPaneAside.displayName = \"SplitPaneAside\";\n\nexport interface SplitPaneMainProps extends React.HTMLAttributes<HTMLElement> {\n  as?: React.ElementType;\n}\n\nexport const SplitPaneMain = React.forwardRef<HTMLElement, SplitPaneMainProps>(\n  ({ className, as: Component = \"article\", children, ...props }, ref) => {\n    return (\n      <Component\n        ref={ref}\n        className={cn(\"flex min-w-0 flex-col gap-4 w-full\", className)}\n        {...props}\n      >\n        {children}\n      </Component>\n    );\n  }\n);\nSplitPaneMain.displayName = \"SplitPaneMain\";\n\nexport function SplitPane({\n  aside,\n  stickyFirst = false,\n  stickyAside,\n  stackBreakpoint = \"lg\",\n  ratio = \"5/7\",\n  minAside = \"320px\",\n  gap = \"lg\",\n  className,\n  children,\n  ...props\n}: SplitPaneProps) {\n  const isSticky = stickyAside !== undefined ? stickyAside : stickyFirst;\n  const minW = typeof minAside === \"number\" ? `${minAside}px` : minAside;\n\n  const gridColsClass =\n    ratio === \"1/1\"\n      ? \"lg:grid-cols-2\"\n      : ratio === \"1/2\"\n      ? \"lg:grid-cols-[1fr_2fr]\"\n      : ratio === \"2/1\"\n      ? \"lg:grid-cols-[2fr_1fr]\"\n      : ratio === \"1/3\"\n      ? \"lg:grid-cols-[1fr_3fr]\"\n      : ratio === \"3/1\"\n      ? \"lg:grid-cols-[3fr_1fr]\"\n      : `lg:grid-cols-[minmax(${minW},5fr)_minmax(0,7fr)]`;\n\n  return (\n    <div\n      className={cn(\n        \"grid items-start w-full\",\n        gridColsClass,\n        GAP_MAP[gap],\n        className\n      )}\n      {...props}\n    >\n      {aside !== undefined ? (\n        <>\n          <SplitPaneAside sticky={isSticky}>{aside}</SplitPaneAside>\n          <SplitPaneMain>{children}</SplitPaneMain>\n        </>\n      ) : (\n        children\n      )}\n    </div>\n  );\n}\n\nSplitPane.Aside = SplitPaneAside;\nSplitPane.Main = SplitPaneMain;\n",
      "type": "registry:ui"
    }
  ]
}