Path: blob/1.0-develop/resources/scripts/components/elements/CopyOnClick.tsx
7461 views
import React, { useEffect, useState } from 'react';1import Fade from '@/components/elements/Fade';2import Portal from '@/components/elements/Portal';3import copy from 'copy-to-clipboard';4import classNames from 'classnames';56interface CopyOnClickProps {7text: string | number | null | undefined;8showInNotification?: boolean;9children: React.ReactNode;10}1112const CopyOnClick = ({ text, showInNotification = true, children }: CopyOnClickProps) => {13const [copied, setCopied] = useState(false);1415useEffect(() => {16if (!copied) return;1718const timeout = setTimeout(() => {19setCopied(false);20}, 2500);2122return () => {23clearTimeout(timeout);24};25}, [copied]);2627if (!React.isValidElement(children)) {28throw new Error('Component passed to <CopyOnClick/> must be a valid React element.');29}3031const child = !text32? React.Children.only(children)33: React.cloneElement(React.Children.only(children), {34className: classNames(children.props.className || '', 'cursor-pointer'),35onClick: (e: React.MouseEvent<HTMLElement>) => {36copy(String(text));37setCopied(true);38if (typeof children.props.onClick === 'function') {39children.props.onClick(e);40}41},42});4344return (45<>46{copied && (47<Portal>48<Fade in appear timeout={250} key={copied ? 'visible' : 'invisible'}>49<div className={'fixed z-50 bottom-0 right-0 m-4'}>50<div className={'rounded-md py-3 px-4 text-gray-200 bg-neutral-600/95 shadow'}>51<p>52{showInNotification53? `Copied "${String(text)}" to clipboard.`54: 'Copied text to clipboard.'}55</p>56</div>57</div>58</Fade>59</Portal>60)}61{child}62</>63);64};6566export default CopyOnClick;676869