{
  "schemaVersion": 1,
  "name": "secret-field",
  "useFor": "Use for API keys or card details. Provide a descriptive label. Use defaultRevealed only when the value should initially be visible.",
  "constraints": [
    "Showing a secret in full by default",
    "Editable secrets (use an input)",
    "Secrets without a copy key"
  ],
  "documentation": "",
  "source": "Extension from opencommerce-agentcard-web src/components/monitoring.tsx (#merchant-filter), copy-button.tsx",
  "exports": [
    "maskSecret",
    "SecretText",
    "SecretField"
  ],
  "client": true,
  "docsUrl": "https://opencommerce-ds.vercel.app/components/secret-field",
  "markdownUrl": "https://opencommerce-ds.vercel.app/r/secret-field.md",
  "examples": [
    {
      "path": "examples/secret-field.tsx",
      "content": "import { SecretField } from \"@/components/ui/secret-field\";\n\nexport function Site() {\n  return (\n    <div className=\"grid max-w-md gap-2\">\n      <p className=\"font-display text-caption text-fg-muted\">API key</p>\n      <SecretField secret=\"ac_live_7Hq2mX9pLw4vR8sN3kTz\" label=\"API key\" />\n    </div>\n  );\n}\n",
      "exports": [
        "Site"
      ],
      "requires": [
        "secret-field"
      ],
      "packages": [],
      "previews": [
        {
          "name": "Site",
          "url": "https://opencommerce-ds.vercel.app/preview/secret-field/Site"
        }
      ]
    }
  ],
  "type": "ui",
  "title": "Secret field",
  "description": "Masked value with reveal and copy controls.",
  "surface": "site",
  "kinds": [],
  "requires": [
    "theme",
    "copy-button",
    "tooltip",
    "utils"
  ],
  "packages": [
    "lucide-react"
  ],
  "files": [
    {
      "path": "components/ui/secret-field.tsx",
      "content": "\"use client\";\n\nimport * as React from \"react\";\nimport { Eye, EyeOff } from \"lucide-react\";\n\nimport { CopyButton } from \"@/components/ui/copy-button\";\nimport { Tooltip, TooltipContent, TooltipTrigger } from \"@/components/ui/tooltip\";\nimport { cn } from \"@/lib/utils\";\n\nconst MASK = \"••••••••••••\";\n\nexport const maskSecret = (secret: string, visibleChars: number) => `${secret.slice(0, visibleChars)}${MASK}`;\n\n/**\n * The secret's text, always as wide as its masked form: revealed, the full value truncates into that same space, so\n * showing it never widens the field or the table column around it.\n */\nexport function SecretText({ secret, masked, isRevealed, className }: { secret: string; masked: string; isRevealed: boolean; className?: string }) {\n  return (\n    <code className={cn(\"relative min-w-0 flex-1\", className)}>\n      <span className={cn(\"block truncate\", isRevealed && \"invisible\")} aria-hidden={isRevealed}>\n        {masked}\n      </span>\n      {isRevealed && <span className=\"absolute inset-0 truncate\">{secret}</span>}\n    </code>\n  );\n}\n\n// A key or a card number in the brand's field (white, 8px corners, the 16 percent ink edge), here 40px tall to hold the\n// small keys: the value masked to its first characters in the platform mono, then a show key and the Copy key.\nfunction SecretField({\n  secret,\n  visibleChars = 8,\n  label = \"key\",\n  defaultRevealed = false,\n  className,\n}: {\n  secret: string;\n  visibleChars?: number;\n  label?: string;\n  /** Starts with the full secret showing, for the one moment right after it's created. */\n  defaultRevealed?: boolean;\n  className?: string;\n}) {\n  const [revealed, setRevealed] = React.useState(defaultRevealed);\n  return (\n    <div data-slot=\"secret-field\" className={cn(\"flex h-10 min-w-0 items-center gap-1.5 rounded-control border border-hairline bg-surface pr-1.5 pl-3\", className)}>\n      <SecretText secret={secret} masked={maskSecret(secret, visibleChars)} isRevealed={revealed} className=\"font-mono text-snippet text-fg\" />\n      <Tooltip>\n        <TooltipTrigger asChild>\n          <button\n            type=\"button\"\n            onClick={() => setRevealed((r) => !r)}\n            aria-label={revealed ? `Hide ${label}` : `Show ${label}`}\n            aria-pressed={revealed}\n            className=\"grid size-7 shrink-0 place-items-center rounded-sm border border-hairline bg-surface text-fg-brand outline-none transition-[background-color,scale] duration-160 ease-out hover:bg-subtle focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-solid focus-visible:outline-focus-ring active:scale-97 motion-reduce:transition-[background-color] motion-reduce:active:scale-100 [&_svg]:size-3.5\"\n          >\n            {revealed ? <EyeOff strokeWidth={1.5} /> : <Eye strokeWidth={1.5} />}\n          </button>\n        </TooltipTrigger>\n        <TooltipContent side=\"top\">{revealed ? \"Hide\" : \"Show\"}</TooltipContent>\n      </Tooltip>\n      <CopyButton value={secret} label={`Copy ${label}`} />\n    </div>\n  );\n}\n\nexport { SecretField };\n"
    }
  ]
}
