{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "author": "Lopifi (https://lopifi.com)",
  "categories": [
    "ledger-tables",
    "finance",
    "accounting"
  ],
  "dependencies": [
    "@base-ui-components/react"
  ],
  "description": "Show/hide/reorder with drag.",
  "files": [
    {
      "content": "\"use client\";\n\nimport { Popover } from \"@base-ui-components/react/popover\";\nimport * as React from \"react\";\nimport { cn } from \"@/lib/ledger/cn\";\nimport { EllipsisVerticalIcon, ViewColumnsIcon } from \"@/components/ledger/icons\";\n\nexport type ManagedColumn = { id: string; label: string; visible: boolean; locked?: boolean };\n\nexport interface ColumnManagerProps {\n  className?: string;\n  columns: ManagedColumn[];\n  onChange: (columns: ManagedColumn[]) => void;\n}\n\n/**\n * Show / hide / reorder. Persisted per user per table. Keyboard reorder via\n * Cmd+arrows, because drag alone is not an accessible reorder.\n */\nexport function ColumnManager({ columns, onChange, className }: ColumnManagerProps) {\n  const [dragIndex, setDragIndex] = React.useState<number | null>(null);\n\n  const move = (from: number, to: number) => {\n    if (to < 0 || to >= columns.length) return;\n    const next = [...columns];\n    const [item] = next.splice(from, 1);\n    next.splice(to, 0, item);\n    onChange(next);\n  };\n\n  return (\n    <Popover.Root>\n      <Popover.Trigger\n        className={cn(\n          \"inline-flex h-8 items-center gap-2 rounded-sm border border-border bg-surface px-3 text-label font-medium\",\n          \"transition-colors duration-1 ease-standard hover:bg-surface-hover\",\n          className,\n        )}\n      >\n        <ViewColumnsIcon aria-hidden=\"true\" className=\"size-3.5\" />\n        Columns\n      </Popover.Trigger>\n      <Popover.Portal>\n        <Popover.Positioner align=\"end\" className=\"z-dropdown\" sideOffset={8}>\n          <Popover.Popup\n            className=\"w-[260px] rounded-md border border-border bg-surface-raised p-2 shadow-elevation-3\"\n            style={{ transformOrigin: \"var(--transform-origin)\" }}\n          >\n            <ul>\n              {columns.map((col, i) => (\n                <li\n                  className=\"flex items-center gap-2 rounded-xs px-2 py-1.5 hover:bg-surface-hover\"\n                  draggable={!col.locked}\n                  key={col.id}\n                  onDragOver={(e) => e.preventDefault()}\n                  onDragStart={() => setDragIndex(i)}\n                  onDrop={() => {\n                    if (dragIndex !== null) move(dragIndex, i);\n                    setDragIndex(null);\n                  }}\n                >\n                  <EllipsisVerticalIcon\n                    aria-hidden=\"true\"\n                    className={cn(\"size-3.5 text-text-tertiary\", col.locked && \"opacity-30\")}\n                  />\n                  <label className=\"flex flex-1 items-center gap-2 text-body\">\n                    <input\n                      checked={col.visible}\n                      className=\"size-4 accent-[var(--accent)]\"\n                      disabled={col.locked}\n                      onChange={() =>\n                        onChange(columns.map((c) => (c.id === col.id ? { ...c, visible: !c.visible } : c)))\n                      }\n                      type=\"checkbox\"\n                    />\n                    {col.label}\n                  </label>\n                  <button\n                    aria-label={`Move ${col.label} up`}\n                    className=\"text-caption text-text-tertiary hover:text-text-primary\"\n                    onClick={() => move(i, i - 1)}\n                    onKeyDown={(e) => {\n                      if (e.metaKey && e.key === \"ArrowUp\") move(i, i - 1);\n                      if (e.metaKey && e.key === \"ArrowDown\") move(i, i + 1);\n                    }}\n                    type=\"button\"\n                  >\n                    ↑\n                  </button>\n                  <button\n                    aria-label={`Move ${col.label} down`}\n                    className=\"text-caption text-text-tertiary hover:text-text-primary\"\n                    onClick={() => move(i, i + 1)}\n                    type=\"button\"\n                  >\n                    ↓\n                  </button>\n                </li>\n              ))}\n            </ul>\n          </Popover.Popup>\n        </Popover.Positioner>\n      </Popover.Portal>\n    </Popover.Root>\n  );\n}\n",
      "path": "components/ledger/column-manager.tsx",
      "target": "components/ledger/column-manager.tsx",
      "type": "registry:component"
    }
  ],
  "name": "column-manager",
  "registryDependencies": [
    "@lopifi/theme",
    "@lopifi/cn",
    "@lopifi/icons"
  ],
  "title": "ColumnManager",
  "type": "registry:component"
}
