@availity/mui-controlled-form 1.2.9 → 1.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.
@@ -1,7 +1,7 @@
1
1
  import { AsyncAutocomplete, AsyncAutocompleteProps } from '@availity/mui-autocomplete';
2
2
  import { RegisterOptions, FieldValues, Controller, useFormContext } from 'react-hook-form';
3
3
  import { ChipTypeMap } from '@mui/material/Chip';
4
- import { ControllerProps } from './Types';
4
+ import { ControllerProps, TransformProp } from './Types';
5
5
 
6
6
  export type ControlledAsyncAutocompleteProps<
7
7
  Option,
@@ -9,12 +9,17 @@ export type ControlledAsyncAutocompleteProps<
9
9
  DisableClearable extends boolean | undefined,
10
10
  FreeSolo extends boolean | undefined,
11
11
  ChipComponent extends React.ElementType = ChipTypeMap['defaultComponent'],
12
+ Output = AsyncAutocompleteProps<Option, Multiple, DisableClearable, FreeSolo, ChipComponent>['value'] | null,
12
13
  > = { defaultToFirstOption?: boolean; defaultToOnlyOption?: boolean } & Omit<
13
14
  AsyncAutocompleteProps<Option, Multiple, DisableClearable, FreeSolo, ChipComponent>,
14
15
  'onBlur' | 'onChange' | 'value' | 'name'
15
16
  > &
16
17
  Pick<RegisterOptions<FieldValues, string>, 'onBlur' | 'onChange' | 'value'> &
17
- ControllerProps;
18
+ ControllerProps &
19
+ TransformProp<
20
+ AsyncAutocompleteProps<Option, Multiple, DisableClearable, FreeSolo, ChipComponent>['value'] | null,
21
+ Output
22
+ >;
18
23
 
19
24
  export const ControlledAsyncAutocomplete = <
20
25
  Option,
@@ -22,6 +27,7 @@ export const ControlledAsyncAutocomplete = <
22
27
  DisableClearable extends boolean | undefined = false,
23
28
  FreeSolo extends boolean | undefined = false,
24
29
  ChipComponent extends React.ElementType = ChipTypeMap['defaultComponent'],
30
+ Output = AsyncAutocompleteProps<Option, Multiple, DisableClearable, FreeSolo, ChipComponent>['value'] | null,
25
31
  >({
26
32
  name,
27
33
  onBlur,
@@ -32,8 +38,9 @@ export const ControlledAsyncAutocomplete = <
32
38
  FieldProps,
33
39
  defaultToFirstOption,
34
40
  defaultToOnlyOption,
41
+ transform,
35
42
  ...rest
36
- }: ControlledAsyncAutocompleteProps<Option, Multiple, DisableClearable, FreeSolo, ChipComponent>) => {
43
+ }: ControlledAsyncAutocompleteProps<Option, Multiple, DisableClearable, FreeSolo, ChipComponent, Output>) => {
37
44
  const { setValue } = useFormContext();
38
45
  return (
39
46
  <Controller
@@ -61,12 +68,12 @@ export const ControlledAsyncAutocomplete = <
61
68
  }}
62
69
  onChange={(event, value, reason) => {
63
70
  if (reason === 'clear') {
64
- onChange(null);
71
+ onChange(transform?.output?.(null) ?? null);
65
72
  }
66
- onChange(value);
73
+ onChange(transform?.output?.(value) ?? value);
67
74
  }}
68
75
  onBlur={onBlur}
