Files
shadcn/apps/v4/hooks/use-copy-to-clipboard.ts
zeekay 05fc512820 feat: sync upstream shadcn/ui — [email protected], v4 app, font system, chart improvements
Upstream sync from shadcn-ui/ui (1686 commits since last merge base).

Key changes:
- packages/shadcn upgraded to 4.1.0 (CLI font transformers, scaffold from github, chart colors)
- apps/v4 replaces apps/www as the primary docs/registry app
- Font system: 25+ heading font registries, font markers utility, @supports override
- Chart improvements: recharts v3 compat, radial chart fixes
- templates/ updated with monorepo variants (astro, vite, react-router, start)
- skills/shadcn AI skill definitions added
- deprecated/ removed (auth, auth-firebase, cli, www)

Preserved Hanzo-only paths: app/, pkg/, demo/, docs/, template/next/
2026-03-24 19:04:31 -07:00

81 lines
1.5 KiB
TypeScript

"use client"
import * as React from "react"
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 function useCopyToClipboard({
timeout = 2000,
onCopy,
}: {
timeout?: number
onCopy?: () => void
} = {}) {
const [isCopied, setIsCopied] = React.useState(false)
const copyToClipboard = async (value: string) => {
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
}
setIsCopied(true)
if (onCopy) {
onCopy()
}
if (timeout !== 0) {
setTimeout(() => {
setIsCopied(false)
}, timeout)
}
return true
}
return { isCopied, copyToClipboard }
}