UNPKG

@sky-mavis/tanto-widget

Version:
82 lines 2.38 kB
import {jsx,jsxs}from'@emotion/react/jsx-runtime';import {useTheme}from'@emotion/react';import {AnimatePresence}from'motion/react';import*as m from'motion/react-m';import {useState,useCallback,useEffect}from'react';import {CheckCircleFillIcon}from'../../assets/CheckCircleFillIcon.mjs';import {CopyIcon}from'../../assets/CopyIcon.mjs';import {Box}from'../box/Box.mjs';import {Button}from'../button/Button.mjs';const DEFAULT_ANIMATION_DURATION = 1_500; function useClipboard(value, duration = DEFAULT_ANIMATION_DURATION) { const [copied, setCopied] = useState(false); const handleCopy = useCallback(async () => { if (copied || !value) return; try { await navigator.clipboard.writeText(value.trim()); setCopied(true); } catch {} }, [value, copied]); useEffect(() => { if (!copied) return; const timer = setTimeout(() => setCopied(false), duration); return () => clearTimeout(timer); }, [copied, duration]); return { copied, handleCopy }; } function CopyButton({ intent = 'secondary', size = 'xsmall', value, children, ...rest }) { const theme = useTheme(); const { copied, handleCopy } = useClipboard(value); const containerStyles = { align: 'center', gap: children ? 4 : 0, mx: children ? 0 : -2 }; return jsx(Button, { intent: intent, size: size, onClick: handleCopy, disabled: !value, ...rest, children: jsxs(Box, { ...containerStyles, children: [jsx(AnimatePresence, { mode: "popLayout", initial: false, children: jsx(m.div, { initial: { opacity: 0, scale: 0.5, rotate: copied ? -180 : 180 }, animate: { opacity: 1, scale: 1, rotate: 0 }, exit: { opacity: 0, scale: 0.5, rotate: copied ? 180 : -180 }, transition: { type: 'spring', stiffness: 300, damping: copied ? 20 : 30 }, children: copied ? jsx(CheckCircleFillIcon, { color: theme.successColor, size: 18 }) : jsx(CopyIcon, { size: 18 }) }, copied.toString()) }), children && jsx("div", { children: children })] }) }); }export{CopyButton};