Skip to content

Commit

Permalink
BREAKING CHANGE: support react-hook-form v7 breaking API changes (#9)
Browse files Browse the repository at this point in the history
* feat: upgrade dependencies by major versions

* support react-hook-form v7
* upgrade tests and storybook stories for each component
* adds StorybookComponentWrapper to easily show form state in each storybook

BREAKING CHANGE: support react-hook-form v7 breaking API changes

* ci: bump node versions for testing
  • Loading branch information
vankhoawin authored Jun 21, 2021
1 parent d266cf9 commit 2e5535c
Show file tree
Hide file tree
Showing 34 changed files with 7,498 additions and 7,339 deletions.
4 changes: 4 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,13 @@ module.exports = {
},

rules: {
'react/jsx-props-no-spreading': 0,
'react/jsx-pascal-case': 0,
'react/jsx-uses-react': 0,
'react/no-multi-comp': 0,
'react/prop-types': 'off', // Since we do not use prop-types
'react/react-in-jsx-scope': 0,
'react/require-default-props': 'off', // Since we do not use prop-types
'import/no-unused-modules': 0,
'@typescript-eslint/ban-ts-comment': 0,

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test-release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [10.x, 12.x]
node-version: [12.x, 14.x]
steps:
- name: Checkout
uses: actions/checkout@v2
Expand Down
8 changes: 7 additions & 1 deletion .storybook/main.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
module.exports = {
stories: ['../src/**/*.stories.tsx'],
addons: ['@storybook/addon-actions', '@storybook/addon-docs', '@storybook/addon-a11y'],
addons: ['@storybook/addon-essentials', '@storybook/addon-a11y'],

// https://github.com/styleguidist/react-docgen-typescript/issues/356

typescript: {
reactDocgen: 'react-docgen',
},
};
8 changes: 3 additions & 5 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
# [1.2.0](https://github.com/vnguyen94/react-hook-form-paste/compare/v1.1.0...v1.2.0) (2021-06-03)


### Features

* **radiogroup, textarea:** add controllerProps fields, add validation stories ([abd2964](https://github.com/vnguyen94/react-hook-form-paste/commit/abd29643b10cec8a6efa9f198de934525083435e))
- **radiogroup, textarea:** add controllerProps fields, add validation stories ([abd2964](https://github.com/vnguyen94/react-hook-form-paste/commit/abd29643b10cec8a6efa9f198de934525083435e))

# [1.1.0](https://github.com/vnguyen94/react-hook-form-paste/compare/v1.0.0...v1.1.0) (2021-03-22)


### Features

* **build:** trigger release ([f1f0582](https://github.com/vnguyen94/react-hook-form-paste/commit/f1f0582b92510ea6c5ac1024700e9db7892b60ce))
* **test:** trigger release ([3cf14ba](https://github.com/vnguyen94/react-hook-form-paste/commit/3cf14ba77ce87a4e1e4c75a26b7c6f7bfa89f6e3))
- **build:** trigger release ([f1f0582](https://github.com/vnguyen94/react-hook-form-paste/commit/f1f0582b92510ea6c5ac1024700e9db7892b60ce))
- **test:** trigger release ([3cf14ba](https://github.com/vnguyen94/react-hook-form-paste/commit/3cf14ba77ce87a4e1e4c75a26b7c6f7bfa89f6e3))

# 1.0.0 (2021-01-08)

Expand Down
76 changes: 31 additions & 45 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

Super-charged [Paste](https://paste.twilio.design) components using [react-hook-form](https://github.com/react-hook-form/react-hook-form) to handle form state.

This library lightly wraps Paste components with required fields `name: string` and `registerRef: React.Ref` props that connect them to a react-hook-form `useForm` hook. This will link the Paste component to the form library, allowing you to reap the benefits of typed, performant forms with minimal effort.
This library lightly wraps Paste components to seamlessly integrate with `react-hook-form`, and handle abstraction wherever needed.

## Getting started

Expand All @@ -19,74 +19,60 @@ yarn install react-hook-form-paste
## Usage

```tsx
import { Theme } from '@twilio-paste/core/theme';
import { Alert } from '@twilio-paste/core/alert';
import { Box } from '@twilio-paste/core/box';
import { Button } from '@twilio-paste/core/button';
import { Label } from '@twilio-paste/core/label';
import * as React from 'react';
import { Stack } from '@twilio-paste/core/stack';
import { useForm } from 'react-hook-form';
import { Input } from 'react-hook-form-paste';

export default {
title: 'Input',
};

interface ITestProps {
interface IFormProps {
emailAddress: string;
}

export const Basic: React.FC = () => {
const { register, handleSubmit } = useForm();
const { register, handleSubmit } = useForm<IFormProps>();

return (
<Theme.Provider theme="default">
<form
onSubmit={handleSubmit((payload) => {
window.alert(JSON.stringify(payload));
})}
>
<Label htmlFor="emailAddress">Email Address</Label>
<Input<ITestProps>
id="emailAddress"
name="emailAddress"
type="email"
placeholder="[email protected]"
registerRef={register}
/>
<form
onSubmit={handleSubmit((payload) => {
window.alert(JSON.stringify(payload));
})}
>
<Stack orientation="vertical" spacing="space80">
<Box>
<Label htmlFor="emailAddress">Email Address</Label>
<Input {...register('emailAddress')} type="email" placeholder="[email protected]" />
</Box>

<Button variant="primary" type="submit">
Submit
</Button>
</form>
</Theme.Provider>
</Stack>
</form>
);
};
```

## Differences between react-hook-form-paste and Paste

react-hook-form-paste also provides TypeScript developers the option of typing their form inputs. Passing in an interface into a form input e.g. `<Input<ITestProps>>` will constrain the `name` field to only keys of that interface.
With the advent of `react-hook-form` v7, `react-hook-form-paste` **is mostly unnecessary**; form type-safety is mostly ensured via the new `{...register('formField')}` pattern which natively work with Paste components. However, there are still some Paste components with more complex state such as `OptionGroup`. For these components, static form-typing can be enforced by passing in an interface into the generic component e.g. `<OptionGroup<IFieldProps>>`. This will constrain the `name` field to only keys of that interface.

## Core Components

| | Props |
| ------------------ | --------------------------------------------------------------------------------------------------------------------------- |
| Checkbox | { name, registerRef } & [CheckboxProps](https://paste.twilio.design/components/checkbox#checkbox-props) |
| CheckboxDisclaimer | { name, registerRef } & [CheckboxDisclaimerProps](https://paste.twilio.design/components/checkbox#checkboxdisclaimer-props) |
| CheckboxGroup | [CheckboxGroupProps](https://paste.twilio.design/components/checkbox#checkboxgroup-props) |
| Input | { name, registerRef } & [InputProps](https://paste.twilio.design/components/input#input-props) |
| Option | [OptionProps](https://paste.twilio.design/components/select#option-props) |
| OptionGroup | [OptionGroupProps](https://paste.twilio.design/components/select#optiongroup-props) |
| Radio | { name, registerRef } & [RadioProps](https://paste.twilio.design/components/radio-group#radio-props) |
| RadioGroup | { name, control } & [RadioGroupProps](https://paste.twilio.design/components/radio-group#radiogroup-props) |
| Select | { name, registerRef } & [SelectProps](https://paste.twilio.design/components/select#select-props) |
| TextArea | { name, control } & [TextAreaProps](https://paste.twilio.design/components/textarea#textarea-props) |

## Using `registerRef` over `ref`

Currently, while using TypeScript there is incompatibility with `React.forwardRef` in that it does not allow the components to be generic with a forwarded ref. Because of this, we have to pass a ref into a HoC under a different name than `ref`. This lets us pass refs and still be able to type the `name` fields.

https://github.com/typescript-cheatsheets/react/issues/106#issuecomment-483342960
https://reactjs.org/docs/refs-and-the-dom.html#exposing-dom-refs-to-parent-components
| Component | Props |
| ------------------ | ------------------------------------------------------------------------------------------------------------------ |
| Checkbox | [CheckboxProps](https://paste.twilio.design/components/checkbox#checkbox-props) |
| CheckboxDisclaimer | [CheckboxDisclaimerProps](https://paste.twilio.design/components/checkbox#checkboxdisclaimer-props) |
| CheckboxGroup | { name } & [CheckboxGroupProps](https://paste.twilio.design/components/checkbox#checkboxgroup-props) |
| Input | [InputProps](https://paste.twilio.design/components/input#input-props) |
| Option | [OptionProps](https://paste.twilio.design/components/select#option-props) |
| OptionGroup | [OptionGroupProps](https://paste.twilio.design/components/select#optiongroup-props) |
| Radio | [RadioProps](https://paste.twilio.design/components/radio-group#radio-props) |
| RadioGroup | { name, controllerProps } & [RadioGroupProps](https://paste.twilio.design/components/radio-group#radiogroup-props) |
| Select | [SelectProps](https://paste.twilio.design/components/select#select-props) |
| TextArea | { name, controllerProps } & [TextAreaProps](https://paste.twilio.design/components/textarea#textarea-props) |

## Contributing

Expand Down
1 change: 1 addition & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
module.exports = {
testEnvironment: 'jsdom',
transform: {
'.(js|jsx)': 'babel-jest',
'.(ts|tsx)': 'babel-jest',
Expand Down
83 changes: 42 additions & 41 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,64 +51,65 @@
]
},
"peerDependencies": {
"@twilio-paste/core": "^8",
"@twilio-paste/core": "^9",
"@twilio-paste/icons": "^5",
"prop-types": "^15",
"react": "^16 | ^17",
"react-dom": "^16 | ^17",
"react-hook-form": "^6",
"react-hook-form": "^7",
"react-uid": "^2"
},
"devDependencies": {
"@babel/core": "^7.13.10",
"@babel/plugin-transform-react-jsx": "^7.12.17",
"@babel/core": "^7.14.6",
"@babel/plugin-transform-react-jsx": "^7.14.5",
"@babel/polyfill": "^7.12.1",
"@babel/preset-react": "^7.12.13",
"@babel/preset-typescript": "^7.13.0",
"@babel/preset-react": "^7.14.5",
"@babel/preset-typescript": "^7.14.5",
"@semantic-release/changelog": "^5.0.1",
"@semantic-release/commit-analyzer": "^8.0.1",
"@semantic-release/git": "^9.0.0",
"@semantic-release/github": "^7.2.0",
"@semantic-release/npm": "^7.0.10",
"@semantic-release/release-notes-generator": "^9.0.2",
"@storybook/addon-a11y": "^6.1.21",
"@storybook/addon-actions": "^6.1.21",
"@storybook/addon-docs": "^6.1.21",
"@storybook/addon-storyshots": "^6.1.21",
"@storybook/addons": "^6.1.21",
"@storybook/react": "^6.1.21",
"@storybook/storybook-deployer": "^2.8.7",
"@testing-library/jest-dom": "^5.11.9",
"@testing-library/react": "^11.2.5",
"@testing-library/react-hooks": "^5.1.0",
"@testing-library/user-event": "^13.0.6",
"@twilio-paste/core": "^8.0.1",
"@semantic-release/github": "^7.2.3",
"@semantic-release/npm": "^7.1.3",
"@semantic-release/release-notes-generator": "^9.0.3",
"@storybook/addon-a11y": "^6.2.9",
"@storybook/addon-actions": "^6.2.9",
"@storybook/addon-docs": "^6.2.9",
"@storybook/addon-essentials": "^6.2.9",
"@storybook/addon-storyshots": "^6.2.9",
"@storybook/addons": "^6.2.9",
"@storybook/react": "^6.2.9",
"@storybook/storybook-deployer": "^2.8.10",
"@testing-library/jest-dom": "^5.14.1",
"@testing-library/react": "^11.2.7",
"@testing-library/react-hooks": "^7.0.0",
"@testing-library/user-event": "^13.1.9",
"@twilio-paste/core": "^9.6.1",
"@twilio-paste/icons": "^5.1.0",
"@types/react": "^17.0.3",
"@types/react-dom": "^17.0.2",
"@typescript-eslint/eslint-plugin": "^4.18.0",
"@typescript-eslint/parser": "^4.18.0",
"babel-jest": "^26.6.3",
"@types/react": "^17.0.11",
"@types/react-dom": "^17.0.7",
"@typescript-eslint/eslint-plugin": "^4.27.0",
"@typescript-eslint/parser": "^4.27.0",
"babel-jest": "^27.0.2",
"babel-loader": "^8.2.2",
"chromatic": "^5.7.0",
"commitizen": "^4.2.3",
"chromatic": "^5.9.2",
"commitizen": "^4.2.4",
"cz-conventional-changelog": "^3.3.0",
"eslint": "^7.22.0",
"eslint-config-twilio": "^1.34.2",
"eslint-config-twilio-react": "^1.34.2",
"eslint-config-twilio-ts": "^1.34.2",
"eslint-plugin-jest-dom": "^3.6.5",
"eslint-plugin-testing-library": "^3.10.2",
"husky": "^5.1.3",
"jest": "^26.6.3",
"lint-staged": "^10.5.4",
"eslint": "^7.28.0",
"eslint-config-twilio": "^1.35.1",
"eslint-config-twilio-react": "^1.35.1",
"eslint-config-twilio-ts": "^1.35.1",
"eslint-plugin-jest-dom": "^3.9.0",
"eslint-plugin-testing-library": "^4.6.0",
"husky": "^6.0.0",
"jest": "^27.0.4",
"lint-staged": "^11.0.0",
"prop-types": "15.7.2",
"react": "^17.0.1",
"react-dom": "^17.0.1",
"react-hook-form": "^6.13.1",
"react-test-renderer": "^17.0.1",
"react-hook-form": "^7.8.8",
"react-test-renderer": "^17.0.2",
"react-uid": "2.3.0",
"semantic-release": "^17.4.2",
"typescript": "4.2.3"
"semantic-release": "^17.4.4",
"typescript": "4.3.3"
}
}
Loading

0 comments on commit 2e5535c

Please sign in to comment.