teqo-backup/src/components/CopyLinkButton.tsx
Francisco Solla 77216481d8 feat(C168): biblioteca de cortes no acervo (origem, download, compartilhar, editar texto)
Lista + detalhe em /campanha/comunicacao/acervo/cortes: busca por título/descrição,\norigem da fala, player do MP4, edição de título/descrição e kill switch de\npublicar/despublicar no mesmo /corte/<id>. Gate speechCatalog fail-closed para\nadvisor/leader. Sem collection/migration nova.
2026-09-15 12:56:51 -03:00

47 lines
1.5 KiB
TypeScript

'use client'
import { CheckIcon, CopyIcon } from 'lucide-react'
import { Button } from '@/components/ui/button'
import { copyFeedbackLabels, copyFeedbackLiveMessages, useCopyFeedback } from '@/lib/copyFeedback'
import { cn } from '@/lib/utils'
type CopyLinkButtonProps = {
/** Absolute URL or a same-origin path — resolved against the current origin on click. */
url: string
variant?: 'default' | 'outline' | 'ghost'
className?: string
}
/**
* The one copy-to-clipboard control of the cut surfaces (public page, result
* card, library): same feedback label/auto-reset and screen-reader live region.
* A relative path is resolved against the current origin on click, so a server
* component can pass `publicPath` directly.
*/
export const CopyLinkButton = ({ url, variant = 'outline', className }: CopyLinkButtonProps) => {
const { feedback, copy } = useCopyFeedback()
return (
<>
<Button
type="button"
variant={variant}
className={cn('min-h-10', className)}
onClick={() => {
void copy(new URL(url, window.location.origin).toString())
}}
>
{feedback === 'copied' ? (
<CheckIcon data-icon="inline-start" aria-hidden="true" />
) : (
<CopyIcon data-icon="inline-start" aria-hidden="true" />
)}
{copyFeedbackLabels[feedback]}
</Button>
<span aria-live="polite" className="sr-only">
{copyFeedbackLiveMessages[feedback]}
</span>
</>
)
}