gab-social/app/javascript/gabsocial/components/button.js

179 lines
4.4 KiB
JavaScript
Raw Normal View History

2020-02-21 00:57:29 +00:00
import { Fragment } from 'react'
2020-02-19 23:57:07 +00:00
import { NavLink } from 'react-router-dom'
import classNames from 'classnames/bind'
2020-02-21 00:57:29 +00:00
import Icon from './icon'
2020-02-19 23:57:07 +00:00
const cx = classNames.bind(_s)
const COLORS = {
primary: 'primary',
secondary: 'secondary',
tertiary: 'tertiary',
2020-02-21 00:57:29 +00:00
white: 'white',
2020-03-26 03:11:32 +00:00
black: 'black',
2020-02-19 23:57:07 +00:00
brand: 'brand',
2020-03-26 03:11:32 +00:00
danger: 'danger',
2020-02-19 23:57:07 +00:00
none: 'none',
}
export default class Button extends PureComponent {
static propTypes = {
children: PropTypes.node,
to: PropTypes.string,
href: PropTypes.string,
onClick: PropTypes.func,
className: PropTypes.string,
icon: PropTypes.string,
2020-02-21 00:57:29 +00:00
iconWidth: PropTypes.string,
iconHeight: PropTypes.string,
iconClassName: PropTypes.string,
2020-02-19 23:57:07 +00:00
color: PropTypes.string,
2020-02-21 00:57:29 +00:00
backgroundColor: PropTypes.string,
2020-02-19 23:57:07 +00:00
block: PropTypes.bool,
text: PropTypes.bool,
disabled: PropTypes.bool,
outline: PropTypes.bool,
2020-02-21 00:57:29 +00:00
narrow: PropTypes.bool,
underlineOnHover: PropTypes.bool,
2020-02-22 23:26:23 +00:00
radiusSmall: PropTypes.bool,
2020-03-14 17:31:29 +00:00
noClasses: PropTypes.bool,
2020-02-19 23:57:07 +00:00
}
static defaultProps = {
2020-02-21 00:57:29 +00:00
color: COLORS.white,
backgroundColor: COLORS.brand,
2020-02-19 23:57:07 +00:00
}
handleClick = (e) => {
if (!this.props.disabled && this.props.onClick) {
this.props.onClick(e)
}
}
setRef = (c) => {
2020-03-14 17:31:29 +00:00
const { buttonRef } = this.props
if (buttonRef) buttonRef(c)
2020-02-19 23:57:07 +00:00
this.node = c
}
focus() {
this.node.focus()
}
2020-02-22 23:26:23 +00:00
render() {
2020-02-21 00:57:29 +00:00
const {
block,
className,
disabled,
text,
to,
icon,
iconWidth,
iconHeight,
iconClassName,
children,
href,
outline,
color,
backgroundColor,
underlineOnHover,
narrow,
2020-02-22 23:26:23 +00:00
radiusSmall,
2020-03-14 17:31:29 +00:00
noClasses,
2020-02-21 00:57:29 +00:00
...otherProps
} = this.props
2020-03-07 04:53:28 +00:00
const theIcon = !!icon ? (
<Icon
id={icon}
width={iconWidth}
2020-03-26 03:11:32 +00:00
height={iconHeight}
2020-03-07 04:53:28 +00:00
className={iconClassName}
/>
) : undefined
2020-02-29 15:42:47 +00:00
2020-03-14 17:31:29 +00:00
const classes = noClasses ? className : cx(className, {
2020-02-19 23:57:07 +00:00
default: 1,
noUnderline: 1,
font: 1,
cursorPointer: 1,
textAlignCenter: 1,
2020-03-06 15:38:22 +00:00
outlineNone: 1,
2020-03-07 04:53:28 +00:00
flexRow: !!children && !!icon,
2020-03-26 03:11:32 +00:00
cursorNotAllowed: disabled,
opacity05: disabled,
2020-02-19 23:57:07 +00:00
2020-02-21 00:57:29 +00:00
backgroundColorPrimary: backgroundColor === COLORS.white,
2020-03-26 03:11:32 +00:00
backgroundColorBlack: backgroundColor === COLORS.black,
2020-02-21 00:57:29 +00:00
backgroundColorBrand: backgroundColor === COLORS.brand,
backgroundTransparent: backgroundColor === COLORS.none,
2020-02-22 23:26:23 +00:00
backgroundSubtle2: backgroundColor === COLORS.tertiary,
2020-02-29 15:42:47 +00:00
backgroundSubtle: backgroundColor === COLORS.secondary,
2020-03-26 03:11:32 +00:00
backgroundColorDanger: backgroundColor === COLORS.danger,
colorPrimary: !!children && color === COLORS.primary,
colorSecondary: !!children && color === COLORS.secondary,
colorTertiary: !!children && color === COLORS.tertiary,
colorWhite: !!children && color === COLORS.white,
colorBrand: !!children && color === COLORS.brand,
2020-02-19 23:57:07 +00:00
2020-02-21 00:57:29 +00:00
borderColorBrand: color === COLORS.brand && outline,
border1PX: outline,
2020-02-19 23:57:07 +00:00
circle: !text,
2020-02-22 23:26:23 +00:00
radiusSmall: radiusSmall,
2020-02-19 23:57:07 +00:00
2020-03-11 23:56:18 +00:00
py5: narrow,
py10: !text && !narrow,
px15: !text,
2020-02-19 23:57:07 +00:00
width100PC: block,
2020-02-21 00:57:29 +00:00
underline_onHover: underlineOnHover,
2020-03-26 03:11:32 +00:00
backgroundSubtle2Dark_onHover: backgroundColor === COLORS.tertiary || backgroundColor === COLORS.secondary,
backgroundColorBlackOpaque_onHover: backgroundColor === COLORS.black,
2020-02-21 00:57:29 +00:00
backgroundColorBrandDark_onHover: backgroundColor === COLORS.brand,
backgroundColorBrand_onHover: color === COLORS.brand && outline,
2020-03-26 03:11:32 +00:00
colorWhite_onHover: !!children && color === COLORS.brand && outline,
2020-03-27 15:29:52 +00:00
fillColorSecondary: !!icon && color === COLORS.secondary,
2020-03-26 03:11:32 +00:00
fillColorWhite: !!icon && color === COLORS.white,
fillColorBrand: !!icon && color === COLORS.brand,
fillColorWhite_onHover: !!icon && color === COLORS.brand && outline,
2020-02-19 23:57:07 +00:00
})
const tagName = !!href ? 'a' : !!to ? 'NavLink' : 'button'
2020-02-21 00:57:29 +00:00
const theChildren = !!icon ? (
<Fragment>
{theIcon}
{children}
</Fragment>
) : children
2020-02-22 23:26:23 +00:00
const options = {
2020-02-29 15:42:47 +00:00
disabled,
2020-02-22 23:26:23 +00:00
className: classes,
ref: this.setRef,
to: to || undefined,
href: href || undefined,
onClick: this.handleClick || undefined,
2020-03-07 04:53:28 +00:00
...otherProps,
2020-02-22 23:26:23 +00:00
}
if (tagName === 'NavLink' && !!to) {
return (
<NavLink {...options}>
{theChildren}
</NavLink>
)
}
return React.createElement(tagName, options, theChildren)
2020-02-19 23:57:07 +00:00
}
}