@availity/mui-controlled-form 2.2.7 → 2.2.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/README.md +1 -1
- package/introduction.mdx +1 -1
- package/package.json +3 -3
- package/src/lib/RHF.stories.tsx +185 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver).
|
|
4
4
|
|
|
5
|
+
## [2.2.8](https://github.com/Availity/element/compare/@availity/mui-controlled-form@2.2.7...@availity/mui-controlled-form@2.2.8) (2026-04-17)
|
|
6
|
+
|
|
7
|
+
### Dependency Updates
|
|
8
|
+
|
|
9
|
+
* `mui-datepicker` updated to version `2.2.7`
|
|
10
|
+
* `theme-provider` updated to version `2.2.7`
|
|
5
11
|
## [2.2.7](https://github.com/Availity/element/compare/@availity/mui-controlled-form@2.2.6...@availity/mui-controlled-form@2.2.7) (2026-03-16)
|
|
6
12
|
|
|
7
13
|
### Dependency Updates
|
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
This package extends the Element's Form components with [react-hook-form](https://react-hook-form.com/). The goal of this package is to decrease the amount of setup involved with building a form using Element components and react-hook-form. If you would like to use another form library, the raw Element form components are also available.
|
|
12
12
|
|
|
13
|
-
Live demo and documentation in our [Storybook](https://availity.github.io/element/?path=/docs/form-components-controlled-form-
|
|
13
|
+
Live demo and documentation in our [Storybook](https://availity.github.io/element/?path=/docs/form-components-controlled-form-readme--docs)
|
|
14
14
|
|
|
15
15
|
Availity standards for design and usage can be found in the [Availity Design Guide](https://design.availity.com/2e36e50c7)
|
|
16
16
|
|
package/introduction.mdx
CHANGED
|
@@ -2,7 +2,7 @@ import { Markdown, Meta } from '@storybook/addon-docs/blocks';
|
|
|
2
2
|
import ReadMe from './README.md?raw';
|
|
3
3
|
import CHANGELOG from './CHANGELOG.md?raw';
|
|
4
4
|
|
|
5
|
-
<Meta title="Form Components/Controlled Form/
|
|
5
|
+
<Meta title="Form Components/Controlled Form/README" />
|
|
6
6
|
|
|
7
7
|
<Markdown>{ReadMe}</Markdown>
|
|
8
8
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@availity/mui-controlled-form",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.8",
|
|
4
4
|
"description": "Availity MUI/react-hook-form controlled form components - part of the @availity/element design system",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react",
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"availity",
|
|
9
9
|
"mui"
|
|
10
10
|
],
|
|
11
|
-
"homepage": "https://availity.github.io/element/?path=/docs/components-controlled-form-
|
|
11
|
+
"homepage": "https://availity.github.io/element/?path=/docs/components-controlled-form-readme--docs",
|
|
12
12
|
"bugs": {
|
|
13
13
|
"url": "https://github.com/Availity/element/issues"
|
|
14
14
|
},
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"dependencies": {
|
|
43
43
|
"@availity/mui-autocomplete": "^2.2.6",
|
|
44
44
|
"@availity/mui-checkbox": "^2.0.2",
|
|
45
|
-
"@availity/mui-datepicker": "^2.0
|
|
45
|
+
"@availity/mui-datepicker": "^2.1.0",
|
|
46
46
|
"@availity/mui-form-utils": "^2.0.5",
|
|
47
47
|
"@availity/mui-textfield": "^2.0.5",
|
|
48
48
|
"react-hook-form": "^7.55.0"
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
|
+
import dayjs from 'dayjs';
|
|
3
|
+
import * as yup from 'yup';
|
|
4
|
+
import { yupResolver } from '@hookform/resolvers/yup';
|
|
5
|
+
import { Button, LoadingButton } from '@availity/mui-button';
|
|
6
|
+
import { FormControl, FormControlLabel, FormLabel, Radio, RequiredKey } from '@availity/mui-form-utils';
|
|
7
|
+
import { ControlledAutocomplete, ControlledDatepicker, ControlledRadioGroup, ControlledSelect, ControlledTextField, FormProvider, SubmitHandler, useForm } from '..';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* All of our controlled form components have `react-hook-form` controllers baked in.
|
|
11
|
+
* For a simpler experience, `@availity/element` exports the necessary `react-hook-form` hooks.
|
|
12
|
+
*
|
|
13
|
+
* - [`FormProvider` component](https://react-hook-form.com/docs/formprovider) - host context object and allow consuming component to subscribe to context and use useForm props and methods.
|
|
14
|
+
* - [`useForm` hook](https://react-hook-form.com/docs/useform) - primary hook that drives `react-hook-form`.
|
|
15
|
+
* - [`useFormContext` hook](https://react-hook-form.com/docs/useformcontext) - allows you to access the form context. Intended to be used in deeply nested structures, where it would become inconvenient to pass the context as a prop.
|
|
16
|
+
* - `SubmitHandler` type
|
|
17
|
+
* - `UseFormProps` type
|
|
18
|
+
* - `UseFormReturn` type
|
|
19
|
+
*
|
|
20
|
+
* For complex forms, you may need to get additional resources directly from `react-hook-form`, i.e. `useWatch`, `useFieldArray`.
|
|
21
|
+
*
|
|
22
|
+
* [Schema-based validation resolvers](https://react-hook-form.com/get-started#SchemaValidation) are available from `@hookform/resolvers`. We've included an example using `yup` but more are supported.
|
|
23
|
+
*
|
|
24
|
+
* For more information, hooks, or components see the [react-hook-form documentation](https://react-hook-form.com/)
|
|
25
|
+
*/
|
|
26
|
+
const meta: Meta = {
|
|
27
|
+
title: 'Form Components/Controlled Form',
|
|
28
|
+
tags: ['autodocs'],
|
|
29
|
+
parameters: { docs: {
|
|
30
|
+
// description: { component: `${FormMigration}`},
|
|
31
|
+
source: { state: true }
|
|
32
|
+
}}
|
|
33
|
+
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export default meta;
|
|
37
|
+
|
|
38
|
+
const dropdownOptions = ['Bulbasaur', 'Squirtle', 'Charmander'];
|
|
39
|
+
|
|
40
|
+
/** Form with controlled form components, `yup`, and `@hookform/resolvers/yup` */
|
|
41
|
+
export const _YupValidation: StoryObj = {
|
|
42
|
+
render: () => {
|
|
43
|
+
const schema = yup.object({
|
|
44
|
+
textField: yup
|
|
45
|
+
.string()
|
|
46
|
+
.max(200, 'Text Field cannot exceed 200 characters.')
|
|
47
|
+
.required('This field is required.'),
|
|
48
|
+
selectField: yup
|
|
49
|
+
.string()
|
|
50
|
+
.required('This Field is required.')
|
|
51
|
+
.nullable(),
|
|
52
|
+
datePicker: yup
|
|
53
|
+
.mixed<dayjs.Dayjs>()
|
|
54
|
+
.required('This Field is required.')
|
|
55
|
+
.nullable(),
|
|
56
|
+
radio: yup
|
|
57
|
+
.string()
|
|
58
|
+
.required('A selection is required'),
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
const isRequired = (name: string) => {
|
|
62
|
+
return(!(schema.describe().fields[name] as yup.SchemaDescription)?.optional || undefined)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
type FormInputsType = yup.InferType<typeof schema>;
|
|
66
|
+
|
|
67
|
+
const onSubmit: SubmitHandler<FormInputsType> = (data) => console.log(data)
|
|
68
|
+
|
|
69
|
+
const methods = useForm({
|
|
70
|
+
defaultValues: {
|
|
71
|
+
textField: "",
|
|
72
|
+
selectField: undefined,
|
|
73
|
+
datePicker: undefined,
|
|
74
|
+
radio: "",
|
|
75
|
+
},
|
|
76
|
+
mode: 'onBlur',
|
|
77
|
+
resolver: yupResolver(schema)
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
return (
|
|
81
|
+
<FormProvider {...methods}>
|
|
82
|
+
<form onSubmit={methods.handleSubmit(onSubmit)}>
|
|
83
|
+
<RequiredKey />
|
|
84
|
+
<ControlledTextField
|
|
85
|
+
name="textField"
|
|
86
|
+
label="Textfield"
|
|
87
|
+
margin="normal"
|
|
88
|
+
fullWidth
|
|
89
|
+
helperText='Max 200 characters'
|
|
90
|
+
required={isRequired('textField')}
|
|
91
|
+
/>
|
|
92
|
+
<ControlledAutocomplete
|
|
93
|
+
name="selectField"
|
|
94
|
+
FieldProps={{
|
|
95
|
+
margin:"normal",
|
|
96
|
+
label: 'Select Field',
|
|
97
|
+
placeholder: 'Value',
|
|
98
|
+
required: isRequired('selectField'),
|
|
99
|
+
}}
|
|
100
|
+
options={dropdownOptions}
|
|
101
|
+
/>
|
|
102
|
+
<ControlledDatepicker
|
|
103
|
+
name="datePicker"
|
|
104
|
+
FieldProps={{
|
|
105
|
+
label: "Date",
|
|
106
|
+
margin: "normal",
|
|
107
|
+
required: isRequired('datePicker')
|
|
108
|
+
}}
|
|
109
|
+
/>
|
|
110
|
+
<ControlledRadioGroup name="radio" label="Radio Group" row aria-required required={isRequired('radio')}>
|
|
111
|
+
<FormControlLabel control={<Radio />} value="1" label="Option 1" />
|
|
112
|
+
<FormControlLabel control={<Radio />} value="2" label="Option 2" />
|
|
113
|
+
</ControlledRadioGroup>
|
|
114
|
+
<LoadingButton loading={methods?.formState?.isSubmitting} type="submit" sx={{mt: 2}}>
|
|
115
|
+
Submit
|
|
116
|
+
</LoadingButton>
|
|
117
|
+
</form>
|
|
118
|
+
</FormProvider>
|
|
119
|
+
)
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/** Form with controlled form components using internal rules for validation.
|
|
124
|
+
*
|
|
125
|
+
* Useful for smaller forms where writing a full schema could be cumbersome.
|
|
126
|
+
*/
|
|
127
|
+
export const _RHFRules: StoryObj = {
|
|
128
|
+
render: () => {
|
|
129
|
+
const methods = useForm({defaultValues: {textField: '', selectField: null, datePicker: null, radio: ''}});
|
|
130
|
+
const onSubmit = (data: any) => console.log(data)
|
|
131
|
+
return (
|
|
132
|
+
<FormProvider {...methods}>
|
|
133
|
+
<form onSubmit={methods.handleSubmit(onSubmit)}>
|
|
134
|
+
<RequiredKey />
|
|
135
|
+
<ControlledTextField
|
|
136
|
+
name="textField"
|
|
137
|
+
label="Textfield"
|
|
138
|
+
margin="normal"
|
|
139
|
+
fullWidth
|
|
140
|
+
required
|
|
141
|
+
rules={{
|
|
142
|
+
required: 'This field is required',
|
|
143
|
+
maxLength: { value: 200, message: 'This field must not exceed 200 characters'}
|
|
144
|
+
}}
|
|
145
|
+
helperText='Max 200 characters'
|
|
146
|
+
/>
|
|
147
|
+
<ControlledAutocomplete
|
|
148
|
+
name="selectField"
|
|
149
|
+
rules={{ required: 'This field is required'}}
|
|
150
|
+
FieldProps={{
|
|
151
|
+
margin:"normal",
|
|
152
|
+
label: 'Select Field',
|
|
153
|
+
placeholder: 'Value',
|
|
154
|
+
required: true,
|
|
155
|
+
}}
|
|
156
|
+
options={dropdownOptions}
|
|
157
|
+
/>
|
|
158
|
+
<ControlledDatepicker
|
|
159
|
+
name="datePicker"
|
|
160
|
+
rules={{ required: 'This field is required' }}
|
|
161
|
+
FieldProps={{
|
|
162
|
+
label: "Date",
|
|
163
|
+
margin: "normal",
|
|
164
|
+
required: true,
|
|
165
|
+
}}
|
|
166
|
+
/>
|
|
167
|
+
<ControlledRadioGroup
|
|
168
|
+
name="radio"
|
|
169
|
+
label="Radio Group"
|
|
170
|
+
row
|
|
171
|
+
aria-required
|
|
172
|
+
required
|
|
173
|
+
rules={{ required: 'This field is required' }}
|
|
174
|
+
>
|
|
175
|
+
<FormControlLabel control={<Radio />} value="1" label="Option 1" />
|
|
176
|
+
<FormControlLabel control={<Radio />} value="2" label="Option 2" />
|
|
177
|
+
</ControlledRadioGroup>
|
|
178
|
+
<LoadingButton loading={methods?.formState?.isSubmitting} type="submit" sx={{mt: 2}}>
|
|
179
|
+
Submit
|
|
180
|
+
</LoadingButton>
|
|
181
|
+
</form>
|
|
182
|
+
</FormProvider>
|
|
183
|
+
)
|
|
184
|
+
}
|
|
185
|
+
}
|