@availity/mui-controlled-form 0.2.5 → 0.3.0

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.
Files changed (46) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/README.md +2 -2
  3. package/dist/index.d.mts +122 -34
  4. package/dist/index.d.ts +122 -34
  5. package/dist/index.js +263 -225
  6. package/dist/index.mjs +279 -240
  7. package/package.json +2 -2
  8. package/src/index.ts +47 -0
  9. package/src/lib/AsyncAutocomplete.stories.tsx +21 -36
  10. package/src/lib/AsyncAutocomplete.test.tsx +17 -53
  11. package/src/lib/AsyncAutocomplete.tsx +23 -20
  12. package/src/lib/Autocomplete.stories.tsx +20 -33
  13. package/src/lib/Autocomplete.test.tsx +7 -37
  14. package/src/lib/Autocomplete.tsx +16 -15
  15. package/src/lib/Checkbox.stories.tsx +50 -43
  16. package/src/lib/Checkbox.test.tsx +14 -46
  17. package/src/lib/Checkbox.tsx +30 -15
  18. package/src/lib/CodesAutocomplete.stories.tsx +21 -35
  19. package/src/lib/CodesAutocomplete.test.tsx +20 -54
  20. package/src/lib/CodesAutocomplete.tsx +23 -20
  21. package/src/lib/ControlledForm.stories.tsx +1 -0
  22. package/src/lib/ControlledForm.tsx +8 -4
  23. package/src/lib/Datepicker.stories.tsx +19 -32
  24. package/src/lib/Datepicker.test.tsx +3 -35
  25. package/src/lib/Datepicker.tsx +18 -10
  26. package/src/lib/Input.stories.tsx +32 -33
  27. package/src/lib/Input.test.tsx +71 -7
  28. package/src/lib/Input.tsx +44 -24
  29. package/src/lib/OrganizationAutocomplete.stories.tsx +30 -35
  30. package/src/lib/OrganizationAutocomplete.test.tsx +23 -57
  31. package/src/lib/OrganizationAutocomplete.tsx +24 -23
  32. package/src/lib/ProviderAutocomplete.stories.tsx +20 -35
  33. package/src/lib/ProviderAutocomplete.test.tsx +29 -63
  34. package/src/lib/ProviderAutocomplete.tsx +22 -20
  35. package/src/lib/RadioGroup.stories.tsx +41 -36
  36. package/src/lib/RadioGroup.test.tsx +3 -35
  37. package/src/lib/RadioGroup.tsx +33 -25
  38. package/src/lib/Select.stories.tsx +78 -45
  39. package/src/lib/Select.test.tsx +8 -36
  40. package/src/lib/Select.tsx +44 -25
  41. package/src/lib/TextField.stories.tsx +26 -34
  42. package/src/lib/TextField.test.tsx +71 -5
  43. package/src/lib/TextField.tsx +55 -37
  44. package/src/lib/Types.tsx +2489 -0
  45. package/src/lib/UtilComponents.tsx +52 -0
  46. package/docs/propDefinitions.tsx +0 -31
@@ -1,12 +1,15 @@
1
1
  import { OrganizationAutocomplete, OrgAutocompleteProps } from '@availity/mui-autocomplete';
2
- import { useFormContext, Controller, RegisterOptions, FieldValues, ControllerProps } from 'react-hook-form';
2
+ import { Controller, RegisterOptions, FieldValues } from 'react-hook-form';
3
+ import { ControllerProps, DeprecatedRulesProps } from './Types';
3
4
 
4
- export type ControlledOrgAutocompleteProps = Omit<OrgAutocompleteProps, 'name'> &
5
- Omit<
6
- RegisterOptions<FieldValues, string>,
7
- 'disabled' | 'valueAsNumber' | 'valueAsDate' | 'setValueAs' | 'max' | 'maxLength' | 'min' | 'minLength'
8
- > &
9
- Pick<ControllerProps, 'defaultValue' | 'shouldUnregister' | 'name'>;
5
+ export type ControlledOrgAutocompleteProps = Omit<OrgAutocompleteProps,
6
+ 'onBlur' | 'onChange' | 'value' | 'name'
7
+ > & Pick<RegisterOptions<FieldValues, string>,
8
+ 'onBlur' | 'onChange' | 'value'
9
+ > & ControllerProps
10
+ //TODO v1 - remove deprecated props
11
+ & Omit<DeprecatedRulesProps, 'max' | 'maxLength' | 'min' | 'minLength'
12
+ >;
10
13
 
