Browse Source

Merge pull request #858 from mrfelton/feat/ui-form-handling

feat(ui): add Form components
renovate/lint-staged-8.x
JimmyMow 6 years ago
committed by GitHub
parent
commit
07a8b2cdf3
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 43
      app/components/UI/FormFieldMessage.js
  2. 90
      app/components/UI/Input.js
  3. 20
      app/components/UI/Label.js
  4. 57
      app/components/UI/Range.js
  5. 156
      app/components/UI/Select.js
  6. 86
      app/components/UI/TextArea.js
  7. 70
      app/components/UI/Toggle.js
  8. 14
      app/themes/dark.js
  9. 3
      package.json
  10. 140
      stories/components/form.stories.js
  11. 21
      test/unit/components/UI/Input.spec.js
  12. 21
      test/unit/components/UI/Range.spec.js
  13. 29
      test/unit/components/UI/Select.spec.js
  14. 21
      test/unit/components/UI/TextArea.spec.js
  15. 21
      test/unit/components/UI/Toggle.spec.js
  16. 51
      test/unit/components/UI/__snapshots__/Input.spec.js.snap
  17. 48
      test/unit/components/UI/__snapshots__/Range.spec.js.snap
  18. 157
      test/unit/components/UI/__snapshots__/Select.spec.js.snap
  19. 51
      test/unit/components/UI/__snapshots__/TextArea.spec.js.snap
  20. 85
      test/unit/components/UI/__snapshots__/Toggle.spec.js.snap
  21. 42
      yarn.lock

43
app/components/UI/FormFieldMessage.js

@ -0,0 +1,43 @@
import React from 'react'
import PropTypes from 'prop-types'
import { Box, Flex } from 'rebass'
import SystemSuccess from 'components/Icon/SystemSuccess'
import SystemWarning from 'components/Icon/SystemWarning'
import SystemError from 'components/Icon/SystemError'
import styled from 'styled-components'
import { variant } from 'styled-system'
const messageStyle = variant({ key: 'messages' })
const Message = styled(Flex)(messageStyle)
/**
* @render react
* @name FormFieldMessage
* @example
* <FormFieldMessage message="Error message" />
*/
class FormFieldMessage extends React.Component {
static displayName = 'FormFieldMessage'
static propTypes = {
variant: PropTypes.string,
children: PropTypes.node
}
render() {
const { children, variant } = this.props
return (
<Message {...this.props} variant={variant}>
<Box mr={1}>
{variant === 'success' && <SystemSuccess />}
{variant === 'warning' && <SystemWarning />}
{variant === 'error' && <SystemError />}
</Box>
{children}
</Message>
)
}
}
export default FormFieldMessage

90
app/components/UI/Input.js

@ -0,0 +1,90 @@
import React from 'react'
import { asField } from 'informed'
import { Input as Base } from 'styled-system-html'
import { withTheme } from 'styled-components'
import { Flex } from 'rebass'
import FormFieldMessage from 'components/UI/FormFieldMessage'
/**
* @render react
* @name Input
* @example
* <Input />
*/
class Input extends React.PureComponent {
static displayName = 'Input'
render() {
const {
onChange,
onBlur,
initialValue,
field,
forwardedRef,
theme,
fieldApi,
fieldState,
justifyContent,
...rest
} = this.props
const { setValue, setTouched } = fieldApi
const { value } = fieldState
let borderColor
if (fieldState.touched) {
if (fieldState.error) {
borderColor = theme.colors.superRed
} else if (value && !fieldState.error) {
borderColor = theme.colors.superGreen
}
}
return (
<Flex flexDirection="column" justifyContent={justifyContent}>
<Base
outline="none"
borderRadius="5px"
borderColor={borderColor || theme.colors.white}
border="1px solid white"
bg="transparent"
color="white"
p={3}
type="text"
fontSize="m"
width={1}
css={{
'&:focus': {
outline: 'none',
border: `1px solid ${borderColor || theme.colors.lightningOrange} }`
}
}}
{...rest}
value={!value && value !== 0 ? '' : value}
name={field}
ref={forwardedRef}
onChange={e => {
setValue(e.target.value)
if (onChange) {
onChange(e)
}
}}
onBlur={e => {
setTouched()
if (onBlur) {
onBlur(e)
}
}}
error={fieldState.error}
/>
{fieldState.error && (
<FormFieldMessage variant="error" justifyContent={justifyContent}>
{fieldState.error}
</FormFieldMessage>
)}
</Flex>
)
}
}
export default asField(withTheme(Input))

