@muvehealth/fixins
Version:
Component library for Muvehealth
114 lines (102 loc) • 3.07 kB
Flow
// @flow
import React, { type Node, Fragment, PureComponent } from 'react'
import { and, any, contains, none, pluck, prop } from 'ramda'
import Box from '../../elements/Box'
import Multiselect from '../../elements/Multiselect'
import { type SelectedItemType } from '../../types'
const hasSuppValue = (suppValue, val) => any(({ label }) => contains(suppValue, label))(val)
const noSuppValue = (suppValue, val) => none(({ label }) => contains(suppValue, label))(val)
const isAddingSuppValue = (suppValue, nextValue, prevValue) => and(
hasSuppValue(suppValue, nextValue),
noSuppValue(suppValue, prevValue),
)
const isRemovingSuppValue = (suppValue, nextValue, prevValue) => and(
hasSuppValue(suppValue, prevValue),
noSuppValue(suppValue, nextValue),
)
type Props = {
change: (string | () => string,
Array<string> | string | () => Array<string> | () => string) => void,
direction?: string,
input: {
name: string,
value: Array<string>,
},
label: string,
maxWidth?: ?number,
meta: {
touched: boolean,
error: string,
dispatch: (() => void) => void,
},
options: Array<{
value: string,
label: string,
}>,
placeholder: string,
render: () => Node,
showSupplementalValue: string,
}
type State = {
showSupplemental: boolean,
}
class MultiselectWithSupplementaryField extends PureComponent<Props, State> {
static defaultProps = {
direction: 'horizontal',
maxWidth: null,
}
state = {
showSupplemental: false,
}
componentWillMount() {
const { input, showSupplementalValue } = this.props
const value = prop('value', input)
if (value && contains(showSupplementalValue, value)) {
this.setState(() => ({
showSupplemental: true,
}))
}
}
handleShowSupplemental = (
nextValue: Array<SelectedItemType>,
prevValue: SelectedItemType | Array<SelectedItemType>,
) => {
const { change, input, showSupplementalValue } = this.props
if (isAddingSuppValue(showSupplementalValue, nextValue, prevValue)) {
this.setState(() => ({
showSupplemental: true,
}))
} else if (isRemovingSuppValue(showSupplementalValue, nextValue, prevValue)) {
this.setState(() => ({
showSupplemental: false,
}))
}
if (change) {
change(prop('name', input), pluck('value', nextValue))
}
}
render() {
const { direction, input, label, maxWidth, meta,
options, placeholder, render } = this.props
const { showSupplemental } = this.state
return (
<Fragment>
<Multiselect
data-test={prop('name', input)}
handleChangeValue={this.handleShowSupplemental}
input={input}
label={label}
maxWidth={maxWidth}
meta={meta}
name={prop('name', input)}
options={options}
placeholder={placeholder}
/>
<Box mt={direction === 'vertical' ? 4 : null}>
{ showSupplemental ? render() : null }
</Box>
</Fragment>
)
}
}
export default MultiselectWithSupplementaryField