11
14
  export const ControlledOrganizationAutocomplete = ({
12
15
  name,
@@ -16,18 +19,16 @@ export const ControlledOrganizationAutocomplete = ({
16
19
  onChange,
17
20
  pattern,
18
21
  required,
22
+ rules = {},
19
23
  shouldUnregister,
20
24
  validate,
21
25
  value,
22
26
  FieldProps,
23
27
  ...rest
24
28
  }: ControlledOrgAutocompleteProps) => {
25
- const { control, getFieldState } = useFormContext();
26
- const errorMessage = getFieldState(name).error?.message;
27
29
  return (
28
30
  <Controller
29
31
  name={name}
30
- control={control}
31
32
  defaultValue={defaultValue}
32
33
  rules={{
33
34
  deps,
@@ -38,25 +39,25 @@ export const ControlledOrganizationAutocomplete = ({
38
39
  shouldUnregister,
39
40
  validate,
40
41
  value,
42
+ ...rules,
41
43
  }}
42
44
  shouldUnregister={shouldUnregister}
43
- render={({ field: { onChange, value, onBlur } }) => (
45
+ render={({ field: { onChange, value, onBlur, ref }, fieldState: { error } }) => (
44
46
  <OrganizationAutocomplete
45
47
  {...rest}
46
48
  FieldProps={{
47
49
  ...FieldProps,
48
- required: typeof required === 'object' ? required.value : !!required,
49
- error: !!errorMessage,
50
- helperText:
51
- errorMessage && typeof errorMessage === 'string' ? (
52
- <>
53
- {errorMessage}
54
- <br />
55
- {FieldProps?.helperText}
56
- </>
57
- ) : (
58
- FieldProps?.helperText
59
- ),
50
+ error: !!error,
51
+ helperText: error?.message ? (
52
+ <>
53
+ {error.message}
54
+ <br />
55
+ {FieldProps?.helperText}
56
+ </>
57
+ ) : (
58
+ FieldProps?.helperText
59
+ ),
60
+ inputRef:ref
60
61
  }}
61
62
  onChange={(event, value, reason) => {
62
63
  if (reason === 'clear') {
@@ -1,19 +1,18 @@
1
1
  import type { Meta, StoryObj } from '@storybook/react';
2
2
  import { ControlledProviderAutocomplete } from './ProviderAutocomplete';
3
- import { ControlledForm } from './ControlledForm';
4
3
  import { Button } from '@availity/mui-button';
5
- import { useFormContext } from 'react-hook-form';
6
4
  import { Paper } from '@availity/mui-paper';
7
5
  import { Typography } from '@availity/mui-typography';
8
6
  import { Grid } from '@availity/mui-layout';
9
7
  import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
10
- import { missingRHFprops } from '../../docs/propDefinitions';
8
+ import { AllControllerPropertiesCategorized, ProviderAutocompletePropsCategorized } from './Types';
9
+ import { FormProvider, useForm } from '..';
11
10
 
12
11
  const meta: Meta<typeof ControlledProviderAutocomplete> = {
13
12
  title: 'Form Components/Controlled Form/Autocomplete/ControlledProviderAutocomplete',
14
13
  component: ControlledProviderAutocomplete,
15
14
  tags: ['autodocs'],
16
- argTypes: missingRHFprops,
15
+ argTypes: {...AllControllerPropertiesCategorized, ...ProviderAutocompletePropsCategorized}
17
16
  };
18
17
 
19
18
  export default meta;
@@ -28,39 +27,25 @@ const client = new QueryClient({
28
27
 
29
28
  export const _ControlledProviderAutoComplete: StoryObj<typeof ControlledProviderAutocomplete> = {
30
29
  render: (args) => {
31
- const SubmittedValues = () => {
32
- const {
33
- getValues,
34
- formState: { isSubmitSuccessful },
35
- } = useFormContext();
30
+ const methods = useForm();
36
31
 
37
- return isSubmitSuccessful ? (
38
- <Paper sx={{ padding: '1.5rem', marginTop: '1.5rem' }}>
39
- <Typography variant="h2">Submitted Values</Typography>
40
- <pre>{JSON.stringify(getValues(), null, 2)}</pre>
41
- </Paper>
42
- ) : null;
43
- };
44
-
45
- const Actions = () => {
46
- const {
47
- reset,
48
- formState: { isSubmitSuccessful },
49
- } = useFormContext();
50
- return (
51
- <Grid container direction="row" justifyContent="space-between" marginTop={1}>
52
- <Button disabled={!isSubmitSuccessful} children="Reset" color="secondary" onClick={() => reset()} />
53
- <Button type="submit" disabled={isSubmitSuccessful} children="Submit" />
54
- </Grid>
55
- );
56
- };
57
32
  return (
58
33
  <QueryClientProvider client={client}>
59
- <ControlledForm values={{ controlledAutocomplete: undefined }} onSubmit={(data) => data}>
60
- <ControlledProviderAutocomplete {...args} />
61
- <Actions />
62
- <SubmittedValues />
63
- </ControlledForm>
34
+ <FormProvider {...methods}>
35
+ <form onSubmit={methods.handleSubmit((data) => data)}>
36
+ <ControlledProviderAutocomplete {...args} />
37
+ <Grid container direction="row" justifyContent="space-between" marginTop={1}>
38
+ <Button disabled={!methods?.formState?.isSubmitSuccessful} children="Reset" color="secondary" onClick={() => methods.reset()} />
39
+ <Button type="submit" disabled={methods?.formState?.isSubmitSuccessful} children="Submit" />
40
+ </Grid>
41
+ { methods?.formState?.isSubmitSuccessful ? (
42
+ <Paper sx={{ padding: '1.5rem', marginTop: '1.5rem' }}>
43
+ <Typography variant="h2">Submitted Values</Typography>
44
+ <pre data-testid="result">{JSON.stringify(methods.getValues(), null, 2)}</pre>
45
+ </Paper>
46
+ ) : null }
47
+ </form>
48
+ </FormProvider>
64
49
  </QueryClientProvider>
65
50
  );
66
51
  },
@@ -74,6 +59,6 @@ export const _ControlledProviderAutoComplete: StoryObj<typeof ControlledProvider
74
59
  },
75
60
  limit: 10,
76
61
  customerId: '1234',
77
- required: 'This is required.',
62
+ rules: { required:'This is required.' },
78
63
  },
79
64
  };
@@ -1,39 +1,9 @@
1
1
  import { fireEvent, render, waitFor } from '@testing-library/react';
2
2
  import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
3
- import { Paper } from '@availity/mui-paper';
4
- import { Typography } from '@availity/mui-typography';
5
- import { useFormContext } from 'react-hook-form';
6
- import { Grid } from '@availity/mui-layout';
7
- import { Button } from '@availity/mui-button';
8
3
  // eslint-disable-next-line @nx/enforce-module-boundaries
9
4
  import { server } from '@availity/mock/src/lib/server';
10
- import { ControlledForm } from './ControlledForm';
11
5
  import { ControlledProviderAutocomplete } from './ProviderAutocomplete';
12
-
13
- const SubmittedValues = () => {
14
- const {
15
- getValues,
16
- formState: { isSubmitSuccessful },
17
- } = useFormContext();
18
-
19
- return isSubmitSuccessful ? (
20
- <Paper sx={{ padding: '1.5rem', marginTop: '1.5rem' }}>
21
- <Typography variant="h2">Submitted Values</Typography>
22
- <pre data-testid="result">{JSON.stringify(getValues(), null, 2)}</pre>
23
- </Paper>
24
- ) : null;
25
- };
26
-
27
- const Actions = () => {
28
- const {
29
- formState: { isSubmitSuccessful },
30
- } = useFormContext();
31
- return (
32
- <Grid container direction="row" justifyContent="space-between">
33
- <Button type="submit" disabled={isSubmitSuccessful} children="Submit" />
34
- </Grid>
35
- );
36
- };
6
+ import { TestForm } from './UtilComponents';
37
7
 
38
8
  const onSubmit = jest.fn();
39
9
 
@@ -61,21 +31,19 @@ describe('ControlledProviderAutocomplete', () => {
61
31
  test('should loadOptions successfully', async () => {
62
32
  const screen = render(
63
33
  <QueryClientProvider client={client}>
64
- <ControlledForm values={{ controlledAutocomplete: undefined }} onSubmit={(data) => data}>
65
- <ControlledProviderAutocomplete
66
- name="controlledProviderAutocomplete"
67
- FieldProps={{
68
- label: 'Provider Select',
69
- helperText: 'Select a Provider from the list',
70
- placeholder: 'Select...',
71
- fullWidth: false,
72
- }}
73
- limit={10}
74
- customerId="1234"
75
- />
76
- <Actions />
77
- <SubmittedValues />
78
- </ControlledForm>
34
+ <TestForm UseFormOptions={{values: { controlledAutocomplete: null }}} onSubmit={onSubmit}>
35
+ <ControlledProviderAutocomplete
36
+ name="controlledProviderAutocomplete"
37
+ FieldProps={{
38
+ label: 'Provider Select',
39
+ helperText: 'Select a Provider from the list',
40
+ placeholder: 'Select...',
41
+ fullWidth: false,
42
+ }}
43
+ limit={10}
44
+ customerId="1234"
45
+ />
46
+ </TestForm>
79
47
  </QueryClientProvider>
80
48
  );
81
49
 
@@ -87,23 +55,21 @@ describe('ControlledProviderAutocomplete', () => {
87
55
  });
88
56
 
89
57
  test('should set the value and submit the form data', async () => {
90
- const screen = render(
91
- <QueryClientProvider client={client}>
92
- <ControlledForm values={{ controlledAutocomplete: undefined }} onSubmit={onSubmit}>
93
- <ControlledProviderAutocomplete
94
- name="controlledProviderAutocomplete"
95
- FieldProps={{
96
- label: 'Provider Select',
97
- helperText: 'Select a Provider from the list',
98
- placeholder: 'Select...',
99
- fullWidth: false,
100
- }}
101
- limit={10}
102
- customerId="1234"
103
- />
104
- <Actions />
105
- <SubmittedValues />
106
- </ControlledForm>
58
+ const screen = render(
59
+ <QueryClientProvider client={client}>
60
+ <TestForm UseFormOptions={{values: { controlledAutocomplete: null }}} onSubmit={onSubmit}>
61
+ <ControlledProviderAutocomplete
62
+ name="controlledProviderAutocomplete"
63
+ FieldProps={{
64
+ label: 'Provider Select',
65
+ helperText: 'Select a Provider from the list',
66
+ placeholder: 'Select...',
67
+ fullWidth: false,
68
+ }}
69
+ limit={10}
70
+ customerId="1234"
71
+ />
72
+ </TestForm>
107
73
  </QueryClientProvider>
108
74
  );
109
75
 
@@ -1,9 +1,14 @@
1
1
  import { ProviderAutocomplete, ProviderAutocompleteProps } from '@availity/mui-autocomplete';
2
- import { useFormContext, Controller, RegisterOptions, FieldValues, ControllerProps } from 'react-hook-form';
2
+ import { Controller, RegisterOptions, FieldValues } from 'react-hook-form';
3
+ import { ControllerProps, DeprecatedRulesProps } from './Types';
3
4
 
4
- export type ControlledProviderAutocompleteProps = Omit<ProviderAutocompleteProps, 'name'> &
5
- Omit<RegisterOptions<FieldValues, string>, 'disabled' | 'valueAsNumber' | 'valueAsDate' | 'setValueAs'> &
6
- Pick<ControllerProps, 'defaultValue' | 'shouldUnregister' | 'name'>;
5
+ export type ControlledProviderAutocompleteProps = Omit<ProviderAutocompleteProps,
6
+ 'onBlur' | 'onChange' | 'value' | 'name'
7
+ > & Pick<RegisterOptions<FieldValues, string>,
8
+ 'onBlur' | 'onChange' | 'value'
9
+ > & ControllerProps
10
+ //TODO v1 - remove deprecated props
11
+ & DeprecatedRulesProps;
7
12
 
8
13
  export const ControlledProviderAutocomplete = ({
9
14
  name,
@@ -17,18 +22,16 @@ export const ControlledProviderAutocomplete = ({
17
22
  onChange,
18
23
  pattern,
19
24
  required,
25
+ rules = {},
20
26
  shouldUnregister,
21
27
  validate,
22
28
  value,
23
29
  FieldProps,
24
30
  ...rest
25
31
  }: ControlledProviderAutocompleteProps) => {
26
- const { control, getFieldState } = useFormContext();
27
- const errorMessage = getFieldState(name).error?.message;
28
32
  return (
29
33
  <Controller
30
34
  name={name}
31
- control={control}
32
35
  defaultValue={defaultValue}
33
36
  rules={{
34
37
  deps,
@@ -43,25 +46,24 @@ export const ControlledProviderAutocomplete = ({
43
46
  shouldUnregister,
44
47
  validate,
45
48
  value,
49
+ ...rules,
46
50
  }}
47
51
  shouldUnregister={shouldUnregister}
48
- render={({ field: { onChange, value, onBlur } }) => (
52
+ render={({ field: { onChange, value, onBlur }, fieldState: { error } }) => (
49
53
  <ProviderAutocomplete
50
54
  {...rest}
51
55
  FieldProps={{
52
56
  ...FieldProps,
53
- required: typeof required === 'object' ? required.value : !!required,
54
- error: !!errorMessage,
55
- helperText:
56
- errorMessage && typeof errorMessage === 'string' ? (
57
- <>
58
- {errorMessage}
59
- <br />
60
- {FieldProps?.helperText}
61
- </>
62
- ) : (
63
- FieldProps?.helperText
64
- ),
57
+ error: !!error,
58
+ helperText: error?.message ? (
59
+ <>
60
+ {error.message}
61
+ <br />
62
+ {FieldProps?.helperText}
63
+ </>
64
+ ) : (
65
+ FieldProps?.helperText
66
+ ),
65
67
  }}
66
68
  onChange={(event, value, reason) => {
67
69
  if (reason === 'clear') {
@@ -1,59 +1,64 @@
1
1
  import type { Meta, StoryObj } from '@storybook/react';
2
2
  import { ControlledRadioGroup, ControlledRadioGroupProps } from './RadioGroup';
3
- import { ControlledForm } from './ControlledForm';
4
3
  import { Button } from '@availity/mui-button';
5
- import { useFormContext } from 'react-hook-form';
6
4
  import { Paper } from '@availity/mui-paper';
7
5
  import { Typography } from '@availity/mui-typography';
8
6
  import { FormControlLabel, Radio } from '@availity/mui-form-utils';
9
7
  import { Grid } from '@availity/mui-layout';
8
+ import { AllControllerPropertiesCategorized, RadioGroupPropsCategorized } from './Types';
9
+ import { FormProvider, useForm } from '..';
10
10
 
11
11
  const meta: Meta<typeof ControlledRadioGroup> = {
12
12
  title: 'Form Components/Controlled Form/ControlledRadioGroup',
13
13
  component: ControlledRadioGroup,
14
14
  tags: ['autodocs'],
15
+ argTypes: {
16
+ ...AllControllerPropertiesCategorized,
17
+ ...RadioGroupPropsCategorized,
18
+ required: {
19
+ table: { category: 'Input Props'}
20
+ }
21
+ },
22
+ parameters: {
23
+ controls: {
24
+ exclude: [
25
+ 'max',
26
+ 'maxLength',
27
+ 'min',
28
+ 'minLength',
29
+ 'pattern',
30
+ 'validate'
31
+ ]
32
+ }
33
+ }
15
34
  };
16
35
 
17
36
  export default meta;
18
37
 
19
38
  export const _ControlledRadioGroup: StoryObj<typeof ControlledRadioGroup> = {
20
39
  render: (args: ControlledRadioGroupProps) => {
21
- const SubmittedValues = () => {
22
- const {
23
- getValues,
24
- formState: { isSubmitSuccessful },
25
- } = useFormContext();
26
-
27
- return isSubmitSuccessful ? (
28
- <Paper sx={{ padding: '1.5rem', marginTop: '1.5rem' }}>
29
- <Typography variant="h2">Submitted Values</Typography>
30
- <pre>{JSON.stringify(getValues(), null, 2)}</pre>
31
- </Paper>
32
- ) : null;
33
- };
40
+ const methods = useForm();
34
41
 
35
- const Actions = () => {
36
- const {
37
- reset,
38
- formState: { isSubmitSuccessful },
39
- } = useFormContext();
40
- return (
41
- <Grid container direction="row" justifyContent="space-between" marginTop={1}>
42
- <Button disabled={!isSubmitSuccessful} children="Reset" color="secondary" onClick={() => reset()} />
43
- <Button type="submit" disabled={isSubmitSuccessful} children="Submit" />
44
- </Grid>
45
- );
46
- };
47
42
  return (
48
- <ControlledForm onSubmit={(data) => data} values={{ controlledRadioGroup: 'N/A' }}>
49
- <ControlledRadioGroup {...args}>
50
- <FormControlLabel control={<Radio />} label="N/A" value="N/A" />
51
- <FormControlLabel control={<Radio />} label="Yes" value="Yes" />
52
- <FormControlLabel control={<Radio />} label="No" value="No" />
53
- </ControlledRadioGroup>
54
- <Actions />
55
- <SubmittedValues />
56
- </ControlledForm>
43
+ <FormProvider {...methods}>
44
+ <form onSubmit={methods.handleSubmit((data) => data)}>
45
+ <ControlledRadioGroup {...args}>
46
+ <FormControlLabel control={<Radio />} label="N/A" value="N/A" />
47
+ <FormControlLabel control={<Radio />} label="Yes" value="Yes" />
48
+ <FormControlLabel control={<Radio />} label="No" value="No" />
49
+ </ControlledRadioGroup>
50
+ <Grid container direction="row" justifyContent="space-between" marginTop={1}>
51
+ <Button disabled={!methods?.formState?.isSubmitSuccessful} children="Reset" color="secondary" onClick={() => methods.reset()} />
52
+ <Button type="submit" disabled={methods?.formState?.isSubmitSuccessful} children="Submit" />
53
+ </Grid>
54
+ { methods?.formState?.isSubmitSuccessful ? (
55
+ <Paper sx={{ padding: '1.5rem', marginTop: '1.5rem' }}>
56
+ <Typography variant="h2">Submitted Values</Typography>
57
+ <pre data-testid="result">{JSON.stringify(methods.getValues(), null, 2)}</pre>
58
+ </Paper>
59
+ ) : null }
60
+ </form>
61
+ </FormProvider>
57
62
  );
58
63
  },
59
64
  args: {
@@ -1,52 +1,20 @@
1
1
  import { render, fireEvent, waitFor } from '@testing-library/react';
2
2
  import { FormControlLabel, Radio } from '@availity/mui-form-utils';
3
- import { useFormContext } from 'react-hook-form';
4
- import { Paper } from '@availity/mui-paper';
5
- import { Typography } from '@availity/mui-typography';
6
- import { Grid } from '@availity/mui-layout';
7
- import { Button } from '@availity/mui-button';
8
- import { ControlledForm } from './ControlledForm';
9
3
  import { ControlledRadioGroup } from './RadioGroup';
10
-
11
- const SubmittedValues = () => {
12
- const {
13
- getValues,
14
- formState: { isSubmitSuccessful },
15
- } = useFormContext();
16
-
17
- return isSubmitSuccessful ? (
18
- <Paper sx={{ padding: '1.5rem', marginTop: '1.5rem' }}>
19
- <Typography variant="h2">Submitted Values</Typography>
20
- <pre data-testid="result">{JSON.stringify(getValues(), null, 2)}</pre>
21
- </Paper>
22
- ) : null;
23
- };
24
-
25
- const Actions = () => {
26
- const {
27
- formState: { isSubmitSuccessful },
28
- } = useFormContext();
29
- return (
30
- <Grid container direction="row" justifyContent="space-between">
31
- <Button type="submit" disabled={isSubmitSuccessful} children="Submit" />
32
- </Grid>
33
- );
34
- };
4
+ import { TestForm } from './UtilComponents';
35
5
 
36
6
  const onSubmit = jest.fn();
37
7
 
38
8
  describe('ControlledRadioGroup', () => {
39
9
  test('should set the value and submit the form data', async () => {
40
10
  const screen = render(
41
- <ControlledForm onSubmit={onSubmit} values={{ controlledRadioGroup: undefined }}>
11
+ <TestForm UseFormOptions={{values: { controlledRadioGroup: undefined }}} onSubmit={onSubmit}>
42
12
  <ControlledRadioGroup name="controlledRadioGroup" label="Radio Group" value="N/A">
43
13
  <FormControlLabel control={<Radio />} label="N/A" value="N/A" />
44
14
  <FormControlLabel control={<Radio />} label="Yes" value="Yes" />
45
15
  <FormControlLabel control={<Radio />} label="No" value="No" />
46
16
  </ControlledRadioGroup>
47
- <Actions />
48
- <SubmittedValues />
49
- </ControlledForm>
17
+ </TestForm>
50
18
  );
51
19
 
52
20
  const option1 = screen.getByDisplayValue('Yes');
@@ -1,25 +1,35 @@
1
1
  import { RadioGroup, RadioGroupProps } from '@availity/mui-form-utils';
2
- import { useFormContext, ControllerProps, Controller, RegisterOptions, FieldValues } from 'react-hook-form';
2
+ import { Controller, RegisterOptions, FieldValues } from 'react-hook-form';
3
3
  import { FormControl, FormLabel, FormHelperText } from '@availity/mui-form-utils';
4
+ import { ControllerProps, DeprecatedRulesProps } from './Types';
4
5
 
5
- export type ControlledRadioGroupProps = RadioGroupProps & {
6
+ export type ControlledRadioGroupProps = {
6
7
  name: string;
7
8
  label: string;
8
9
  helperText?: string;
9
- } & Omit<
10
- RegisterOptions<FieldValues, string>,
11
- | 'disabled'
12
- | 'valueAsNumber'
13
- | 'valueAsDate'
14
- | 'setValueAs'
15
- | 'max'
16
- | 'maxLength'
17
- | 'min'
18
- | 'minLength'
19
- | 'pattern'
20
- | 'validate'
21
- > &
22
- Pick<ControllerProps, 'defaultValue' | 'shouldUnregister' | 'name'>;
10
+ } & Omit <RadioGroupProps,
11
+ 'onBlur' | 'onChange' | 'value' | 'name'
12
+ > & Pick<RegisterOptions<FieldValues, string>,
13
+ 'onBlur' | 'onChange' | 'value'
14
+ > & ControllerProps
15
+ //TODO v1 - remove deprecated props
16
+ & Omit<DeprecatedRulesProps,
17
+ 'max'
18
+ | 'maxLength'
19
+ | 'min'
20
+ | 'minLength'
21
+ | 'pattern'
22
+ | 'required'
23
+ | 'validate'
24
+ > & {
25
+ /** If `true`, will add `aria-required` to `input`.
26
+ *
27
+ * @deprecated There has been a collision of properties. The boolean value
28
+ * to mark the input as required will remain in future versions, but the
29
+ * required object for `react-hook-form` has been moved to the `rules` prop.
30
+ */
31
+ required?: boolean | RegisterOptions['required'];
32
+ };
23
33
 
24
34
  export const ControlledRadioGroup = ({
25
35
  name,
@@ -30,27 +40,25 @@ export const ControlledRadioGroup = ({
30
40
  onBlur,
31
41
  onChange,
32
42
  required,
43
+ rules = {},
33
44
  shouldUnregister,
34
45
  value,
35
46
  ...rest
36
47
  }: ControlledRadioGroupProps) => {
37
- const { control, getFieldState } = useFormContext();
38
- const errorMessage = getFieldState(name).error?.message;
39
48
  return (
40
49
  <Controller
41
- control={control}
42
50
  name={name}
43
51
  defaultValue={defaultValue}
44
- rules={{ deps, onBlur, onChange, required, shouldUnregister, value }}
52
+ rules={{ deps, onBlur, onChange, required: typeof required === 'boolean' ? undefined : required, shouldUnregister, value, ...rules }}
45
53
  shouldUnregister={shouldUnregister}
46
- render={({ field }) => (
47
- <FormControl error={!!errorMessage}>
48
- <FormLabel required={typeof required === 'object' ? required.value : !!required}>{label}</FormLabel>
54
+ render={({ field: {disabled, ...field}, fieldState: { error } }) => (
55
+ <FormControl error={!!error} disabled={disabled} required={!!required}>
56
+ <FormLabel>{label}</FormLabel>
49
57
  <RadioGroup {...field} {...rest} />
50
58
  <FormHelperText>
51
- {errorMessage && typeof errorMessage === 'string' ? (
59
+ {error?.message ? (
52
60
  <>
53
- {errorMessage}
61
+ {error.message}
54
62
  <br />
55
63
  {helperText}
56
64
  </>