20
app/components/UI/Label.js

@ -0,0 +1,20 @@
import React from 'react'
import { Label as Base } from 'styled-system-html'
/**
* @render react
* @name Label
* @example
* <Label />
*/
class Label extends React.Component {
static displayName = 'Label'
render() {
return (
<Base css={{ display: 'block' }} color="white" fontWeight="bold" mb={1} {...this.props} />
)
}
}
export default Label

57
app/components/UI/Range.js

@ -0,0 +1,57 @@
import React from 'react'
import { asField } from 'informed'
import styled, { withTheme } from 'styled-components'
const Input = styled.input`
overflow: hidden;
width: 100%;
appearance: none;
outline: none;
::-webkit-slider-runnable-track {
height: 8px;
appearance: none;
background-color: ${props => props.theme.colors.gray};
margin-top: -1px;
}
::-webkit-slider-thumb {
width: 8px;
appearance: none;
height: 8px;
cursor: ew-resize;
background: ${props => props.theme.colors.white};
box-shadow: -1000px 0 0 1000px orange;
}
`
const Range = asField(({ fieldState, fieldApi, ...props }) => {
const { value } = fieldState
const { setValue, setTouched } = fieldApi
const { onChange, onBlur, initialValue, forwardedRef, ...rest } = props
return (
<Input
{...rest}
type="range"
min={0}
max={100}
step={1}
ref={forwardedRef}
value={value || initialValue || '0'}
onChange={e => {
setValue(e.target.value)
if (onChange) {
onChange(e)
}
}}
onBlur={e => {
setTouched()
if (onBlur) {
onBlur(e)
}
}}
/>
)
})
export default withTheme(Range)

156
app/components/UI/Select.js

