From 037fdbaa1762955c7011f11732fac2ec9c41ea20 Mon Sep 17 00:00:00 2001 From: meriadec Date: Thu, 28 Jun 2018 16:35:09 +0200 Subject: [PATCH] Button now listen global focus state (tab key) --- src/components/base/Button/index.js | 126 ++++++++++++++++++---------- 1 file changed, 80 insertions(+), 46 deletions(-) diff --git a/src/components/base/Button/index.js b/src/components/base/Button/index.js index ed745d14..7268d316 100644 --- a/src/components/base/Button/index.js +++ b/src/components/base/Button/index.js @@ -1,11 +1,12 @@ // @flow -import React from 'react' +import React, { PureComponent } from 'react' import styled from 'styled-components' import { space, fontSize, fontWeight, color } from 'styled-system' import noop from 'lodash/noop' import { track } from 'analytics/segment' +import { isGlobalTabEnabled } from 'config/global-tab' import { darken, lighten, rgba } from 'styles/helpers' import fontFamily from 'styles/styled/fontFamily' import { focusedShadowStyle } from 'components/base/Box/Tabbable' @@ -16,21 +17,28 @@ type Style = any // FIXME const buttonStyles: { [_: string]: Style } = { default: { - default: noop, + default: p => ` + box-shadow: ${p.isFocused ? focusedShadowStyle : ''} + `, active: p => ` background: ${rgba(p.theme.colors.fog, 0.3)}; `, hover: p => ` background: ${rgba(p.theme.colors.fog, 0.2)}; `, - focus: () => ` - box-shadow: ${focusedShadowStyle}; - `, }, primary: { default: p => ` background: ${p.disabled ? `${p.theme.colors.lightFog} !important` : p.theme.colors.wallet}; color: ${p.disabled ? p.theme.colors.grey : p.theme.colors.white}; + box-shadow: ${ + p.isFocused + ? ` + 0 0 0 1px ${darken(p.theme.colors.wallet, 0.3)} inset, + 0 0 0 1px ${rgba(p.theme.colors.wallet, 0.5)}, + 0 0 0 4px ${rgba(p.theme.colors.wallet, 0.3)};` + : '' + } `, hover: p => ` background: ${lighten(p.theme.colors.wallet, 0.05)}; @@ -38,17 +46,20 @@ const buttonStyles: { [_: string]: Style } = { active: p => ` background: ${darken(p.theme.colors.wallet, 0.1)}; `, - focus: p => ` - box-shadow: - 0 0 0 1px ${darken(p.theme.colors.wallet, 0.3)} inset, - 0 0 0 1px ${rgba(p.theme.colors.wallet, 0.5)}, - 0 0 0 4px ${rgba(p.theme.colors.wallet, 0.3)}; - `, }, danger: { default: p => ` background: ${p.disabled ? `${p.theme.colors.lightFog} !important` : p.theme.colors.alertRed}; color: ${p.disabled ? p.theme.colors.grey : p.theme.colors.white}; + box-shadow: ${ + p.isFocused + ? ` + 0 0 0 1px ${darken(p.theme.colors.alertRed, 0.3)} inset, + 0 0 0 1px ${rgba(p.theme.colors.alertRed, 0.5)}, + 0 0 0 4px ${rgba(p.theme.colors.alertRed, 0.3)}; + ` + : '' + } `, hover: p => ` background: ${lighten(p.theme.colors.alertRed, 0.1)}; @@ -56,12 +67,6 @@ const buttonStyles: { [_: string]: Style } = { active: p => ` background: ${darken(p.theme.colors.alertRed, 0.1)}; `, - focus: p => ` - box-shadow: - 0 0 0 1px ${darken(p.theme.colors.alertRed, 0.3)} inset, - 0 0 0 1px ${rgba(p.theme.colors.alertRed, 0.5)}, - 0 0 0 4px ${rgba(p.theme.colors.alertRed, 0.3)}; - `, }, outline: { default: p => ` @@ -114,18 +119,22 @@ const buttonStyles: { [_: string]: Style } = { function getStyles(props, state) { let output = `` - const defaultStyle = buttonStyles.default[state] - if (defaultStyle) { - output += defaultStyle(props) || '' - } + let hasModifier = false for (const s in buttonStyles) { if (buttonStyles.hasOwnProperty(s) && props[s] === true) { const style = buttonStyles[s][state] if (style) { + hasModifier = true output += style(props) } } } + if (!hasModifier) { + const defaultStyle = buttonStyles.default[state] + if (defaultStyle) { + output += defaultStyle(props) || '' + } + } return output } @@ -176,34 +185,59 @@ type Props = { eventProperties?: Object, } -const Button = (props: Props) => { - const { disabled } = props - const { onClick, children, isLoading, event, eventProperties, ...rest } = props - const isClickDisabled = disabled || isLoading - const onClickHandler = e => { - if (onClick) { - if (event) { - track(event, eventProperties) - } - onClick(e) +class Button extends PureComponent< + Props, + { + isFocused: boolean, + }, +> { + static defaultProps = { + onClick: noop, + primary: false, + small: false, + padded: false, + danger: false, + } + + state = { + isFocused: false, + } + + handleFocus = () => { + if (isGlobalTabEnabled()) { + this.setState({ isFocused: true }) } } - return ( - - {isLoading ? : children} - - ) -} -Button.defaultProps = { - children: undefined, - disabled: undefined, - icon: undefined, - onClick: noop, - primary: false, - small: false, - padded: false, - danger: false, + handleBlur = () => { + this.setState({ isFocused: false }) + } + + render() { + const { isFocused } = this.state + const { disabled } = this.props + const { onClick, children, isLoading, event, eventProperties, ...rest } = this.props + const isClickDisabled = disabled || isLoading + const onClickHandler = e => { + if (onClick) { + if (event) { + track(event, eventProperties) + } + onClick(e) + } + } + return ( + + {isLoading ? : children} + + ) + } } export default Button