copyToClipboardButton.tsx 1.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. import styled from '@emotion/styled';
  2. import {Button, ButtonProps} from 'sentry/components/button';
  3. import {IconCopy} from 'sentry/icons';
  4. import useCopyToClipboard from 'sentry/utils/useCopyToClipboard';
  5. type Overwrite<T, U> = Pick<T, Exclude<keyof T, keyof U>> & U;
  6. type Props = {
  7. text: string;
  8. children?: React.ReactNode;
  9. iconSize?: React.ComponentProps<typeof IconCopy>['size'];
  10. onError?: undefined | ((error: Error) => void);
  11. } & Overwrite<
  12. Omit<ButtonProps, 'children'>,
  13. Partial<
  14. Pick<ButtonProps, 'aria-label'> & {onCopy: undefined | ((copiedText: string) => void)}
  15. >
  16. >;
  17. export function CopyToClipboardButton({
  18. iconSize,
  19. onCopy,
  20. onError,
  21. text,
  22. ...props
  23. }: Props) {
  24. const {onClick, label} = useCopyToClipboard({
  25. text,
  26. onCopy,
  27. onError,
  28. });
  29. return (
  30. <CopyButton
  31. aria-label={label}
  32. size={props.size}
  33. title={label}
  34. tooltipProps={{delay: 0}}
  35. translucentBorder
  36. onClick={e => {
  37. onClick();
  38. props.onClick?.(e);
  39. }}
  40. {...props}
  41. >
  42. <IconCopy size={iconSize} />
  43. </CopyButton>
  44. );
  45. }
  46. const CopyButton = styled(Button)`
  47. color: ${p => p.theme.subText};
  48. `;