@ -0,0 +1,156 @@
import React from 'react'
import PropTypes from 'prop-types'
import { asField } from 'informed'
import Input from 'components/UI/Input'
import styled, { withTheme } from 'styled-components'
import Downshift from 'downshift'
import { Box } from 'rebass'
import system from '@rebass/components'
const SelectOptionList = styled.ul`
padding: 0;
margin-top: 0;
position: absolute;
z-index: 2;
width: 100%;
max-height: 20rem;
overflow-y: auto;
overflow-x: hidden;
outline: 0;
transition: opacity 0.1s ease;
border: ${props => (props.isOpen ? null : 'none')};
background-color: ${props => props.theme.colors.lightestBackground};
`
const SelectOptionItem = styled(
system(
{
extend: Box,
as: 'li',
p: 3,
backgroundColor: 'lightestBackground'
},
'space',
'color'
)
)`
outline: none;
cursor: pointer;
`
const ControllerButton = styled('button')({
backgroundColor: 'transparent',
border: 'none',
position: 'absolute',
right: '5px',
top: 0,
cursor: 'pointer',
width: '47px',
display: 'flex',
flexDirection: 'column',
height: '50px',
justifyContent: 'center',
alignItems: 'center',
outline: 'none'
})
const ArrowIcon = ({ isOpen }) => (
<svg
viewBox="0 0 20 20"
preserveAspectRatio="none"
width={16}
fill="transparent"
stroke="#979797"
strokeWidth="1.1px"
transform={isOpen ? 'rotate(180)' : null}
>
<path d="M1,6 L10,15 L19,6" />
</svg>
)
ArrowIcon.propTypes = {
isOpen: PropTypes.bool
}
const itemToString = item => (item ? item.value : '')
/**
* @render react
* @name Select
*/
class Select extends React.PureComponent {
static displayName = 'Select'
static defaultProps = {
items: []
}
render() {
const { fieldApi, items, theme, ...rest } = this.props
return (
<Downshift
itemToString={itemToString}
// When an item is selected, set the item in the Informed form state.
onSelect={item => fieldApi.setValue(item.value)}
// If an invalid value has been typed into the input, set it back to the currently slected item.
onInputValueChange={(inputValue, stateAndHelpers) => {
if (inputValue && inputValue !== itemToString(stateAndHelpers.selectedItem)) {
fieldApi.setValue(itemToString(stateAndHelpers.selectedItem))
}
}}
>
{({
getInputProps,
getItemProps,
getMenuProps,
getToggleButtonProps,
isOpen,
highlightedIndex,
selectedItem,
openMenu,
closeMenu,
toggleMenu
}) => (
<div style={{ position: 'relative' }}>
<div style={{ position: 'relative' }}>
<ControllerButton {...getToggleButtonProps()}>
<ArrowIcon isOpen={isOpen} />
</ControllerButton>
<Input
placeholder="Please select"
{...rest}
{...getInputProps({
onBlur: closeMenu,
onFocus: openMenu,
onMouseDown: toggleMenu
})}
/>
</div>
<SelectOptionList {...getMenuProps()}>
{isOpen
? items.map((item, index) => (
<SelectOptionItem
key=""
{...getItemProps({
key: item.value,
index,
item
})}
style={{
backgroundColor:
highlightedIndex === index ? theme.colors.lightningOrange : null,
fontWeight: selectedItem === item ? 'bold' : 'normal'
}}
>
{item.label || item.value}
</SelectOptionItem>
))
: null}
</SelectOptionList>
</div>
)}
</Downshift>
)
}
}
export default withTheme(asField(Select))

86
app/components/UI/TextArea.js

@ -0,0 +1,86 @@
import React from 'react'
import { asField } from 'informed'
import { TextArea as Base } from 'styled-system-html'
import { withTheme } from 'styled-components'
import { Flex } from 'rebass'
import FormFieldMessage from 'components/UI/FormFieldMessage'
/**
* @render react
* @name TextArea
* @example
* <TextArea />
*/
class TextArea extends React.PureComponent {
static displayName = 'TextArea'
render() {
const {
onChange,
onBlur,
initialValue,
forwardedRef,
theme,
fieldApi,
fieldState,
justifyContent,
...rest
} = this.props
const { setValue, setTouched } = fieldApi
const { value } = fieldState
let borderColor
if (fieldState.error) {
borderColor = theme.colors.superRed
} else if (value && !fieldState.error) {
borderColor = theme.colors.superGreen
}
return (
<Flex flexDirection="column" justifyContent={justifyContent}>
<Base
outline="none"
borderRadius="5px"
borderColor={borderColor || theme.colors.white}
border="1px solid white"
bg="transparent"
color="white"
p={3}
type="text"
fontSize="m"
width={1}
rows="5"
css={{
'&:focus': {
outline: 'none',
border: `1px solid ${borderColor || theme.colors.lightningOrange} }`
}
}}
{...rest}
ref={forwardedRef}
value={!value && value !== 0 ? '' : value}
onChange={e => {
setValue(e.target.value)
if (onChange) {
onChange(e)
}
}}
onBlur={e => {
setTouched()
if (onBlur) {
onBlur(e)
}
}}
error={fieldState.error}
/>
{fieldState.error && (
<FormFieldMessage variant="error" justifyContent={justifyContent}>
{fieldState.error}
</FormFieldMessage>
)}
</Flex>
)
}
}
export default asField(withTheme(TextArea))

70
app/components/UI/Toggle.js

