From 67fc130c0f2353a8788a96fc06ca48726efce859 Mon Sep 17 00:00:00 2001 From: Mathew Morris Date: Fri, 13 Sep 2019 12:24:51 -0500 Subject: [PATCH 01/11] Adds padding and default color --- src/Form/Input.js | 2 ++ src/Form/Input.stories.js | 25 +++++++++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/src/Form/Input.js b/src/Form/Input.js index ba3b8b8..d0e2b5b 100644 --- a/src/Form/Input.js +++ b/src/Form/Input.js @@ -12,6 +12,7 @@ const InputContainer = createComponent({ name: 'InputContainer', style: css` position: relative; + color: ${p => p.theme.colors.greyDarker}; `, }); @@ -33,6 +34,7 @@ const StyledInput = createComponent({ outline: none; width: 100%; padding: 8px; + padding-right: 24px; border-radius: ${borderRadius}px; transition: 250ms all; -webkit-appearance: none; diff --git a/src/Form/Input.stories.js b/src/Form/Input.stories.js index 9546682..b2d9202 100644 --- a/src/Form/Input.stories.js +++ b/src/Form/Input.stories.js @@ -1,4 +1,5 @@ import React from 'react'; +import { object, select } from '@storybook/addon-knobs/react'; import Formbot from './Formbot'; import Button from '../Button'; import { Input } from './Input'; @@ -73,3 +74,27 @@ export const Styles = () => ( }} /> ); + +export const Icon = () => { + const iconProps = { + color: 'greyDarker', + size: 16, + }; + + const iconOptions = { + Information: 'information-outline', + Visibility: 'eye-outline', + Alert: 'alert', + 'Area 51': 'alien', + }; + + return ( + + ); +}; From 0dc94e5839838461fa52290aa152840930393509 Mon Sep 17 00:00:00 2001 From: Mathew Morris Date: Fri, 13 Sep 2019 12:30:30 -0500 Subject: [PATCH 02/11] Form Error styled --- src/Form/FormError.js | 5 +++-- src/Form/Input.stories.js | 2 ++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Form/FormError.js b/src/Form/FormError.js index 4f07ca1..6be534a 100644 --- a/src/Form/FormError.js +++ b/src/Form/FormError.js @@ -10,9 +10,10 @@ const FormErrorContainer = createComponent({ tag: 'span', style: css` display: block; - margin: 4px 0 0 4px; + margin: 8px 0 0 1px; color: ${p => p.theme.colors.red}; - font-size: 10px; + font-size: 12px; + font-weight: 500; `, }); diff --git a/src/Form/Input.stories.js b/src/Form/Input.stories.js index b2d9202..45e4437 100644 --- a/src/Form/Input.stories.js +++ b/src/Form/Input.stories.js @@ -64,6 +64,8 @@ export const FloatingLabel = () => ; export const Disabled = () => ; +export const Error = () => ; + export const Styles = () => ( Date: Fri, 13 Sep 2019 12:32:17 -0500 Subject: [PATCH 03/11] Updates snapshots --- src/Form/__snapshots__/DateInput.spec.js.snap | 2 ++ src/Form/__snapshots__/PhoneInput.spec.js.snap | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/Form/__snapshots__/DateInput.spec.js.snap b/src/Form/__snapshots__/DateInput.spec.js.snap index 6b4354b..e3eeab8 100644 --- a/src/Form/__snapshots__/DateInput.spec.js.snap +++ b/src/Form/__snapshots__/DateInput.spec.js.snap @@ -14,6 +14,7 @@ exports[` snapshot 1`] = ` .c2 { position: relative; + color: #767980; } .c3 { @@ -23,6 +24,7 @@ exports[` snapshot 1`] = ` outline: none; width: 100%; padding: 8px; + padding-right: 24px; border-radius: 8px; -webkit-transition: 250ms all; transition: 250ms all; diff --git a/src/Form/__snapshots__/PhoneInput.spec.js.snap b/src/Form/__snapshots__/PhoneInput.spec.js.snap index d1ecaec..565e29d 100644 --- a/src/Form/__snapshots__/PhoneInput.spec.js.snap +++ b/src/Form/__snapshots__/PhoneInput.spec.js.snap @@ -14,6 +14,7 @@ exports[` snapshot 1`] = ` .c2 { position: relative; + color: #767980; } .c3 { @@ -23,6 +24,7 @@ exports[` snapshot 1`] = ` outline: none; width: 100%; padding: 8px; + padding-right: 24px; border-radius: 8px; -webkit-transition: 250ms all; transition: 250ms all; From bab822e828a541e437e562a6a7de6fff3656e308 Mon Sep 17 00:00:00 2001 From: Mathew Morris Date: Fri, 13 Sep 2019 12:53:36 -0500 Subject: [PATCH 04/11] Moves Left icon when floating input --- src/Form/Input.js | 14 +++++++++----- src/Form/Input.stories.js | 3 ++- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/Form/Input.js b/src/Form/Input.js index d0e2b5b..44336d1 100644 --- a/src/Form/Input.js +++ b/src/Form/Input.js @@ -84,18 +84,23 @@ const StyledInput = createComponent({ `}; `, }); - const StyledIcon = styled(Icon)` position: absolute; top: 50%; transform: translateY(-50%); + transition: 250ms all; `; const LeftIcon = createComponent({ name: 'InputLeftIcon', as: StyledIcon, - style: css` + style: ({ isFloating }) => css` left: 8px; + + ${isFloating && + css` + top: 65%; + `} `, }); @@ -106,7 +111,6 @@ const RightIcon = createComponent({ right: 8px; `, }); - const StyledTextArea = StyledInput.withComponent('textarea'); const AutogrowShadow = createComponent({ @@ -309,7 +313,7 @@ export class Input extends Component { const { focused, height, value } = this.state; - const isFloating = floating && value !== undefined && `${value}`.trim(); + const isFloating = floating && value !== undefined && !!`${value}`.trim(); const inputProps = { ...rest, @@ -352,7 +356,7 @@ export class Input extends Component { {floating && Label} - {leftIcon && } + {leftIcon && } {rightIcon && } diff --git a/src/Form/Input.stories.js b/src/Form/Input.stories.js index 45e4437..4cad5c2 100644 --- a/src/Form/Input.stories.js +++ b/src/Form/Input.stories.js @@ -1,5 +1,5 @@ import React from 'react'; -import { object, select } from '@storybook/addon-knobs/react'; +import { object, select, boolean } from '@storybook/addon-knobs/react'; import Formbot from './Formbot'; import Button from '../Button'; import { Input } from './Input'; @@ -96,6 +96,7 @@ export const Icon = () => { leftIconProps={object('Left Icon Props', { ...iconProps })} rightIcon={select('Right Icon', iconOptions, 'eye-outline')} rightIconProps={object('Right Icon Props', { ...iconProps })} + floating={boolean('Floating', false)} {...defaultInputProps} /> ); From a419c69bc58a52cce94daac547bb75375bfdb4c4 Mon Sep 17 00:00:00 2001 From: Mathew Morris Date: Fri, 13 Sep 2019 14:43:20 -0500 Subject: [PATCH 05/11] Puts left icon up with floating label --- src/Form/Input.js | 26 ++++++++++++++++++-------- src/Form/Label.js | 19 ++++++++++++++----- 2 files changed, 32 insertions(+), 13 deletions(-) diff --git a/src/Form/Input.js b/src/Form/Input.js index 44336d1..c0c8b9f 100644 --- a/src/Form/Input.js +++ b/src/Form/Input.js @@ -66,16 +66,17 @@ const StyledInput = createComponent({ } } + ${leftIcon && + css` + padding-left: ${(leftIconProps.size || 16) + 12}px; + `}; + ${isFloating && css` line-height: 14px; padding-top: 14px; padding-bottom: 0px; - `}; - - ${leftIcon && - css` - padding-left: ${(leftIconProps.size || 16) + 12}px; + padding-left: 8px; `}; ${rightIcon && @@ -94,12 +95,20 @@ const StyledIcon = styled(Icon)` const LeftIcon = createComponent({ name: 'InputLeftIcon', as: StyledIcon, - style: ({ isFloating }) => css` + style: ({ isFocused, isFloating, theme }) => css` left: 8px; ${isFloating && css` - top: 65%; + top: 6px; + transform: none; + font-size: 12px; + line-height: 14px; + + ${isFocused && + css` + color: ${theme.colors.primary}; + `} `} `, }); @@ -344,6 +353,7 @@ export class Input extends Component { isFloating={isFloating} isFocused={focused} isDisabled={disabled} + hasLeftIcon={!!leftIcon} error={error}> {label} @@ -356,7 +366,7 @@ export class Input extends Component { {floating && Label} - {leftIcon && } + {leftIcon && } {rightIcon && } diff --git a/src/Form/Label.js b/src/Form/Label.js index 0913ccf..92c18f8 100644 --- a/src/Form/Label.js +++ b/src/Form/Label.js @@ -4,7 +4,7 @@ import { themeGet, createComponent } from '../utils'; const Label = createComponent({ name: 'Label', tag: 'label', - style: ({ isFloatable, isFloating, isFocused, isDisabled, theme }) => css` + style: ({ hasLeftIcon, isFloatable, isFloating, isFocused, isDisabled, theme }) => css` display: block; transition: 250ms; margin: 0 0 4px 4px; @@ -13,12 +13,21 @@ const Label = createComponent({ ${isFloatable && css` position: absolute; - top: 6px; - left: 8px; - opacity: ${isFloating ? 1 : 0}; + left: ${hasLeftIcon ? 24 : 8}px; + opacity: 0; margin: 0; - font-size: 12px; + font-size: 16px; line-height: 14px; + top: 50%; + transform: translateY(-50%); + + ${isFloating && + css` + font-size: 12px; + top: 6px; + transform: none; + opacity: 1; + `} `}; ${isFocused && From 2421282a15f424a2d6307c49bd6d419c7844d74f Mon Sep 17 00:00:00 2001 From: Mathew Morris Date: Fri, 13 Sep 2019 14:46:19 -0500 Subject: [PATCH 06/11] Updates baseFontSize --- src/theme.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/theme.js b/src/theme.js index a9c5e54..7d30166 100644 --- a/src/theme.js +++ b/src/theme.js @@ -62,7 +62,7 @@ export default (overrides = {}) => { const radii = [0, 2, 4]; const typography = { - fontSize: 14, + fontSize: 16, bodyFontFamily: 'Avenir', headerFontFamily: 'Tiempos', }; From 56547f2edc8869faee8f4c9736d7c821b208d04b Mon Sep 17 00:00:00 2001 From: Mathew Morris Date: Fri, 13 Sep 2019 14:50:51 -0500 Subject: [PATCH 07/11] Updates snapshot --- src/Form/__snapshots__/DateInput.spec.js.snap | 2 +- src/Form/__snapshots__/PhoneInput.spec.js.snap | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Form/__snapshots__/DateInput.spec.js.snap b/src/Form/__snapshots__/DateInput.spec.js.snap index e3eeab8..34ed038 100644 --- a/src/Form/__snapshots__/DateInput.spec.js.snap +++ b/src/Form/__snapshots__/DateInput.spec.js.snap @@ -30,7 +30,7 @@ exports[` snapshot 1`] = ` transition: 250ms all; -webkit-appearance: none; font-family: inherit; - font-size: 14px; + font-size: 16px; color: #494D55; box-sizing: border-box; } diff --git a/src/Form/__snapshots__/PhoneInput.spec.js.snap b/src/Form/__snapshots__/PhoneInput.spec.js.snap index 565e29d..24f3672 100644 --- a/src/Form/__snapshots__/PhoneInput.spec.js.snap +++ b/src/Form/__snapshots__/PhoneInput.spec.js.snap @@ -30,7 +30,7 @@ exports[` snapshot 1`] = ` transition: 250ms all; -webkit-appearance: none; font-family: inherit; - font-size: 14px; + font-size: 16px; color: #494D55; box-sizing: border-box; } From 87f0ed605e3cd13bf0f82c931a090020dcce3faa Mon Sep 17 00:00:00 2001 From: Mathew Morris Date: Fri, 13 Sep 2019 18:10:31 -0500 Subject: [PATCH 08/11] Floating input changes --- src/Form/Input.js | 77 ++++++++++++++++++++++++++------------- src/Form/Input.stories.js | 17 ++++----- src/Form/Label.js | 11 ++++-- 3 files changed, 65 insertions(+), 40 deletions(-) diff --git a/src/Form/Input.js b/src/Form/Input.js index c0c8b9f..d4cbc70 100644 --- a/src/Form/Input.js +++ b/src/Form/Input.js @@ -20,6 +20,7 @@ const StyledInput = createComponent({ name: 'Input', tag: 'input', style: ({ + isFloatable, isFloating, theme, borderRadius = theme.radius, @@ -44,7 +45,8 @@ const StyledInput = createComponent({ box-sizing: border-box; &:hover, - &:active { + &:active, + & + label &:hover { border-color: ${theme.colors.greyDark}; } @@ -54,6 +56,7 @@ const StyledInput = createComponent({ ::placeholder { color: ${theme.colors.greyDarker}; + opacity: ${isFloatable ? 0 : 1}; } &[disabled] { @@ -67,41 +70,53 @@ const StyledInput = createComponent({ } ${leftIcon && + !isFloatable && css` padding-left: ${(leftIconProps.size || 16) + 12}px; `}; + ${rightIcon && + css` + padding-right: ${(rightIconProps.size || 16) + 32}px; + `}; + ${isFloating && css` line-height: 14px; padding-top: 14px; padding-bottom: 0px; - padding-left: 8px; - `}; - - ${rightIcon && - css` - padding-right: ${(rightIconProps.size || 16) + 32}px; `}; `, }); + const StyledIcon = styled(Icon)` - position: absolute; - top: 50%; - transform: translateY(-50%); - transition: 250ms all; + ${({ theme, isDisabled }) => css` + position: absolute; + top: 50%; + transform: translateY(-50%); + transition: 250ms all; + + ${isDisabled && + css` + color: ${theme.colors.grey}; + `} + `} `; const LeftIcon = createComponent({ name: 'InputLeftIcon', as: StyledIcon, - style: ({ isFocused, isFloating, theme }) => css` + style: ({ isFocused, isFloating, isFloatable, theme }) => css` left: 8px; + ${isFloatable && + css` + position: static; + padding-right: 4px; + `} + ${isFloating && css` - top: 6px; - transform: none; font-size: 12px; line-height: 14px; @@ -296,6 +311,12 @@ export class Input extends Component { this.ref.current.blur(); } + handleLabelClick = () => { + if (this.props.floating) { + this.focus(); + } + }; + render() { const { style, @@ -322,7 +343,7 @@ export class Input extends Component { const { focused, height, value } = this.state; - const isFloating = floating && value !== undefined && !!`${value}`.trim(); + const isFloating = (floating && value !== undefined && !!`${value}`.trim()) || (floating && focused); const inputProps = { ...rest, @@ -345,16 +366,16 @@ export class Input extends Component { disabled, }; + const statusProps = { + isFloatable: floating, + isFloating, + isFocused: focused, + isDisabled: disabled, + }; + const Label = label ? ( - + + {leftIcon && } {label} ) : null; @@ -366,9 +387,13 @@ export class Input extends Component { {floating && Label} - {leftIcon && } + {leftIcon && !floating && ( + + )} - {rightIcon && } + {rightIcon && ( + + )} {multiline ? : } diff --git a/src/Form/Input.stories.js b/src/Form/Input.stories.js index 4cad5c2..fec9b8f 100644 --- a/src/Form/Input.stories.js +++ b/src/Form/Input.stories.js @@ -54,7 +54,8 @@ export const Multiline = () => ( ); @@ -62,7 +63,7 @@ export const Autogrow = () => ; -export const Disabled = () => ; +export const Disabled = () => ; export const Error = () => ; @@ -78,11 +79,6 @@ export const Styles = () => ( ); export const Icon = () => { - const iconProps = { - color: 'greyDarker', - size: 16, - }; - const iconOptions = { Information: 'information-outline', Visibility: 'eye-outline', @@ -92,11 +88,12 @@ export const Icon = () => { return ( ); diff --git a/src/Form/Label.js b/src/Form/Label.js index 92c18f8..37d3d8f 100644 --- a/src/Form/Label.js +++ b/src/Form/Label.js @@ -4,7 +4,7 @@ import { themeGet, createComponent } from '../utils'; const Label = createComponent({ name: 'Label', tag: 'label', - style: ({ hasLeftIcon, isFloatable, isFloating, isFocused, isDisabled, theme }) => css` + style: ({ isFloatable, isFloating, isFocused, isDisabled, theme }) => css` display: block; transition: 250ms; margin: 0 0 4px 4px; @@ -13,20 +13,23 @@ const Label = createComponent({ ${isFloatable && css` position: absolute; - left: ${hasLeftIcon ? 24 : 8}px; - opacity: 0; margin: 0; font-size: 16px; line-height: 14px; + left: 8px; top: 50%; transform: translateY(-50%); + user-select: none; + + &:hover { + cursor: text; + } ${isFloating && css` font-size: 12px; top: 6px; transform: none; - opacity: 1; `} `}; From a18d8e7dedeb83f0a37baf1cf14ad72ec42b8b76 Mon Sep 17 00:00:00 2001 From: Mathew Morris Date: Mon, 16 Sep 2019 10:40:21 -0500 Subject: [PATCH 09/11] Styles textarea --- src/Form/Input.js | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/Form/Input.js b/src/Form/Input.js index d4cbc70..f7007b2 100644 --- a/src/Form/Input.js +++ b/src/Form/Input.js @@ -135,7 +135,17 @@ const RightIcon = createComponent({ right: 8px; `, }); -const StyledTextArea = StyledInput.withComponent('textarea'); + +const StyledTextArea = createComponent({ + name: 'TextArea', + as: StyledInput.withComponent('textarea'), + style: ({ isFloatable, isFloating }) => css` + ${isFloatable && isFloating && + css` + padding-top: 24px; + `} + `, +}); const AutogrowShadow = createComponent({ name: 'AutogrowShadow', From 2abfc4aa96b8a2752e6a3c811b45c2da9bebc1ae Mon Sep 17 00:00:00 2001 From: Mathew Morris Date: Mon, 16 Sep 2019 10:41:36 -0500 Subject: [PATCH 10/11] Reverts multiline input --- src/Form/Input.stories.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Form/Input.stories.js b/src/Form/Input.stories.js index fec9b8f..c5666a0 100644 --- a/src/Form/Input.stories.js +++ b/src/Form/Input.stories.js @@ -54,8 +54,7 @@ export const Multiline = () => ( ); From 50ed0e4d9cd0d6cd569f8a91126e37e71d3e2df1 Mon Sep 17 00:00:00 2001 From: Mathew Morris Date: Mon, 16 Sep 2019 10:42:55 -0500 Subject: [PATCH 11/11] Updates snapshots --- src/Form/__snapshots__/DateInput.spec.js.snap | 7 ++++++- src/Form/__snapshots__/PhoneInput.spec.js.snap | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/Form/__snapshots__/DateInput.spec.js.snap b/src/Form/__snapshots__/DateInput.spec.js.snap index 34ed038..de8ac49 100644 --- a/src/Form/__snapshots__/DateInput.spec.js.snap +++ b/src/Form/__snapshots__/DateInput.spec.js.snap @@ -36,7 +36,8 @@ exports[` snapshot 1`] = ` } .c3:hover, -.c3:active { +.c3:active, +.c3 + label .c3:hover { border-color: #A4A6AA; } @@ -46,18 +47,22 @@ exports[` snapshot 1`] = ` .c3::-webkit-input-placeholder { color: #767980; + opacity: 1; } .c3::-moz-placeholder { color: #767980; + opacity: 1; } .c3:-ms-input-placeholder { color: #767980; + opacity: 1; } .c3::placeholder { color: #767980; + opacity: 1; } .c3[disabled] { diff --git a/src/Form/__snapshots__/PhoneInput.spec.js.snap b/src/Form/__snapshots__/PhoneInput.spec.js.snap index 24f3672..512e5d9 100644 --- a/src/Form/__snapshots__/PhoneInput.spec.js.snap +++ b/src/Form/__snapshots__/PhoneInput.spec.js.snap @@ -36,7 +36,8 @@ exports[` snapshot 1`] = ` } .c3:hover, -.c3:active { +.c3:active, +.c3 + label .c3:hover { border-color: #A4A6AA; } @@ -46,18 +47,22 @@ exports[` snapshot 1`] = ` .c3::-webkit-input-placeholder { color: #767980; + opacity: 1; } .c3::-moz-placeholder { color: #767980; + opacity: 1; } .c3:-ms-input-placeholder { color: #767980; + opacity: 1; } .c3::placeholder { color: #767980; + opacity: 1; } .c3[disabled] {