{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "resizable-panels",
  "type": "registry:ui",
  "title": "Resizable panels",
  "description": "Split panes with draggable, keyboard operable handles, min and max sizes, snap to collapse and nested groups in either direction.",
  "dependencies": [
    "lucide-react"
  ],
  "registryDependencies": [
    "utils"
  ],
  "files": [
    {
      "path": "registry/ui/resizable-panels.tsx",
      "type": "registry:ui",
      "target": "components/ui/resizable-panels.tsx",
      "content": "\"use client\"\nimport * as React from \"react\"\nimport { ChevronRightIcon, FileCodeIcon, FileJsonIcon, FileTextIcon, FolderOpenIcon, HashIcon } from \"lucide-react\"\nimport { cn } from \"@/lib/utils\"\n\n/** Split panes with draggable, keyboard operable handles, min and max sizes, snap to collapse and nested groups in either direction. */\ntype Orientation = \"horizontal\" | \"vertical\"\n\ntype ResizablePanelProps = {\n  /** Starting size in percent of the group. Panels without one share what is left. */\n  defaultSize?: number\n  /** Smallest size in percent while dragging. */\n  minSize?: number\n  /** Largest size in percent. */\n  maxSize?: number\n  /** Snap to `collapsedSize` when dragged well below `minSize`. */\n  collapsible?: boolean\n  /** Size in percent when collapsed. */\n  collapsedSize?: number\n  /** Called when the panel collapses or expands. */\n  onCollapse?: (collapsed: boolean) => void\n  children?: React.ReactNode\n  className?: string\n}\n\ntype ResizableHandleProps = {\n  /** Accessible name of the separator. */\n  \"aria-label\"?: string\n  /** Show the grip pill at the middle of the handle at rest, not only on hover. */\n  withGrip?: boolean\n  className?: string\n}\n\ntype ResizablePanelsProps = {\n  /** Panels and handles: `ResizablePanel` and `ResizableHandle` children, nestable. Leave empty for the editor demo. */\n  children?: React.ReactNode\n  /** Direction the panels are laid out in. */\n  orientation?: Orientation\n  /** Controlled sizes in percent, one per panel. */\n  sizes?: number[]\n  /** Starting sizes in percent when uncontrolled. Overrides each panel's `defaultSize`. */\n  defaultSizes?: number[]\n  /** Fires with the new sizes on every drag, key press or snap. */\n  onSizesChange?: (sizes: number[]) => void\n  /** Percent moved per arrow key. Shift multiplies by five. */\n  keyboardStep?: number\n  /** Two panel shorthand: content of the first panel. */\n  left?: React.ReactNode\n  /** Two panel shorthand: content of the second panel. */\n  right?: React.ReactNode\n  /** Two panel shorthand: starting size of the first panel in percent. */\n  initial?: number\n  className?: string\n}\n\ntype PanelConfig = { min: number; max: number; def?: number; collapsible: boolean; collapsedSize: number }\n\ntype GroupContextValue = {\n  id: string\n  orientation: Orientation\n  sizes: number[]\n  panels: PanelConfig[]\n  defaults: number[]\n  step: number\n  active: number | null\n  rootRef: React.RefObject<HTMLDivElement | null>\n  commit: (next: number[]) => void\n  setActive: (i: number | null) => void\n}\n\nconst GroupContext = React.createContext<GroupContextValue | null>(null)\nconst PanelIndexContext = React.createContext(-1)\nconst HandleIndexContext = React.createContext(-1)\n\nconst clamp = (v: number, lo: number, hi: number) => Math.min(hi, Math.max(lo, v))\n\n/** True once the element is narrower than `max` px. False during SSR. */\nfunction useNarrow(ref: React.RefObject<HTMLElement | null>, max: number) {\n  const [narrow, setNarrow] = React.useState(false)\n  React.useEffect(() => {\n    const el = ref.current\n    if (!el || typeof ResizeObserver === \"undefined\") return\n    const ro = new ResizeObserver((entries) => setNarrow(entries[0].contentRect.width < max))\n    ro.observe(el)\n    return () => ro.disconnect()\n  }, [ref, max])\n  return narrow\n}\nconst round = (v: number) => Math.round(v * 100) / 100\n\n/** Spread sizes so they sum to 100: explicit defaults are scaled only when they overflow; the rest share the remainder. */\nfunction normalize(panels: PanelConfig[], given?: number[]): number[] {\n  const n = panels.length\n  if (!n) return []\n  const explicit = panels.map((p, i) => given?.[i] ?? p.def)\n  const known = explicit.filter((v): v is number => typeof v === \"number\")\n  const sum = known.reduce((a, b) => a + b, 0)\n  const unknown = n - known.length\n  let out: number[]\n  if (unknown === 0) out = explicit.map((v) => (sum ? ((v as number) / sum) * 100 : 100 / n))\n  else {\n    const rest = Math.max(0, 100 - sum)\n    out = explicit.map((v) => (typeof v === \"number\" ? v : rest / unknown))\n    const total = out.reduce((a, b) => a + b, 0)\n    if (total !== 100) out = out.map((v) => (v / total) * 100)\n  }\n  return out.map(round)\n}\n\n/** Move the boundary between panel i and i+1 by `delta` percent, honouring min, max and collapse snapping. */\nfunction resizePair(sizes: number[], i: number, delta: number, panels: PanelConfig[]): number[] | null {\n  const pa = panels[i]\n  const pb = panels[i + 1]\n  if (!pa || !pb) return null\n  const total = sizes[i] + sizes[i + 1]\n  const settle = (size: number, p: PanelConfig) => {\n    if (p.collapsible) {\n      const threshold = p.collapsedSize + (p.min - p.collapsedSize) / 2\n      if (size < threshold) return p.collapsedSize\n      if (size < p.min) return p.min\n    } else if (size < p.min) return p.min\n    return Math.min(size, p.max)\n  }\n  const valid = (size: number, p: PanelConfig) => (p.collapsible && Math.abs(size - p.collapsedSize) < 0.001) || (size >= p.min - 0.001 && size <= p.max + 0.001)\n  let a = settle(sizes[i] + delta, pa)\n  let b = settle(total - a, pb)\n  a = total - b\n  if (!valid(a, pa)) {\n    a = clamp(a, pa.min, pa.max)\n    b = total - a\n    if (!valid(b, pb)) return null\n  }\n  const next = sizes.slice()\n  next[i] = round(a)\n  next[i + 1] = round(b)\n  return next\n}\n\nfunction ResizablePanel({ defaultSize, minSize, maxSize, collapsible, collapsedSize, onCollapse, children, className }: ResizablePanelProps) {\n  void defaultSize\n  void minSize\n  void maxSize\n  void collapsedSize\n  const group = React.useContext(GroupContext)\n  const index = React.useContext(PanelIndexContext)\n  const size = group?.sizes[index] ?? 100\n  const config = group?.panels[index]\n  const collapsed = Boolean(collapsible && config && Math.abs(size - config.collapsedSize) < 0.001)\n  const wasCollapsed = React.useRef(collapsed)\n  React.useEffect(() => {\n    if (wasCollapsed.current !== collapsed) {\n      wasCollapsed.current = collapsed\n      onCollapse?.(collapsed)\n    }\n  }, [collapsed, onCollapse])\n  return (\n    <div\n      id={group ? `${group.id}-panel-${index}` : undefined}\n      data-slot=\"resizable-panel\"\n      data-collapsed={collapsed || undefined}\n      className={cn(\"relative min-h-0 min-w-0 overflow-hidden\", className)}\n      style={{ flexGrow: size, flexShrink: 1, flexBasis: 0 }}\n    >\n      {children}\n    </div>\n  )\n}\n\nfunction ResizableHandle({ \"aria-label\": ariaLabel, withGrip = false, className }: ResizableHandleProps) {\n  const group = React.useContext(GroupContext)\n  const index = React.useContext(HandleIndexContext)\n  const drag = React.useRef<{ pos: number; sizes: number[]; span: number } | null>(null)\n  if (!group || index < 0 || index >= group.panels.length - 1) return null\n  const horizontal = group.orientation === \"horizontal\"\n  const before = group.panels[index]\n  const size = group.sizes[index]\n  const active = group.active === index\n\n  const move = (delta: number, from = group.sizes) => {\n    const next = resizePair(from, index, delta, group.panels)\n    if (next) group.commit(next)\n  }\n  const reset = () => {\n    const pair = group.defaults[index] + group.defaults[index + 1]\n    const total = group.sizes[index] + group.sizes[index + 1]\n    const want = pair ? (group.defaults[index] / pair) * total : total / 2\n    move(want - group.sizes[index])\n  }\n\n  return (\n    <div\n      role=\"separator\"\n      tabIndex={0}\n      aria-orientation={horizontal ? \"vertical\" : \"horizontal\"}\n      aria-label={ariaLabel ?? `Resize ${horizontal ? \"columns\" : \"rows\"}`}\n      aria-controls={`${group.id}-panel-${index}`}\n      aria-valuenow={Math.round(size)}\n      aria-valuemin={before.collapsible ? before.collapsedSize : before.min}\n      aria-valuemax={before.max}\n      data-slot=\"resizable-handle\"\n      data-active={active || undefined}\n      onPointerDown={(e) => {\n        if (e.button !== 0) return\n        e.preventDefault()\n        const root = group.rootRef.current\n        if (!root) return\n        const rect = root.getBoundingClientRect()\n        const own = e.currentTarget.getBoundingClientRect()\n        const handles = root.querySelectorAll(`:scope > [data-slot=\"resizable-handle\"]`).length\n        const span = (horizontal ? rect.width : rect.height) - handles * (horizontal ? own.width : own.height)\n        drag.current = { pos: horizontal ? e.clientX : e.clientY, sizes: group.sizes.slice(), span: Math.max(1, span) }\n        e.currentTarget.setPointerCapture(e.pointerId)\n        group.setActive(index)\n      }}\n      onPointerMove={(e) => {\n        const d = drag.current\n        if (!d) return\n        const delta = (((horizontal ? e.clientX : e.clientY) - d.pos) / d.span) * 100\n        move(delta, d.sizes)\n      }}\n      onPointerUp={() => {\n        drag.current = null\n        group.setActive(null)\n      }}\n      onPointerCancel={() => {\n        drag.current = null\n        group.setActive(null)\n      }}\n      onDoubleClick={reset}\n      onKeyDown={(e) => {\n        const step = group.step * (e.shiftKey ? 5 : 1)\n        const dec = horizontal ? \"ArrowLeft\" : \"ArrowUp\"\n        const inc = horizontal ? \"ArrowRight\" : \"ArrowDown\"\n        if (e.key === dec) move(-step)\n        else if (e.key === inc) move(step)\n        else if (e.key === \"Home\") move(-100)\n        else if (e.key === \"End\") move(100)\n        else if (e.key === \"Enter\" && before.collapsible) {\n          const collapsed = Math.abs(size - before.collapsedSize) < 0.001\n          move(collapsed ? group.defaults[index] - size : before.collapsedSize - size)\n        } else return\n        e.preventDefault()\n      }}\n      className={cn(\n        \"group/handle relative z-10 flex shrink-0 touch-none items-center justify-center outline-none select-none\",\n        horizontal ? \"w-2 cursor-col-resize\" : \"h-2 cursor-row-resize\",\n        className\n      )}\n    >\n      <span\n        aria-hidden\n        className={cn(\n          \"absolute bg-border transition-[background-color,width,height] duration-[140ms] ease-hairline\",\n          horizontal ? \"inset-y-0 left-1/2 w-px -translate-x-1/2\" : \"inset-x-0 top-1/2 h-px -translate-y-1/2\",\n          \"group-hover/handle:bg-border-strong group-focus-visible/handle:bg-accent group-data-[active]/handle:bg-accent\",\n          horizontal ? \"group-focus-visible/handle:w-0.5 group-data-[active]/handle:w-0.5\" : \"group-focus-visible/handle:h-0.5 group-data-[active]/handle:h-0.5\"\n        )}\n      />\n      <span\n        aria-hidden\n        data-slot=\"resizable-handle-thumb\"\n        className={cn(\n          \"relative rounded-full bg-border-strong transition-[opacity,background-color] duration-[140ms] ease-hairline\",\n          horizontal ? \"h-6 w-1\" : \"h-1 w-6\",\n          withGrip ? \"opacity-100\" : \"opacity-0 group-hover/handle:opacity-100 group-focus-visible/handle:opacity-100 group-data-[active]/handle:opacity-100\",\n          \"group-focus-visible/handle:bg-accent group-data-[active]/handle:bg-accent\"\n        )}\n      />\n    </div>\n  )\n}\n\nfunction isPanel(el: React.ReactNode): el is React.ReactElement<ResizablePanelProps> {\n  return React.isValidElement(el) && el.type === ResizablePanel\n}\n\n/**\n * Split panes for editors, inspectors and dashboards. Drag a handle to\n * resize; the hairline swells to accent under the hand. Arrow keys move it,\n * Shift jumps, Home and End slam it, Enter collapses a collapsible pane and\n * a double click resets the pair. Controlled or uncontrolled sizes, nothing\n * is persisted. With no children it renders a three pane editor demo.\n */\nfunction ResizablePanels({\n  children,\n  orientation = \"horizontal\",\n  sizes: sizesProp,\n  defaultSizes,\n  onSizesChange,\n  keyboardStep = 2,\n  left,\n  right,\n  initial = 50,\n  className,\n}: ResizablePanelsProps) {\n  const id = React.useId().replace(/[^a-zA-Z0-9-]/g, \"\")\n  const rootRef = React.useRef<HTMLDivElement>(null)\n  const [active, setActive] = React.useState<number | null>(null)\n  const demo = !children && left === undefined && right === undefined\n  const narrow = useNarrow(rootRef, 560)\n  /* The zero prop demo stacks its panes on narrow screens. */\n  const dir: Orientation = demo && narrow ? \"vertical\" : orientation\n\n  /* Children are inspected directly, so the built in layouts are arrays of panels and handles, not a wrapper element. */\n  const content =\n    children ??\n    (left !== undefined || right !== undefined\n      ? [\n          <ResizablePanel key=\"left\" defaultSize={initial} minSize={20} maxSize={80} className=\"overflow-auto p-4\">{left}</ResizablePanel>,\n          <ResizableHandle key=\"handle\" />,\n          <ResizablePanel key=\"right\" className=\"overflow-auto p-4\">{right}</ResizablePanel>,\n        ]\n      : editorDemo())\n  const kids = React.Children.toArray(content)\n  const panels = kids.filter(isPanel).map<PanelConfig>((el) => ({\n    min: Math.max(0, el.props.minSize ?? 10),\n    max: Math.min(100, el.props.maxSize ?? 100),\n    def: el.props.defaultSize,\n    collapsible: Boolean(el.props.collapsible),\n    collapsedSize: Math.max(0, el.props.collapsedSize ?? 0),\n  }))\n  const signature = panels.map((p) => `${p.min}/${p.max}/${p.def ?? \"-\"}/${p.collapsible ? 1 : 0}/${p.collapsedSize}`).join(\"|\")\n  // eslint-disable-next-line react-hooks/exhaustive-deps\n  const stablePanels = React.useMemo(() => panels, [signature])\n  // eslint-disable-next-line react-hooks/exhaustive-deps\n  const defaults = React.useMemo(() => normalize(stablePanels, defaultSizes), [stablePanels, defaultSizes?.join(\",\")])\n  const [inner, setInner] = React.useState<number[]>(defaults)\n  const raw = sizesProp ?? inner\n  const sizes = raw.length === stablePanels.length ? raw : defaults\n\n  const commit = React.useCallback(\n    (next: number[]) => {\n      if (sizesProp === undefined) setInner(next)\n      onSizesChange?.(next)\n    },\n    [sizesProp, onSizesChange]\n  )\n\n  const ctx = React.useMemo<GroupContextValue>(\n    () => ({ id, orientation: dir, sizes, panels: stablePanels, defaults, step: keyboardStep, active, rootRef, commit, setActive }),\n    [id, dir, sizes, stablePanels, defaults, keyboardStep, active, commit]\n  )\n\n  let panelIndex = 0\n  const rendered = kids.map((child, i) => {\n    if (isPanel(child)) {\n      const index = panelIndex++\n      return (\n        <PanelIndexContext.Provider key={child.key ?? `p${i}`} value={index}>\n          {child}\n        </PanelIndexContext.Provider>\n      )\n    }\n    if (React.isValidElement(child) && child.type === ResizableHandle) {\n      return (\n        <HandleIndexContext.Provider key={child.key ?? `h${i}`} value={panelIndex - 1}>\n          {child}\n        </HandleIndexContext.Provider>\n      )\n    }\n    return child\n  })\n\n  return (\n    <GroupContext.Provider value={ctx}>\n      <div\n        ref={rootRef}\n        data-slot=\"resizable-panels\"\n        data-orientation={dir}\n        data-dragging={active !== null || undefined}\n        className={cn(\n          \"flex h-full w-full min-w-0 overflow-hidden\",\n          dir === \"vertical\" ? \"flex-col\" : \"flex-row\",\n          active !== null && (dir === \"vertical\" ? \"cursor-row-resize select-none\" : \"cursor-col-resize select-none\"),\n          demo && \"max-w-4xl rounded-xl border border-border bg-surface text-fg shadow-raised\",\n          demo && (narrow ? \"h-[30rem]\" : \"h-80\"),\n          className\n        )}\n      >\n        {rendered}\n      </div>\n    </GroupContext.Provider>\n  )\n}\n\n/* ── Demo content: a slice of the Lumen editor built from plain divs ──────── */\n\nconst FILES: { name: string; depth: number; icon: React.ElementType; tone: string; active?: boolean }[] = [\n  { name: \"app\", depth: 0, icon: FolderOpenIcon, tone: \"text-fg-subtle\" },\n  { name: \"invoices\", depth: 1, icon: FolderOpenIcon, tone: \"text-fg-subtle\" },\n  { name: \"page.tsx\", depth: 2, icon: FileCodeIcon, tone: \"text-info\", active: true },\n  { name: \"invoice-card.tsx\", depth: 2, icon: FileCodeIcon, tone: \"text-info\" },\n  { name: \"layout.tsx\", depth: 1, icon: FileCodeIcon, tone: \"text-info\" },\n  { name: \"globals.css\", depth: 1, icon: HashIcon, tone: \"text-accent-fg\" },\n  { name: \"package.json\", depth: 0, icon: FileJsonIcon, tone: \"text-warning\" },\n  { name: \"README.md\", depth: 0, icon: FileTextIcon, tone: \"text-fg-muted\" },\n]\n\nconst CODE: React.ReactNode[] = [\n  <><span className=\"text-accent-fg\">export</span> <span className=\"text-accent-fg\">async function</span> <span className=\"text-info\">InvoicePage</span>({\"{\"} params {\"}\"}) {\"{\"}</>,\n  <>  <span className=\"text-accent-fg\">const</span> invoice = <span className=\"text-accent-fg\">await</span> lumen.invoices.<span className=\"text-info\">get</span>(params.id)</>,\n  <>  <span className=\"text-accent-fg\">const</span> total = <span className=\"text-info\">formatMoney</span>(invoice.total, invoice.currency)</>,\n  <>  <span className=\"text-accent-fg\">return</span> (</>,\n  <>    {\"<\"}<span className=\"text-success\">InvoiceCard</span></>,\n  <>      number={\"{\"}invoice.number{\"}\"}</>,\n  <>      customer={\"{\"}invoice.customer.name{\"}\"}</>,\n  <>      total={\"{\"}total{\"}\"}</>,\n  <>      status=<span className=\"text-warning\">&quot;paid&quot;</span></>,\n  <>    /{\">\"}</>,\n  <>  )</>,\n  <>{\"}\"}</>,\n]\n\nfunction PaneHeader({ children, meta }: { children: React.ReactNode; meta?: React.ReactNode }) {\n  return (\n    <div className=\"flex h-8 shrink-0 items-center justify-between gap-2 border-b border-border px-3\">\n      <span className=\"truncate font-mono text-[10px] font-medium tracking-[0.06em] text-fg-muted uppercase\">{children}</span>\n      {meta ? <span className=\"shrink-0 font-mono text-[10px] text-fg-subtle tabular-nums\">{meta}</span> : null}\n    </div>\n  )\n}\n\nfunction editorDemo(): React.ReactNode[] {\n  return [\n    <ResizablePanel key=\"explorer\" defaultSize={22} minSize={14} maxSize={40} collapsible collapsedSize={0}>\n      <div className=\"flex h-full flex-col bg-sunken\">\n        <PaneHeader meta=\"8\">Explorer</PaneHeader>\n        <ul className=\"min-w-0 flex-1 space-y-px overflow-auto p-1.5\">\n          {FILES.map((f) => (\n            <li\n              key={f.name + f.depth}\n              className={cn(\"flex h-6 items-center gap-1.5 truncate rounded-md pr-2 text-xs\", f.active ? \"bg-accent-soft text-fg\" : \"text-fg-muted\")}\n              style={{ paddingLeft: 6 + f.depth * 12 }}\n            >\n              {f.icon === FolderOpenIcon ? <ChevronRightIcon aria-hidden className=\"size-3 shrink-0 rotate-90 text-fg-subtle\" /> : <span className=\"size-3 shrink-0\" />}\n              <f.icon aria-hidden className={cn(\"size-3.5 shrink-0\", f.tone)} />\n              <span className=\"truncate\">{f.name}</span>\n            </li>\n          ))}\n        </ul>\n      </div>\n    </ResizablePanel>,\n    <ResizableHandle key=\"h1\" aria-label=\"Resize explorer\" />,\n    <ResizablePanel key=\"editor\" defaultSize={48} minSize={30}>\n      <ResizablePanels orientation=\"vertical\">\n        <ResizablePanel defaultSize={70} minSize={30}>\n          <div className=\"flex h-full min-w-0 flex-col\">\n            <PaneHeader meta=\"TSX\">app/invoices/page.tsx</PaneHeader>\n            <pre className=\"min-w-0 flex-1 overflow-hidden p-3 font-mono text-[11.5px] leading-[1.7] text-fg\">\n              {CODE.map((line, i) => (\n                <span key={i} className=\"flex gap-3 whitespace-pre\">\n                  <span className=\"w-4 shrink-0 text-right text-fg-subtle tabular-nums select-none\">{i + 1}</span>\n                  <span>{line}</span>\n                </span>\n              ))}\n            </pre>\n          </div>\n        </ResizablePanel>\n        <ResizableHandle aria-label=\"Resize terminal\" />\n        <ResizablePanel defaultSize={30} minSize={16} collapsible collapsedSize={0}>\n          <div className=\"flex h-full min-w-0 flex-col bg-sunken\">\n            <PaneHeader meta=\"zsh\">Terminal</PaneHeader>\n            <pre className=\"overflow-hidden p-3 font-mono text-[11px] leading-[1.7] whitespace-pre text-fg-muted\">\n              <span className=\"block\"><span className=\"text-accent-fg\">$</span> pnpm dev</span>\n              <span className=\"block\">  <span className=\"text-success\">ready</span> on http://localhost:3000</span>\n              <span className=\"block\">  <span className=\"text-info\">GET</span> /invoices/LUM-0147 <span className=\"text-fg-subtle\">200 in 38ms</span></span>\n            </pre>\n          </div>\n        </ResizablePanel>\n      </ResizablePanels>\n    </ResizablePanel>,\n    <ResizableHandle key=\"h2\" aria-label=\"Resize preview\" />,\n    <ResizablePanel key=\"preview\" defaultSize={30} minSize={20}>\n      <div className=\"flex h-full min-w-0 flex-col\">\n        <PaneHeader meta=\"Live\">Preview</PaneHeader>\n        <div className=\"min-w-0 flex-1 overflow-auto bg-bg p-3\">\n          <div className=\"min-w-0 rounded-lg border border-border bg-surface p-3 shadow-raised\">\n            <div className=\"flex items-center justify-between gap-2\">\n              <span className=\"truncate font-mono text-[10px] text-fg-subtle\">LUM-0147</span>\n              <span className=\"shrink-0 rounded-full bg-success/15 px-1.5 py-px text-[10px] font-medium text-success\">Paid</span>\n            </div>\n            <p className=\"mt-2 truncate text-xs font-medium text-fg\">Northwind Traders</p>\n            <p className=\"truncate text-[11px] text-fg-muted\">12 seats, Lumen Pro</p>\n            <p className=\"mt-3 text-lg font-medium tracking-[-0.01em] text-fg tabular-nums\">$1,840.00</p>\n            <div className=\"mt-3 h-1.5 w-full overflow-hidden rounded-full bg-sunken\">\n              <div className=\"h-full w-full rounded-full bg-accent\" />\n            </div>\n          </div>\n        </div>\n      </div>\n    </ResizablePanel>,\n  ]\n}\n\nexport { ResizablePanels, ResizablePanel, ResizableHandle }\nexport type { ResizablePanelsProps, ResizablePanelProps, ResizableHandleProps }\n"
    }
  ]
}