@ -0,0 +1,70 @@
import React from 'react'
import styled from 'styled-components'
import { Checkbox, asField } from 'informed'
const Wrapper = styled.div`
position: relative;
.switch {
position: relative;
display: inline-block;
width: 35px;
height: 22px;
}
.switch input {
opacity: 0;
width: 0;
height: 0;
}
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: ${props => props.theme.colors.gray};
transition: 0.4s;
border-radius: 34px;
}
.slider:before {
position: absolute;
content: '';
height: 20px;
width: 20px;
left: 1px;
bottom: 1px;
background-color: white;
transition: 0.4s;
border-radius: 50%;
box-shadow: 1px 1px 3px ${props => props.theme.colors.invisibleGray};
}
input:checked + .slider {
background-color: ${props => props.theme.colors.superGreen};
}
input:focus + .slider {
box-shadow: 0 0 1px #2196f3;
}
input:checked + .slider:before {
transform: translateX(13px);
}
`
const Toggle = ({ fieldState, ...props }) => (
<Wrapper>
<label // eslint-disable-line jsx-a11y/label-has-for,jsx-a11y/label-has-associated-control
className="switch"
>
<Checkbox type="checkbox" fieldState={fieldState} {...props} />
<span className="slider round" />
</label>
</Wrapper>
)
export default asField(Toggle)

14
app/themes/dark.js

@ -45,11 +45,23 @@ const cards = {
color: colors.superRed
}
}
const messages = {
success: {
color: colors.superGreen
},
warning: {
color: colors.lightningOrange
},
error: {
color: colors.superRed
}
}
export default {
name: 'dark',
...base,
colors,
buttons,
cards
cards,
messages
}

3
package.json

@ -309,12 +309,14 @@
"country-data-lookup": "^0.0.3",
"debug": "^4.1.0",
"debug-logger": "^0.4.1",
"downshift": "^3.1.0",
"electron": "^3.0.4",
"electron-is-dev": "^1.0.1",
"electron-store": "^2.0.0",
"font-awesome": "^4.7.0",
"get-port": "^4.0.0",
"history": "^4.7.2",
"informed": "^1.10.7",
"is-electron-renderer": "^2.0.1",
"javascript-state-machine": "^3.1.0",
"jstimezonedetect": "^1.0.6",
@ -340,6 +342,7 @@
"source-map-support": "^0.5.9",
"split2": "^3.0.0",
"styled-components": "^4.0.0-beta.10",
"styled-system-html": "^2.0.2",
"tildify": "^1.2.0",
"untildify": "^3.0.3",
"validator": "^10.8.0"

140
stories/components/form.stories.js

@ -0,0 +1,140 @@
import React from 'react'
import { storiesOf } from '@storybook/react'
import { action } from '@storybook/addon-actions'
import { Box } from 'rebass'
import Page from 'components/UI/Page'
import MainContent from 'components/UI/MainContent'
import Input from 'components/UI/Input'
import Label from 'components/UI/Label'
import Select from 'components/UI/Select'
import TextArea from 'components/UI/TextArea'
import Button from 'components/UI/Button'
import Toggle from 'components/UI/Toggle'
import Range from 'components/UI/Range'
import { Form } from 'informed'
const validate = value => {
return !value || value.length < 5 ? 'Field must be at least five characters' : null
}
const selectItems = [
{ label: '- Please select -', value: '' },
{ label: 'Apple', value: 'apple' },
{ value: 'pear' },
{ value: 'orange' },
{ value: 'grape' },
{ value: 'banana' }
]
storiesOf('Components.Form', module)
.add('Input', () => (
<Form>
<Input field="fieldName" id="field-name" />
</Form>
))
.add('Label', () => (
<Form>
<Label htmlFor="id">Label</Label>
</Form>
))
.add('TextArea', () => (
<Form>
<TextArea field="fieldName" placeholder="Type here" />
</Form>
))
.add('Select', () => (
<Form>
<Select field="fieldName" items={selectItems} />
</Form>
))
.add('Toggle', () => (
<Form>
<Toggle field="checkbox" />
</Form>
))
.add('Range', () => (
<Form>
<Range field="range" />
</Form>
))
.add('Example form', () => (
<Page>
<MainContent>
<Form>
{({ formState }) => (
<React.Fragment>
<Box mb={3}>
<Box>
<Label htmlFor="input1">Example Field</Label>
</Box>
<Box>
<Input
field="input1"
id="field-name"
placeholder="Type here"
validate={validate}
validateOnBlur
/>
</Box>
</Box>
<Box mb={3}>
<Box>
<Label htmlFor="textarea1">Example Textarea</Label>
</Box>
<Box>
<TextArea
field="textarea1"
placeholder="Type here"
validate={validate}
validateOnBlur
/>
</Box>
</Box>
<Box mb={3}>
<Box>
<Label htmlFor="selectfield1">Example Select</Label>
</Box>
<Box>
<Select
field="selectfield1"
items={selectItems}
onChange={action('change')}
validate={validate}
validateOnBlur
/>
</Box>
</Box>
<Box mb={3}>
<Box>
<Label htmlFor="checkbox1">Example Toggle</Label>
</Box>
<Box>
<Toggle field="checkbox1" onChange={action('change')} />
</Box>
</Box>
<Box mb={3}>
<Box>
<Label htmlFor="slider1">Example Range</Label>
</Box>
<Box>
<Range field="slider1" onChange={action('change')} />
</Box>
</Box>
<Box mb={3}>
<Button>Submit</Button>
</Box>
<Box bg="lightestBackground">
<pre>{JSON.stringify(formState, null, 2)}</pre>
</Box>
</React.Fragment>
)}
</Form>
</MainContent>
</Page>
))

