@availity/mui-controlled-form 0.2.6 → 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 +7 -0
  2. package/README.md +2 -2
  3. package/dist/index.d.mts +122 -26
  4. package/dist/index.d.ts +122 -26
  5. package/dist/index.js +174 -132
  6. package/dist/index.mjs +174 -131
  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 +13 -6
  12. package/src/lib/Autocomplete.stories.tsx +20 -33
  13. package/src/lib/Autocomplete.test.tsx +7 -37
  14. package/src/lib/Autocomplete.tsx +21 -16
  15. package/src/lib/Checkbox.stories.tsx +48 -46
  16. package/src/lib/Checkbox.test.tsx +14 -46
  17. package/src/lib/Checkbox.tsx +19 -16
  18. package/src/lib/CodesAutocomplete.stories.tsx +21 -35
  19. package/src/lib/CodesAutocomplete.test.tsx +20 -54
  20. package/src/lib/CodesAutocomplete.tsx +13 -6
  21. package/src/lib/ControlledForm.stories.tsx +1 -0
  22. package/src/lib/ControlledForm.tsx +7 -3
  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 -8
  26. package/src/lib/Input.stories.tsx +32 -38
  27. package/src/lib/Input.test.tsx +71 -7
  28. package/src/lib/Input.tsx +30 -15
  29. package/src/lib/OrganizationAutocomplete.stories.tsx +30 -35
  30. package/src/lib/OrganizationAutocomplete.test.tsx +23 -57
  31. package/src/lib/OrganizationAutocomplete.tsx +14 -9
  32. package/src/lib/ProviderAutocomplete.stories.tsx +20 -35
  33. package/src/lib/ProviderAutocomplete.test.tsx +29 -63
  34. package/src/lib/ProviderAutocomplete.tsx +11 -5
  35. package/src/lib/RadioGroup.stories.tsx +41 -36
  36. package/src/lib/RadioGroup.test.tsx +3 -35
  37. package/src/lib/RadioGroup.tsx +31 -20
  38. package/src/lib/Select.stories.tsx +66 -93
  39. package/src/lib/Select.test.tsx +8 -36
  40. package/src/lib/Select.tsx +30 -15
  41. package/src/lib/TextField.stories.tsx +26 -39
  42. package/src/lib/TextField.test.tsx +71 -5
  43. package/src/lib/TextField.tsx +32 -17
  44. package/src/lib/Types.tsx +2489 -0
  45. package/src/lib/UtilComponents.tsx +52 -0
  46. package/docs/propDefinitions.tsx +0 -31
