/
githubmirror
/
ui
Обзор
Документация
Войти
/
githubmirror
/
ui
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
apps/v4/components/copy-button.tsx
121 строка
3 KB
shadcn
fix
03 мар 2026, 15:38
03 мар 2026, 15:38
a4dafd1
Код
Авторство
О чём код?
"use client" import * as React from "react" import { IconCheck, IconCopy } from "@tabler/icons-react" import { trackEvent, type Event } from "@/lib/events" import { cn } from "@/lib/utils" import { Button } from "@/registry/new-york-v4/ui/button" function legacyCopyToClipboard(value: string) { const textArea = document.createElement("textarea") textArea.value = value textArea.setAttribute("readonly", "") textArea.style.position = "fixed" textArea.style.opacity = "0" textArea.style.pointerEvents = "none" document.body.appendChild(textArea) textArea.focus() textArea.select() textArea.setSelectionRange(0, value.length) let hasCopied = false try { hasCopied = document.execCommand("copy") } catch { hasCopied = false } document.body.removeChild(textArea) return hasCopied } export async function copyToClipboardWithMeta(value: string, event?: Event) { if (typeof window === "undefined") { return false } if (!value) { return false } let hasCopied = false if (navigator.clipboard?.writeText) { try { await navigator.clipboard.writeText(value) hasCopied = true } catch { hasCopied = legacyCopyToClipboard(value) } } else { hasCopied = legacyCopyToClipboard(value) } if (!hasCopied) { return false } if (event) { trackEvent(event) } return true } export function CopyButton({ value, className, variant = "ghost", event, ...props }: React.ComponentProps<typeof Button> & { value: string src?: string event?: Event["name"] tooltip?: string }) { const [hasCopied, setHasCopied] = React.useState(false) React.useEffect(() => { if (hasCopied) { const timer = setTimeout(() => setHasCopied(false), 2000) return () => clearTimeout(timer) } }, [hasCopied]) return ( <Button data-slot="copy-button" data-copied={hasCopied} size="icon" variant={variant} className={cn( "absolute top-3 right-2 z-10 size-7 bg-code hover:opacity-100 focus-visible:opacity-100", className )} onClick={async () => { const hasCopied = await copyToClipboardWithMeta( value, event ? { name: event, properties: { code: value, }, } : undefined ) if (hasCopied) { setHasCopied(true) } }} {...props} > <span className="sr-only">Copy</span> {hasCopied ? <IconCheck /> : <IconCopy />} </Button> ) }