21
test/unit/components/UI/Input.spec.js

@ -0,0 +1,21 @@
import React from 'react'
import { Form } from 'informed'
import Input from 'components/UI/Input'
import renderer from 'react-test-renderer'
import { dark } from 'themes'
import { ThemeProvider } from 'styled-components'
describe('component.UI.Input', () => {
it('should render correctly', () => {
const tree = renderer
.create(
<ThemeProvider theme={dark}>
<Form>
<Input field="name" theme={dark} />
</Form>
</ThemeProvider>
)
.toJSON()
expect(tree).toMatchSnapshot()
})
})

21
test/unit/components/UI/Range.spec.js

@ -0,0 +1,21 @@
import React from 'react'
import { Form } from 'informed'
import Range from 'components/UI/Range'
import renderer from 'react-test-renderer'
import { dark } from 'themes'
import { ThemeProvider } from 'styled-components'
describe('component.UI.Range', () => {
it('should render correctly', () => {
const tree = renderer
.create(
<ThemeProvider theme={dark}>
<Form>
<Range field="name" />
</Form>
</ThemeProvider>
)
.toJSON()
expect(tree).toMatchSnapshot()
})
})

29
test/unit/components/UI/Select.spec.js

@ -0,0 +1,29 @@
import React from 'react'
import { Form } from 'informed'
import Select from 'components/UI/Select'
import renderer from 'react-test-renderer'
import { dark } from 'themes'
import { ThemeProvider } from 'styled-components'
describe('component.UI.Toggle', () => {
it('should render correctly', () => {
const selectItems = [
{ label: '- Please select -', value: '' },
{ label: 'Apple', value: 'apple' },
{ value: 'pear' },
{ value: 'orange' },
{ value: 'grape' },
{ value: 'banana' }
]
const tree = renderer
.create(
<ThemeProvider theme={dark}>
<Form>
<Select field="name" items={selectItems} />
</Form>
</ThemeProvider>
)
.toJSON()
expect(tree).toMatchSnapshot()
})
})

21
test/unit/components/UI/TextArea.spec.js

@ -0,0 +1,21 @@
import React from 'react'
import { Form } from 'informed'
import Input from 'components/UI/Input'
import renderer from 'react-test-renderer'
import { dark } from 'themes'
import { ThemeProvider } from 'styled-components'
describe('component.UI.Input', () => {
it('should render correctly', () => {
const tree = renderer
.create(
<ThemeProvider theme={dark}>
<Form>
<Input field="name" />
</Form>
</ThemeProvider>
)
.toJSON()
expect(tree).toMatchSnapshot()
})
})

