button.tsx 1.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. import { useCallback } from 'react';
  2. import classNames from 'classnames';
  3. interface BaseProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
  4. block?: boolean;
  5. secondary?: boolean;
  6. text?: JSX.Element;
  7. }
  8. interface PropsWithChildren extends BaseProps {
  9. text?: never;
  10. }
  11. interface PropsWithText extends BaseProps {
  12. text: JSX.Element;
  13. children: never;
  14. }
  15. type Props = PropsWithText | PropsWithChildren;
  16. export const Button: React.FC<Props> = ({
  17. text,
  18. type = 'button',
  19. onClick,
  20. disabled,
  21. block,
  22. secondary,
  23. className,
  24. title,
  25. children,
  26. ...props
  27. }) => {
  28. const handleClick = useCallback<React.MouseEventHandler<HTMLButtonElement>>(
  29. (e) => {
  30. if (!disabled && onClick) {
  31. onClick(e);
  32. }
  33. },
  34. [disabled, onClick],
  35. );
  36. return (
  37. <button
  38. className={classNames('button', className, {
  39. 'button-secondary': secondary,
  40. 'button--block': block,
  41. })}
  42. disabled={disabled}
  43. onClick={handleClick}
  44. title={title}
  45. type={type}
  46. {...props}
  47. >
  48. {text ?? children}
  49. </button>
  50. );
  51. };