2018-03-26 23:32:43 +02:00
|
|
|
// @flow
|
|
|
|
import * as React from 'react';
|
|
|
|
import Icon from 'component/common/icon';
|
|
|
|
import classnames from 'classnames';
|
|
|
|
|
|
|
|
type Props = {
|
|
|
|
onClick: ?(any) => any,
|
|
|
|
href: ?string,
|
|
|
|
title: ?string,
|
|
|
|
label: ?string,
|
|
|
|
icon: ?string,
|
|
|
|
iconRight: ?string,
|
|
|
|
disabled: ?boolean,
|
|
|
|
children: ?React.Node,
|
|
|
|
navigate: ?string,
|
|
|
|
// TODO: these (nav) should be a reusable type
|
|
|
|
doNavigate: (string, ?any) => void,
|
|
|
|
navigateParams: any,
|
|
|
|
className: ?string,
|
|
|
|
description: ?string,
|
|
|
|
type: string,
|
|
|
|
button: ?string, // primary, secondary, alt, link
|
|
|
|
noPadding: ?boolean, // to remove padding and allow circular buttons
|
2018-10-21 10:57:39 +02:00
|
|
|
iconColor?: string,
|
2018-12-19 06:44:53 +01:00
|
|
|
iconSize?: number,
|
|
|
|
constrict: ?boolean, // to shorten the button and ellipsis, only use for links
|
2019-01-15 17:16:30 +01:00
|
|
|
selected: ?boolean,
|
2018-03-26 23:32:43 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
class Button extends React.PureComponent<Props> {
|
|
|
|
static defaultProps = {
|
|
|
|
type: 'button',
|
|
|
|
};
|
|
|
|
|
|
|
|
render() {
|
|
|
|
const {
|
|
|
|
onClick,
|
|
|
|
href,
|
|
|
|
title,
|
|
|
|
label,
|
|
|
|
icon,
|
|
|
|
iconRight,
|
|
|
|
disabled,
|
|
|
|
children,
|
|
|
|
navigate,
|
|
|
|
navigateParams,
|
|
|
|
doNavigate,
|
|
|
|
className,
|
|
|
|
description,
|
|
|
|
button,
|
|
|
|
type,
|
|
|
|
noPadding,
|
2018-05-23 05:48:22 +02:00
|
|
|
iconColor,
|
2018-12-19 06:44:53 +01:00
|
|
|
iconSize,
|
|
|
|
constrict,
|
2019-01-15 17:16:30 +01:00
|
|
|
selected,
|
2018-03-26 23:32:43 +02:00
|
|
|
...otherProps
|
|
|
|
} = this.props;
|
|
|
|
|
|
|
|
const combinedClassName = classnames(
|
2019-02-13 17:27:20 +01:00
|
|
|
'button',
|
2018-03-26 23:32:43 +02:00
|
|
|
{
|
2019-02-13 17:27:20 +01:00
|
|
|
'button--no-padding': noPadding,
|
2018-03-26 23:32:43 +02:00
|
|
|
},
|
|
|
|
button
|
|
|
|
? {
|
2019-02-13 17:27:20 +01:00
|
|
|
'button--primary': button === 'primary',
|
|
|
|
'button--secondary': button === 'secondary',
|
|
|
|
'button--alt': button === 'alt',
|
|
|
|
'button--danger': button === 'danger',
|
|
|
|
'button--inverse': button === 'inverse',
|
|
|
|
'button--disabled': disabled,
|
|
|
|
'button--link': button === 'link',
|
|
|
|
'button--constrict': constrict,
|
|
|
|
'button--selected': selected,
|
2018-03-26 23:32:43 +02:00
|
|
|
}
|
2019-02-13 17:27:20 +01:00
|
|
|
: 'button--no-style',
|
2018-03-26 23:32:43 +02:00
|
|
|
className
|
|
|
|
);
|
|
|
|
|
|
|
|
const extendedOnClick =
|
|
|
|
!onClick && navigate
|
|
|
|
? event => {
|
|
|
|
event.stopPropagation();
|
|
|
|
doNavigate(navigate, navigateParams || {});
|
|
|
|
}
|
|
|
|
: onClick;
|
|
|
|
|
|
|
|
const content = (
|
2019-02-13 17:27:20 +01:00
|
|
|
<span className="button__content">
|
2018-12-19 06:44:53 +01:00
|
|
|
{icon && <Icon icon={icon} iconColor={iconColor} size={iconSize} />}
|
2019-02-13 17:27:20 +01:00
|
|
|
{label && <span className="button__label">{label}</span>}
|
2018-03-26 23:32:43 +02:00
|
|
|
{children && children}
|
2018-12-19 06:44:53 +01:00
|
|
|
{iconRight && <Icon icon={iconRight} iconColor={iconColor} size={iconSize} />}
|
2018-03-26 23:32:43 +02:00
|
|
|
</span>
|
|
|
|
);
|
|
|
|
|
|
|
|
return href ? (
|
|
|
|
<a className={combinedClassName} href={href} title={title}>
|
|
|
|
{content}
|
|
|
|
</a>
|
|
|
|
) : (
|
|
|
|
<button
|
2018-05-10 04:47:08 +02:00
|
|
|
title={title}
|
2018-03-26 23:32:43 +02:00
|
|
|
aria-label={description || label || title}
|
|
|
|
className={combinedClassName}
|
|
|
|
onClick={extendedOnClick}
|
|
|
|
disabled={disabled}
|
|
|
|
type={type}
|
|
|
|
{...otherProps}
|
|
|
|
>
|
|
|
|
{content}
|
|
|
|
</button>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export default Button;
|