You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. import { makeStyles } from '@material-ui/core';
  2. import clsx from 'clsx';
  3. import React from 'react';
  4. import Icon from '../../icons/components/Icon';
  5. import { BUTTON_TYPES } from '../../react/constants';
  6. import { withPixelLineHeight } from '../../styles/functions.web';
  7. import { ButtonProps } from './types';
  8. interface IButtonProps extends ButtonProps {
  9. /**
  10. * Whether or not the button should be full width.
  11. */
  12. fullWidth?: boolean,
  13. /**
  14. * The id of the button.
  15. */
  16. id?: string;
  17. /**
  18. * Click callback.
  19. */
  20. onClick: () => void;
  21. /**
  22. * Which size the button should be.
  23. */
  24. size?: 'small' | 'medium' | 'large';
  25. }
  26. const useStyles = makeStyles((theme: any) => {
  27. return {
  28. button: {
  29. backgroundColor: theme.palette.action01,
  30. color: theme.palette.text01,
  31. borderRadius: theme.shape.borderRadius,
  32. padding: '10px 16px',
  33. display: 'flex',
  34. alignItems: 'center',
  35. justifyContent: 'center',
  36. border: 0,
  37. ...withPixelLineHeight(theme.typography.bodyShortBold),
  38. transition: 'background .2s',
  39. cursor: 'pointer',
  40. '&:hover': {
  41. backgroundColor: theme.palette.action01Hover
  42. },
  43. '&:active': {
  44. backgroundColor: theme.palette.action01Active
  45. },
  46. '&:focus': {
  47. outline: 0,
  48. boxShadow: `0px 0px 0px 2px ${theme.palette.focus01}`
  49. },
  50. '& svg': {
  51. fill: theme.palette.icon01
  52. }
  53. },
  54. primary: {},
  55. secondary: {
  56. backgroundColor: theme.palette.action02,
  57. color: theme.palette.text04,
  58. '&:hover': {
  59. backgroundColor: theme.palette.action02Hover
  60. },
  61. '&:active': {
  62. backgroundColor: theme.palette.action02Active
  63. },
  64. '& svg': {
  65. fill: theme.palette.icon04
  66. }
  67. },
  68. tertiary: {
  69. backgroundColor: theme.palette.action03,
  70. '&:hover': {
  71. backgroundColor: theme.palette.action03Hover
  72. },
  73. '&:active': {
  74. backgroundColor: theme.palette.action03Active
  75. }
  76. },
  77. destructive: {
  78. backgroundColor: theme.palette.actionDanger,
  79. '&:hover': {
  80. backgroundColor: theme.palette.actionDangerHover
  81. },
  82. '&:active': {
  83. backgroundColor: theme.palette.actionDangerActive
  84. }
  85. },
  86. disabled: {
  87. backgroundColor: theme.palette.disabled01,
  88. color: theme.palette.text03,
  89. '&:hover': {
  90. backgroundColor: theme.palette.disabled01,
  91. color: theme.palette.text03
  92. },
  93. '&:active': {
  94. backgroundColor: theme.palette.disabled01,
  95. color: theme.palette.text03
  96. },
  97. '& svg': {
  98. fill: theme.palette.icon03
  99. }
  100. },
  101. iconButton: {
  102. padding: '10px'
  103. },
  104. textWithIcon: {
  105. marginLeft: `${theme.spacing(2)}px`
  106. },
  107. small: {
  108. padding: '8px 16px',
  109. ...withPixelLineHeight(theme.typography.labelBold),
  110. '&.iconButton': {
  111. padding: '6px'
  112. }
  113. },
  114. medium: {},
  115. large: {
  116. padding: '13px 16px',
  117. ...withPixelLineHeight(theme.typography.bodyShortBoldLarge),
  118. '&.iconButton': {
  119. padding: '14px'
  120. }
  121. },
  122. fullWidth: {
  123. width: '100%'
  124. }
  125. };
  126. });
  127. const Button = ({
  128. accessibilityLabel,
  129. disabled,
  130. fullWidth,
  131. icon,
  132. id,
  133. label,
  134. onClick,
  135. size = 'medium',
  136. type = BUTTON_TYPES.PRIMARY
  137. }: IButtonProps) => {
  138. const styles = useStyles();
  139. return (
  140. <button
  141. aria-label = { accessibilityLabel }
  142. className = { clsx(styles.button, styles[type],
  143. disabled && styles.disabled,
  144. icon && !label && `${styles.iconButton} iconButton`,
  145. styles[size], fullWidth && styles.fullWidth) }
  146. disabled = { disabled }
  147. { ...(id ? { id } : {}) }
  148. onClick = { onClick }
  149. type = 'button'>
  150. {icon && <Icon
  151. size = { 20 }
  152. src = { icon } />}
  153. {label && <span className = { icon ? styles.textWithIcon : '' }>{label}</span>}
  154. </button>
  155. );
  156. };
  157. export default Button;