import React from 'react'; import PropTypes from 'prop-types'; import classnames from 'classnames'; import Box from '../../ui/box'; import { Icon, ICON_NAMES } from '../icon'; import { Text } from '../text'; import { ALIGN_ITEMS, DISPLAY, JUSTIFY_CONTENT, TEXT_COLORS, TEXT, SIZES, FLEX_DIRECTION, } from '../../../helpers/constants/design-system'; import { BUTTON_BASE_SIZES } from './button-base.constants'; export const ButtonBase = ({ as = 'button', block, children, className, href, size = BUTTON_BASE_SIZES.MD, icon, iconPositionRight, loading, disabled, iconProps, ...props }) => { const Tag = href ? 'a' : as; return ( <Box as={Tag} href={href} paddingLeft={size === BUTTON_BASE_SIZES.AUTO ? 0 : 4} paddingRight={size === BUTTON_BASE_SIZES.AUTO ? 0 : 4} className={classnames( 'mm-button', `mm-button--size-${size}`, { 'mm-button--loading': loading, 'mm-button--disabled': disabled, 'mm-button--block': block, }, className, )} disabled={disabled} display={DISPLAY.INLINE_FLEX} justifyContent={JUSTIFY_CONTENT.CENTER} alignItems={ALIGN_ITEMS.CENTER} {...props} > <Text as="span" className="mm-button__content" alignItems={ALIGN_ITEMS.CENTER} justifyContent={JUSTIFY_CONTENT.CENTER} flexDirection={ iconPositionRight ? FLEX_DIRECTION.ROW_REVERSE : FLEX_DIRECTION.ROW } gap={2} variant={size === BUTTON_BASE_SIZES.AUTO ? TEXT.INHERIT : TEXT.BODY_MD} color={TEXT_COLORS.INHERIT} > {icon && ( <Icon name={icon} size={size === BUTTON_BASE_SIZES.AUTO ? SIZES.AUTO : SIZES.SM} {...iconProps} /> )} {children} </Text> {loading && ( <Icon className="mm-button__icon-loading" name={ICON_NAMES.LOADING_FILLED} size={size === BUTTON_BASE_SIZES.AUTO ? SIZES.AUTO : SIZES.MD} /> )} </Box> ); }; ButtonBase.propTypes = { /** * The polymorphic `as` prop allows you to change the root HTML element of the Button component between `button` and `a` tag */ as: PropTypes.string, /** * Boolean prop to quickly activate box prop display block */ block: PropTypes.bool, /** * The children to be rendered inside the ButtonBase */ children: PropTypes.node, /** * An additional className to apply to the ButtonBase. */ className: PropTypes.string, /** * Boolean to disable button */ disabled: PropTypes.bool, /** * When an `href` prop is passed, ButtonBase will automatically change the root element to be an `a` (anchor) tag */ href: PropTypes.string, /** * Add icon to left side of button text passing icon name * The name of the icon to display. Should be one of ICON_NAMES */ icon: PropTypes.string, // Can't set PropTypes.oneOf(ICON_NAMES) because ICON_NAMES is an environment variable /** * Boolean that when true will position the icon on right of children * Icon default position left */ iconPositionRight: PropTypes.bool, /** * iconProps accepts all the props from Icon */ iconProps: PropTypes.object, /** * Boolean to show loading spinner in button */ loading: PropTypes.bool, /** * The size of the ButtonBase. * Possible values could be 'SIZES.AUTO', 'SIZES.SM'(32px), 'SIZES.MD'(40px), 'SIZES.LG'(48px), */ size: PropTypes.oneOf(Object.values(BUTTON_BASE_SIZES)), /** * ButtonBase accepts all the props from Box */ ...Box.propTypes, };