{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "web-preview",
  "title": "Web Preview",
  "description": "A small browser for what the agent built, with device widths.",
  "dependencies": [
    "lucide-react"
  ],
  "registryDependencies": [
    "utils",
    "https://ui.cuelark.com/r/theme.json"
  ],
  "files": [
    {
      "path": "src/registry/cuelark/ui/web-preview.tsx",
      "content": "\"use client\";\n\nimport * as React from \"react\";\nimport { ArrowLeftIcon, ArrowRightIcon, ExternalLinkIcon, MonitorIcon, RotateCwIcon, SmartphoneIcon, TabletIcon } from \"lucide-react\";\n\nimport { cn } from \"@/lib/utils\";\n\ntype WebPreviewProps = React.ComponentProps<\"div\"> & {\n  /** The page to show. */\n  url: string;\n  onUrlChange?: (url: string) => void;\n  /** Render custom content instead of an iframe (e.g. a sandboxed component preview). */\n  children?: React.ReactNode;\n};\n\nconst WIDTHS = { desktop: \"100%\", tablet: \"768px\", mobile: \"390px\" } as const;\n\n/** A small browser for what an agent built: address bar, reload, open-in-new-tab and desktop/tablet/mobile widths. */\nfunction WebPreview({ url, onUrlChange, className, children, ...props }: WebPreviewProps) {\n  const [draft, setDraft] = React.useState(url);\n  const [device, setDevice] = React.useState<keyof typeof WIDTHS>(\"desktop\");\n  const [key, setKey] = React.useState(0);\n  React.useEffect(() => setDraft(url), [url]);\n  const btn = \"grid size-7 place-items-center rounded-md text-muted-foreground outline-none hover:bg-muted hover:text-foreground focus-visible:ring-3 focus-visible:ring-ring/50 aria-pressed:bg-muted aria-pressed:text-foreground [&_svg]:size-3.5\";\n\n  return (\n    <div data-slot=\"web-preview\" className={cn(\"flex min-h-80 flex-col overflow-hidden rounded-2xl border border-border bg-card\", className)} {...props}>\n      <div className=\"flex items-center gap-1 border-b border-border px-2 py-1.5\">\n        <button type=\"button\" aria-label=\"Back\" className={btn}>\n          <ArrowLeftIcon />\n        </button>\n        <button type=\"button\" aria-label=\"Forward\" className={btn}>\n          <ArrowRightIcon />\n        </button>\n        <button type=\"button\" aria-label=\"Reload\" className={btn} onClick={() => setKey((k) => k + 1)}>\n          <RotateCwIcon />\n        </button>\n        <form\n          className=\"mx-1 flex-1\"\n          onSubmit={(e) => {\n            e.preventDefault();\n            onUrlChange?.(draft);\n          }}\n        >\n          <input value={draft} onChange={(e) => setDraft(e.target.value)} aria-label=\"Address\" className=\"h-7 w-full rounded-md bg-muted px-2.5 font-mono text-xs outline-none focus-visible:ring-3 focus-visible:ring-ring/40\" />\n        </form>\n        {([\"desktop\", \"tablet\", \"mobile\"] as const).map((d) => {\n          const Icon = d === \"desktop\" ? MonitorIcon : d === \"tablet\" ? TabletIcon : SmartphoneIcon;\n          return (\n            <button key={d} type=\"button\" aria-label={d} aria-pressed={device === d} onClick={() => setDevice(d)} className={btn}>\n              <Icon />\n            </button>\n          );\n        })}\n        {/^https?:\\/\\//.test(url) && (\n          <a href={url} target=\"_blank\" rel=\"noopener noreferrer\" aria-label=\"Open in new tab\" className={btn}>\n            <ExternalLinkIcon />\n          </a>\n        )}\n      </div>\n      <div className=\"flex flex-1 justify-center bg-muted/40 p-2\">\n        <div className=\"h-full overflow-hidden rounded-lg bg-background ring-1 ring-border transition-[width] duration-300 ease-cue\" style={{ width: WIDTHS[device], maxWidth: \"100%\" }}>\n          {children ?? <iframe key={key} src={url} title=\"Preview\" className=\"size-full min-h-72 border-0\" sandbox=\"allow-scripts allow-same-origin allow-forms\" />}\n        </div>\n      </div>\n    </div>\n  );\n}\n\nexport { WebPreview };\nexport type { WebPreviewProps };\n",
      "type": "registry:ui"
    }
  ],
  "docs": "Docs and examples: https://ui.cuelark.com/components/web-preview",
  "categories": [
    "agents"
  ],
  "type": "registry:ui"
}