@muvehealth/fixins
Version:
Component library for Muvehealth
187 lines (180 loc) • 4.99 kB
Flow
// @flow
import React, { PureComponent } from 'react'
import styled from 'react-emotion'
import withProps from 'recompose/withProps'
import { color, space, themeGet } from 'styled-system'
import { prop } from 'ramda'
import Box from '../Box'
import ErrorMessage from '../ErrorMessage'
import Label from '../Label'
import { DataCalendar } from '../Icons'
import { isNotEmptyOrNotNil, shouldForwardProp } from '../../utils'
import { type InputType, type MetaType } from '../../types'
const modifierStyles = (props) => {
switch (props.modifier) {
case 'pill':
return {
backgroundColor: 'rgba(255,255,255,0.4)',
borderRadius: 100,
'&:focus': {
backgroundColor: 'rgba(255,255,255,0.6)',
},
'::placeholder': {
color: themeGet('colors.white', '#FFFFFF')(props),
},
'&:focus::placeholder': {
color: themeGet('colors.white', '#4A4A4A')(props),
},
}
default:
return {
backgroundColor: themeGet('colors.inputGray', '#F0F0F0')(props),
borderRadius: props.borderRadius || 6,
position: 'relative',
'&:focus': {
backgroundColor: themeGet('colors.white', '#FFFFFF')(props),
border: `solid 1px ${themeGet('colors.lighterGray', '#E6E7E8')(props)}`,
},
'::placeholder': {
color: themeGet('colors.black', '#000000')(props),
},
'&:focus::placeholder': {
color: themeGet('colors.white', '#FFFFFF')(props),
},
'[type="date"]::-webkit-calendar-picker-indicator': {
width: 18,
height: 18,
backgroundColor: 'transparent',
backgroundImage:
`url("data:image/svg+xml;charset=utf8,${DataCalendar('%231FD4DB')}")`,
backgroundPosition: 'center',
backgroundRepeat: 'no-repeat',
color: 'transparent',
opacity: 1,
},
'[type="date"]::-webkit-clear-button': {
position: 'absolute',
left: 88,
color: 'red',
},
'[type="date"]': {
WebkitAppearance: 'unset',
},
}
}
}
const TextInput = withProps({
px: 3,
})(styled('input', { shouldForwardProp })(
{
border: 0,
outline: 'none',
'@media print': {
border: '1px solid',
},
minWidth: 48,
},
space,
color,
({ height, width, ...rest }) => ({
fontFamily: themeGet('primaryFont', 'Montserrat, -apple-system, sans-serif')(rest),
fontSize: themeGet('fontSizes[1]', '12')(rest),
height: height || 40,
width: width || '100%',
color: themeGet('colors.black', '#000000')(rest),
...modifierStyles(rest),
}),
))
type Props = {
autoComplete?: string,
hiddenError?: boolean,
id?: string,
input?: InputType,
label?: string,
labelModifier?: string,
meta?: MetaType,
modifier?: string,
noLabel?: boolean,
pattern?: string,
placeholder?: string,
readOnly?: boolean,
type?: string,
}
class Input extends PureComponent<Props> {
static defaultProps = {
autoComplete: undefined,
hiddenError: false,
id: undefined,
input: { name: undefined },
label: undefined,
labelModifier: undefined,
meta: { touched: false, error: '', warning: '' },
modifier: undefined,
noLabel: false,
pattern: undefined,
placeholder: undefined,
readOnly: false,
type: 'text',
}
render() {
const {
autoComplete,
hiddenError,
id,
input,
label,
labelModifier,
meta,
modifier,
noLabel,
pattern,
placeholder,
readOnly,
type,
...styles
} = this.props
return (
<Box {...styles} maxWidth={[336, 'none']} width="100%">
<Label
hidden={noLabel}
htmlFor={prop('name', input)}
modifier={labelModifier}
>
{noLabel === true ? placeholder : label}
</Label>
<TextInput
autoComplete={autoComplete}
id={prop('name', input)}
modifier={modifier}
name={prop('name', input)}
onBlur={prop('onBlur', input)}
onChange={prop('onChange', input)}
onFocus={prop('onFocus', input)}
pattern={pattern}
placeholder={placeholder}
readOnly={readOnly}
type={type}
value={prop('value', input)}
/>
{ prop('touched', meta) === true && isNotEmptyOrNotNil(prop('error', meta))
&& (
<ErrorMessage
isPillStyle={modifier === 'pill'}
message={prop('error', meta)}
/>
)
}
{ hiddenError === false && prop('touched', meta) === true && isNotEmptyOrNotNil(prop('warning', meta))
&& (
<ErrorMessage
isPillStyle={modifier === 'pill'}
message={prop('warning', meta)}
status="warning"
/>
)
}
</Box>
)
}
}
export default Input