Skip to content

Instantly share code, notes, and snippets.

@matheusazzi
Last active May 13, 2022 19:33
Show Gist options
  • Save matheusazzi/252937418dd28f0bebc15b4a48264d09 to your computer and use it in GitHub Desktop.
Save matheusazzi/252937418dd28f0bebc15b4a48264d09 to your computer and use it in GitHub Desktop.
Button.jsx
import React from 'react'
import PropTypes from 'prop-types'
import classnames from 'classnames'
import styles from './button.module.css'
const cx = classnames.bind(styles)
const defaultProps = {
as: 'default',
shape: 'rect',
size: 'md',
action: () => {}
}
const propTypes = {
as: PropTypes.oneOf(['default', 'default-outline', 'primary', 'primary-outline']),
type: PropTypes.oneOf([undefined, 'button', 'submit', 'reset']),
size: PropTypes.oneOf(['sm', 'md', 'lg']),
shape: PropTypes.oneOf(['rect', 'circle']),
block: PropTypes.bool,
disabled: PropTypes.bool,
loading: PropTypes.bool,
action: PropTypes.func,
children: PropTypes.node,
icon: PropTypes.func,
focused: PropTypes.bool,
className: PropTypes.oneOfType([
PropTypes.string,
PropTypes.array,
PropTypes.object
])
}
const Button = (props) => {
const {
as,
type,
shape,
size,
icon,
block,
disabled,
loading,
focused,
action,
children
} = props
const className = cx(styles.button, {
[styles[`button--${as}`]]: as,
[styles[`button--${shape}`]]: shape,
[styles[`button--${size}`]]: size,
[styles['button--iconed']]: icon,
[styles['button--block']]: block,
[styles['button--disabled']]: disabled,
[styles['button--focused']]: focused,
[styles['button--loading']]: loading
}, props.className)
const interactive = !disabled && !loading
const clickHandler = (event) => {
interactive && action(event)
}
return (
<button
{...(type && { type })}
{...(!interactive && { disabled: true })}
className={className}
onClick={clickHandler}
>
{ icon && icon() }
{children}
</button>
)
}
Button.propTypes = propTypes
Button.defaultProps = defaultProps
export default Button
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment