From 4e8d8c0e298f31984b0a70c387c111ce36d9a492 Mon Sep 17 00:00:00 2001 From: Jimmy Somsanith Date: Sun, 16 Jun 2019 22:47:29 +0200 Subject: [PATCH 1/6] fix: input accessibility --- src/components/Input.js | 38 +++++--- src/components/Input.stories.js | 160 +++++++++++++++++++++++++++----- 2 files changed, 163 insertions(+), 35 deletions(-) diff --git a/src/components/Input.js b/src/components/Input.js index 8aa16800..25149e4a 100644 --- a/src/components/Input.js +++ b/src/components/Input.js @@ -6,7 +6,7 @@ import { jiggle } from './shared/animation'; import { Icon } from './Icon'; // prettier-ignore -const Label = styled.span` +const Label = styled.label` font-weight: ${props => props.appearance !== 'code' && typography.weight.extrabold}; font-family: ${props => props.appearance === 'code' && typography.type.code }; font-size: ${props => props.appearance === 'code' ? typography.size.s1 : typography.size.s2 }px; @@ -39,6 +39,11 @@ const InputText = styled.input.attrs({ type: 'text' })` &:-webkit-autofill { -webkit-box-shadow: 0 0 0 3em ${color.lightest} inset; } `; +const Error = styled.div` + position: absolute; + right: 0; +`; + // prettier-ignore const InputWrapper = styled.div` display: inline-block; @@ -94,7 +99,7 @@ const InputWrapper = styled.div` `} } - &:before { + ${Error} { position: absolute; top: 50%; right: 1px; @@ -103,12 +108,10 @@ const InputWrapper = styled.div` transition: all 200ms ease-out; font-family: ${props => props.appearance === 'code' ? typography.type.code : typography.type.primary } ; font-size: ${typography.size.s1}px; - content: attr(data-error); line-height: 1em; opacity: 0; padding: .25em 1.25em .25em .5em; pointer-events: none; - z-index: 1; background: ${props => props.appearance !== 'tertiary' && @@ -159,29 +162,31 @@ const InputWrapper = styled.div` `} ${props => props.error && css` - &:before { + ${Error} { color: ${color.negative}; transform: translate3d(0%, -50%, 0); opacity: 1; } - &:hover:before { + ${InputText}:hover + ${Error}, + ${InputText}:focus + ${Error} { opacity: 0; transform: translate3d(100%, -50%, 0); } ${props.focused && css` - &:before { + ${Error} { opacity: 0; transform: translate3d(100%, -50%, 0); } `} ${props.appearance === 'code' && css` - &:before { + ${Error} { opacity: 0; } - &:hover:before { + ${InputText}:hover + ${Error}, + ${InputText}:focus + ${Error} { transform: translate3d(0%, -100%, 0); opacity: 1; } @@ -206,11 +211,11 @@ const InputContainer = styled.div` ${props => props.orientation === 'horizontal' && css` display: table-row; - ${LabelWrapper}, ${InputWrapper} { + ${Label}, ${InputWrapper} { display: table-cell; } - ${LabelWrapper} { + ${Label} { width: 1px; padding-right: 20px; vertical-align: middle; @@ -224,6 +229,7 @@ const InputContainer = styled.div` `; export function Input({ + id, value, label, orientation, @@ -245,7 +251,9 @@ export function Input({ {label && ( - + )} - - {icon && } + {icon && } + + {error} ); } Input.propTypes = { + id: PropTypes.string.isRequired, value: PropTypes.string, appearance: PropTypes.oneOf(['default', 'secondary', 'tertiary', 'pill', 'code']), label: PropTypes.string, diff --git a/src/components/Input.stories.js b/src/components/Input.stories.js index f7a71890..a8d84091 100644 --- a/src/components/Input.stories.js +++ b/src/components/Input.stories.js @@ -9,19 +9,42 @@ storiesOf('Design System|forms/Input', module) .addParameters({ component: Input }) .add('all inputs', () => (
- - + + - - - + + + ( - - - - - + + + + + ( - - - - + + + + ( - - - - + + + +
)) - .add('pill', () => ) + .add('pill', () => ( + + )) .add('code', () => (
- - + + Date: Mon, 17 Jun 2019 09:39:51 +0200 Subject: [PATCH 2/6] Fix label valign --- src/components/Input.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/Input.js b/src/components/Input.js index 25149e4a..7eb1bea1 100644 --- a/src/components/Input.js +++ b/src/components/Input.js @@ -211,11 +211,11 @@ const InputContainer = styled.div` ${props => props.orientation === 'horizontal' && css` display: table-row; - ${Label}, ${InputWrapper} { + ${LabelWrapper}, ${InputWrapper} { display: table-cell; } - ${Label} { + ${LabelWrapper} { width: 1px; padding-right: 20px; vertical-align: middle; From f969516a807c3326529d144c309b0ccb4e6e43a6 Mon Sep 17 00:00:00 2001 From: Jimmy Somsanith Date: Mon, 17 Jun 2019 10:55:58 +0200 Subject: [PATCH 3/6] Remove extra space in error div whe it is empty or hidden --- src/components/Input.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/Input.js b/src/components/Input.js index 7eb1bea1..6a54ea29 100644 --- a/src/components/Input.js +++ b/src/components/Input.js @@ -172,6 +172,7 @@ const InputWrapper = styled.div` ${InputText}:focus + ${Error} { opacity: 0; transform: translate3d(100%, -50%, 0); + padding: 0; } ${props.focused && css` From a4a1063850ea7ca16a7e458516d78e842e88bd26 Mon Sep 17 00:00:00 2001 From: Jimmy Somsanith Date: Mon, 17 Jun 2019 11:36:28 +0200 Subject: [PATCH 4/6] Remove extra padding in chromatic --- src/components/Input.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/Input.js b/src/components/Input.js index 6a54ea29..8a476dad 100644 --- a/src/components/Input.js +++ b/src/components/Input.js @@ -110,7 +110,6 @@ const InputWrapper = styled.div` font-size: ${typography.size.s1}px; line-height: 1em; opacity: 0; - padding: .25em 1.25em .25em .5em; pointer-events: none; background: ${props => @@ -166,6 +165,7 @@ const InputWrapper = styled.div` color: ${color.negative}; transform: translate3d(0%, -50%, 0); opacity: 1; + padding: .25em 1.25em .25em .5em; } ${InputText}:hover + ${Error}, @@ -190,6 +190,7 @@ const InputWrapper = styled.div` ${InputText}:focus + ${Error} { transform: translate3d(0%, -100%, 0); opacity: 1; + padding: .25em 1.25em .25em .5em; } `} From 4fc6e491c398ebe4013cd7f28acbc18d8fb32aac Mon Sep 17 00:00:00 2001 From: Jimmy Somsanith Date: Mon, 17 Jun 2019 21:46:47 +0200 Subject: [PATCH 5/6] Make label required and add a hideLabel props --- src/components/Input.js | 39 +++++++++++----- src/components/Input.stories.js | 80 +++++++++++++++++++++++---------- 2 files changed, 84 insertions(+), 35 deletions(-) diff --git a/src/components/Input.js b/src/components/Input.js index 8a476dad..e6e82c2b 100644 --- a/src/components/Input.js +++ b/src/components/Input.js @@ -15,6 +15,19 @@ const Label = styled.label` // prettier-ignore const LabelWrapper = styled.div` margin-bottom: 0.33em; + + ${props => props.hideLabel && css` + border: 0px !important; + clip: rect(0 0 0 0) !important; + -webkit-clip-path: inset(100%) !important; + clip-path: inset(100%) !important; + height: 1px !important; + overflow: hidden !important; + padding: 0px !important; + position: absolute !important; + white-space: nowrap !important; + width: 1px !important; + `} `; // prettier-ignore @@ -205,7 +218,6 @@ const InputWrapper = styled.div` animation: ${jiggle} 700ms ease-out; path { fill: ${color.negative}; } } - `} `; // prettier-ignore @@ -234,6 +246,7 @@ export function Input({ id, value, label, + hideLabel, orientation, icon, error, @@ -243,21 +256,22 @@ export function Input({ lastErrorValue, ...props }) { + const errorId = `${id}-error`; let errorMessage = error; if (lastErrorValue) { if (value !== lastErrorValue) { errorMessage = null; } } + return ( - {label && ( - - - - )} + + + + {icon && } - - {error} + + {error} ); @@ -277,7 +291,8 @@ Input.propTypes = { id: PropTypes.string.isRequired, value: PropTypes.string, appearance: PropTypes.oneOf(['default', 'secondary', 'tertiary', 'pill', 'code']), - label: PropTypes.string, + label: PropTypes.string.isRequired, + hideLabel: PropTypes.bool, orientation: PropTypes.oneOf(['vertical', 'horizontal']), icon: PropTypes.string, error: PropTypes.string, @@ -289,7 +304,7 @@ Input.propTypes = { Input.defaultProps = { value: '', appearance: 'default', - label: null, + hideLabel: false, orientation: 'vertical', icon: null, error: null, diff --git a/src/components/Input.stories.js b/src/components/Input.stories.js index a8d84091..7fd50a0d 100644 --- a/src/components/Input.stories.js +++ b/src/components/Input.stories.js @@ -9,11 +9,19 @@ storiesOf('Design System|forms/Input', module) .addParameters({ component: Input }) .add('all inputs', () => ( - + - + @@ -73,21 +84,31 @@ storiesOf('Design System|forms/Input', module) - + @@ -209,7 +242,8 @@ storiesOf('Design System|forms/Input', module) Date: Mon, 17 Jun 2019 22:23:51 +0200 Subject: [PATCH 6/6] Fix 2 stories --- src/components/Input.js | 1 + src/components/Input.stories.js | 10 ++++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/components/Input.js b/src/components/Input.js index e6e82c2b..9dc9d6a3 100644 --- a/src/components/Input.js +++ b/src/components/Input.js @@ -176,6 +176,7 @@ const InputWrapper = styled.div` ${props => props.error && css` ${Error} { color: ${color.negative}; + background: none; transform: translate3d(0%, -50%, 0); opacity: 1; padding: .25em 1.25em .25em .5em; diff --git a/src/components/Input.stories.js b/src/components/Input.stories.js index 7fd50a0d..11574e97 100644 --- a/src/components/Input.stories.js +++ b/src/components/Input.stories.js @@ -80,7 +80,13 @@ storiesOf('Design System|forms/Input', module) placeholder="Placeholder" onChange={onChange} /> - + - +