@@ -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 { 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,6 +22,7 @@ export const ControlledProviderAutocomplete = ({
17
22
  onChange,
18
23
  pattern,
19
24
  required,
25
+ rules = {},
20
26
  shouldUnregister,
21
27
  validate,
22
28
  value,
@@ -40,6 +46,7 @@ export const ControlledProviderAutocomplete = ({
40
46
  shouldUnregister,
41
47
  validate,
42
48
  value,
49
+ ...rules,
43
50
  }}
44
51
  shouldUnregister={shouldUnregister}
45
52
  render={({ field: { onChange, value, onBlur }, fieldState: { error } }) => (
@@ -47,7 +54,6 @@ export const ControlledProviderAutocomplete = ({
47
54
  {...rest}
48
55
  FieldProps={{
49
56
  ...FieldProps,
50
- required: typeof required === 'object' ? required.value : !!required,
51
57
  error: !!error,
52
58
  helperText: error?.message ? (
53
59
  <>
@@ -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 { 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,6 +40,7 @@ export const ControlledRadioGroup = ({
30
40
  onBlur,
31
41
  onChange,
32
42
  required,
43
+ rules = {},
33
44
  shouldUnregister,
34
45
  value,
35
46
  ...rest
@@ -38,11 +49,11 @@ export const ControlledRadioGroup = ({
38
49
  <Controller
39
50
  name={name}
40
51
  defaultValue={defaultValue}
41
- rules={{ deps, onBlur, onChange, required, shouldUnregister, value }}
52
+ rules={{ deps, onBlur, onChange, required: typeof required === 'boolean' ? undefined : required, shouldUnregister, value, ...rules }}
42
53
  shouldUnregister={shouldUnregister}
43
- render={({ field, fieldState: { error } }) => (
44
- <FormControl error={!!error}>
45
- <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>
46
57
  <RadioGroup {...field} {...rest} />
47
58
  <FormHelperText>
48
59
  {error?.message ? (
@@ -1,133 +1,106 @@
1
1
  import type { Meta, StoryObj } from '@storybook/react';
2
2
  import { ControlledSelect } from './Select';
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 { MenuItem } from '@availity/mui-menu';
10
8
  import { FormControl, FormLabel } from '@availity/mui-form-utils';
9
+ import { AllControllerPropertiesCategorized, SelectPropsCategorized } from './Types';
10
+ import { FormProvider, useForm } from '..';
11
11
 
12
12
  const meta: Meta<typeof ControlledSelect> = {
13
13
  title: 'Form Components/Controlled Form/ControlledSelect',
14
14
  component: ControlledSelect,
15
15
  tags: ['autodocs'],
16
+ argTypes: {...AllControllerPropertiesCategorized, ...SelectPropsCategorized},
17
+ parameters: {
18
+ controls: {
19
+ exclude: [
20
+ 'className',
21
+ 'defaultChecked',
22
+ 'onError',
23
+ 'ref',
24
+ 'style',
25
+ 'tabIndex'
26
+ ]
27
+ }
28
+ }
16
29
  };
17
30
 
18
31
  export default meta;
19
32
 
20
33
  export const _ControlledSelect: StoryObj<typeof ControlledSelect> = {
21
34
  render: (args) => {
22
- const SubmittedValues = () => {
23
- const {
24
- getValues,
25
- formState: { isSubmitSuccessful },
26
- } = useFormContext();
27
-
28
- return isSubmitSuccessful ? (
29
- <Paper sx={{ padding: '1.5rem', marginTop: '1.5rem' }}>
30
- <Typography variant="h2">Submitted Values</Typography>
31
- <pre>{JSON.stringify(getValues(), null, 2)}</pre>
32
- </Paper>
33
- ) : null;
34
- };
35
-
36
- const Actions = () => {
37
- const {
38
- reset,
39
- formState: { isSubmitSuccessful },
40
- } = useFormContext();
41
- return (
42
- <Grid container direction="row" justifyContent="space-between" marginTop={1}>
43
- <Button
44
- disabled={!isSubmitSuccessful}
45
- children="Reset"
46
- color="secondary"
47
- onClick={() => reset({ [args.name]: '' })}
48
- />
49
- <Button type="submit" disabled={isSubmitSuccessful} children="Submit" />
50
- </Grid>
51
- );
52
- };
35
+ const methods = useForm();
53
36
 
54
37
  return (
55
- <ControlledForm values={{ [args.name]: '' }} onSubmit={(data) => data} noValidate>
56
- <FormControl>
57
- <FormLabel id={`${args.id}-label`}>{args.label}</FormLabel>
58
- <ControlledSelect {...args} labelId={`${args.id}-label`}>
59
- <MenuItem value={1}>Option 1</MenuItem>
60
- <MenuItem value={2}>Option 2</MenuItem>
61
- <MenuItem value={3}>Option 3</MenuItem>
62
- </ControlledSelect>
63
- <Actions />
64
- <SubmittedValues />
65
- </FormControl>
66
- </ControlledForm>
38
+ <FormProvider {...methods}>
39
+ <form onSubmit={methods.handleSubmit((data) => data)}>
40
+ <FormControl>
41
+ <FormLabel id={`${args.id}-label`}>{args.label}</FormLabel>
42
+ <ControlledSelect {...args} labelId={`${args.id}-label`}>
43
+ <MenuItem value={1}>Option 1</MenuItem>
44
+ <MenuItem value={2}>Option 2</MenuItem>
45
+ <MenuItem value={3}>Option 3</MenuItem>
46
+ </ControlledSelect>
47
+ </FormControl>
48
+ <Grid container direction="row" justifyContent="space-between" marginTop={1}>
49
+ <Button disabled={!methods?.formState?.isSubmitSuccessful} children="Reset" color="secondary" onClick={() => methods.reset()} />
50
+ <Button type="submit" disabled={methods?.formState?.isSubmitSuccessful} children="Submit" />
51
+ </Grid>
52
+ { methods?.formState?.isSubmitSuccessful ? (
53
+ <Paper sx={{ padding: '1.5rem', marginTop: '1.5rem' }}>
54
+ <Typography variant="h2">Submitted Values</Typography>
55
+ <pre data-testid="result">{JSON.stringify(methods.getValues(), null, 2)}</pre>
56
+ </Paper>
57
+ ) : null }
58
+ </form>
59
+ </FormProvider>
67
60
  );
68
61
  },
69
62
  args: {
70
63
  name: 'controlledSelect',
71
- required: 'This is required.',
64
+ required: true,
65
+ rules: { required:'This is required.' },
72
66
  label: 'Select Label',
73
67
  },
74
68
  };
75
69
 
76
70
  export const _ControlledMultiSelect: StoryObj<typeof ControlledSelect> = {
77
71
  render: (args) => {
78
- const SubmittedValues = () => {
79
- const {
80
- getValues,
81
- formState: { isSubmitSuccessful },
82
- } = useFormContext();
83
-
84
- return isSubmitSuccessful ? (
85
- <Paper sx={{ padding: '1.5rem', marginTop: '1.5rem' }}>
86
- <Typography variant="h2">Submitted Values</Typography>
87
- <pre>{JSON.stringify(getValues(), null, 2)}</pre>
88
- </Paper>
89
- ) : null;
90
- };
91
-
92
- const Actions = () => {
93
- const {
94
- reset,
95
- formState: { isSubmitSuccessful },
96
- } = useFormContext();
97
- return (
98
- <Grid container direction="row" justifyContent="space-between" marginTop={1}>
99
- <Button
100
- disabled={!isSubmitSuccessful}
101
- children="Reset"
102
- color="secondary"
103
- onClick={() => reset({ [args.name]: [] })}
104
- />
105
- <Button type="submit" disabled={isSubmitSuccessful} children="Submit" />
106
- </Grid>
107
- );
108
- };
72
+ const methods = useForm({values:{ [args.name]: [] }});
109
73
 
110
74
  return (
111
- <ControlledForm values={{ [args.name]: [] }} onSubmit={(data) => data} noValidate>
112
- <FormControl>
113
- <FormLabel id={`${args.id}-label`}>{args.label}</FormLabel>
114
- <ControlledSelect {...args} labelId={`${args.id}-label`}>
115
- <MenuItem value={1}>Option 1</MenuItem>
116
- <MenuItem value={2}>Option 2</MenuItem>
117
- <MenuItem value={3}>Option 3</MenuItem>
118
- <MenuItem value={4}>Option 4</MenuItem>
119
- <MenuItem value={5}>Option 5</MenuItem>
120
- <MenuItem value={6}>Option 6</MenuItem>
121
- </ControlledSelect>
122
- <Actions />
123
- <SubmittedValues />
124
- </FormControl>
125
- </ControlledForm>
75
+ <FormProvider {...methods}>
76
+ <form onSubmit={methods.handleSubmit((data) => data)}>
77
+ <FormControl>
78
+ <FormLabel id={`${args.id}-label`}>{args.label}</FormLabel>
79
+ <ControlledSelect {...args} labelId={`${args.id}-label`}>
80
+ <MenuItem value={1}>Option 1</MenuItem>
81
+ <MenuItem value={2}>Option 2</MenuItem>
82
+ <MenuItem value={3}>Option 3</MenuItem>
83
+ <MenuItem value={4}>Option 4</MenuItem>
84
+ <MenuItem value={5}>Option 5</MenuItem>
85
+ <MenuItem value={6}>Option 6</MenuItem>
86
+ </ControlledSelect>
87
+ </FormControl>
88
+ <Grid container direction="row" justifyContent="space-between" marginTop={1}>
89
+ <Button disabled={!methods?.formState?.isSubmitSuccessful} children="Reset" color="secondary" onClick={() => methods.reset()} />
90
+ <Button type="submit" disabled={methods?.formState?.isSubmitSuccessful} children="Submit" />
91
+ </Grid>
92
+ <Paper sx={{ padding: '1.5rem', marginTop: '1.5rem' }}>
93
+ <Typography variant="h2">Submitted Values</Typography>
94
+ <pre>{JSON.stringify(methods.getValues(), null, 2)}</pre>
95
+ </Paper>
96
+ </form>
97
+ </FormProvider>
126
98
  );
127
99
  },
128
100
  args: {
129
101
  name: 'controlledMutliSelect',
130
- required: 'This is required.',
102
+ required: true,
103
+ rules: { required:'This is required.' },
131
104
  label: 'Select Label',
132
105
  multiple: true,
133
106
  },
@@ -1,52 +1,24 @@
1
1
  import { render, fireEvent, waitFor } from '@testing-library/react';
2
- import { useFormContext } from 'react-hook-form';
3
2
  import { Paper } from '@availity/mui-paper';
4
3
  import { Typography } from '@availity/mui-typography';
5
4
  import { Grid } from '@availity/mui-layout';
6
5
  import { Button } from '@availity/mui-button';
7
- import { ControlledForm } from './ControlledForm';
8
6
  import { ControlledSelect } from './Select';
9
7
  import { MenuItem } from '@availity/mui-menu';
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
- };
8
+ import { TestForm } from './UtilComponents';
35
9
 
36
10
  const onSubmit = jest.fn();
37
11
 
38
12
  describe('ControlledSelect', () => {
39
13
  test('should render the error styling if an error is returned', async () => {
40
14
  const screen = render(
41
- <ControlledForm values={{ controlledSelect: undefined }} onSubmit={onSubmit}>
42
- <ControlledSelect name="controlledSelect">
43
- <MenuItem value={1}>Option 1</MenuItem>
44
- <MenuItem value={2}>Option 2</MenuItem>
45
- <MenuItem value={3}>Option 3</MenuItem>
46
- </ControlledSelect>
47
- <Actions />
48
- <SubmittedValues />
49
- </ControlledForm>
15
+ <TestForm UseFormOptions={{values: { controlledSelect: undefined }}} onSubmit={onSubmit}>
16
+ <ControlledSelect name="controlledSelect">
17
+ <MenuItem value={1}>Option 1</MenuItem>
18
+ <MenuItem value={2}>Option 2</MenuItem>
19
+ <MenuItem value={3}>Option 3</MenuItem>
20
+ </ControlledSelect>
21
+ </TestForm>
50
22
  );
51
23
 
52
24
  const dropdown = screen.getByRole('combobox');