{"$schema":"https://ui.shadcn.com/schema/registry-item.json","name":"snippet","type":"registry:ui","title":"snippet","description":"Snippet is a component that allows you to display and copy code in a tabbed interface.","author":"Hayden Bleasel <hello@haydenbleasel.com>","dependencies":["lucide-react"],"devDependencies":[],"registryDependencies":["button","tabs"],"files":[{"type":"registry:ui","path":"index.tsx","content":"\"use client\";\n\nimport { CheckIcon, CopyIcon } from \"lucide-react\";\nimport {\n  type ComponentProps,\n  cloneElement,\n  type HTMLAttributes,\n  type ReactElement,\n  useState,\n} from \"react\";\nimport { Button } from \"@/components/ui/button\";\nimport { Tabs, TabsContent, TabsList, TabsTrigger } from \"@/components/ui/tabs\";\nimport { cn } from \"@/lib/utils\";\n\nexport type SnippetProps = ComponentProps<typeof Tabs>;\n\nexport const Snippet = ({ className, ...props }: SnippetProps) => (\n  <Tabs\n    className={cn(\n      \"group w-full gap-0 overflow-hidden rounded-md border\",\n      className\n    )}\n    {...props}\n  />\n);\n\nexport type SnippetHeaderProps = HTMLAttributes<HTMLDivElement>;\n\nexport const SnippetHeader = ({ className, ...props }: SnippetHeaderProps) => (\n  <div\n    className={cn(\n      \"flex flex-row items-center justify-between border-b bg-secondary p-1\",\n      className\n    )}\n    {...props}\n  />\n);\n\nexport type SnippetCopyButtonProps = ComponentProps<typeof Button> & {\n  value: string;\n  onCopy?: () => void;\n  onError?: (error: Error) => void;\n  timeout?: number;\n};\n\nexport const SnippetCopyButton = ({\n  asChild,\n  value,\n  onCopy,\n  onError,\n  timeout = 2000,\n  children,\n  ...props\n}: SnippetCopyButtonProps) => {\n  const [isCopied, setIsCopied] = useState(false);\n\n  const copyToClipboard = () => {\n    if (\n      typeof window === \"undefined\" ||\n      !navigator.clipboard.writeText ||\n      !value\n    ) {\n      return;\n    }\n\n    navigator.clipboard.writeText(value).then(() => {\n      setIsCopied(true);\n      onCopy?.();\n\n      setTimeout(() => setIsCopied(false), timeout);\n    }, onError);\n  };\n\n  if (asChild) {\n    return cloneElement(children as ReactElement, {\n      // @ts-expect-error - we know this is a button\n      onClick: copyToClipboard,\n    });\n  }\n\n  const icon = isCopied ? <CheckIcon size={14} /> : <CopyIcon size={14} />;\n\n  return (\n    <Button\n      className=\"opacity-0 transition-opacity group-hover:opacity-100\"\n      onClick={copyToClipboard}\n      size=\"icon\"\n      variant=\"ghost\"\n      {...props}\n    >\n      {children ?? icon}\n    </Button>\n  );\n};\n\nexport type SnippetTabsListProps = ComponentProps<typeof TabsList>;\n\nexport const SnippetTabsList = TabsList;\n\nexport type SnippetTabsTriggerProps = ComponentProps<typeof TabsTrigger>;\n\nexport const SnippetTabsTrigger = ({\n  className,\n  ...props\n}: SnippetTabsTriggerProps) => (\n  <TabsTrigger className={cn(\"gap-1.5\", className)} {...props} />\n);\n\nexport type SnippetTabsContentProps = ComponentProps<typeof TabsContent>;\n\nexport const SnippetTabsContent = ({\n  className,\n  children,\n  ...props\n}: SnippetTabsContentProps) => (\n  <TabsContent\n    asChild\n    className={cn(\"mt-0 bg-background p-4 text-sm\", className)}\n    {...props}\n  >\n    <pre className=\"truncate\">{children}</pre>\n  </TabsContent>\n);\n","target":"components/kibo-ui/snippet/index.tsx"}],"css":{}}