Skip to content
This repository has been archived by the owner on May 7, 2021. It is now read-only.

Commit

Permalink
rebuilt the howdiditstart page using checkbox component.
Browse files Browse the repository at this point in the history
  • Loading branch information
amazingphilippe committed Feb 10, 2020
1 parent 224e8dd commit 0554387
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 170 deletions.
30 changes: 17 additions & 13 deletions f2/src/components/Field/index.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,28 @@
/** @jsx jsx */
import { jsx } from '@emotion/core'
import PropTypes from 'prop-types'
import { render } from 'react-dom'
import { FormErrorMessage, FormControl } from '@chakra-ui/core'
import { FormHelperText } from '../FormHelperText'
import { FormLabel } from '../FormLabel'
import { Field as FieldAdapter } from 'react-final-form'
import { UniqueID } from '../unique-id'

export const Field = (name, label, helperText, errorMessage, children) => {
render(
<FieldAdapter name={name}>
{props => (
<FormControl>
<FormLabel htmlFor={name}>{label}</FormLabel>
<FormHelperText>{helperText}</FormHelperText>
<FormErrorMessage>{errorMessage}</FormErrorMessage>
{children}
</FormControl>
)}
</FieldAdapter>,
export const Field = ({ name, label, helperText, errorMessage, component }) => {
return (
<UniqueID>
{id => {
return (
<FormControl aria-labelledby={id}>
<FormLabel id={id} htmlFor={name}>
{label}
</FormLabel>
<FormHelperText>{helperText}</FormHelperText>
<FormErrorMessage>{errorMessage}</FormErrorMessage>
<FieldAdapter id={name} component={component} />
</FormControl>
)
}}
</UniqueID>
)
}

Expand Down
33 changes: 24 additions & 9 deletions f2/src/components/FormArrayControl/index.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
/** @jsx jsx */
import PropTypes from 'prop-types'
import { jsx } from '@emotion/core'
import { FormErrorMessage, FormControl } from '@chakra-ui/core'
import { FormErrorMessage, FormControl, Stack } from '@chakra-ui/core'
import { useField } from 'react-final-form'
import { FormLabel } from '../FormLabel'
import { FormHelperText } from '../FormHelperText'
import { UniqueID } from '../unique-id'

export const FormArrayControl = ({
label,
Expand All @@ -18,14 +19,28 @@ export const FormArrayControl = ({
meta: { error, touched },
} = useField(name, { subscription: { touched: true, error: true } })
return (
<FormControl as="fieldset" {...rest} isInvalid={error && touched}>
<FormLabel as="legend" htmlFor={name}>
{label}
</FormLabel>
<FormHelperText>{helperText}</FormHelperText>
<FormErrorMessage>{errorMessage}</FormErrorMessage>
{children}
</FormControl>
<UniqueID>
{id => {
return (
<FormControl
as="fieldset"
aria-labelledby={id}
isInvalid={error && touched}
{...rest}
>
<FormLabel id={id} as="legend" htmlFor={name}>
{label}
</FormLabel>
<FormHelperText>{helperText}</FormHelperText>
<FormErrorMessage>{errorMessage}</FormErrorMessage>
{/** This component comes with a group attribute. We don't need to use Chakra's <CheckboxGroup> or <RadioGroup> as per the Chakra docs */}
<Stack shouldWrapChildren spacing={4}>
{children}
</Stack>
</FormControl>
)
}}
</UniqueID>
)
}

Expand Down
22 changes: 12 additions & 10 deletions f2/src/components/checkbox/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export const CheckboxAdapter = ({
value,
defaultIsChecked,
children,
...props
}) => {
const {
input: { checked, ...input },
Expand All @@ -24,19 +25,18 @@ export const CheckboxAdapter = ({
})

return (
<Checkbox input={input} isChecked={checked} isInvalid={error && touched}>
<Checkbox
input={input}
isChecked={checked}
isInvalid={error && touched}
conditionalField={props.conditionalField}
>
{children}
</Checkbox>
)
}

export const Checkbox = ({
input,
label,
isChecked,
conditionalField,
...props
}) => {
export const Checkbox = ({ input, label, isChecked, ...props }) => {
return (
<UniqueID>
{id => {
Expand Down Expand Up @@ -80,7 +80,9 @@ export const Checkbox = ({
</Text>
</Flex>

{isChecked && <ConditionalForm>{conditionalField}</ConditionalForm>}
{isChecked && (
<ConditionalForm>{props.conditionalField}</ConditionalForm>
)}
</React.Fragment>
)
}}
Expand All @@ -89,6 +91,6 @@ export const Checkbox = ({
}

Checkbox.propTypes = {
conditionalField: PropTypes.object,
conditionalField: PropTypes.any,
children: PropTypes.any,
}
192 changes: 54 additions & 138 deletions f2/src/forms/HowDidItStartForm.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,70 +2,16 @@ import React from 'react'
import PropTypes from 'prop-types'
import { useLingui } from '@lingui/react'
import { Trans } from '@lingui/macro'
import { Form, Field, useField } from 'react-final-form'
import { Form } from 'react-final-form'
import { NextAndCancelButtons } from '../components/next-and-cancel-buttons'
import { Checkbox } from '../components/checkbox'
import { Radio, RadioAdapter } from '../components/radio'
import {
FormControl,
Stack,
Box,
RadioGroup,
CheckboxGroup,
} from '@chakra-ui/core'
import { FormHelperText } from '../components/FormHelperText'
import { TextArea } from '../components/text-area'
import { CheckboxAdapter } from '../components/checkbox'
import { RadioAdapter } from '../components/radio'
import { Stack, Box, RadioGroup, CheckboxGroup } from '@chakra-ui/core'
import { useStateValue } from '../utils/state'
import { FormLabel } from '../components/FormLabel'
import { ConditionalForm } from '../components/container'
import { FormArrayControl } from '../components/FormArrayControl'
import { Field as ConditionalField } from '../components/Field'

const Control = ({ name, ...rest }) => {
const {
meta: { error, touched },
} = useField(name, { subscription: { touched: true, error: true } })
return <FormControl {...rest} isInvalid={error && touched} />
}

const CheckboxArrayControl = ({ name, value, defaultIsChecked, children }) => {
const {
input: { checked, ...input },
meta: { error, touched },
} = useField(name, {
type: 'checkbox', // important for RFF to manage the checked prop
value, // important for RFF to manage list of strings
defaultIsChecked,
})

return (
<Checkbox {...input} isChecked={checked} isInvalid={error && touched}>
{children}
</Checkbox>
)
}

const RadioButtonArrayControl = ({
name,
value,
defaultIsChecked,
children,
}) => {
const {
input: { checked, ...input },
meta: { error, touched },
} = useField(name, {
type: 'radio',
value,
defaultIsChecked,
})

return (
<Radio {...input} isChecked={checked} isInvalid={error && touched}>
{children}
</Radio>
)
}
import { Field } from '../components/Field'
import { TextArea } from '../components/text-area'
import { TextInput } from '../components/TextInput'

const validate = () => {
return {}
Expand Down Expand Up @@ -178,98 +124,68 @@ export const HowDidItStartForm = props => {
label={<Trans id="howDidTheyReachYou.question" />}
helperText={<Trans id="howDidTheyReachYou.reminder" />}
>
<CheckboxGroup spacing={4}>
{questionsList.map(question => {
return (
<Box key={question.channel}>
<CheckboxArrayControl
name="howDidTheyReachYou"
value={question.channel}
isChecked={howdiditstart.howDidTheyReachYou.includes(
question.channel,
)}
>
{i18n._(question.channel)}
<ConditionalField
{/** All questions have conditional fields. It makes sense to use the map function */}
{questionsList.map(question => {
return (
<React.Fragment key={question.channel}>
<CheckboxAdapter
name="howDidTheyReachYou"
value={question.channel}
isChecked={howdiditstart.howDidTheyReachYou.includes(
question.channel,
)}
conditionalField={
<Field
name={question.name}
label={<Trans id={question.label} />}
helperText={<Trans id={question.hint} />}
>
<TextArea
name={props.input.name}
value={props.input.value}
onChange={props.input.onChange}
/>
</ConditionalField>
</CheckboxArrayControl>
{values.howDidTheyReachYou.includes(question.channel) && (
<ConditionalForm>
<Field name={question.name}>
{props => (
<FormControl>
<FormLabel htmlFor={question.name}>
<Trans id={question.label} />
</FormLabel>
<FormHelperText>
<Trans id={question.hint} />
</FormHelperText>
<TextArea
id={question.hint}
name={props.input.name}
value={props.input.value}
onChange={props.input.onChange}
/>
</FormControl>
)}
</Field>
</ConditionalForm>
)}
</Box>
)
})}
</CheckboxGroup>
component={TextArea}
/>
}
>
{i18n._(question.channel)}
</CheckboxAdapter>
</React.Fragment>
)
})}
</FormArrayControl>

<FormArrayControl
name="whenDidItStart"
label={<Trans id="whenDidItStart.label" />}
>
<RadioGroup spacing={4}>
{whenDidItStart.map(key => {
return (
<React.Fragment key={key}>
<RadioAdapter
name="whenDidItStart"
value={key}
isChecked={timeline.whenDidItStart.includes(key)}
>
{i18n._(key)}
</RadioAdapter>
</React.Fragment>
)
})}
</RadioGroup>
{whenDidItStart.map(key => {
return (
<React.Fragment key={key}>
<RadioAdapter
name="whenDidItStart"
value={key}
isChecked={timeline.whenDidItStart.includes(key)}
>
{i18n._(key)}
</RadioAdapter>
</React.Fragment>
)
})}
</FormArrayControl>

<FormArrayControl
name="howManyTimes"
label={<Trans id="howManyTimes.label" />}
>
<RadioGroup spacing={4}>
{howManyTimes.map(key => {
return (
<Box key={key}>
<RadioAdapter
name="howManyTimes"
value={key}
isChecked={recurrenceCheck.howManyTimes.includes(key)}
>
{i18n._(key)}
</RadioAdapter>
</Box>
)
})}
</RadioGroup>
{howManyTimes.map(key => {
return (
<Box key={key}>
<RadioAdapter
name="howManyTimes"
value={key}
isChecked={recurrenceCheck.howManyTimes.includes(key)}
>
{i18n._(key)}
</RadioAdapter>
</Box>
)
})}
</FormArrayControl>
<NextAndCancelButtons
next={<Trans id="howDidItStartPage.nextPage" />}
Expand Down

0 comments on commit 0554387

Please sign in to comment.