wash-cli 0.20.2

wasmcloud Shell (wash) CLI tool
import {Slot} from '@radix-ui/react-slot';
import {Check, Copy} from 'lucide-react';
import {MouseEvent, ReactNode, forwardRef, useEffect, useState} from 'react';
import {cn} from 'lib/utils';
import {Button} from 'ui/button';
import {ButtonProps} from 'ui/button/Button';

interface CopyButtonProps extends Omit<ButtonProps, 'children'> {
  text: string;
  children?: ReactNode | ((copied: boolean) => ReactNode);
}

const CopyButton = forwardRef<HTMLButtonElement, CopyButtonProps>(
  ({asChild, onClick, children, className, ...props}: CopyButtonProps, ref) => {
    const Comp = asChild ? Slot : Button;
    const [copied, setCopied] = useState(false);

    useEffect(() => {
      if (copied) {
        const timeout = setTimeout(() => setCopied(false), 2000);
        return (): void => clearTimeout(timeout);
      }
    }, [copied]);

    const handleClick = (event: MouseEvent<HTMLButtonElement>): void => {
      navigator.clipboard.writeText(props.text);
      setCopied(true);
      onClick?.(event);
    };

    if (children) {
      return (
        <Comp ref={ref} onClick={handleClick} {...props}>
          {typeof children === 'function' ? children(copied) : children}
        </Comp>
      );
    }

    const iconClass = cn('w-3 h-3');

    return (
      <Comp ref={ref} onClick={handleClick} {...props} className={cn('h-6 w-6', className)}>
        {copied ? <Check className={iconClass} /> : <Copy className={iconClass} />}
      </Comp>
    );
  },
);

CopyButton.displayName = 'CopyButton';

export {CopyButton};