index.tsx 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. "use client";
  2. import { Check } from "@phosphor-icons/react/dist/ssr/Check";
  3. import { Copy } from "@phosphor-icons/react/dist/ssr/Copy";
  4. import clsx from "clsx";
  5. import type { ComponentProps } from "react";
  6. import { Button } from "../unstyled/Button/index.jsx";
  7. import { useCopy } from "../useCopy";
  8. import styles from "./index.module.scss";
  9. type OwnProps = {
  10. text: string;
  11. iconOnly?: boolean | undefined;
  12. };
  13. type Props = Omit<
  14. ComponentProps<typeof Button>,
  15. keyof OwnProps | "onPress" | "afterIcon"
  16. > &
  17. OwnProps;
  18. export const CopyButton = ({
  19. text,
  20. iconOnly,
  21. children,
  22. className,
  23. ...props
  24. }: Props) => {
  25. const { isCopied, copy } = useCopy(text);
  26. return (
  27. <Button
  28. onPress={copy}
  29. className={clsx(styles.copyButton, className)}
  30. data-is-copied={isCopied ? "" : undefined}
  31. data-icon-only={iconOnly ? "" : undefined}
  32. {...props}
  33. >
  34. {(...args) => (
  35. <>
  36. <span className={styles.contents}>
  37. {typeof children === "function"
  38. ? children(...args)
  39. : (children ?? "Copy")}
  40. </span>
  41. <div className={styles.iconContainer}>
  42. <Copy className={styles.copyIcon} />
  43. <Check className={styles.checkIcon} />
  44. </div>
  45. </>
  46. )}
  47. </Button>
  48. );
  49. };