{
  "schemaVersion": 1,
  "name": "command",
  "useFor": "Use Command for an inline list and CommandDialog for a palette. Connect each CommandItem onSelect to navigation or an action. Bind the dialog to Cmd/Ctrl K when needed.",
  "constraints": [
    "Animating the palette open",
    "A drop shadow on the panel",
    "Rows without keyboard support",
    "Icons in every row instead of a title and a line"
  ],
  "documentation": "",
  "source": "Extension from opencommerce-agentcard-web src/app/globals.css (.win, .win-bar, .code)",
  "exports": [
    "Command",
    "CommandDialog",
    "CommandEmpty",
    "CommandFooter",
    "CommandGroup",
    "CommandInput",
    "CommandItem",
    "CommandList",
    "CommandSeparator"
  ],
  "client": true,
  "docsUrl": "https://opencommerce-ds.vercel.app/components/command",
  "markdownUrl": "https://opencommerce-ds.vercel.app/r/command.md",
  "examples": [
    {
      "path": "examples/command.tsx",
      "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport { Button } from \"@/components/ui/button\";\nimport { Command, CommandDialog, CommandEmpty, CommandFooter, CommandGroup, CommandInput, CommandItem, CommandList } from \"@/components/ui/command\";\n\nconst GUIDES: Record<string, string> = {\n  \"Add the commerce tool to your agent\": \"Install the SDK and pass agentcard.tools.commerce() to your agent's tools.\",\n  \"Search a store's catalog\": \"Your agent asks for products in plain words and gets back items it can buy.\",\n  \"How we store cards\": \"Cards are tokenized through your payment provider; your agent never sees the card details.\",\n  \"Get your Agentcard credentials\": \"Create credentials in your Agentcard account and keep the secret on your server.\",\n  \"Deploy to Vercel\": \"Add your credentials as server environment variables before deploying your agent.\",\n};\nfunction Guide({ title }: { title: string }) {\n  return title ? <section aria-label=\"Selected guide\" className=\"mt-4 grid gap-2 text-body-sm\"><h3 className=\"font-display\">{title}</h3><p className=\"text-fg-muted\">{GUIDES[title]}</p></section> : null;\n}\n\nfunction Results({ onSelect }: { onSelect: (value: string) => void }) {\n  return (\n    <>\n      <CommandInput placeholder=\"Search the guides\" aria-label=\"Search the guides\" hint=\"Esc\" />\n      <CommandList>\n        <CommandEmpty>No results.</CommandEmpty>\n        <CommandGroup heading=\"Start here\">\n          <CommandItem description=\"Getting started\" onSelect={() => onSelect(\"Add the commerce tool to your agent\")}>Add the commerce tool to your agent</CommandItem>\n          <CommandItem description=\"Getting started\" onSelect={() => onSelect(\"Search a store's catalog\")}>Search a store's catalog</CommandItem>\n          <CommandItem description=\"Payments\" onSelect={() => onSelect(\"How we store cards\")}>How we store cards</CommandItem>\n        </CommandGroup>\n        <CommandGroup heading=\"Set up\">\n          <CommandItem description=\"Setup\" onSelect={() => onSelect(\"Get your Agentcard credentials\")}>Get your Agentcard credentials</CommandItem>\n          <CommandItem description=\"Setup\" onSelect={() => onSelect(\"Deploy to Vercel\")}>Deploy to Vercel</CommandItem>\n        </CommandGroup>\n      </CommandList>\n      <CommandFooter>\n        <span>\n          <kbd>↑</kbd>\n          <kbd>↓</kbd> to move\n        </span>\n        <span>\n          <kbd>↵</kbd> to open\n        </span>\n        <span>\n          <kbd>Esc</kbd> to close\n        </span>\n      </CommandFooter>\n    </>\n  );\n}\n\nexport function Site() {\n  const [guide, setGuide] = React.useState(\"\");\n  return (\n    <div className=\"grid max-w-160 gap-4\"><Command name=\"search.guides\" className=\"max-w-160\">\n      <Results onSelect={setGuide} />\n    </Command>\n    <Guide title={guide} />\n    </div>\n  );\n}\n\nfunction Palette({ defaultOpen = false }: { defaultOpen?: boolean }) {\n  const [guide, setGuide] = React.useState(\"\");\n  const [open, setOpen] = React.useState(defaultOpen);\n  React.useEffect(() => {\n    const onKey = (event: KeyboardEvent) => {\n      if ((event.metaKey || event.ctrlKey) && event.key.toLowerCase() === \"k\") {\n        event.preventDefault();\n        setOpen((now) => !now);\n      }\n    };\n    document.addEventListener(\"keydown\", onKey);\n    return () => document.removeEventListener(\"keydown\", onKey);\n  }, []);\n  return (\n    <>\n      <Button variant=\"secondary\" onClick={() => setOpen(true)}>\n        Search the guides\n      </Button>\n      <CommandDialog open={open} onOpenChange={setOpen} name=\"search.guides\" title=\"Search the guides\" description=\"Search every section of every guide\">\n        <Results onSelect={(value) => { setGuide(value); setOpen(false); }} />\n      </CommandDialog>\n      <Guide title={guide} />\n    </>\n  );\n}\n\nexport function Open() {\n  return (\n    <div className=\"h-170\">\n      <Palette defaultOpen />\n    </div>\n  );\n}\n",
      "exports": [
        "Site",
        "Open"
      ],
      "requires": [
        "command",
        "button"
      ],
      "packages": [],
      "previews": [
        {
          "name": "Site",
          "url": "https://opencommerce-ds.vercel.app/preview/command/Site"
        },
        {
          "name": "Open",
          "url": "https://opencommerce-ds.vercel.app/preview/command/Open"
        }
      ]
    }
  ],
  "type": "ui",
  "title": "Command",
  "description": "Searchable command list or dialog with keyboard navigation.",
  "surface": "site",
  "kinds": [],
  "requires": [
    "theme",
    "dialog",
    "window",
    "utils"
  ],
  "packages": [
    "@radix-ui/react-dialog",
    "cmdk"
  ],
  "files": [
    {
      "path": "components/ui/command.tsx",
      "content": "\"use client\";\n\nimport * as React from \"react\";\nimport * as DialogPrimitive from \"@radix-ui/react-dialog\";\nimport { Command as CommandPrimitive } from \"cmdk\";\n\nimport { Dialog, DialogPortal } from \"@/components/ui/dialog\";\nimport { WindowBar } from \"@/components/ui/window\";\nimport { cn } from \"@/lib/utils\";\n\n// A search palette as one of the brand's windows: white on the 16 percent ink edge with 12px corners and a soft drop,\n// the mist window bar on top (`name`), then the field: a search mark and a 52px input in 16px Inter over a 9 percent\n// rule. Groups are headed in the 11.5px platform mono at 64 percent ink, ruled apart; a row is a 15px Inter title over a\n// 12px line at 64 percent ink, the highlighted one on the pale blue with a blue return mark. The dialog lays it 12vh from\n// the top over the ink scrim with a light blur. It opens from the keyboard many times a day, so nothing animates: the\n// palette, the highlight and the return mark appear at once.\n\nfunction SearchMark({ className }: { className?: string }) {\n  return (\n    <svg aria-hidden viewBox=\"0 0 16 16\" className={cn(\"size-3.75 shrink-0 fill-none stroke-current [stroke-linecap:round] [stroke-width:1.5]\", className)}>\n      <circle cx=\"7\" cy=\"7\" r=\"4.75\" />\n      <path d=\"M10.5 10.5 14 14\" />\n    </svg>\n  );\n}\n\nfunction Command({ className, name, children, ...props }: React.ComponentProps<typeof CommandPrimitive> & { name?: React.ReactNode }) {\n  return (\n    <CommandPrimitive\n      data-slot=\"command\"\n      className={cn(\"flex max-h-[72vh] w-full flex-col overflow-hidden rounded-panel border border-line-window bg-surface text-fg shadow-floating\", className)}\n      {...props}\n    >\n      {name ? <WindowBar aria-hidden name={name} className=\"[&>span:nth-child(2)]:text-left\" /> : null}\n      {children}\n    </CommandPrimitive>\n  );\n}\n\nfunction CommandDialog({\n  title = \"Search\",\n  description = \"Search for a page or an action\",\n  name = \"search\",\n  className,\n  children,\n  ...props\n}: React.ComponentProps<typeof Dialog> & { title?: string; description?: string; name?: React.ReactNode; className?: string }) {\n  return (\n    <Dialog {...props}>\n      <DialogPortal>\n        <DialogPrimitive.Overlay\n          data-slot=\"command-overlay\"\n          className=\"fixed inset-0 z-50 bg-scrim backdrop-blur-xs\"\n        />\n        <DialogPrimitive.Content data-slot=\"command-dialog\" className=\"fixed top-[12vh] left-1/2 z-50 flex w-[calc(100%-2rem)] max-w-160 -translate-x-1/2 outline-none\">\n          <DialogPrimitive.Title className=\"sr-only\">{title}</DialogPrimitive.Title>\n          <DialogPrimitive.Description className=\"sr-only\">{description}</DialogPrimitive.Description>\n          <Command name={name} className={className}>\n            {children}\n          </Command>\n        </DialogPrimitive.Content>\n      </DialogPortal>\n    </Dialog>\n  );\n}\n\n/** The field: a blue search mark, the 19px display input, and an optional hint at the right (`hint=\"Esc\"`). */\nfunction CommandInput({ className, hint, ...props }: React.ComponentProps<typeof CommandPrimitive.Input> & { hint?: React.ReactNode }) {\n  return (\n    <div data-slot=\"command-input-wrapper\" className=\"flex shrink-0 items-center gap-2.5 border-b border-line px-4 text-fg-muted\">\n      <SearchMark />\n      <CommandPrimitive.Input\n        data-slot=\"command-input\"\n        className={cn(\n          \"h-13 min-w-0 flex-1 bg-transparent font-sans text-body text-fg caret-primary outline-none placeholder:text-fg-faint disabled:opacity-50 [&::-webkit-search-cancel-button]:hidden\",\n          className,\n        )}\n        {...props}\n      />\n      {hint ? <kbd className=\"shrink-0 font-mono text-caption text-fg-faint\">{hint}</kbd> : null}\n    </div>\n  );\n}\n\nfunction CommandList({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.List>) {\n  return (\n    <CommandPrimitive.List\n      data-slot=\"command-list\"\n      className={cn(\"min-h-0 flex-1 scroll-py-2 overflow-x-hidden overflow-y-auto px-2 pt-1.5 pb-2 [scrollbar-color:var(--ds-color-border-default)_transparent] [scrollbar-width:thin]\", className)}\n      {...props}\n    />\n  );\n}\n\nfunction CommandEmpty({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.Empty>) {\n  return <CommandPrimitive.Empty data-slot=\"command-empty\" className={cn(\"px-3.5 py-4.5 font-sans text-body-sm text-fg-muted\", className)} {...props} />;\n}\n\n// A group's heading in the 11.5px platform mono at 64 percent ink; every group after the first visible one is ruled\n// off by a 9 percent ink line.\nfunction CommandGroup({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.Group>) {\n  return (\n    <CommandPrimitive.Group\n      data-slot=\"command-group\"\n      className={cn(\n        \"[&_[cmdk-group-heading]]:px-3.5 [&_[cmdk-group-heading]]:pt-3 [&_[cmdk-group-heading]]:pb-1.5 [&_[cmdk-group-heading]]:font-mono [&_[cmdk-group-heading]]:text-bar [&_[cmdk-group-heading]]:leading-body [&_[cmdk-group-heading]]:text-fg-muted [[cmdk-group]:not([hidden])~&]:mt-1.5 [[cmdk-group]:not([hidden])~&]:border-t [[cmdk-group]:not([hidden])~&]:border-line [[cmdk-group]:not([hidden])~&_[cmdk-group-heading]]:pt-3.5\",\n        className,\n      )}\n      {...props}\n    />\n  );\n}\n\nfunction CommandSeparator({ className, ...props }: React.ComponentProps<typeof CommandPrimitive.Separator>) {\n  return <CommandPrimitive.Separator data-slot=\"command-separator\" className={cn(\"my-1.5 border-t border-line\", className)} {...props} />;\n}\n\n/** A row: the title (children) in 15px Inter, an optional `description` under it, the return mark when\n * highlighted. */\nfunction CommandItem({ className, children, description, ...props }: React.ComponentProps<typeof CommandPrimitive.Item> & { description?: React.ReactNode }) {\n  return (\n    <CommandPrimitive.Item\n      data-slot=\"command-item\"\n      className={cn(\n        \"group/item relative grid cursor-pointer gap-0.75 rounded-sm py-2.5 pr-10 pl-3.5 text-fg outline-none select-none data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-40 data-[selected=true]:bg-blue-5\",\n        className,\n      )}\n      {...props}\n    >\n      <span className=\"flex min-w-0 items-center gap-2.5 font-sans text-button leading-body [&_svg]:size-4 [&_svg]:shrink-0 [&_svg]:text-fg-brand\">{children}</span>\n      {description ? <span className=\"truncate font-sans text-caption leading-normal text-fg-muted\">{description}</span> : null}\n      <span aria-hidden className=\"absolute top-1/2 right-3.5 -translate-y-1/2 font-mono text-body-sm text-fg-brand opacity-0 group-data-[selected=true]/item:opacity-100\">\n        ↵\n      </span>\n    </CommandPrimitive.Item>\n  );\n}\n\n// The keys under the list: the sky bar, blue 10px labels, each key a small white box on a blue edge. Hidden on phones,\n// which have no keyboard to hint at.\nfunction CommandFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"command-footer\"\n      aria-hidden\n      className={cn(\n        \"flex shrink-0 gap-4.5 border-t border-line bg-window-bar px-3.5 py-2 font-mono text-micro text-fg-muted max-md:hidden [&>span]:inline-flex [&>span]:items-center [&>span]:gap-1 [&_kbd]:min-w-4.5 [&_kbd]:rounded-[calc(var(--ds-radius-control)/2)] [&_kbd]:border [&_kbd]:border-hairline [&_kbd]:bg-surface [&_kbd]:px-1 [&_kbd]:py-px [&_kbd]:text-center [&_kbd]:font-[inherit] [&_kbd]:leading-4\",\n        className,\n      )}\n      {...props}\n    />\n  );\n}\n\nexport { Command, CommandDialog, CommandEmpty, CommandFooter, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator };\n"
    }
  ]
}
