2022-10-04 18:55:51 +02:00
|
|
|
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 {
|
2023-02-02 21:15:26 +01:00
|
|
|
AlignItems,
|
2022-10-04 18:55:51 +02:00
|
|
|
DISPLAY,
|
2023-02-02 21:15:26 +01:00
|
|
|
JustifyContent,
|
|
|
|
TextColor,
|
|
|
|
TextVariant,
|
|
|
|
Size,
|
|
|
|
BorderRadius,
|
|
|
|
BackgroundColor,
|
2022-10-04 18:55:51 +02:00
|
|
|
} from '../../../helpers/constants/design-system';
|
2022-11-03 19:41:16 +01:00
|
|
|
import { BUTTON_BASE_SIZES } from './button-base.constants';
|
2022-10-04 18:55:51 +02:00
|
|
|
|
|
|
|
export const ButtonBase = ({
|
|
|
|
as = 'button',
|
|
|
|
block,
|
|
|
|
children,
|
|
|
|
className,
|
2022-11-03 19:41:16 +01:00
|
|
|
href,
|
|
|
|
size = BUTTON_BASE_SIZES.MD,
|
2023-02-22 18:42:06 +01:00
|
|
|
startIconName,
|
|
|
|
startIconProps,
|
|
|
|
endIconName,
|
|
|
|
endIconProps,
|
2022-10-04 18:55:51 +02:00
|
|
|
loading,
|
|
|
|
disabled,
|
2023-01-26 19:32:11 +01:00
|
|
|
iconLoadingProps,
|
|
|
|
textProps,
|
2022-10-04 18:55:51 +02:00
|
|
|
...props
|
|
|
|
}) => {
|
2022-11-03 19:41:16 +01:00
|
|
|
const Tag = href ? 'a' : as;
|
2022-10-04 18:55:51 +02:00
|
|
|
return (
|
|
|
|
<Box
|
2022-10-14 00:39:22 +02:00
|
|
|
as={Tag}
|
2023-02-02 21:15:26 +01:00
|
|
|
backgroundColor={BackgroundColor.backgroundAlternative}
|
|
|
|
color={TextColor.textDefault}
|
2022-11-22 21:25:49 +01:00
|
|
|
href={href}
|
2023-01-26 19:32:11 +01:00
|
|
|
paddingLeft={4}
|
|
|
|
paddingRight={4}
|
2022-10-04 18:55:51 +02:00
|
|
|
className={classnames(
|
2023-01-13 22:58:09 +01:00
|
|
|
'mm-button-base',
|
2022-10-04 18:55:51 +02:00
|
|
|
{
|
2023-01-26 19:32:11 +01:00
|
|
|
[`mm-button-base--size-${size}`]:
|
|
|
|
Object.values(BUTTON_BASE_SIZES).includes(size),
|
2023-01-13 22:58:09 +01:00
|
|
|
'mm-button-base--loading': loading,
|
|
|
|
'mm-button-base--disabled': disabled,
|
|
|
|
'mm-button-base--block': block,
|
2022-10-04 18:55:51 +02:00
|
|
|
},
|
|
|
|
className,
|
|
|
|
)}
|
|
|
|
disabled={disabled}
|
|
|
|
display={DISPLAY.INLINE_FLEX}
|
2023-02-02 21:15:26 +01:00
|
|
|
justifyContent={JustifyContent.center}
|
|
|
|
alignItems={AlignItems.center}
|
|
|
|
borderRadius={BorderRadius.pill}
|
2022-10-04 18:55:51 +02:00
|
|
|
{...props}
|
|
|
|
>
|
|
|
|
<Text
|
|
|
|
as="span"
|
2023-01-13 22:58:09 +01:00
|
|
|
className="mm-button-base__content"
|
2023-02-02 21:15:26 +01:00
|
|
|
justifyContent={JustifyContent.center}
|
|
|
|
alignItems={AlignItems.center}
|
2022-10-04 18:55:51 +02:00
|
|
|
gap={2}
|
2023-02-02 21:15:26 +01:00
|
|
|
variant={TextVariant.bodyMd}
|
|
|
|
color={TextColor.inherit}
|
2023-01-26 19:32:11 +01:00
|
|
|
{...textProps}
|
2022-10-04 18:55:51 +02:00
|
|
|
>
|
2023-02-22 18:42:06 +01:00
|
|
|
{startIconName && (
|
|
|
|
<Icon name={startIconName} size={Size.SM} {...startIconProps} />
|
|
|
|
)}
|
2022-10-04 18:55:51 +02:00
|
|
|
{children}
|
2023-02-22 18:42:06 +01:00
|
|
|
{endIconName && (
|
|
|
|
<Icon name={endIconName} size={Size.SM} {...endIconProps} />
|
|
|
|
)}
|
2022-10-04 18:55:51 +02:00
|
|
|
</Text>
|
|
|
|
{loading && (
|
|
|
|
<Icon
|
2023-01-26 19:32:11 +01:00
|
|
|
className="mm-button-base__icon-loading"
|
2023-01-24 18:39:46 +01:00
|
|
|
name={ICON_NAMES.LOADING}
|
2023-02-02 21:15:26 +01:00
|
|
|
size={Size.MD}
|
2023-01-26 19:32:11 +01:00
|
|
|
{...iconLoadingProps}
|
2022-10-04 18:55:51 +02:00
|
|
|
/>
|
|
|
|
)}
|
|
|
|
</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,
|
2023-01-13 22:58:09 +01:00
|
|
|
/**
|
|
|
|
* Additional props to pass to the Text component that wraps the button children
|
|
|
|
*/
|
|
|
|
buttonTextProps: PropTypes.shape(Text.PropTypes),
|
2022-10-04 18:55:51 +02:00
|
|
|
/**
|
|
|
|
* 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,
|
2022-11-03 19:41:16 +01:00
|
|
|
/**
|
|
|
|
* When an `href` prop is passed, ButtonBase will automatically change the root element to be an `a` (anchor) tag
|
|
|
|
*/
|
|
|
|
href: PropTypes.string,
|
2022-10-04 18:55:51 +02:00
|
|
|
/**
|
2023-02-22 18:42:06 +01:00
|
|
|
* Add icon to start (left side) of button text passing icon name
|
2022-10-04 18:55:51 +02:00
|
|
|
* The name of the icon to display. Should be one of ICON_NAMES
|
|
|
|
*/
|
2023-02-22 18:42:06 +01:00
|
|
|
startIconName: PropTypes.oneOf(Object.values(ICON_NAMES)),
|
2022-10-04 18:55:51 +02:00
|
|
|
/**
|
2023-02-22 18:42:06 +01:00
|
|
|
* iconProps accepts all the props from Icon
|
|
|
|
*/
|
|
|
|
startIconProps: PropTypes.shape(Icon.PropTypes),
|
|
|
|
/**
|
|
|
|
* Add icon to end (right side) of button text passing icon name
|
|
|
|
* The name of the icon to display. Should be one of ICON_NAMES
|
2022-10-04 18:55:51 +02:00
|
|
|
*/
|
2023-02-22 18:42:06 +01:00
|
|
|
endIconName: PropTypes.oneOf(Object.values(ICON_NAMES)),
|
2022-10-04 18:55:51 +02:00
|
|
|
/**
|
|
|
|
* iconProps accepts all the props from Icon
|
|
|
|
*/
|
2023-02-22 18:42:06 +01:00
|
|
|
endIconProps: PropTypes.shape(Icon.PropTypes),
|
2023-01-26 19:32:11 +01:00
|
|
|
/**
|
|
|
|
* iconLoadingProps accepts all the props from Icon
|
|
|
|
*/
|
|
|
|
iconLoadingProps: PropTypes.shape(Icon.PropTypes),
|
2022-10-04 18:55:51 +02:00
|
|
|
/**
|
|
|
|
* Boolean to show loading spinner in button
|
|
|
|
*/
|
|
|
|
loading: PropTypes.bool,
|
|
|
|
/**
|
|
|
|
* The size of the ButtonBase.
|
2023-02-02 21:15:26 +01:00
|
|
|
* Possible values could be 'Size.SM'(32px), 'Size.MD'(40px), 'Size.LG'(48px),
|
2023-01-26 19:32:11 +01:00
|
|
|
*/
|
|
|
|
size: PropTypes.oneOfType([
|
|
|
|
PropTypes.shape(BUTTON_BASE_SIZES),
|
|
|
|
PropTypes.string,
|
|
|
|
]),
|
|
|
|
/**
|
|
|
|
* textProps accepts all the props from Icon
|
2022-10-04 18:55:51 +02:00
|
|
|
*/
|
2023-01-26 19:32:11 +01:00
|
|
|
textProps: PropTypes.shape(Text.PropTypes),
|
2022-10-04 18:55:51 +02:00
|
|
|
/**
|
|
|
|
* ButtonBase accepts all the props from Box
|
|
|
|
*/
|
|
|
|
...Box.propTypes,
|
|
|
|
};
|