{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "ink/clipboard",
  "title": "Clipboard",
  "description": "Copy-to-clipboard button with success feedback",
  "dependencies": [
    "ink"
  ],
  "registryDependencies": [
    "https://termcn.dev/r/ink/interaction.json",
    "https://termcn.dev/r/ink/terminal-style.json",
    "https://termcn.dev/r/ink/use-clipboard.json",
    "https://termcn.dev/r/ink/use-theme.json",
    "https://termcn.dev/r/ink/use-unicode.json"
  ],
  "files": [
    {
      "path": "registry/ui/clipboard.tsx",
      "content": "import { Box, Text } from \"ink\";\nimport React, { useState, useCallback, useEffect } from \"react\";\n\nimport { useClipboard } from \"@/hooks/use-clipboard\";\nimport {\n  isActivationKey,\n  useInteraction,\n} from \"@/hooks/use-interaction\";\nimport type { InteractionProps } from \"@/hooks/use-interaction\";\nimport { useTheme } from \"@/hooks/use-theme\";\nimport { useUnicode } from \"@/hooks/use-unicode\";\nimport { resolveBorderStyle } from \"@/lib/terminal-style\";\n\nexport interface ClipboardProps extends InteractionProps {\n  value: string;\n  label?: string;\n  successMessage?: string;\n  timeout?: number;\n  errorMessage?: string;\n  \"aria-label\"?: string;\n}\n\nexport const Clipboard = ({\n  value,\n  label,\n  successMessage = \"Copied!\",\n  timeout = 2000,\n  errorMessage = \"Copy failed\",\n  id,\n  autoFocus,\n  isActive,\n  disabled,\n  \"aria-label\": ariaLabel,\n}: ClipboardProps) => {\n  const unicode = useUnicode();\n  const theme = useTheme();\n  const { write } = useClipboard();\n  const [copied, setCopied] = useState(false);\n  const [error, setError] = useState<string>();\n\n  const doCopy = useCallback(async () => {\n    try {\n      await write(value);\n      setCopied(true);\n      setError(undefined);\n    } catch {\n      setCopied(false);\n      setError(errorMessage);\n    }\n  }, [errorMessage, write, value]);\n\n  useEffect(() => {\n    if (!copied) {\n      return;\n    }\n    const timer = setTimeout(() => setCopied(false), timeout);\n    return () => clearTimeout(timer);\n  }, [copied, timeout]);\n\n  const { isFocused } = useInteraction(\n    (input, key) => {\n      if (input === \"c\" || isActivationKey(input, key)) {\n        void doCopy();\n      }\n    },\n    { autoFocus, disabled, id, isActive }\n  );\n\n  return (\n    <Box\n      flexDirection=\"column\"\n      gap={0}\n      aria-role=\"button\"\n      aria-label={\n        ariaLabel ??\n        `${label ?? \"Copy value\"}. ${copied ? successMessage : (error ?? \"Press Enter or Space to copy.\")}`\n      }\n      aria-state={{ disabled: disabled || undefined }}\n    >\n      {label && <Text color={theme.colors.mutedForeground}>{label}</Text>}\n      <Box gap={2} alignItems=\"center\">\n        <Box\n          borderStyle={resolveBorderStyle(\"round\", unicode)}\n          borderColor={theme.colors.border}\n          paddingX={1}\n        >\n          <Text color={theme.colors.foreground}>{value}</Text>\n        </Box>\n        <Box\n          borderStyle={resolveBorderStyle(\"round\", unicode)}\n          borderColor={\n            error\n              ? theme.colors.error\n              : copied\n                ? theme.colors.success\n                : theme.colors.primary\n          }\n          paddingX={1}\n        >\n          <Text\n            color={\n              error\n                ? theme.colors.error\n                : copied\n                  ? theme.colors.success\n                  : theme.colors.primary\n            }\n            bold\n          >\n            {error ??\n              (copied\n                ? `${unicode ? \"✓\" : \"v\"} ${successMessage}`\n                : `${isFocused ? \"> \" : \"\"}Copy`)}\n          </Text>\n        </Box>\n      </Box>\n      {!copied && (\n        <Text aria-hidden color={theme.colors.mutedForeground} dimColor>\n          press c or space to copy\n        </Text>\n      )}\n    </Box>\n  );\n};\n",
      "type": "registry:ui"
    }
  ],
  "categories": [
    "utility"
  ],
  "type": "registry:ui"
}