21
test/unit/components/UI/Toggle.spec.js

@ -0,0 +1,21 @@
import React from 'react'
import { Form } from 'informed'
import Toggle from 'components/UI/Toggle'
import renderer from 'react-test-renderer'
import { dark } from 'themes'
import { ThemeProvider } from 'styled-components'
describe('component.UI.Toggle', () => {
it('should render correctly', () => {
const tree = renderer
.create(
<ThemeProvider theme={dark}>
<Form>
<Toggle field="name" />
</Form>
</ThemeProvider>
)
.toJSON()
expect(tree).toMatchSnapshot()
})
})

51
test/unit/components/UI/__snapshots__/Input.spec.js.snap

@ -0,0 +1,51 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`component.UI.Input should render correctly 1`] = `
.c1 {
padding: 16px;
width: 100%;
font-size: 13px;
color: #ffffff;
background-color: transparent;
color: #ffffff;
background-color: transparent;
border: 1px solid white;
border: 1px solid white;
border-color: #ffffff;
border-radius: 5px;
}
.c1:focus {
outline: none;
border: 1px solid #fd9800;
}
.c0 {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column;
}
<form
onReset={[Function]}
onSubmit={[Function]}
>
<div
className="c0"
>
<input
className="c1"
name="name"
onBlur={[Function]}
onChange={[Function]}
outline="none"
type="text"
value=""
/>
</div>
</form>
`;

48
test/unit/components/UI/__snapshots__/Range.spec.js.snap

@ -0,0 +1,48 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`component.UI.Range should render correctly 1`] = `
.c0 {
overflow: hidden;
width: 100%;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
outline: none;
}
.c0::-webkit-slider-runnable-track {
height: 8px;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
background-color: #959595;
margin-top: -1px;
}
.c0::-webkit-slider-thumb {
width: 8px;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
height: 8px;
cursor: ew-resize;
background: #ffffff;
box-shadow: -1000px 0 0 1000px orange;
}
<form
onReset={[Function]}
onSubmit={[Function]}
>
<input
className="c0"
max={100}
min={0}
onBlur={[Function]}
onChange={[Function]}
step={1}
type="range"
value="0"
/>
</form>
`;

157
test/unit/components/UI/__snapshots__/Select.spec.js.snap

@ -0,0 +1,157 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`component.UI.Toggle should render correctly 1`] = `
.c2 {
padding: 16px;
width: 100%;
font-size: 13px;
color: #ffffff;
background-color: transparent;
color: #ffffff;
background-color: transparent;
border: 1px solid white;
border: 1px solid white;
border-color: #ffffff;
border-radius: 5px;
}
.c2:focus {
outline: none;
border: 1px solid #fd9800;
}
.c1 {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column;
}
.c3 {
padding: 0;
margin-top: 0;
position: absolute;
z-index: 2;
width: 100%;
max-height: 20rem;
overflow-y: auto;
overflow-x: hidden;
outline: 0;
-webkit-transition: opacity 0.1s ease;
transition: opacity 0.1s ease;
border: none;
background-color: #373947;
}
.c0 {
background-color: transparent;
border: none;
position: absolute;
right: 5px;
top: 0;
cursor: pointer;
width: 47px;
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column;
height: 50px;
-webkit-box-pack: center;
-webkit-justify-content: center;
-ms-flex-pack: center;
justify-content: center;
-webkit-align-items: center;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
outline: none;
}
<form
onReset={[Function]}
onSubmit={[Function]}
>
<div
aria-expanded={false}
aria-haspopup="listbox"
aria-labelledby="downshift-0-label"
aria-owns={null}
role="combobox"
style={
Object {
"position": "relative",
}
}
>
<div
style={
Object {
"position": "relative",
}
}
>
<button
aria-haspopup={true}
aria-label="open menu"
className="c0"
data-toggle={true}
onBlur={[Function]}
onClick={[Function]}
onKeyDown={[Function]}
onKeyUp={[Function]}
role="button"
type="button"
>
<svg
fill="transparent"
preserveAspectRatio="none"
stroke="#979797"
strokeWidth="1.1px"
transform={null}
viewBox="0 0 20 20"
width={16}
>
<path
d="M1,6 L10,15 L19,6"
/>
</svg>
</button>
<div
className="c1"
>
<input
aria-activedescendant={null}
aria-autocomplete="list"
aria-controls={null}
aria-labelledby="downshift-0-label"
autoComplete="off"
className="c2"
id="downshift-0-input"
name="name"
onBlur={[Function]}
onChange={[Function]}
onFocus={[Function]}
onKeyDown={[Function]}
onMouseDown={[Function]}
outline="none"
placeholder="Please select"
type="text"
value=""
/>
</div>
</div>
<ul
aria-labelledby="downshift-0-label"
className="c3"
id="downshift-0-menu"
role="listbox"
/>
</div>
</form>
`;

