'use client' import React, { type ComponentProps } from 'react' import { SvgCheck, SvgCopy } from '@chainlink/blocks-icons' import { cn } from '../../utils/cn' import { ButtonIcon } from '../Button' import { Popover, PopoverArrow, PopoverContent, PopoverTrigger, } from '../Popover' import { CopyRoot, CopyTrigger, useCopy, useCopyContext, type CopyRootProps, type CopyTriggerProps, } from './CopyPrimitive' // Re-export primitives export { CopyRoot, CopyTrigger, useCopy, useCopyContext } export type { CopyRootProps, CopyTriggerProps } // ============================================================================ // CopyButton // ============================================================================ export type CopyButtonProps = { /** * The text to copy. If provided, can be used standalone without CopyRoot. * If omitted, reads from CopyRoot context. */ text?: string } & Omit, 'children'> /** * A copy trigger styled as a ButtonIcon (xs size). * Can be used within a CopyRoot or standalone with the `text` prop. * * @example * ```tsx * // Standalone * * * // Within CopyRoot * * * * ``` */ export const CopyButton = ({ text, className, ...buttonIconProps }: CopyButtonProps) => { const { isCopied, copy } = useCopy(text) const [popoverOpen, setPopoverOpen] = React.useState(false) return ( { e.stopPropagation() copy() }} onMouseEnter={() => setPopoverOpen(true)} onMouseLeave={() => setPopoverOpen(false)} className={cn('[&_svg]:size-3', className)} size="xs" {...buttonIconProps} > {isCopied ? : } {isCopied ? 'Copied!' : 'Copy'} ) } // ============================================================================ // CopyIcon // ============================================================================ export type CopyIconProps = { /** * The text to copy. If provided, can be used standalone without CopyRoot. * If omitted, reads from CopyRoot context. */ text?: string /** * Additional class names for the icon button. */ className?: string } /** * A minimal copy icon trigger. * Can be used within a CopyRoot or standalone with the `text` prop. * * @example * ```tsx * // Standalone * * * // Within CopyRoot * * * * ``` */ export const CopyIcon = ({ text, className }: CopyIconProps) => { return } // ============================================================================ // Copy (High-level component) // ============================================================================ export interface CopyProps extends React.HTMLAttributes { /** * The text to be copied to the clipboard. */ text: string /** * The visual variant of the copy trigger. * @default 'button' */ variant?: 'button' | 'icon' } /** * High-level copy component that displays content with a copy button/icon. * * @example * ```tsx * * 0x1234...abcd * * ``` */ export const Copy = ({ text, children, variant = 'button', className, ...props }: CopyProps) => { return ( {children} {variant === 'button' && } {variant === 'icon' && } ) }