2022-09-13 07:36:00 +00:00
|
|
|
import { Theme } from '@mui/material';
|
2022-07-20 06:19:59 +00:00
|
|
|
import React from 'react';
|
2022-08-22 09:40:59 +00:00
|
|
|
import { useTranslation } from 'react-i18next';
|
2022-09-13 07:36:00 +00:00
|
|
|
import { makeStyles } from 'tss-react/mui';
|
2022-07-20 06:19:59 +00:00
|
|
|
|
2022-07-27 08:40:34 +00:00
|
|
|
import Icon from '../../../icons/components/Icon';
|
|
|
|
import { withPixelLineHeight } from '../../../styles/functions.web';
|
|
|
|
import { BUTTON_TYPES } from '../../constants';
|
|
|
|
import { ButtonProps } from '../types';
|
2022-07-20 06:19:59 +00:00
|
|
|
|
|
|
|
interface IButtonProps extends ButtonProps {
|
|
|
|
|
2022-07-27 09:33:50 +00:00
|
|
|
/**
|
|
|
|
* Class name used for additional styles.
|
|
|
|
*/
|
2022-09-08 09:52:36 +00:00
|
|
|
className?: string;
|
2022-07-27 09:33:50 +00:00
|
|
|
|
2022-07-20 06:19:59 +00:00
|
|
|
/**
|
|
|
|
* Whether or not the button should be full width.
|
|
|
|
*/
|
2022-09-08 09:52:36 +00:00
|
|
|
fullWidth?: boolean;
|
2022-07-20 06:19:59 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* The id of the button.
|
|
|
|
*/
|
|
|
|
id?: string;
|
|
|
|
|
2022-07-28 13:45:32 +00:00
|
|
|
/**
|
|
|
|
* Whether or not the button is a submit form button.
|
|
|
|
*/
|
|
|
|
isSubmit?: boolean;
|
|
|
|
|
2022-07-20 06:19:59 +00:00
|
|
|
/**
|
2022-08-22 09:40:59 +00:00
|
|
|
* Text to be displayed on the component.
|
|
|
|
* Used when there's no labelKey.
|
2022-07-20 06:19:59 +00:00
|
|
|
*/
|
2022-08-22 09:40:59 +00:00
|
|
|
label?: string;
|
2022-07-20 06:19:59 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Which size the button should be.
|
|
|
|
*/
|
|
|
|
size?: 'small' | 'medium' | 'large';
|
2022-07-27 09:33:50 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Data test id.
|
|
|
|
*/
|
|
|
|
testId?: string;
|
2022-07-20 06:19:59 +00:00
|
|
|
}
|
|
|
|
|
2022-09-13 07:36:00 +00:00
|
|
|
const useStyles = makeStyles()((theme: Theme) => {
|
2022-07-20 06:19:59 +00:00
|
|
|
return {
|
|
|
|
button: {
|
|
|
|
backgroundColor: theme.palette.action01,
|
|
|
|
color: theme.palette.text01,
|
|
|
|
borderRadius: theme.shape.borderRadius,
|
|
|
|
padding: '10px 16px',
|
|
|
|
display: 'flex',
|
|
|
|
alignItems: 'center',
|
|
|
|
justifyContent: 'center',
|
|
|
|
border: 0,
|
|
|
|
...withPixelLineHeight(theme.typography.bodyShortBold),
|
|
|
|
transition: 'background .2s',
|
|
|
|
cursor: 'pointer',
|
|
|
|
|
|
|
|
'&:hover': {
|
|
|
|
backgroundColor: theme.palette.action01Hover
|
|
|
|
},
|
|
|
|
|
|
|
|
'&:active': {
|
|
|
|
backgroundColor: theme.palette.action01Active
|
|
|
|
},
|
|
|
|
|
|
|
|
'&:focus': {
|
|
|
|
outline: 0,
|
|
|
|
boxShadow: `0px 0px 0px 2px ${theme.palette.focus01}`
|
|
|
|
},
|
|
|
|
|
2022-09-13 07:36:00 +00:00
|
|
|
'& div > svg': {
|
2022-07-20 06:19:59 +00:00
|
|
|
fill: theme.palette.icon01
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
primary: {},
|
|
|
|
|
|
|
|
secondary: {
|
|
|
|
backgroundColor: theme.palette.action02,
|
|
|
|
color: theme.palette.text04,
|
|
|
|
|
|
|
|
'&:hover': {
|
|
|
|
backgroundColor: theme.palette.action02Hover
|
|
|
|
},
|
|
|
|
|
|
|
|
'&:active': {
|
|
|
|
backgroundColor: theme.palette.action02Active
|
|
|
|
},
|
|
|
|
|
2022-09-13 07:36:00 +00:00
|
|
|
'& div > svg': {
|
2022-07-20 06:19:59 +00:00
|
|
|
fill: theme.palette.icon04
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
tertiary: {
|
|
|
|
backgroundColor: theme.palette.action03,
|
|
|
|
|
|
|
|
'&:hover': {
|
|
|
|
backgroundColor: theme.palette.action03Hover
|
|
|
|
},
|
|
|
|
|
|
|
|
'&:active': {
|
|
|
|
backgroundColor: theme.palette.action03Active
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
destructive: {
|
|
|
|
backgroundColor: theme.palette.actionDanger,
|
|
|
|
|
|
|
|
'&:hover': {
|
|
|
|
backgroundColor: theme.palette.actionDangerHover
|
|
|
|
},
|
|
|
|
|
|
|
|
'&:active': {
|
|
|
|
backgroundColor: theme.palette.actionDangerActive
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
disabled: {
|
|
|
|
backgroundColor: theme.palette.disabled01,
|
|
|
|
color: theme.palette.text03,
|
|
|
|
|
|
|
|
'&:hover': {
|
|
|
|
backgroundColor: theme.palette.disabled01,
|
|
|
|
color: theme.palette.text03
|
|
|
|
},
|
|
|
|
|
|
|
|
'&:active': {
|
|
|
|
backgroundColor: theme.palette.disabled01,
|
|
|
|
color: theme.palette.text03
|
|
|
|
},
|
|
|
|
|
2022-09-13 07:36:00 +00:00
|
|
|
'& div > svg': {
|
2022-07-20 06:19:59 +00:00
|
|
|
fill: theme.palette.icon03
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
iconButton: {
|
|
|
|
padding: '10px'
|
|
|
|
},
|
|
|
|
|
|
|
|
textWithIcon: {
|
2022-09-13 07:36:00 +00:00
|
|
|
marginLeft: theme.spacing(2)
|
2022-07-20 06:19:59 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
small: {
|
|
|
|
padding: '8px 16px',
|
|
|
|
...withPixelLineHeight(theme.typography.labelBold),
|
|
|
|
|
|
|
|
'&.iconButton': {
|
|
|
|
padding: '6px'
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
medium: {},
|
|
|
|
|
|
|
|
large: {
|
|
|
|
padding: '13px 16px',
|
|
|
|
...withPixelLineHeight(theme.typography.bodyShortBoldLarge),
|
|
|
|
|
|
|
|
'&.iconButton': {
|
|
|
|
padding: '14px'
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
fullWidth: {
|
|
|
|
width: '100%'
|
|
|
|
}
|
|
|
|
};
|
|
|
|
});
|
|
|
|
|
2022-08-25 11:35:19 +00:00
|
|
|
const Button = React.forwardRef<any, any>(({
|
2022-07-20 06:19:59 +00:00
|
|
|
accessibilityLabel,
|
2022-07-27 09:33:50 +00:00
|
|
|
className,
|
2022-07-20 06:19:59 +00:00
|
|
|
disabled,
|
|
|
|
fullWidth,
|
|
|
|
icon,
|
|
|
|
id,
|
2022-07-28 13:45:32 +00:00
|
|
|
isSubmit,
|
2022-07-20 06:19:59 +00:00
|
|
|
label,
|
2022-08-22 09:40:59 +00:00
|
|
|
labelKey,
|
2022-07-28 13:45:32 +00:00
|
|
|
onClick = () => null,
|
2022-07-20 06:19:59 +00:00
|
|
|
size = 'medium',
|
2022-07-27 09:33:50 +00:00
|
|
|
testId,
|
2022-07-20 06:19:59 +00:00
|
|
|
type = BUTTON_TYPES.PRIMARY
|
2022-08-25 11:35:19 +00:00
|
|
|
}: IButtonProps, ref) => {
|
2022-09-13 07:36:00 +00:00
|
|
|
const { classes: styles, cx } = useStyles();
|
2022-08-22 09:40:59 +00:00
|
|
|
const { t } = useTranslation();
|
2022-07-20 06:19:59 +00:00
|
|
|
|
|
|
|
return (
|
|
|
|
<button
|
|
|
|
aria-label = { accessibilityLabel }
|
2022-09-13 07:36:00 +00:00
|
|
|
className = { cx(styles.button, styles[type],
|
2022-07-20 06:19:59 +00:00
|
|
|
disabled && styles.disabled,
|
2022-08-22 09:40:59 +00:00
|
|
|
icon && !(labelKey || label) && `${styles.iconButton} iconButton`,
|
2022-07-27 09:33:50 +00:00
|
|
|
styles[size], fullWidth && styles.fullWidth, className) }
|
|
|
|
data-testid = { testId }
|
2022-07-20 06:19:59 +00:00
|
|
|
disabled = { disabled }
|
|
|
|
{ ...(id ? { id } : {}) }
|
|
|
|
onClick = { onClick }
|
2022-08-25 11:35:19 +00:00
|
|
|
ref = { ref }
|
2022-08-01 07:05:17 +00:00
|
|
|
title = { accessibilityLabel }
|
2022-07-28 13:45:32 +00:00
|
|
|
type = { isSubmit ? 'submit' : 'button' }>
|
2022-07-20 06:19:59 +00:00
|
|
|
{icon && <Icon
|
|
|
|
size = { 20 }
|
|
|
|
src = { icon } />}
|
2022-08-22 09:40:59 +00:00
|
|
|
{(labelKey || label) && <span className = { icon ? styles.textWithIcon : '' }>
|
|
|
|
{labelKey ? t(labelKey) : label}
|
|
|
|
</span>}
|
2022-07-20 06:19:59 +00:00
|
|
|
</button>
|
|
|
|
);
|
2022-08-25 11:35:19 +00:00
|
|
|
});
|
2022-07-20 06:19:59 +00:00
|
|
|
|
|
|
|
export default Button;
|