{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "feature-drag-drop-organizer",
  "title": "Feature Drag Drop Organizer",
  "type": "registry:block",
  "files": [
    {
      "path": "packages/registry-react/blocks/feature-drag-drop-organizer/FeatureDragDropOrganizer.tsx",
      "content": "'use client'\n\nimport * as React from 'react'\nimport { Activity, ArrowDown, ArrowRight, ArrowUp, Check, Copy, Eye, EyeOff, Layers, RotateCcw } from 'lucide-react'\nimport { Badge } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { Card, CardContent } from '@/components/ui/card'\nimport { cn } from '@/lib/utils'\n\nexport interface LayoutWidget {\n  id: string\n  name: string\n  category: string\n  visible: boolean\n  colSpan: number\n  previewSnippet: string\n}\n\nexport interface FeatureDragDropOrganizerProps {\n  title?: string\n  description?: string\n  className?: string\n}\n\nconst INITIAL_WIDGETS: LayoutWidget[] = [\n  {\n    id: 'widget-kpi',\n    name: 'Real-time KPI Metrics',\n    category: 'Analytics',\n    visible: true,\n    colSpan: 12,\n    previewSnippet: '3 Cards: $124.5k MRR • 18ms Latency • 99.99% Uptime',\n  },\n  {\n    id: 'widget-chart',\n    name: 'Traffic Sparkline Chart',\n    category: 'Telemetry',\n    visible: true,\n    colSpan: 8,\n    previewSnippet: 'SVG Real-time stream (35,000 req/s live)',\n  },\n  {\n    id: 'widget-nodes',\n    name: 'Edge PoP Status',\n    category: 'Infrastructure',\n    visible: true,\n    colSpan: 4,\n    previewSnippet: '8 global edge regions active (optimal)',\n  },\n  {\n    id: 'widget-feed',\n    name: 'Deployment Activity Feed',\n    category: 'Workflows',\n    visible: true,\n    colSpan: 12,\n    previewSnippet: 'sha-a81f9c deployed to edge via CLI (2 mins ago)',\n  },\n]\n\nexport function FeatureDragDropOrganizer({\n  title = 'Arrange dashboard layouts intuitively with zero boilerplate.',\n  description = 'Customize widget order, toggle component visibility, and export clean declarative JSON layout schemas for your application.',\n  className,\n}: FeatureDragDropOrganizerProps) {\n  const [widgets, setWidgets] = React.useState<LayoutWidget[]>([...INITIAL_WIDGETS])\n  const [copied, setCopied] = React.useState(false)\n\n  function moveWidget(index: number, direction: 'up' | 'down') {\n    const targetIndex = direction === 'up' ? index - 1 : index + 1\n    if (targetIndex < 0 || targetIndex >= widgets.length) return\n\n    const updated = [...widgets]\n    const [removed] = updated.splice(index, 1)\n    updated.splice(targetIndex, 0, removed)\n    setWidgets(updated)\n  }\n\n  function toggleVisibility(index: number) {\n    setWidgets((prev) => {\n      const next = [...prev]\n      next[index] = { ...next[index], visible: !next[index].visible }\n      return next\n    })\n  }\n\n  function resetLayout() {\n    setWidgets(JSON.parse(JSON.stringify(INITIAL_WIDGETS)))\n  }\n\n  const exportJson = React.useMemo(() => {\n    return JSON.stringify(\n      widgets.map((w, idx) => ({\n        order: idx,\n        id: w.id,\n        name: w.name,\n        visible: w.visible,\n        colSpan: w.colSpan,\n      })),\n      null,\n      2,\n    )\n  }, [widgets])\n\n  async function copyJson() {\n    try {\n      await navigator.clipboard.writeText(exportJson)\n      setCopied(true)\n      setTimeout(() => {\n        setCopied(false)\n      }, 2000)\n    } catch {\n      // fallback\n    }\n  }\n\n  return (\n    <section\n      data-slot=\"feature-drag-drop-organizer\"\n      className={cn('bg-background relative overflow-hidden py-16 sm:py-24', className)}\n    >\n      <div className=\"mx-auto max-w-7xl px-4 sm:px-6 lg:px-8\">\n        {/* Section Header */}\n        <div className=\"mx-auto max-w-3xl space-y-4 text-center\">\n          <a\n            href=\"#layout-organizer\"\n            className=\"group border-border/80 bg-secondary/60 hover:bg-secondary text-foreground inline-flex items-center gap-2 rounded-full border px-3.5 py-1 text-xs font-medium shadow-2xs transition-colors\"\n          >\n            <Layers className=\"text-primary size-3.5\" />\n            <span>Composable Layout Workbench</span>\n            <ArrowRight className=\"text-muted-foreground size-3 transition-transform group-hover:translate-x-0.5\" />\n          </a>\n\n          <h2 className=\"text-foreground text-3xl font-bold tracking-tight sm:text-4xl\">{title}</h2>\n\n          <p className=\"text-muted-foreground text-base sm:text-lg\">{description}</p>\n        </div>\n\n        {/* Workbench Grid (2 Columns: Controls & Live Canvas) */}\n        <div className=\"mt-12 grid grid-cols-1 gap-6 lg:grid-cols-12\">\n          {/* Left: Widget Re-ordering Controls (6 Cols) */}\n          <Card className=\"border-border bg-card flex flex-col justify-between shadow-xs lg:col-span-6\">\n            <CardContent className=\"space-y-5 p-6\">\n              <div className=\"border-border flex items-center justify-between border-b pb-3\">\n                <div className=\"flex items-center gap-2\">\n                  <Layers className=\"text-primary size-4\" />\n                  <span className=\"text-foreground text-sm font-semibold\">Widget Hierarchy</span>\n                </div>\n                <Button\n                  variant=\"ghost\"\n                  size=\"sm\"\n                  className=\"text-muted-foreground hover:text-foreground h-7 gap-1 px-2 font-mono text-xs active:scale-95\"\n                  onClick={resetLayout}\n                >\n                  <RotateCcw className=\"size-3\" />\n                  <span>Reset</span>\n                </Button>\n              </div>\n\n              {/* Reorderable List of Widgets */}\n              <div className=\"space-y-2\">\n                {widgets.map((widget, idx) => (\n                  <div\n                    key={widget.id}\n                    className={cn(\n                      'flex items-center justify-between rounded-lg border p-3 transition-colors',\n                      widget.visible ? 'border-border bg-background' : 'border-border/60 bg-muted/30 opacity-60',\n                    )}\n                  >\n                    <div className=\"flex min-w-0 items-center gap-3\">\n                      <div className=\"text-muted-foreground flex items-center gap-1\">\n                        <button\n                          type=\"button\"\n                          disabled={idx === 0}\n                          className=\"hover:bg-muted rounded p-1 transition-[colors,transform] active:scale-90 disabled:opacity-30\"\n                          onClick={() => moveWidget(idx, 'up')}\n                        >\n                          <ArrowUp className=\"size-3.5\" />\n                        </button>\n                        <button\n                          type=\"button\"\n                          disabled={idx === widgets.length - 1}\n                          className=\"hover:bg-muted rounded p-1 transition-[colors,transform] active:scale-90 disabled:opacity-30\"\n                          onClick={() => moveWidget(idx, 'down')}\n                        >\n                          <ArrowDown className=\"size-3.5\" />\n                        </button>\n                      </div>\n\n                      <div className=\"min-w-0 space-y-0.5\">\n                        <div className=\"flex items-center gap-2\">\n                          <span className=\"text-foreground text-xs font-bold\">{widget.name}</span>\n                          <Badge variant=\"outline\" className=\"border-border text-muted-foreground text-xs\">\n                            {widget.category}\n                          </Badge>\n                        </div>\n                        <div className=\"text-muted-foreground truncate text-xs\">{widget.previewSnippet}</div>\n                      </div>\n                    </div>\n\n                    <Button\n                      variant=\"ghost\"\n                      size=\"icon\"\n                      className=\"text-muted-foreground hover:text-foreground size-8 shrink-0 active:scale-95\"\n                      onClick={() => toggleVisibility(idx)}\n                    >\n                      {widget.visible ? <Eye className=\"text-primary size-3.5\" /> : <EyeOff className=\"size-3.5\" />}\n                    </Button>\n                  </div>\n                ))}\n              </div>\n\n              {/* Export JSON Box */}\n              <div className=\"border-border space-y-2 border-t pt-2\">\n                <div className=\"flex items-center justify-between text-xs\">\n                  <span className=\"text-foreground font-medium\">Generated Layout JSON</span>\n                  <Button\n                    variant=\"ghost\"\n                    size=\"sm\"\n                    className=\"h-6 gap-1 px-2 font-mono text-xs active:scale-95\"\n                    onClick={copyJson}\n                  >\n                    {copied ? <Check className=\"text-primary size-3\" /> : <Copy className=\"size-3\" />}\n                    <span>{copied ? 'Copied' : 'Copy JSON'}</span>\n                  </Button>\n                </div>\n                <pre className=\"border-border bg-muted/40 text-muted-foreground max-h-32 overflow-y-auto rounded-lg border p-2.5 font-mono text-xs\">\n                  <code>{exportJson}</code>\n                </pre>\n              </div>\n            </CardContent>\n          </Card>\n\n          {/* Right: Live Canvas Preview (6 Cols) */}\n          <Card className=\"border-border bg-card flex flex-col justify-between shadow-xs lg:col-span-6\">\n            <CardContent className=\"space-y-4 p-6\">\n              <div className=\"border-border flex items-center justify-between border-b pb-3\">\n                <div className=\"flex items-center gap-2\">\n                  <Activity className=\"text-success size-4\" />\n                  <span className=\"text-foreground text-sm font-semibold\">Rendered Canvas Preview</span>\n                </div>\n                <span className=\"text-success font-mono text-xs\">Live Synchronized</span>\n              </div>\n\n              {/* Simulated Dashboard Canvas with Reordered Components */}\n              <div className=\"border-border/80 bg-background/80 space-y-3 rounded-lg border p-4\">\n                {widgets.map((widget) =>\n                  widget.visible ? (\n                    <div\n                      key={widget.id}\n                      className=\"border-border bg-muted/30 space-y-1 rounded-lg border p-3 transition-colors\"\n                    >\n                      <div className=\"text-foreground flex items-center justify-between text-xs font-semibold\">\n                        <span>{widget.name}</span>\n                        <span className=\"text-muted-foreground font-mono text-xs\">col-span-{widget.colSpan}</span>\n                      </div>\n                      <div className=\"text-muted-foreground text-xs\">{widget.previewSnippet}</div>\n                    </div>\n                  ) : null,\n                )}\n              </div>\n            </CardContent>\n          </Card>\n        </div>\n      </div>\n    </section>\n  )\n}\n",
      "type": "registry:block",
      "target": "~/components/blocks/feature-drag-drop-organizer/FeatureDragDropOrganizer.tsx"
    },
    {
      "path": "packages/registry-react/blocks/feature-drag-drop-organizer/index.ts",
      "content": "export { FeatureDragDropOrganizer } from './FeatureDragDropOrganizer'\nexport type { FeatureDragDropOrganizerProps, LayoutWidget } from './FeatureDragDropOrganizer'\n",
      "type": "registry:block",
      "target": "~/components/blocks/feature-drag-drop-organizer/index.ts"
    }
  ],
  "dependencies": [
    "lucide-react"
  ],
  "devDependencies": [],
  "registryDependencies": [
    "https://uipkge.dev/r/react/badge.json",
    "https://uipkge.dev/r/react/button.json",
    "https://uipkge.dev/r/react/card.json"
  ],
  "description": "Interactive dashboard block layout organizer with position reordering, visibility toggling, and JSON schema export.",
  "categories": [
    "feature",
    "marketing"
  ]
}