51
test/unit/components/UI/__snapshots__/TextArea.spec.js.snap

@ -0,0 +1,51 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`component.UI.Input should render correctly 1`] = `
.c1 {
padding: 16px;
width: 100%;
font-size: 13px;
color: #ffffff;
background-color: transparent;
color: #ffffff;
background-color: transparent;
border: 1px solid white;
border: 1px solid white;
border-color: #ffffff;
border-radius: 5px;
}
.c1:focus {
outline: none;
border: 1px solid #fd9800;
}
.c0 {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column;
}
<form
onReset={[Function]}
onSubmit={[Function]}
>
<div
className="c0"
>
<input
className="c1"
name="name"
onBlur={[Function]}
onChange={[Function]}
outline="none"
type="text"
value=""
/>
</div>
</form>
`;

85
test/unit/components/UI/__snapshots__/Toggle.spec.js.snap

@ -0,0 +1,85 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`component.UI.Toggle should render correctly 1`] = `
.c0 {
position: relative;
}
.c0 .switch {
position: relative;
display: inline-block;
width: 35px;
height: 22px;
}
.c0 .switch input {
opacity: 0;
width: 0;
height: 0;
}
.c0 .slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #959595;
-webkit-transition: 0.4s;
transition: 0.4s;
border-radius: 34px;
}
.c0 .slider:before {
position: absolute;
content: '';
height: 20px;
width: 20px;
left: 1px;
bottom: 1px;
background-color: white;
-webkit-transition: 0.4s;
transition: 0.4s;
border-radius: 50%;
box-shadow: 1px 1px 3px #555;
}
.c0 input:checked + .slider {
background-color: #39e673;
}
.c0 input:focus + .slider {
box-shadow: 0 0 1px #2196f3;
}
.c0 input:checked + .slider:before {
-webkit-transform: translateX(13px);
-ms-transform: translateX(13px);
transform: translateX(13px);
}
<form
onReset={[Function]}
onSubmit={[Function]}
>
<div
className="c0"
>
<label
className="switch"
>
<input
checked={false}
name="name"
onBlur={[Function]}
onChange={[Function]}
type="checkbox"
/>
<span
className="slider round"
/>
</label>
</div>
</form>
`;

42
yarn.lock

