From 8ac2a7c60f0f29edeb581c905336dc09167ca65a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Se=CC=81rgio=20Ramos?= Date: Mon, 16 Jan 2017 19:44:08 +0000 Subject: [PATCH] refactor Input and Select --- ui/src/components/form/label-row.js | 23 ++++ ui/src/components/form/label.js | 24 ++++ ui/src/components/form/msg.js | 29 +++++ ui/src/components/form/outlet.js | 67 +++++++++++ ui/src/components/form/view.js | 7 ++ ui/src/components/input/index.js | 176 ++++++++-------------------- ui/src/components/select/index.js | 158 ++++++++++--------------- ui/src/components/select/story.js | 82 ++++++++++--- 8 files changed, 328 insertions(+), 238 deletions(-) create mode 100644 ui/src/components/form/label-row.js create mode 100644 ui/src/components/form/label.js create mode 100644 ui/src/components/form/msg.js create mode 100644 ui/src/components/form/outlet.js create mode 100644 ui/src/components/form/view.js diff --git a/ui/src/components/form/label-row.js b/ui/src/components/form/label-row.js new file mode 100644 index 00000000..225e2092 --- /dev/null +++ b/ui/src/components/form/label-row.js @@ -0,0 +1,23 @@ +const Column = require('../column'); +const React = require('react'); +const Row = require('../row'); + +const LabelRow = (props) => { + const labels = React.Children.map(props.children, (children) => ( + + {children} + + )); + + return ( + + {labels} + + ); +}; + +LabelRow.propTypes = { + children: React.PropTypes.node +}; + +module.exports = LabelRow; diff --git a/ui/src/components/form/label.js b/ui/src/components/form/label.js new file mode 100644 index 00000000..ce0ead13 --- /dev/null +++ b/ui/src/components/form/label.js @@ -0,0 +1,24 @@ +const constants = require('../../shared/constants'); +const fns = require('../../shared/functions'); +const Styled = require('styled-components'); + +const { + colors +} = constants; + +const { + remcalc +} = fns; + +const { + default: styled +} = Styled; + +module.exports = styled.label` + width: 100%; + font-size: ${remcalc(16)}; + font-weight: 600; + font-style: normal; + font-stretch: normal; + color: ${colors.brandSecondaryColor}; +`; diff --git a/ui/src/components/form/msg.js b/ui/src/components/form/msg.js new file mode 100644 index 00000000..c5378b46 --- /dev/null +++ b/ui/src/components/form/msg.js @@ -0,0 +1,29 @@ +const constants = require('../../shared/constants'); +const Label = require('./label'); +const match = require('../../shared/match'); +const Styled = require('styled-components'); + +const { + breakpoints, + colors +} = constants; + +const { + default: styled +} = Styled; + +const color = match.prop({ + warning: colors.inputWarning, + error: colors.inputError, + //disabled: colors.brandInactiveColor +})('type'); + + +module.exports = styled(Label)` + color: ${color}; + + ${breakpoints.medium` + float: right; + text-align: right; + `} +`; diff --git a/ui/src/components/form/outlet.js b/ui/src/components/form/outlet.js new file mode 100644 index 00000000..53048999 --- /dev/null +++ b/ui/src/components/form/outlet.js @@ -0,0 +1,67 @@ +const constants = require('../../shared/constants'); +const fns = require('../../shared/functions'); +const Styled = require('styled-components'); + +const { + colors, + boxes +} = constants; + +const { + remcalc +} = fns; + +const { + css +} = Styled; + +const colorWithDisabled = (props) => props.disabled + ? colors.brandInactiveColor + : colors.fonts.regular; + +const colorWithDefaultValue = (props) => props.value === props.defaultValue + ? colors.brandInactiveColor + : colorWithDisabled(props); + +const color = (props) => props.defaultValue + ? colorWithDefaultValue(props) + : colorWithDisabled(props); + +const height = (props) => !props.multiple + ? remcalc(48) + : 'auto'; + +const paddingTop = (props) => props.multiple + ? remcalc(20) + : remcalc(13); + +module.exports = css` + box-sizing: border-box; + + width: 100%; + height: ${height}; + + margin-bottom: ${remcalc(8)}; + margin-top: ${remcalc(8)}; + padding: ${paddingTop} ${remcalc(18)}; + + border-radius: ${boxes.borderRadius}; + background-color: ${colors.brandPrimaryColor}; + box-shadow: ${boxes.insetShaddow}; + border: ${boxes.border.unchecked}; + + font-size: ${remcalc(16)}; + line-height: normal !important; + font-weight: normal; + font-style: normal; + font-stretch: normal; + color: ${color}; + + appearance: none; + outline: 0; + + &:focus { + border-color: ${colors.brandPrimary}; + outline: 0; + } +`; diff --git a/ui/src/components/form/view.js b/ui/src/components/form/view.js new file mode 100644 index 00000000..c95c7c88 --- /dev/null +++ b/ui/src/components/form/view.js @@ -0,0 +1,7 @@ +const Styled = require('styled-components'); + +const { + default: styled +} = Styled; + +module.exports = styled.div``; \ No newline at end of file diff --git a/ui/src/components/input/index.js b/ui/src/components/input/index.js index d9120564..de997652 100644 --- a/ui/src/components/input/index.js +++ b/ui/src/components/input/index.js @@ -1,162 +1,80 @@ -const React = require('react'); - -const composers = require('../../shared/composers'); -const constants = require('../../shared/constants'); const fns = require('../../shared/functions'); +const React = require('react'); const Styled = require('styled-components'); -const { - boxes, - colors -} = constants; +const Label = require('../form/label'); +const LabelRow = require('../form/label-row'); +const Msg = require('../form/msg'); +const Outlet = require('../form/outlet'); +const View = require('../form/view'); const { - remcalc, + rndId } = fns; const { - baseBox -} = composers; - -const { - default: styled, - css + default: styled } = Styled; -const successBakcground = css` - background-color: ${colors.brandSecondary}; - background-image: url('./input-confirm.svg'); - background-repeat: no-repeat; - background-position: 98% ${remcalc(20)}; +const StyledInput = styled.input` + ${Outlet} `; -const defaultBackground = css` - background-color: ${colors.brandSecondary}; -`; +const Input = (props) => { + const { + children, + id = rndId(), + label = '', + error = '', + warning = '' + } = props; -const Label = styled.label` - color: ${props => props.error ? colors.alert : colors.fonts.regular} -`; + const viewProps = [ + 'children', + 'style', + 'className' + ]; -const InputField = styled.input` - ${baseBox()}; + // reset props for + const newProps = Object.keys(props).reduce((sum, key) => ({ + ...sum, + [key]: viewProps.indexOf(key) < 0 ? props[key] : null + }),{}); - ${props => props.success ? successBakcground : defaultBackground } + const _label = !label.length ? null : ( + + ); - border-color: ${props => props.error ? colors.alert : 'auto'} - color: ${props => props.error ? colors.alert : colors.fonts.semibold} - display: block; - font-size: ${remcalc(16)}; - padding: ${remcalc('15 18')}; - visibility: visible; - width: 100%; + const msgType = error ? 'error' : (warning ? 'warning' : null); - &:focus { - border-color: ${boxes.border.checked}; - outline: none; - } -`; - -const Error = styled.span` - float: right; - color: ${colors.alert}; - font-size: ${remcalc(14)}; -`; - -const Input = ({ - autoComplete, - autoFocus, - children, - className, - disabled = false, - error, - form, - id, - inputMode, - label, - labelledby, - list, - name, - onChange, - pattern, - placeholder, - readOnly, - required, - selectionDirection, - spellCheck, - style, - success, - tabIndex, - type, - value -}) => { - const _label = label || children; - const _children = label && children ? children : null; - const _error = error ? ({error}) : null; + const _msg = !(error || warning) ? null : ( + + {error ? error : warning} + + ); return ( -
- - {_error} - - {_children} -
+ {_msg} + + + {children} + ); }; Input.propTypes = { - autoComplete: React.PropTypes.string, - autoFocus: React.PropTypes.bool, children: React.PropTypes.node, className: React.PropTypes.string, - disabled: React.PropTypes.bool, error: React.PropTypes.string, - form: React.PropTypes.string, id: React.PropTypes.string, - inputMode: React.PropTypes.string, label: React.PropTypes.string, - labelledby: React.PropTypes.string, - list: React.PropTypes.string, - name: React.PropTypes.string, - onChange: React.PropTypes.func, - pattern: React.PropTypes.string, - placeholder: React.PropTypes.string, - readOnly: React.PropTypes.bool, - required: React.PropTypes.bool, - selectionDirection: React.PropTypes.string, - spellCheck: React.PropTypes.bool, style: React.PropTypes.object, - success: React.PropTypes.bool, - tabIndex: React.PropTypes.string, - type: React.PropTypes.string, - value: React.PropTypes.string + warning: React.PropTypes.string }; module.exports = Input; diff --git a/ui/src/components/select/index.js b/ui/src/components/select/index.js index f9d4dde5..8168fac2 100644 --- a/ui/src/components/select/index.js +++ b/ui/src/components/select/index.js @@ -1,123 +1,91 @@ const fns = require('../../shared/functions'); -const composers = require('../../shared/composers'); const React = require('react'); const Styled = require('styled-components'); -const { - rndId, - remcalc -} = fns; +const Label = require('../form/label'); +const LabelRow = require('../form/label-row'); +const Msg = require('../form/msg'); +const Outlet = require('../form/outlet'); +const View = require('../form/view'); const { - pseudoEl -} = composers; + rndId +} = fns; const { default: styled } = Styled; -// TODO: this should be a constant -const StyledLabel = styled.div` - color: #464646; -`; - -const SelectWrapper = styled.div` - position: relative; - display: inline-block; - - &:after { - border-left: ${remcalc(5)} solid transparent; - border-right: ${remcalc(5)} solid transparent; - border-bottom: ${remcalc(5)} solid black; - - ${pseudoEl({ - top: remcalc(25), - right: remcalc(20) - })} - } -`; - +const defaultValue = rndId(); const StyledSelect = styled.select` - font-size: ${remcalc(16)}; - min-width: ${remcalc(288)}; - min-height: ${remcalc(54)}; - border-radius: ${remcalc(4)}; - padding-left: ${remcalc(20)}; - background-color: #FFFFFF; - box-shadow: inset 0 ${remcalc(3)} 0 0 rgba(0, 0, 0, 0.05); - border: solid ${remcalc(1)} #D8D8D8; - -webkit-appearance: none; - - &:before { - ${pseudoEl()} - } - - /* select[multiple] is valid CSS syntax - not added to lint library yet */ - /* stylelint-disable */ - &[multiple] { - /* stylelint-enable */ - padding-left: 0; - padding-right: 0; - - & option { - padding-left: ${remcalc(15)}; - padding-right: ${remcalc(15)}; - width: 100%; - } - } + ${Outlet} `; -const Select = ({ - autoFocus, - children, - className, - disabled, - form, - id = rndId(), - label, - multiple, - name, - required, - selected -}) => { - return ( -
- - {label} - +const Select = (props) => { + const { + children, + disabled = false, + error = '', + id = rndId(), + label = '', + multiple = false, + placeholder = '', + value = defaultValue, + warning = '' + } = props; - - - {children} - - -
+ const _label = !label.length ? null : ( + + ); + + const _placeholder = !placeholder ? null : ( + + ); + + const msgType = error ? 'error' : (warning ? 'warning' : null); + + const _msg = !(error || warning) ? null : ( + + {error ? error : warning} + + ); + + return ( + + + {_label} + {_msg} + + + {_placeholder} + {children} + + ); }; Select.propTypes = { - autoFocus: React.PropTypes.bool, children: React.PropTypes.node, - className: React.PropTypes.string, disabled: React.PropTypes.bool, - form: React.PropTypes.string, + error: React.PropTypes.string, id: React.PropTypes.string, label: React.PropTypes.string, multiple: React.PropTypes.bool, - name: React.PropTypes.string, - required: React.PropTypes.bool, - selected: React.PropTypes.bool + placeholder: React.PropTypes.string, + value: React.PropTypes.string, + warning: React.PropTypes.string }; module.exports = Select; diff --git a/ui/src/components/select/story.js b/ui/src/components/select/story.js index 871941c3..697d5833 100644 --- a/ui/src/components/select/story.js +++ b/ui/src/components/select/story.js @@ -5,22 +5,76 @@ const { } = require('@kadira/storybook'); const Select = require('./'); +const Base = require('../base'); + storiesOf('Select', module) .add('Default', () => ( - + + + + )) + .add('disabled', () => ( + + + + )) + .add('selected', () => ( + + + )) .add('multiple', () => ( - - )); \ No newline at end of file + + + + )) + .add('warning', () => ( + + + + )) + .add('error', () => ( + + + + ));