{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "app-row",
  "title": "App Row",
  "description": "App directory row with an icon tile, name, blurb and a connect action.",
  "dependencies": [
    "lucide-react@^1.27.0"
  ],
  "registryDependencies": [
    "@pestoui/button",
    "@pestoui/icon-tile",
    "@pestoui/style",
    "@pestoui/utils"
  ],
  "files": [
    {
      "path": "pestoui/components/app-row.tsx",
      "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { Check, Plus } from \"lucide-react\"\n\nimport { Button } from \"@/components/ui/button\"\nimport { IconTile } from \"@/components/icon-tile\"\nimport { cn } from \"@/lib/utils\"\n\n/* App directory row — icon tile, name + blurb, connect action */\nexport function AppRow({\n  icon,\n  name,\n  description,\n  connected = false,\n  className,\n}: {\n  icon: React.ReactNode\n  name: string\n  description: string\n  connected?: boolean\n  className?: string\n}) {\n  /* Connecting is the only state this row owns, so the check landing is the\n     only thing worth animating — the row itself is a static list item, and a\n     directory of them is exactly where a hover lift turns into noise.\n\n     The ref is what keeps a list that renders with half its rows already\n     connected from popping every tick at once on first paint: only a row that\n     has been seen disconnected animates its check in. It latches on rather than\n     tracking the previous value, so an unrelated re-render mid-animation cannot\n     pull the class back off and cancel it. */\n  const wasDisconnected = React.useRef(!connected)\n  if (!connected) {\n    wasDisconnected.current = true\n  }\n\n  return (\n    <div className={cn(\"flex items-center gap-4 py-3\", className)}>\n      <IconTile variant=\"soft\" size=\"lg\">\n        {icon}\n      </IconTile>\n      <div className=\"min-w-0 flex-1\">\n        <div className=\"text-body-lg font-semibold tracking-snug\">{name}</div>\n        <div className=\"mt-0.5 truncate text-body text-muted-foreground\">\n          {description}\n        </div>\n      </div>\n      {connected ? (\n        <Check\n          aria-label=\"Connected\"\n          className={cn(\n            \"mr-2 size-5 shrink-0 text-muted-foreground\",\n            wasDisconnected.current &&\n              \"animate-in fade-in zoom-in-90 blur-in-3 duration-spring-swap ease-spring-swap\"\n          )}\n        />\n      ) : (\n        <Button variant=\"outline\" size=\"icon\" aria-label={`Connect ${name}`}>\n          <Plus className=\"size-4.5\" />\n        </Button>\n      )}\n    </div>\n  )\n}\n",
      "type": "registry:component"
    }
  ],
  "type": "registry:component"
}