@ -5436,7 +5436,7 @@ css-selector-tokenizer@^0.7.0:
fastparse "^1.1.1"
regexpu-core "^1.0.0"
css-to-react-native@^2.2.2:
css-to-react-native@^2.0.3, css-to-react-native@^2.2.2:
version "2.2.2"
resolved "https://registry.yarnpkg.com/css-to-react-native/-/css-to-react-native-2.2.2.tgz#c077d0f7bf3e6c915a539e7325821c9dd01f9965"
integrity sha512-w99Fzop1FO8XKm0VpbQp3y5mnTnaS+rtCvS+ylSEOK76YXO5zoHQx/QMB1N54Cp+Ya9jB9922EHrh14ld4xmmw==
@ -6107,6 +6107,15 @@ dotenv@^6.0.0:
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-6.1.0.tgz#9853b6ca98292acb7dec67a95018fa40bccff42c"
integrity sha512-/veDn2ztgRlB7gKmE3i9f6CmDIyXAy6d5nBq+whO9SLX+Zs1sXEgFLPi+aSuWqUuusMfbi84fT8j34fs1HaYUw==
downshift@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/downshift/-/downshift-3.1.0.tgz#3a7b4fc26e9d563c745db3a5172437239e0bb8a8"
integrity sha512-lk6uBqobNfnumEitDp/GIAAgLK8ad2lHmieKpwZ8bvl7fDIXvJr/26P+CeI/vvQqrjo4YpBrijUNFr8Qqz1dxg==
dependencies:
"@babel/runtime" "^7.1.2"
compute-scroll-into-view "^1.0.9"
prop-types "^15.6.0"
duplexer2@~0.1.4:
version "0.1.4"
resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.1.4.tgz#8b12dab878c0d69e3e7891051662a32fc6bddcc1"
@ -8772,6 +8781,13 @@ inflight@^1.0.4, inflight@~1.0.6:
once "^1.3.0"
wrappy "1"
informed@^1.10.7:
version "1.10.7"
resolved "https://registry.yarnpkg.com/informed/-/informed-1.10.7.tgz#78774436444f21c8b1368eb746012d5f9420ee87"
integrity sha512-+5tYieUyHSPdX8RJ8Pg9gVMsBUi6GBDKDriUg31be4t332CVBZssS+pNZokwJTwkG1T7rxMYXH4o+HfHN/pqLw==
dependencies:
"@babel/runtime-corejs2" "^7.0.0-rc.1"
inherits@2, inherits@2.0.3, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.0, inherits@~2.0.1, inherits@~2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
@ -15797,6 +15813,21 @@ style-search@^0.1.0:
resolved "https://registry.yarnpkg.com/style-search/-/style-search-0.1.0.tgz#7958c793e47e32e07d2b5cafe5c0bf8e12e77902"
integrity sha1-eVjHk+R+MuB9K1yv5cC/jhLneQI=
styled-components@^3.4.5:
version "3.4.10"
resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-3.4.10.tgz#9a654c50ea2b516c36ade57ddcfa296bf85c96e1"
integrity sha512-TA8ip8LoILgmSAFd3r326pKtXytUUGu5YWuqZcOQVwVVwB6XqUMn4MHW2IuYJ/HAD81jLrdQed8YWfLSG1LX4Q==
dependencies:
buffer "^5.0.3"
css-to-react-native "^2.0.3"
fbjs "^0.8.16"
hoist-non-react-statics "^2.5.0"
prop-types "^15.5.4"
react-is "^16.3.1"
stylis "^3.5.0"
stylis-rule-sheet "^0.0.10"
supports-color "^3.2.3"
styled-components@^4.0.0-beta.10:
version "4.0.0"
resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-4.0.0.tgz#bd37d79408246302051cd63f52a3539f70aa3197"
@ -15811,6 +15842,15 @@ styled-components@^4.0.0-beta.10:
stylis "^3.5.0"
stylis-rule-sheet "^0.0.10"
styled-system-html@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/styled-system-html/-/styled-system-html-2.0.2.tgz#2a95f7720eea44b33d0e29c77289f070fe3dd318"
integrity sha512-QtqV+xc16ogG9ni+k/ZLytQ7Q5mpd+jCd1SioUUgm/6YaptSRop5+2qiKLL4acUxIV3liKuZbGyhxGsWeA0Dlg==
dependencies:
html-tags "^2.0.0"
styled-components "^3.4.5"
system-components "^3.0.0"
styled-system@^3.0.1, styled-system@^3.1.4:
version "3.1.11"
resolved "https://registry.yarnpkg.com/styled-system/-/styled-system-3.1.11.tgz#a91a38cf7a0f0e625b897a04fdd506a359a3629f"

Loading…
Cancel
Save