UNPKG

backpack-ui

Version:

Lonely Planet's Components

289 lines (245 loc) 5.38 kB
import React from "react"; import radium from "radium"; import assign from "object-assign"; import settings from "../../../settings.json"; import { lighten } from "../../utils/color"; import { outline } from "../../utils/mixins"; const hoverStyles = { base: { textDecoration: "none", }, blue: { backgroundColor: lighten(settings.color.blue, 7), color: settings.color.white, }, white: { backgroundColor: settings.color.white, color: lighten(settings.color.blue, 14), }, }; const styles = { base: { appearance: "none", backfaceVisibility: "hidden", border: 0, borderRadius: 0, cursor: "pointer", display: "inline-block", fontWeight: 600, lineHeight: 1, paddingLeft: `${30 / 13}em`, paddingRight: `${30 / 13}em`, textAlign: "center", textDecoration: "none", letterSpacing: "0.6px", textTransform: "uppercase", transition: `color ${settings.timing.default} ease-in-out, background-color ${settings.timing.default} ease-in-out, opacity ${settings.timing.default} ease-in-out`, verticalAlign: "middle", whiteSpace: "nowrap", ":hover": hoverStyles.base, ":active": hoverStyles.base, ":focus": assign({}, hoverStyles.base, outline()), }, color: { blue: { backgroundColor: settings.color.blue, color: settings.color.white, ":hover": hoverStyles.blue, ":focus": hoverStyles.blue, ":active": hoverStyles.blue, }, white: { backgroundColor: settings.color.white, color: settings.color.blue, ":hover": hoverStyles.white, ":focus": hoverStyles.white, ":active": hoverStyles.white, }, }, size: { tiny: { fontSize: "9px", paddingBottom: `${9 / 9}em`, paddingLeft: `${19 / 9}em`, paddingRight: `${19 / 9}em`, paddingTop: `${12 / 9}em`, }, small: { fontSize: "11px", paddingBottom: `${15 / 11}em`, paddingTop: `${18 / 11}em`, }, medium: { fontSize: "13px", paddingBottom: `${21 / 13}em`, paddingTop: `${26 / 13}em`, }, large: { fontSize: "15px", paddingBottom: `${23 / 15}em`, paddingTop: `${28 / 15}em`, }, huge: { fontSize: "17px", paddingBottom: `${25 / 17}em`, paddingTop: `${30 / 17}em`, }, }, type: { rounded: { base: { borderRadius: "100px", // a value large enough to scale paddingLeft: `${19 / 9}em`, paddingRight: `${19 / 9}em`, paddingTop: `${12 / 9}em`, }, tiny: { paddingBottom: `${9 / 9}em`, }, small: { paddingBottom: `${10 / 9}em`, }, medium: { paddingBottom: `${9 / 9}em`, }, large: { paddingBottom: `${10 / 9}em`, }, huge: { paddingBottom: `${9 / 9}em`, }, }, full: { display: "block", width: "100%", }, }, disabled: { cursor: "not-allowed", opacity: 0.5, }, }; /** * Button component * * @usage * <Button href="/foo">Bar</Button> */ function Button({ href, children, onClick, color, size, rounded, full, border, disabled, customStyles, }) { const Element = href ? "a" : "button"; const role = Element === "a" ? "button" : ""; const style = [ styles.base, color && styles.color[color], size && styles.size[size], rounded && styles.type.rounded.base, rounded && styles.type.rounded[size], full && styles.type.full, customStyles, disabled && styles.disabled, border && { boxShadow: `0 0 0 1px ${(color === "white") ? settings.color.blue : settings.color.white} inset`, }, ]; return ( <Element className="Button" style={style} href={href} onClick={onClick} role={role} disabled={disabled} > {children} </Element> ); } Button.propTypes = { /** * Pass an href prop to make the button an `a` element instead of a `button` */ href: React.PropTypes.string, /** * Content for the button */ children: React.PropTypes.node.isRequired, /** * Function to run when the button is clicked */ onClick: React.PropTypes.func, /** * Color of the button */ color: React.PropTypes.oneOf([ "blue", "white", ]), /** * Size of the button * tiny: 30 px tall * small: 44 px tall * medium: 60 px tall * large: 66 px tall * huge: 72 px tall */ size: React.PropTypes.oneOf([ "tiny", "small", "medium", "large", "huge", ]), /** * Use a rounded button */ rounded: React.PropTypes.bool, /** * Allow button to span available width */ full: React.PropTypes.bool, /** * Special styles passed in props */ customStyles: React.PropTypes.objectOf( React.PropTypes.oneOfType([ React.PropTypes.string, React.PropTypes.number, React.PropTypes.object, ]), ), /** * Use a border */ border: React.PropTypes.bool, /** * Disable button */ disabled: React.PropTypes.bool, }; Button.defaultProps = { href: "", onClick: null, color: "blue", size: "medium", rounded: false, full: false, border: false, children: "Button", disabled: false, customStyles: null, }; Button.styles = styles; export default radium(Button);