69
- value={value || null}
76
+ value={transform?.input?.(value) ?? value ?? null}
70
77
  loadOptions={async (offset, limit, inputValue) => {
71
78
  const { options, hasMore, offset: returnedOffsetValue } = await rest.loadOptions(offset, limit, inputValue);
72
79
 
@@ -1,7 +1,7 @@
1
1
  import { Autocomplete, AutocompleteProps } from '@availity/mui-autocomplete';
2
2
  import { RegisterOptions, FieldValues, Controller } from 'react-hook-form';
3
3
  import { ChipTypeMap } from '@mui/material/Chip';
4
- import { ControllerProps } from './Types';
4
+ import { ControllerProps, TransformProp } from './Types';
5
5
 
6
6
  export type ControlledAutocompleteProps<
7
7
  T,
@@ -9,12 +9,14 @@ export type ControlledAutocompleteProps<
9
9
  DisableClearable extends boolean | undefined,
10
10
  FreeSolo extends boolean | undefined,
11
11
  ChipComponent extends React.ElementType = ChipTypeMap['defaultComponent'],
12
+ Output = AutocompleteProps<T, Multiple, DisableClearable, FreeSolo, ChipComponent>['value'] | null,
12
13
  > = Omit<
13
14
  AutocompleteProps<T, Multiple, DisableClearable, FreeSolo, ChipComponent>,
14
15
  'onBlur' | 'onChange' | 'value' | 'name'
15
16
  > &
16
17
  Pick<RegisterOptions<FieldValues, string>, 'onBlur' | 'onChange' | 'value'> &
17
- ControllerProps;
18
+ ControllerProps &
19
+ TransformProp<AutocompleteProps<T, Multiple, DisableClearable, FreeSolo, ChipComponent>['value'] | null, Output>;
18
20
 
19
21
  export const ControlledAutocomplete = <
20
22
  T,
@@ -22,6 +24,7 @@ export const ControlledAutocomplete = <
22
24
  DisableClearable extends boolean | undefined = false,
23
25
  FreeSolo extends boolean | undefined = false,
24
26
  ChipComponent extends React.ElementType = ChipTypeMap['defaultComponent'],
27
+ Output = AutocompleteProps<T, Multiple, DisableClearable, FreeSolo, ChipComponent>['value'] | null,
25
28
  >({
26
29
  name,
27
30
  FieldProps,
@@ -31,8 +34,9 @@ export const ControlledAutocomplete = <
31
34
  onChange,
32
35
  shouldUnregister,
33
36
  value,
37
+ transform,
34
38
  ...rest
35
- }: ControlledAutocompleteProps<T, Multiple, DisableClearable, FreeSolo, ChipComponent>) => {
39
+ }: ControlledAutocompleteProps<T, Multiple, DisableClearable, FreeSolo, ChipComponent, Output>) => {
36
40
  return (
37
41
  <Controller
38
42
  name={name}
@@ -65,12 +69,12 @@ export const ControlledAutocomplete = <
65
69
  }}
66
70
  onChange={(event, value, reason) => {
67
71
  if (reason === 'clear') {
68
- onChange(null);
72
+ onChange(transform?.output?.(null) ?? null);
69
73
  }
70
- onChange(value);
74
+ onChange(transform?.output?.(value) ?? value);
71
75
  }}
72
76
  onBlur={onBlur}
73
- value={value || null}
77
+ value={transform?.input?.(value) ?? value ?? null}
74
78
  />
75
79
  )}
76
80
  />
@@ -1,12 +1,12 @@
1
1
  import { Checkbox, CheckboxProps } from '@availity/mui-checkbox';
2
2
  import { RegisterOptions, FieldValues, Controller } from 'react-hook-form';
3
- import { ControllerProps } from './Types';
3
+ import { ControllerProps, TransformProp } from './Types';
4
4
 
5
- export type ControlledCheckboxProps = Omit<CheckboxProps, 'disabled' | 'onBlur' | 'onChange' | 'value' | 'name'> &
5
+ export type ControlledCheckboxProps<Output = boolean> = Omit<CheckboxProps, 'disabled' | 'onBlur' | 'onChange' | 'value' | 'name'> &
6
6
  Pick<RegisterOptions<FieldValues, string>, 'disabled' | 'onBlur' | 'onChange' | 'value'> &
7
- ControllerProps;
7
+ ControllerProps & TransformProp<boolean, Output>;
8
8
 
