import React, { useState, useRef, useEffect } from "react"; import { CopyToClipboard } from "react-copy-to-clipboard"; import { Bubble } from "../bubble"; import { useTranslation } from "../i18n"; import { Icon } from "../icon"; import { injectValue } from "../_util/inject-value"; import { noop } from "../_util/noop"; import { TriggerProps } from "../popover"; import { StyledProps } from "../_type"; export interface CopyProps { /** * 待复制的文本内容 */ text: string; /** * 复制事件触发回调,其中 `context` 中 `result`: * - `true` 复制成功 * - `false` 复制失败 */ onCopy?: (text: string, context: { result: boolean }) => void; /** * 自定义按钮提示 * @default copied => copied ? "复制成功" : "复制" (已处理国际化) */ tips?: React.ReactNode | ((copied: boolean) => React.ReactNode); /** * 自定义按钮渲染 * @default * @docType React.ReactNode | ((copied: boolean) => React.ReactNode) */ children?: React.ReactNode | ((copied: boolean) => React.ReactNode); } function HoverTrigger({ setVisible, openDelay = 50, closeDelay = 100, render, onReset, }: TriggerProps & { onReset: () => void }) { const commonProps = { onMouseEnter: () => { onReset(); setVisible(true, openDelay); }, onMouseLeave: () => setVisible(false, closeDelay), }; return render({ overlayProps: commonProps, childrenProps: commonProps, }); } HoverTrigger.displayName = "CopyHoverTrigger"; export function Copy(props: CopyProps) { const t = useTranslation(); const { text, tips = copied => (copied ? t.copied : t.copy), onCopy = noop, children = , } = props; const [copied, setCopied] = useState(false); const timerRef = useRef(null); useEffect(() => () => clearTimeout(timerRef.current), []); const element = injectValue(children)(copied) as React.ReactElement; return ( { setCopied(false); clearTimeout(timerRef.current); }, }, ]} content={injectValue(tips)(copied)} > { onCopy(text, { result }); if (result) { if (timerRef.current) { clearTimeout(timerRef.current); } setCopied(true); timerRef.current = setTimeout(() => setCopied(false), 1500); } }} > {React.isValidElement(element) ? ( React.cloneElement(element, { style: { cursor: "pointer", ...(element.props.style || {}) }, }) ) : ( {element} )} ); } Copy.displayName = "Copy";