@muvehealth/fixins
Version:
Component library for Muvehealth
157 lines (149 loc) • 3.77 kB
Flow
// @flow
import React, { PureComponent } from 'react'
import styled from 'react-emotion'
import { map, prop } from 'ramda'
import { space, themeGet } from 'styled-system'
import Box from '../Box'
import ErrorMessage from '../ErrorMessage'
import Label from '../Label'
import { DataDownArrow } from '../Icons'
import { isNotEmptyOrNotNil } from '../../utils'
import { type EventType, type InputType, type MetaType } from '../../types'
type Props = {
input?: InputType,
label: string,
meta?: MetaType,
noLabel?: boolean,
onChange?: (e: EventType) => void,
options?: Array<{
label: string,
value: ?string,
}>,
placeholder?: string,
}
class Select extends PureComponent<Props> {
static defaultProps = {
placeholder: null,
options: [],
meta: { touched: false, error: '' },
noLabel: false,
onChange: null,
input: { name: null },
}
render() {
const {
input,
label,
meta,
onChange,
options,
placeholder,
noLabel,
...styles
} = this.props
return (
// $FlowFixMe: Don't want to limit styled-system props
<Box width="100%" {...styles}>
<Label
hidden={noLabel}
htmlFor={prop('name', input)}
textStyle="caps"
mb={2}
>
{label}
</Label>
<Container m={0} width="100%">
<Input
id={prop('name', input)}
name={prop('name', input)}
onBlur={prop('onBlur', input)}
onChange={onChange || prop('onChange', input)}
onFocus={prop('onFocus', input)}
px={3}
py={2}
value={prop('value', input)}
>
{ placeholder !== '__skip__'
&& (
<option value="">
{placeholder}
</option>
)
}
{
map(option => (
<option key={option.value} value={option.value}>
{option.label}
</option>
), options)
}
</Input>
</Container>
{ prop('touched', meta) === true && isNotEmptyOrNotNil(prop('error', meta))
&& (
<ErrorMessage
message={prop('error', meta)}
/>
)
}
</Box>
)
}
}
export default Select
//-----------------------------------------------
const Container = styled(Box)({
borderRadius: 6,
verticalAlign: 'middle',
position: 'relative',
height: 40,
lineHeight: '40px',
minWidth: 115,
'::after': {
backgroundImage:
`url("data:image/svg+xml;charset=utf8,${DataDownArrow('%23000000')}")`,
backgroundPosition: 'center',
backgroundRepeat: 'no-repeat',
transition: '.25s all ease',
content: '""',
position: 'absolute',
top: 0,
right: 16,
bottom: 0,
pointerEvents: 'none',
width: 14,
},
'@media print': {
border: '1px solid',
'::after': {
top: 1,
},
},
})
const Input = styled('select')(
{
cursor: 'pointer',
width: '100%',
height: '100%',
border: 'none',
fontSize: 14,
WebkitAppearance: 'none',
'fieldset[disabled] &': {
cursor: 'default',
},
},
props => ({
backgroundColor: themeGet('colors.inputGray', '#F0F0F0')(props),
color: themeGet('colors.black', '#000000')(props),
fontSize: themeGet('fontSizes[1]', '12')(props),
'&:focus': {
outline: 0,
backgroundColor: themeGet('colors.white', '#FFFFFF')(props),
border: `solid 1px ${themeGet('colors.lighterGray', '#E6E7E8')(props)}`,
},
'::placeholder': {
fontFamily: themeGet('primaryFont', 'Montserrat, -apple-system, sans-serif')(props),
},
}),
space,
)