9
- export const ControlledCheckbox = ({
9
+ export const ControlledCheckbox = <Output = boolean,>({
10
10
  name,
11
11
  disabled,
12
12
  onChange,
@@ -15,8 +15,9 @@ export const ControlledCheckbox = ({
15
15
  defaultValue = false,
16
16
  rules = {},
17
17
  shouldUnregister,
18
+ transform,
18
19
  ...rest
19
- }: ControlledCheckboxProps) => {
20
+ }: ControlledCheckboxProps<Output>) => {
20
21
  return (
21
22
  <Controller
22
23
  name={name}
@@ -35,8 +36,8 @@ export const ControlledCheckbox = ({
35
36
  required={typeof rules.required === 'object' ? rules.required.value : !!rules.required}
36
37
  {...rest}
37
38
  {...field}
38
- checked={field.value}
39
- onChange={(e) => field.onChange(e.target.checked)}
39
+ checked={transform?.input?.(field.value) ?? field.value}
40
+ onChange={(e) => field.onChange(transform?.output?.(e.target.checked) ?? e.target.checked)}
40
41
  />
41
42
  )}
42
43
  />
@@ -1,4 +1,4 @@
1
- import type { Code } from '@availity/mui-autocomplete';
1
+ import type { AsyncAutocompleteProps, Code } from '@availity/mui-autocomplete';
2
2
  import { fetchCodes, handleGetCodesOptionLabel } from '@availity/mui-autocomplete';
3
3
  import { ApiConfig } from '@availity/api-axios';
4
4
  import { ChipTypeMap } from '@mui/material/Chip';
@@ -11,8 +11,12 @@ export interface ControlledCodesAutocompleteProps<
11
11
  DisableClearable extends boolean | undefined = false,
12
12
  FreeSolo extends boolean | undefined = false,
13
13
  ChipComponent extends React.ElementType = ChipTypeMap['defaultComponent'],
14
+ Output = AsyncAutocompleteProps<Option, Multiple, DisableClearable, FreeSolo, ChipComponent>['value'] | null,
14
15
  > extends Omit<
15
- Optional<ControlledAsyncAutocompleteProps<Option, Multiple, DisableClearable, FreeSolo, ChipComponent>, 'queryKey'>,
16
+ Optional<
17
+ ControlledAsyncAutocompleteProps<Option, Multiple, DisableClearable, FreeSolo, ChipComponent, Output>,
18
+ 'queryKey'
19
+ >,
16
20
  'loadOptions'
17
21
  > {
18
22
  /** The code list id. */
@@ -21,22 +25,21 @@ export interface ControlledCodesAutocompleteProps<
21
25
  apiConfig?: ApiConfig;
22
26
  }
23
27
 
24
- export const ControlledCodesAutocomplete = ({
25
- name,
26
- defaultValue,
27
- onBlur,
28
- onChange,
29
- rules = {},
30
- shouldUnregister,
31
- value,
32
- FieldProps,
28
+ export const ControlledCodesAutocomplete = <
29
+ Option = Code,
30
+ Multiple extends boolean | undefined = false,
31
+ DisableClearable extends boolean | undefined = false,
32
+ FreeSolo extends boolean | undefined = false,
33
+ ChipComponent extends React.ElementType = ChipTypeMap['defaultComponent'],
34
+ Output = AsyncAutocompleteProps<Option, Multiple, DisableClearable, FreeSolo, ChipComponent>['value'] | null,
35
+ >({
33
36
  apiConfig = {},
34
37
  queryOptions,
35
38
  queryKey = 'codes-autocomplete',
36
39
  list,
37
40
  watchParams,
38
41
  ...rest
39
- }: ControlledCodesAutocompleteProps) => {
42
+ }: ControlledCodesAutocompleteProps<Option, Multiple, DisableClearable, FreeSolo, ChipComponent, Output>) => {
40
43
  const handleLoadOptions = async (offset: number, limit: number, inputValue: string) => {
41
44
  const resp = await fetchCodes({
42
45
  ...apiConfig,
@@ -48,14 +51,6 @@ export const ControlledCodesAutocomplete = ({
48
51
 
49
52
  return (
50
53
  <ControlledAsyncAutocomplete
51
- name={name}
52
- defaultValue={defaultValue}
53
- onBlur={onBlur}
54
- onChange={onChange}
55
- rules={rules}
56
- shouldUnregister={shouldUnregister}
57
- value={value}
58
- FieldProps={FieldProps}
59
54
  getOptionLabel={handleGetCodesOptionLabel}
60
55
  queryKey={queryKey}
61
56
  queryOptions={{ enabled: !!list, ...queryOptions }}
@@ -6,17 +6,18 @@ import { Typography } from '@availity/mui-typography';
6
6
  import { Grid } from '@availity/mui-layout';
7
7
  import { AllControllerPropertiesCategorized, DatepickerPropsCategorized } from './Types';
8
8
  import { FormProvider, useForm } from '..';
9
+ import dayjs, { Dayjs } from 'dayjs';
9
10
 
10
11
  const meta: Meta<typeof ControlledDatepicker> = {
11
12
  title: 'Form Components/Controlled Form/ControlledDatepicker',
12
13
  component: ControlledDatepicker,
13
14
  tags: ['autodocs'],
14
- argTypes: {...AllControllerPropertiesCategorized, ...DatepickerPropsCategorized}
15
+ argTypes: { ...AllControllerPropertiesCategorized, ...DatepickerPropsCategorized },
15
16
  };
16
17
 
17
18
  export default meta;
18
19
 
19
- export const _ControlledInput: StoryObj<typeof ControlledDatepicker> = {
20
+ export const _ControlledDatePicker: StoryObj<typeof ControlledDatepicker> = {
20
21
  render: (args: ControlledDatepickerProps) => {
21
22
  const methods = useForm();
22
23
 
@@ -25,15 +26,20 @@ export const _ControlledInput: StoryObj<typeof ControlledDatepicker> = {
25
26
  <form onSubmit={methods.handleSubmit((data) => data)}>
26
27
  <ControlledDatepicker {...args} />
27
28
  <Grid container direction="row" justifyContent="space-between" marginTop={1}>
28
- <Button disabled={!methods?.formState?.isSubmitSuccessful} children="Reset" color="secondary" onClick={() => methods.reset()} />
29
+ <Button
30
+ disabled={!methods?.formState?.isSubmitSuccessful}
31
+ children="Reset"
32
+ color="secondary"
33
+ onClick={() => methods.reset()}
34
+ />
29
35
  <Button type="submit" disabled={methods?.formState?.isSubmitSuccessful} children="Submit" />
30
36
  </Grid>
31
- { methods?.formState?.isSubmitSuccessful ? (
37
+ {methods?.formState?.isSubmitSuccessful ? (
32
38
  <Paper sx={{ padding: '1.5rem', marginTop: '1.5rem' }}>
33
39
  <Typography variant="h2">Submitted Values</Typography>
34
40
  <pre data-testid="result">{JSON.stringify(methods.getValues(), null, 2)}</pre>
35
41
  </Paper>
36
- ) : null }
42
+ ) : null}
37
43
  </form>
38
44
  </FormProvider>
39
45
  );
@@ -48,3 +54,53 @@ export const _ControlledInput: StoryObj<typeof ControlledDatepicker> = {
48
54
  },
49
55
  },
50
56
  };
57
+
58
+ export const _ControlledDatePickerTransform: StoryObj<typeof ControlledDatepicker> = {
59
+ parameters: {
60
+ docs: {
61
+ description: {
62
+ story:
63
+ 'In this example, the underlying value is stored as a string in the form values, but the datepicker always receives a Dayjs object. The transform prop is used to convert the value to and from the format you want to store in the underlying form values. You can see the underlying value when submitting the form.',
64
+ },
65
+ },
66
+ },
67
+ render: (args: ControlledDatepickerProps) => {
68
+ const methods = useForm();
69
+
70
+ return (
71
+ <FormProvider {...methods}>
72
+ <form onSubmit={methods.handleSubmit((data) => data)}>
73
+ <ControlledDatepicker {...args} />
74
+ <Grid container direction="row" justifyContent="space-between" marginTop={1}>
75
+ <Button
76
+ disabled={!methods?.formState?.isSubmitSuccessful}
77
+ children="Reset"
78
+ color="secondary"
79
+ onClick={() => methods.reset()}
80
+ />
81
+ <Button type="submit" disabled={methods?.formState?.isSubmitSuccessful} children="Submit" />
82
+ </Grid>
83
+ {methods?.formState?.isSubmitSuccessful ? (
84
+ <Paper sx={{ padding: '1.5rem', marginTop: '1.5rem' }}>
85
+ <Typography variant="h2">Submitted Values</Typography>
86
+ <pre data-testid="result">{JSON.stringify(methods.getValues(), null, 2)}</pre>
87
+ </Paper>
88
+ ) : null}
89
+ </form>
90
+ </FormProvider>
91
+ );
92
+ },
93
+ args: {
94
+ transform: {
95
+ output: (value: Dayjs) => value?.format('LL'),
96
+ input: (value: string) => (value ? dayjs(value, 'LL') : null),
97
+ },
98
+ name: 'controlledDatepickerTransform',
99
+ FieldProps: {
100
+ fullWidth: false,
101
+ helperText: 'Help text for the field',
102
+ helpTopicId: '1234',
103
+ label: 'Date',
104
+ },
105
+ },
106
+ };
@@ -1,12 +1,17 @@
1
1
  import { Datepicker, DatepickerProps } from '@availity/mui-datepicker';
2
2
  import { RegisterOptions, FieldValues, Controller } from 'react-hook-form';
3
- import { ControllerProps } from './Types';
3
+ import { ControllerProps, TransformProp } from './Types';
4
+ import { Dayjs } from 'dayjs';
4
5
 
5
- export type ControlledDatepickerProps = Omit<DatepickerProps, 'onBlur' | 'onChange' | 'value' | 'name'> &
6
+ export type ControlledDatepickerProps<Output = Dayjs | null> = Omit<
7
+ DatepickerProps,
8
+ 'onBlur' | 'onChange' | 'value' | 'name'
9
+ > &
6
10
  Pick<RegisterOptions<FieldValues, string>, 'onBlur' | 'onChange' | 'value'> &
7
- ControllerProps;
11
+ ControllerProps &
12
+ TransformProp<Dayjs | null, Output>;
8
13
 
9
- export const ControlledDatepicker = ({
14
+ export const ControlledDatepicker = <Output = Dayjs | null,>({
10
15
  name,
11
16
  defaultValue,
12
17
  onBlur,
@@ -15,8 +20,9 @@ export const ControlledDatepicker = ({
15
20
  shouldUnregister,
16
21
  value,
17
22
  FieldProps,
23
+ transform,
18
24
  ...rest
19
- }: ControlledDatepickerProps) => {
25
+ }: ControlledDatepickerProps<Output>) => {
20
26
  return (
21
27
  <Controller
22
28
  name={name}
@@ -50,8 +56,8 @@ export const ControlledDatepicker = ({
50
56
  onBlur: onBlur,
51
57
  },
52
58
  }}
53
- onChange={onChange}
54
- value={value || null}
59
+ onChange={(e) => onChange(transform?.output?.(e) ?? e)}
60
+ value={transform?.input?.(value) ?? value ?? null}
55
61
  />
56
62
  )}
57
63
  />
package/src/lib/Input.tsx CHANGED
@@ -1,12 +1,13 @@
1
1
  import { Input, InputProps } from '@availity/mui-form-utils';
2
2
  import { RegisterOptions, FieldValues, Controller } from 'react-hook-form';
3
- import { ControllerProps } from './Types';
3
+ import { ControllerProps, TransformProp } from './Types';
4
4
 
5
- export type ControlledInputProps = Omit<InputProps, 'onBlur' | 'onChange' | 'value' | 'name'> &
5
+ export type ControlledInputProps<Output = string> = Omit<InputProps, 'onBlur' | 'onChange' | 'value' | 'name'> &
6
6
  Pick<RegisterOptions<FieldValues, string>, 'onBlur' | 'onChange' | 'value'> &
7
- ControllerProps;
7
+ ControllerProps &
8
+ TransformProp<string, Output>;
8
9
 
9
- export const ControlledInput = ({
10
+ export const ControlledInput = <Output = string,>({
10
11
  name,
11
12
  defaultValue,
12
13
  disabled,
@@ -15,8 +16,9 @@ export const ControlledInput = ({
15
16
  rules = {},
16
17
  shouldUnregister,
17
18
  value,
19
+ transform,
18
20
  ...rest
19
- }: ControlledInputProps) => {
21
+ }: ControlledInputProps<Output>) => {
20
22
  return (
21
23
  <Controller
22
24
  name={name}
@@ -35,6 +37,8 @@ export const ControlledInput = ({
35
37
  required={typeof rules.required === 'object' ? rules.required.value : !!rules.required}
36
38
  {...rest}
37
39
  {...field}
40
+ onChange={(e) => field.onChange(transform?.output?.(e.target.value) ?? e)}
41
+ value={transform?.input?.(field.value) ?? field.value ?? ''}
38
42
  error={!!error}
39
43
  />
40
44
  )}
@@ -1,4 +1,4 @@
1
- import type { Organization } from '@availity/mui-autocomplete';
1
+ import type { AsyncAutocompleteProps, Organization } from '@availity/mui-autocomplete';
2
2
  import { handleGetOrgOptionLabel, fetchOrgs } from '@availity/mui-autocomplete';
3
3
  import type { ChipTypeMap } from '@mui/material/Chip';
4
4
  import type { ApiConfig } from '@availity/api-axios';
@@ -11,27 +11,30 @@ export interface ControlledOrgAutocompleteProps<
11
11
  DisableClearable extends boolean | undefined = false,
12
12
  FreeSolo extends boolean | undefined = false,
13
13
  ChipComponent extends React.ElementType = ChipTypeMap['defaultComponent'],
14
+ Output = AsyncAutocompleteProps<Option, Multiple, DisableClearable, FreeSolo, ChipComponent>['value'] | null,
14
15
  > extends Omit<
15
- Optional<ControlledAsyncAutocompleteProps<Option, Multiple, DisableClearable, FreeSolo, ChipComponent>, 'queryKey'>,
16
+ Optional<
17
+ ControlledAsyncAutocompleteProps<Option, Multiple, DisableClearable, FreeSolo, ChipComponent, Output>,
18
+ 'queryKey'
19
+ >,
16
20
  'loadOptions'
17
21
  > {
18
22
  /** Axios ApiConfig */
19
23
  apiConfig?: ApiConfig;
20
24
  }
21
25
 
22
- export const ControlledOrganizationAutocomplete = ({
23
- name,
24
- defaultValue,
25
- onBlur,
26
- onChange,
27
- rules = {},
28
- shouldUnregister,
29
- value,
30
- FieldProps,
26
+ export const ControlledOrganizationAutocomplete = <
27
+ Option = Organization,
28
+ Multiple extends boolean | undefined = false,
29
+ DisableClearable extends boolean | undefined = false,
30
+ FreeSolo extends boolean | undefined = false,
31
+ ChipComponent extends React.ElementType = ChipTypeMap['defaultComponent'],
32
+ Output = AsyncAutocompleteProps<Option, Multiple, DisableClearable, FreeSolo, ChipComponent>['value'] | null,
33
+ >({
31
34
  queryKey = 'org-autocomplete',
32
35
  apiConfig = {},
33
36
  ...rest
34
- }: ControlledOrgAutocompleteProps) => {
37
+ }: ControlledOrgAutocompleteProps<Option, Multiple, DisableClearable, FreeSolo, ChipComponent, Output>) => {
35
38
  const handleLoadOptions = async (offset: number, limit: number) => {
36
39
  const resp = await fetchOrgs({ ...apiConfig, params: { dropdown: true, ...apiConfig.params, offset, limit } });
37
40
 
@@ -39,14 +42,6 @@ export const ControlledOrganizationAutocomplete = ({
39
42
  };
40
43
  return (
41
44
  <ControlledAsyncAutocomplete
42
- name={name}
43
- defaultValue={defaultValue}
44
- onBlur={onBlur}
45
- onChange={onChange}
46
- rules={rules}
47
- shouldUnregister={shouldUnregister}
48
- value={value}
49
- FieldProps={FieldProps}
50
45
  getOptionLabel={handleGetOrgOptionLabel}
51
46
  queryKey={queryKey}
52
47
  {...rest}
@@ -1,4 +1,4 @@
1
- import type { Provider } from '@availity/mui-autocomplete';
1
+ import type { AsyncAutocompleteProps, Provider } from '@availity/mui-autocomplete';
2
2
  import { handleGetProviderOptionLabel, fetchProviders } from '@availity/mui-autocomplete';
3
3
  import type { ChipTypeMap } from '@mui/material/Chip';
4
4
  import type { Optional } from './utils';
@@ -11,8 +11,9 @@ export interface ControlledProviderAutocompleteProps<
11
11
  DisableClearable extends boolean | undefined = false,
12
12
  FreeSolo extends boolean | undefined = false,
13
13
  ChipComponent extends React.ElementType = ChipTypeMap['defaultComponent'],
14
+ Output = AsyncAutocompleteProps<Option, Multiple, DisableClearable, FreeSolo, ChipComponent>['value'] | null,
14
15
  > extends Omit<
15
- Optional<ControlledAsyncAutocompleteProps<Option, Multiple, DisableClearable, FreeSolo, ChipComponent>, 'queryKey'>,
16
+ Optional<ControlledAsyncAutocompleteProps<Option, Multiple, DisableClearable, FreeSolo, ChipComponent, Output>, 'queryKey'>,
16
17
  'loadOptions'
17
18
  > {
18
19
  /** Customer ID of the Organization you are requesting the providers for */
@@ -21,20 +22,19 @@ export interface ControlledProviderAutocompleteProps<
21
22
  apiConfig?: ApiConfig;
22
23
  }
23
24
 
24
- export const ControlledProviderAutocomplete = ({
25
- name,
26
- defaultValue,
27
- onBlur,
28
- onChange,
29
- rules = {},
30
- shouldUnregister,
31
- value,
32
- FieldProps,
25
+ export const ControlledProviderAutocomplete = <
26
+ Option = Provider,
27
+ Multiple extends boolean | undefined = false,
28
+ DisableClearable extends boolean | undefined = false,
29
+ FreeSolo extends boolean | undefined = false,
30
+ ChipComponent extends React.ElementType = ChipTypeMap['defaultComponent'],
31
+ Output = AsyncAutocompleteProps<Option, Multiple, DisableClearable, FreeSolo, ChipComponent>['value'] | null,
32
+ >({
33
33
  apiConfig = {},
34
34
  customerId,
35
35
  queryKey = 'prov-autocomplete',
36
36
  ...rest
37
- }: ControlledProviderAutocompleteProps) => {
37
+ }: ControlledProviderAutocompleteProps<Option, Multiple, DisableClearable, FreeSolo, ChipComponent, Output>) => {
38
38
  const handleLoadOptions = async (offset: number, limit: number, inputValue: string) => {
39
39
  const resp = await fetchProviders(customerId, {
40
40
  ...apiConfig,
@@ -45,14 +45,6 @@ export const ControlledProviderAutocomplete = ({
45
45
  };
46
46
  return (
47
47
  <ControlledAsyncAutocomplete
48
- name={name}
49
- defaultValue={defaultValue}
50
- onBlur={onBlur}
51
- onChange={onChange}
52
- rules={rules}
53
- shouldUnregister={shouldUnregister}
54
- value={value}
55
- FieldProps={FieldProps}
56
48
  getOptionLabel={handleGetProviderOptionLabel}
57
49
  queryOptions={{ enabled: !!customerId }}
58
50
  queryKey={queryKey}
@@ -1,18 +1,19 @@
1
1
  import { FormControlProps, RadioGroup, RadioGroupProps } from '@availity/mui-form-utils';
2
2
  import { Controller, RegisterOptions, FieldValues } from 'react-hook-form';
3
3
  import { FormControl, FormLabel, FormHelperText } from '@availity/mui-form-utils';
4
- import { ControllerProps } from './Types';
4
+ import { ControllerProps, TransformProp } from './Types';
5
5
 
6
- export type ControlledRadioGroupProps = {
6
+ export type ControlledRadioGroupProps<Output = string> = {
7
7
  name: string;
8
8
  label: string;
9
9
  helperText?: string;
10
10
  } & Omit<RadioGroupProps, 'onBlur' | 'onChange' | 'value' | 'name'> &
11
11
  Pick<RegisterOptions<FieldValues, string>, 'onBlur' | 'onChange' | 'value'> &
12
12
  ControllerProps &
13
+ TransformProp<string, Output> &
13
14
  Pick<FormControlProps, 'required'>;
14
15
 
15
- export const ControlledRadioGroup = ({
16
+ export const ControlledRadioGroup = <Output = string,>({
16
17
  name,
17
18
  helperText,
18
19
  label,
@@ -23,8 +24,9 @@ export const ControlledRadioGroup = ({
23
24
  rules = {},
24
25
  shouldUnregister,
25
26
  value,
27
+ transform,
26
28
  ...rest
27
- }: ControlledRadioGroupProps) => {
29
+ }: ControlledRadioGroupProps<Output>) => {
28
30
  return (
29
31
  <Controller
30
32
  name={name}
@@ -38,7 +40,12 @@ export const ControlledRadioGroup = ({
38
40
  required={!!required || (typeof rules.required === 'object' ? rules.required.value : !!rules.required)}
39
41
  >
40
42
  <FormLabel>{label}</FormLabel>
41
- <RadioGroup {...field} {...rest} />
43
+ <RadioGroup
44
+ {...field}
45
+ onChange={(e) => field.onChange(transform?.output?.(e.target.value) ?? e)}
46
+ value={transform?.input?.(field.value) ?? field.value ?? ''}
47
+ {...rest}
48
+ />
42
49
  <FormHelperText>
43
50
  {error?.message ? (
44
51
  <>
@@ -1,12 +1,16 @@
1
1
  import { Select, SelectProps } from '@availity/mui-form-utils';
2
2
  import { RegisterOptions, FieldValues, Controller } from 'react-hook-form';
3
- import { ControllerProps } from './Types';
3
+ import { ControllerProps, TransformProp } from './Types';
4
4
 
5
- export type ControlledSelectProps = Omit<SelectProps, 'onBlur' | 'onChange' | 'value' | 'name'> &
5
+ export type ControlledSelectProps<Output = string, Input = unknown> = Omit<
6
+ SelectProps<Input>,
7
+ 'onBlur' | 'onChange' | 'value' | 'name'
8
+ > &
6
9
  Pick<RegisterOptions<FieldValues, string>, 'onBlur' | 'onChange' | 'value'> &
7
- ControllerProps;
10
+ ControllerProps &
11
+ TransformProp<Input, Output>;
8
12
 
9
- export const ControlledSelect = ({
13
+ export const ControlledSelect = <Output = string, Input = unknown>({
10
14
  name,
11
15
  defaultValue,
12
16
  disabled,
@@ -15,8 +19,9 @@ export const ControlledSelect = ({
15
19
  rules = {},
16
20
  shouldUnregister,
17
21
  value,
22
+ transform,
18
23
  ...rest
19
- }: ControlledSelectProps) => {
24
+ }: ControlledSelectProps<Output, Input>) => {
20
25
  return (
21
26
  <Controller
22
27
  name={name}
@@ -35,6 +40,8 @@ export const ControlledSelect = ({
35
40
  required={typeof rules.required === 'object' ? rules.required.value : !!rules.required}
36
41
  {...rest}
37
42
  {...field}
43
+ onChange={(e) => field.onChange(transform?.output?.(e.target.value) ?? e)}
44
+ value={transform?.input?.(field.value) ?? field.value ?? ''}
38
45
  error={!!error}
39
46
  />
40
47
  )}
@@ -1,12 +1,13 @@
1
1
  import { TextField, TextFieldProps } from '@availity/mui-textfield';
2
2
  import { RegisterOptions, FieldValues, Controller } from 'react-hook-form';
3
- import { ControllerProps } from './Types';
3
+ import { ControllerProps, TransformProp } from './Types';
4
4
 
5
- export type ControlledTextFieldProps = Omit<TextFieldProps, 'onBlur' | 'onChange' | 'value' | 'name'> &
5
+ export type ControlledTextFieldProps<Output = string> = Omit<TextFieldProps, 'onBlur' | 'onChange' | 'value' | 'name'> &
6
6
  Pick<RegisterOptions<FieldValues, string>, 'onBlur' | 'onChange' | 'value'> &
7
- ControllerProps;
7
+ ControllerProps &
8
+ TransformProp<string, Output>;
8
9
 
9
- export const ControlledTextField = ({
10
+ export const ControlledTextField = <Output = string,>({
10
11
  name,
11
12
  defaultValue,
12
13
  disabled,
@@ -16,8 +17,9 @@ export const ControlledTextField = ({
16
17
  rules = {},
17
18
  shouldUnregister,
18
19
  value,
20
+ transform,
19
21
  ...rest
20
- }: ControlledTextFieldProps) => {
22
+ }: ControlledTextFieldProps<Output>) => {
21
23
  return (
22
24
  <Controller
23
25
  name={name}
@@ -35,6 +37,8 @@ export const ControlledTextField = ({
35
37
  <TextField
36
38
  required={typeof rules.required === 'object' ? rules.required.value : !!rules.required}
37
39
  {...field}
40
+ onChange={(e) => field.onChange(transform?.output?.(e.target.value) ?? e)}
41
+ value={transform?.input?.(field.value) ?? field.value ?? ''}
38
42
  {...rest}
39
43
  slotProps={{
40
44
  ...rest.slotProps,