import PropTypes from 'prop-types';
import { clsm } from '../../utils';
import { forwardRef } from 'react';
import { Link, useLocation } from 'react-router-dom';
import { motion } from 'framer-motion';
import Spinner from '../Spinner';
import {
BUTTON_BASE_CLASSES as baseClasses,
BUTTON_LINK_CLASSES as linkClasses,
BUTTON_VARIANT_CLASSES as variantClasses,
BUTTON_HOVER_CLASSES as hoverClasses
} from './ButtonTheme';
const Button = forwardRef(
(
{
'data-testid': dataTestId,
animationProps,
ariaControls,
ariaDisabled,
ariaLabel,
ariaSelected,
children,
className,
customStyles,
disableHover,
id,
isDisabled,
isLoading,
name,
onClick,
onFocus,
onKeyDown,
onMouseDown,
role,
state,
saveLocationFromState,
tabIndex,
to,
type,
variant
},
ref
) => {
const location = useLocation();
const commonProps = {
...(!!ariaControls ? { 'aria-controls': ariaControls } : {}),
...(!!ariaLabel ? { 'aria-label': ariaLabel } : {}),
...(!!role ? { role: role } : {}),
...(ariaSelected !== null ? { 'aria-selected': ariaSelected } : {}),
...(tabIndex !== null ? { tabIndex } : {}),
'aria-disabled': ariaDisabled,
'data-testid': dataTestId,
id,
name,
ref,
onClick,
style: customStyles
};
const classes = clsm([
'button',
variant,
...baseClasses,
...variantClasses[variant],
...(disableHover ? [] : hoverClasses[variant]),
type === 'nav' && linkClasses,
className
]);
if (type === 'nav') {
if (!to) {
throw new Error("Button with type 'nav' requires a valid 'to' prop.");
}
return (
{children}
);
}
return (
{isLoading ? : children}
);
}
);
Button.defaultProps = {
'data-testid': undefined,
animationProps: undefined,
ariaControls: '',
ariaDisabled: false,
ariaLabel: '',
ariaSelected: null,
className: '',
customStyles: {},
disableHover: false,
id: undefined,
isDisabled: false,
isLoading: false,
state: {},
name: '',
onBlur: undefined,
onClick: undefined,
onFocus: undefined,
onKeyDown: undefined,
onMouseDown: undefined,
role: '',
saveLocationFromState: false,
tabIndex: null,
to: '',
type: 'button',
variant: 'primary',
width: ''
};
Button.propTypes = {
'data-testid': PropTypes.string,
animationProps: PropTypes.object,
ariaControls: PropTypes.string,
ariaDisabled: PropTypes.bool,
ariaLabel: PropTypes.string,
ariaSelected: PropTypes.bool,
children: PropTypes.node.isRequired,
className: PropTypes.string,
customStyles: PropTypes.object,
state: PropTypes.object,
disableHover: PropTypes.bool,
id: PropTypes.string,
isDisabled: PropTypes.bool,
isLoading: PropTypes.bool,
name: PropTypes.string,
onClick: PropTypes.func,
onFocus: PropTypes.func,
onKeyDown: PropTypes.func,
onMouseDown: PropTypes.func,
role: PropTypes.string,
saveLocationFromState: PropTypes.bool,
tabIndex: PropTypes.number,
to: PropTypes.string,
type: PropTypes.oneOf(['button', 'submit', 'reset', 'nav']),
variant: PropTypes.oneOf([
'primary',
'secondary',
'tertiary',
'destructive',
'icon',
'primaryText',
'secondaryText',
'tertiaryText'
])
};
export default Button;