Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow specification of group's input props #571

Merged
merged 6 commits into from
Jul 4, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions docs.md
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,7 @@ Clicking an unselected checkbox adds its value to this array, and clicking a sel
* `input` **[Object][148]** A `redux-form` [input][149] object
* `meta` **[Object][148]** A `redux-form` [meta][150] object
* `options` **[Array][146]** An array of checkbox values (strings, numbers, or key-value pairs)
* `checkboxInputProps` **[Object][148]** An object of key-value pairs representing props to pass down to all checkbox inputs (optional, default `{}`)

### Examples

Expand All @@ -396,6 +397,32 @@ function TodoForm ({ handleSubmit, pristine, invalid, submitting }) {
export default TodoForm
```

```javascript
function TodoForm ({ handleSubmit, pristine, invalid, submitting }) {
return (
<form onSubmit={ handleSubmit }>
<Field
name="completedTodos"
component={ CheckboxGroup }
options={[
'Eat breakfast',
'Respond to emails',
'Take out the trash',
]}
checkboxInputProps={{
className: 'checkbox-input--secondary',
}}
/>
<SubmitButton {...{ pristine, invalid, submitting }}>
Submit
</SubmitButton>
</form>
)
}

export default TodoForm
```

## CloudinaryFileInput

A wrapper around a file input component (defaults to [FileInput][36]) that automatically uploads files to cloudinary via the [cloudinaryUploader][151] HOC.
Expand Down Expand Up @@ -765,6 +792,7 @@ The value of the entire `RadioGroup` component is the value of the currently sel
* `input` **[Object][148]** A `redux-form` [input][149] object
* `meta` **[Object][148]** A `redux-form` [meta][150] object
* `options` **[Array][146]** An array of radio button values (strings, numbers, booleans, or key-value pairs)
* `radioInputProps` **[Object][148]** An object of key-value pairs representing props to pass down to all radio inputs (optional, default `{}`)

### Examples

Expand All @@ -791,6 +819,32 @@ function FavoriteFoodForm ({ handleSubmit, pristine, invalid, submitting }) {
export default FavoriteFoodForm
```

```javascript
function FavoriteFoodForm ({ handleSubmit, pristine, invalid, submitting }) {
return (
<form onSubmit={ handleSubmit }>
<Field
name="favoriteFood"
component={ RadioGroup }
options={[
'Bananas',
'Pineapples',
'Potatoes',
]}
radioInputProps={{
className: 'radio-input--secondary',
}}
/>
<SubmitButton {...{ pristine, invalid, submitting }}>
Submit
</SubmitButton>
</form>
)
}

export default FavoriteFoodForm
```

## Select

A select input that can be used in a `redux-form`-controlled form.
Expand Down
3 changes: 3 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
module.exports = {
'setupFiles': [
'./test/setup.js',
],
"watchPathIgnorePatterns": [
"<rootDir>/node_modules",
]
}
37 changes: 34 additions & 3 deletions migration-guides/v7.0.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ This version contains the following breaking changes:
15. `<Modal />` no longer overwrites the default modal or overlay class
16. `<Modal />` targets #root instead of the body
17. `<DateInput />`s dependency on react-datepicker was upgraded from v1 to v4
18. `@launchpadlab/lp-hoc` was removed as a dependency
18. `<RadioGroup />` and `<CheckboxGroup />` components no longer pass className prop to inputs
19. `@launchpadlab/lp-hoc` was removed as a dependency

The required changes for each item are detailed below.

Expand Down Expand Up @@ -397,7 +398,37 @@ More details: https://github.com/Hacker0x01/react-datepicker/releases.

Of these breaking changes, the deprecation of `moment` has the highest likelihood of affecting your application. This will only impact your application if you referenced the `moment` library elsewhere in the codebase **without** installing the package directly as a dependency.

## 18. `@launchpadlab/lp-hoc` was removed as a dependency
## 18. `<RadioGroup />` and `<CheckboxGroup />` components no longer pass className prop to inputs
This change might affect the styles in your application. If you are passing in the `className` prop and your styles rely on targeting both the outer-most fieldset _and_ the inputs, you can either update your scss or you can pass in the same class name via `<type>InputProps`.

### Before
```jsx
<RadioGroup className="custom-radio-group" />
```

```scss
.custom-radio-group {
margin-bottom: 2px;
}
```
### After
```scss
.custom-radio-group {
margin-bottom: 2px;
input {
margin-bottom: 2px;
}
}
```
Or,
```jsx
<RadioGroup
className="custom-radio-group"
radioInputProps={{ className: 'custom-radio-group' }}
/>
```

## 19. `@launchpadlab/lp-hoc` was removed as a dependency
With the introduction of hooks, `lp-hoc` is no longer necessary and will soon be archived. To accommodate this, the dependency was removed from this library. This change only introduced **one** breaking change, which affected the `CloudinaryFileInput`. All other components that relied on `lp-hoc` utilities did not have any changes in interface or functionality but the utilities that these components relied on were removed as exports from this library, which projects may currently rely on.

If you're using `<CloudinaryFileInput>`, you will need to pass in an additional required prop: `apiAdapter`. This adapter needs to respond to the `post` method and return a Promise. For typical LPL projects, this will be the `api` adapter which can be imported from `services/api.js`.
Expand All @@ -408,4 +439,4 @@ If your project relies on any of the following utils imported from `@launchpad/l
- sortablePropTypes
- toggle
- togglePropTypes
- onOutsideClick
- onOutsideClick
42 changes: 38 additions & 4 deletions src/forms/inputs/checkbox-group.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React from 'react'
import PropTypes from 'prop-types'
import Checkbox from './checkbox'
import {
checkboxGroupPropTypes,
Expand Down Expand Up @@ -27,6 +28,7 @@ import { addToArray, removeFromArray, serializeOptions, compose } from '../../ut
* @param {Object} input - A `redux-form` [input](http://redux-form.com/6.5.0/docs/api/Field.md/#input-props) object
* @param {Object} meta - A `redux-form` [meta](http://redux-form.com/6.5.0/docs/api/Field.md/#meta-props) object
* @param {Array} options - An array of checkbox values (strings, numbers, or key-value pairs)
* @param {Object} [checkboxInputProps={}] - An object of key-value pairs representing props to pass down to all checkbox inputs
* @example
*
* function TodoForm ({ handleSubmit, pristine, invalid, submitting }) {
Expand All @@ -49,15 +51,44 @@ import { addToArray, removeFromArray, serializeOptions, compose } from '../../ut
* }
*
* export default TodoForm
*
* @example
* function TodoForm ({ handleSubmit, pristine, invalid, submitting }) {
* return (
* <form onSubmit={ handleSubmit }>
* <Field
* name="completedTodos"
* component={ CheckboxGroup }
* options={[
* 'Eat breakfast',
* 'Respond to emails',
* 'Take out the trash',
* ]}
* checkboxInputProps={{
* className: 'checkbox-input--secondary',
* }}
* />
* <SubmitButton {...{ pristine, invalid, submitting }}>
* Submit
* </SubmitButton>
* </form>
* )
* }
*
* export default TodoForm
*/

const propTypes = {
...checkboxGroupPropTypes,
className: PropTypes.string,
checkboxInputProps: PropTypes.object,
options: fieldOptionsType
}

const defaultProps = {
options: []
className: 'CheckboxGroup',
checkboxInputProps: {},
options: [],
}

function CheckboxGroupLegend ({ name, label }) {
Expand All @@ -72,6 +103,8 @@ function CheckboxGroup (props) {
input: { value, onChange, name },
meta, // eslint-disable-line no-unused-vars
options,
className,
checkboxInputProps,
...rest
} = omitLabelProps(props)
const optionObjects = serializeOptions(options)
Expand All @@ -85,8 +118,8 @@ function CheckboxGroup (props) {
}
return (
<LabeledField
className="CheckboxGroup"
labelComponent={ CheckboxGroupLegend }
className={className}
labelComponent={CheckboxGroupLegend}
{ ...props }
>
{
Expand All @@ -102,7 +135,8 @@ function CheckboxGroup (props) {
},
meta: {},
label: option.key,
...rest
...rest,
...checkboxInputProps,
}}
/>
)
Expand Down
43 changes: 38 additions & 5 deletions src/forms/inputs/radio-group.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react'
// import PropTypes from 'prop-types'
import PropTypes from 'prop-types'
import {
convertNameToLabel,
radioGroupPropTypes,
Expand All @@ -26,6 +26,7 @@ import { serializeOptions, filterInvalidDOMProps } from '../../utils'
* @param {Object} input - A `redux-form` [input](http://redux-form.com/6.5.0/docs/api/Field.md/#input-props) object
* @param {Object} meta - A `redux-form` [meta](http://redux-form.com/6.5.0/docs/api/Field.md/#meta-props) object
* @param {Array} options - An array of radio button values (strings, numbers, booleans, or key-value pairs)
* @param {Object} [radioInputProps={}] - An object of key-value pairs representing props to pass down to all radio inputs
* @example
*
* function FavoriteFoodForm ({ handleSubmit, pristine, invalid, submitting }) {
Expand All @@ -48,15 +49,44 @@ import { serializeOptions, filterInvalidDOMProps } from '../../utils'
* }
*
* export default FavoriteFoodForm
*
* @example
* function FavoriteFoodForm ({ handleSubmit, pristine, invalid, submitting }) {
* return (
* <form onSubmit={ handleSubmit }>
* <Field
* name="favoriteFood"
* component={ RadioGroup }
* options={[
* 'Bananas',
* 'Pineapples',
* 'Potatoes',
* ]}
* radioInputProps={{
* className: 'radio-input--secondary',
* }}
* />
* <SubmitButton {...{ pristine, invalid, submitting }}>
* Submit
* </SubmitButton>
* </form>
* )
* }
*
* export default FavoriteFoodForm
*/

const propTypes = {
...radioGroupPropTypes,
options: fieldOptionsType
className: PropTypes.string,
options: fieldOptionsType,
radioInputProps: PropTypes.object,
}

const defaultProps = {
options: []
options: [],
className: 'RadioGroup',
radioInputProps: {},
}

function RadioGroupLegend ({ label, name }) {
Expand Down Expand Up @@ -99,12 +129,14 @@ function RadioGroup (props) {
input: { value, onChange, name },
meta, // eslint-disable-line no-unused-vars
options,
className,
radioInputProps,
...rest
} = omitLabelProps(props)
const optionObjects = serializeOptions(options)
return (
<LabeledField
className="RadioGroup"
className={className}
labelComponent={ RadioGroupLegend }
{ ...props }
>
Expand All @@ -124,7 +156,8 @@ function RadioGroup (props) {
meta: {},
checked: value === option.value,
label: option.key,
...rest
...rest,
...radioInputProps,
}}
/>
)
Expand Down
16 changes: 16 additions & 0 deletions stories/forms/inputs/checkbox-group.story.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ const options = [
{ key: 'Third Option', value: '3' }
]

const SpecialLabel = ({ id, label }) => (
<span>
<label htmlFor={id}><em>{label}</em></label>
</span>
)

storiesOf('CheckboxGroup', module)
.add('with default label', () => (
<CheckboxGroup
Expand Down Expand Up @@ -64,3 +70,13 @@ storiesOf('CheckboxGroup', module)
meta={{}}
/>
))
.add('with input props specified', () => (
<CheckboxGroup
input={inputProps}
meta={{}}
options={options}
checkboxInputProps={{
labelComponent: SpecialLabel
}}
/>
))
16 changes: 16 additions & 0 deletions stories/forms/inputs/radio-group.story.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ const options = [
{ key: 'Third Option', value: '3' }
]

const SpecialLabel = ({ id, label }) => (
<span>
<label htmlFor={id}><em>{label}</em></label>
</span>
)

storiesOf('RadioGroup', module)
.add('with default label', () => (
<RadioGroup
Expand Down Expand Up @@ -79,4 +85,14 @@ storiesOf('RadioGroup', module)
meta={{}}
options={[{ key: 'Yes', value: true }, { key: 'No', value: false }]}
/>
))
.add('with input props specified', () => (
<RadioGroup
input={inputProps}
meta={{}}
options={options}
radioInputProps={{
labelComponent: SpecialLabel
}}
/>
))
Loading