@muvehealth/fixins
Version:
Component library for Muvehealth
168 lines (161 loc) • 4.77 kB
Flow
// @flow
import React, { PureComponent } from 'react'
import { prop } from 'ramda'
import Box from '../../elements/Box'
import GridBox from '../../elements/GridBox'
import ErrorMessage from '../../elements/ErrorMessage'
import Grid from '../../elements/Grid'
import Label from '../../elements/Label'
import Radio from '../../elements/Radio'
import { isNotEmptyOrNotNil, mapIndexed } from '../../utils'
import { type EventType, type InputType, type MetaType } from '../../types'
const mainGridModifierProps = (modifier, cols = '4') => {
switch (modifier) {
case 'vertical':
return {
gridGap: 2,
}
case 'leftJustifiedLabel':
return {
gridTemplateColumns: ['1fr', `repeat(${cols}, 1fr)`],
gridTemplateRows: [`repeat(${cols}, 1fr)`, '1fr'],
gridGap: 3,
alignItems: 'center',
}
default:
return {
gridTemplateColumns: ['1fr', `repeat(${cols}, 1fr)`],
gridTemplateRows: [`repeat(${cols}, 1fr)`, '1fr'],
gridGap: 3,
}
}
}
type Props = {
cols?: string,
gridStyles?: {},
input?: InputType,
label: string,
labelColor?: ?string,
labelModifier?: ?string,
labelTextStyle?: string,
meta?: MetaType,
modifier?: string,
noLabel?: boolean,
name?: string,
onBlur?: ?(EventType) => void,
onBlurDouble?: ?(string) => (EventType) => void,
onChangeDouble?: ?(string) => (EventType) => void,
onChange?: ?(EventType) => void,
readOnly?: boolean,
values: Array<{
label: string,
value: string,
id?: ?string,
}>,
}
class RadioGroup extends PureComponent<Props> {
static defaultProps = {
cols: '4',
gridStyles: undefined,
input: undefined,
labelColor: undefined,
labelModifier: undefined,
labelTextStyle: 'caps',
meta: undefined,
modifier: 'horizontal',
name: undefined,
noLabel: false,
onBlur: undefined,
onBlurDouble: undefined,
onChange: undefined,
onChangeDouble: undefined,
readOnly: false,
}
render() {
const { cols, gridStyles, input,
label, labelColor, labelModifier, labelTextStyle,
meta, modifier, name, noLabel, onBlur, onBlurDouble,
onChange, onChangeDouble, readOnly, values, ...styles } = this.props
const inputName = name != null ? name : prop('name', input)
return (
<Box {...styles}>
{ modifier !== 'leftJustifiedLabel'
&& (
<Label
color={labelColor}
fontSize={2}
hidden={noLabel}
htmlFor={inputName}
mb={4}
textStyle={labelModifier === 'decal' ? 'uppercase' : labelTextStyle}
modifier={labelModifier}
>
{label}
</Label>
)
}
<Grid
role="radiogroup"
onChange={prop('onChange', input)}
onBlur={prop('onBlur', input)}
onFocus={prop('onFocus', input)}
{...mainGridModifierProps(modifier, cols)}
// $FlowFixMe: Dont want to limit styled-system props
{...gridStyles}
>
{ modifier === 'leftJustifiedLabel'
&& (
<GridBox
gridColumnStart="1"
gridRowStart="1"
gridColumnEnd={['span 1', 'span 2']}
gridRowEnd={['span 2', 'span 1']}
>
<Label
hidden={noLabel}
htmlFor={inputName}
mb={0}
textStyle="caps"
fontSize={2}
>
{label}
</Label>
</GridBox>
)
}
{ mapIndexed(({ label: optionLabel, value: optionValue, id }, index) => (
<Radio
checked={prop('value', input) === optionValue}
id={`${inputName}-${optionLabel}`}
key={optionLabel}
label={optionLabel}
name={inputName}
onFocus={prop('onFocus', input)}
onBlur={
onBlurDouble != null && isNotEmptyOrNotNil(id)
? onBlurDouble(id) : onBlur
}
onChange={
onChangeDouble != null && isNotEmptyOrNotNil(id)
? onChangeDouble(id) : onChange
}
tabIndex={index === 0 ? '0' : '-1'}
readOnly={readOnly}
value={optionValue}
/>
), values)
}
</Grid>
{ prop('touched', meta) === true && isNotEmptyOrNotNil(prop('error', meta))
&& (
<ErrorMessage
message={prop('error', meta)}
maxWidth={116}
/>
)
}
</Box>
)
}
}
export default RadioGroup