@availity/mui-controlled-form 1.1.3 → 1.2.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.
- package/CHANGELOG.md +10 -0
- package/dist/index.d.mts +28 -9
- package/dist/index.d.ts +28 -9
- package/dist/index.js +135 -130
- package/dist/index.mjs +147 -142
- package/package.json +3 -2
- package/src/lib/AsyncAutocomplete.stories.tsx +57 -33
- package/src/lib/AsyncAutocomplete.tsx +19 -9
- package/src/lib/CodesAutocomplete.tsx +47 -42
- package/src/lib/OrganizationAutocomplete.tsx +36 -42
- package/src/lib/ProviderAutocomplete.tsx +44 -44
- package/src/lib/Types.tsx +8 -0
- package/src/lib/utils.tsx +1 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { AsyncAutocomplete, AsyncAutocompleteProps } from '@availity/mui-autocomplete';
|
|
2
|
-
import { RegisterOptions, FieldValues, Controller } from 'react-hook-form';
|
|
2
|
+
import { RegisterOptions, FieldValues, Controller, useFormContext } from 'react-hook-form';
|
|
3
3
|
import { ChipTypeMap } from '@mui/material/Chip';
|
|
4
4
|
import { ControllerProps } from './Types';
|
|
5
5
|
|
|
@@ -9,7 +9,7 @@ export type ControlledAsyncAutocompleteProps<
|
|
|
9
9
|
DisableClearable extends boolean | undefined,
|
|
10
10
|
FreeSolo extends boolean | undefined,
|
|
11
11
|
ChipComponent extends React.ElementType = ChipTypeMap['defaultComponent'],
|
|
12
|
-
> = Omit<
|
|
12
|
+
> = { defaultToFirstOption?: boolean; defaultToOnlyOption?: boolean } & Omit<
|
|
13
13
|
AsyncAutocompleteProps<Option, Multiple, DisableClearable, FreeSolo, ChipComponent>,
|
|
14
14
|
'onBlur' | 'onChange' | 'value' | 'name'
|
|
15
15
|
> &
|
|
@@ -30,19 +30,16 @@ export const ControlledAsyncAutocomplete = <
|
|
|
30
30
|
shouldUnregister,
|
|
31
31
|
value,
|
|
32
32
|
FieldProps,
|
|
33
|
+
defaultToFirstOption,
|
|
34
|
+
defaultToOnlyOption,
|
|
33
35
|
...rest
|
|
34
36
|
}: ControlledAsyncAutocompleteProps<Option, Multiple, DisableClearable, FreeSolo, ChipComponent>) => {
|
|
37
|
+
const { setValue } = useFormContext();
|
|
35
38
|
return (
|
|
36
39
|
<Controller
|
|
37
40
|
name={name}
|
|
38
41
|
defaultValue={rest.defaultValue}
|
|
39
|
-
rules={{
|
|
40
|
-
onBlur,
|
|
41
|
-
onChange,
|
|
42
|
-
shouldUnregister,
|
|
43
|
-
value,
|
|
44
|
-
...rules,
|
|
45
|
-
}}
|
|
42
|
+
rules={{ onBlur, onChange, shouldUnregister, value, ...rules }}
|
|
46
43
|
shouldUnregister={shouldUnregister}
|
|
47
44
|
render={({ field: { onChange, value, onBlur, ref }, fieldState: { error } }) => (
|
|
48
45
|
<AsyncAutocomplete
|
|
@@ -70,6 +67,19 @@ export const ControlledAsyncAutocomplete = <
|
|
|
70
67
|
}}
|
|
71
68
|
onBlur={onBlur}
|
|
72
69
|
value={value || null}
|
|
70
|
+
loadOptions={async (offset, limit, inputValue) => {
|
|
71
|
+
const { options, hasMore, offset: returnedOffsetValue } = await rest.loadOptions(offset, limit, inputValue);
|
|
72
|
+
|
|
73
|
+
if (defaultToFirstOption && offset === 0) {
|
|
74
|
+
setValue(name, options[0]);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (defaultToOnlyOption && offset === 0 && options.length === 1) {
|
|
78
|
+
setValue(name, options[0]);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return { options, hasMore, offset: returnedOffsetValue };
|
|
82
|
+
}}
|
|
73
83
|
/>
|
|
74
84
|
)}
|
|
75
85
|
/>
|
|
@@ -1,10 +1,25 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import type { Code } from '@availity/mui-autocomplete';
|
|
2
|
+
import { fetchCodes, handleGetCodesOptionLabel } from '@availity/mui-autocomplete';
|
|
3
|
+
import { ApiConfig } from '@availity/api-axios';
|
|
4
|
+
import { ChipTypeMap } from '@mui/material/Chip';
|
|
5
|
+
import type { Optional } from './utils';
|
|
6
|
+
import { ControlledAsyncAutocomplete, ControlledAsyncAutocompleteProps } from './AsyncAutocomplete';
|
|
4
7
|
|
|
5
|
-
export
|
|
6
|
-
|
|
7
|
-
|
|
8
|
+
export interface ControlledCodesAutocompleteProps<
|
|
9
|
+
Option = Code,
|
|
10
|
+
Multiple extends boolean | undefined = false,
|
|
11
|
+
DisableClearable extends boolean | undefined = false,
|
|
12
|
+
FreeSolo extends boolean | undefined = false,
|
|
13
|
+
ChipComponent extends React.ElementType = ChipTypeMap['defaultComponent'],
|
|
14
|
+
> extends Omit<
|
|
15
|
+
Optional<ControlledAsyncAutocompleteProps<Option, Multiple, DisableClearable, FreeSolo, ChipComponent>, 'queryKey'>,
|
|
16
|
+
'loadOptions'
|
|
17
|
+
> {
|
|
18
|
+
/** The code list id. */
|
|
19
|
+
list: string;
|
|
20
|
+
/** Config passed to the AvCodesApi.query function */
|
|
21
|
+
apiConfig?: ApiConfig;
|
|
22
|
+
}
|
|
8
23
|
|
|
9
24
|
export const ControlledCodesAutocomplete = ({
|
|
10
25
|
name,
|
|
@@ -15,48 +30,38 @@ export const ControlledCodesAutocomplete = ({
|
|
|
15
30
|
shouldUnregister,
|
|
16
31
|
value,
|
|
17
32
|
FieldProps,
|
|
33
|
+
apiConfig = {},
|
|
34
|
+
queryOptions,
|
|
35
|
+
queryKey = 'codes-autocomplete',
|
|
36
|
+
list,
|
|
37
|
+
watchParams,
|
|
18
38
|
...rest
|
|
19
39
|
}: ControlledCodesAutocompleteProps) => {
|
|
40
|
+
const handleLoadOptions = async (offset: number, limit: number, inputValue: string) => {
|
|
41
|
+
const resp = await fetchCodes({
|
|
42
|
+
...apiConfig,
|
|
43
|
+
params: { ...apiConfig.params, list, offset, limit, q: inputValue },
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
return resp;
|
|
47
|
+
};
|
|
48
|
+
|
|
20
49
|
return (
|
|
21
|
-
<
|
|
50
|
+
<ControlledAsyncAutocomplete
|
|
22
51
|
name={name}
|
|
23
52
|
defaultValue={defaultValue}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
shouldUnregister,
|
|
28
|
-
value,
|
|
29
|
-
...rules,
|
|
30
|
-
}}
|
|
53
|
+
onBlur={onBlur}
|
|
54
|
+
onChange={onChange}
|
|
55
|
+
rules={rules}
|
|
31
56
|
shouldUnregister={shouldUnregister}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
<>
|
|
41
|
-
{error.message}
|
|
42
|
-
<br />
|
|
43
|
-
{FieldProps?.helperText}
|
|
44
|
-
</>
|
|
45
|
-
) : (
|
|
46
|
-
FieldProps?.helperText
|
|
47
|
-
),
|
|
48
|
-
inputRef: ref,
|
|
49
|
-
}}
|
|
50
|
-
onChange={(event, value, reason) => {
|
|
51
|
-
if (reason === 'clear') {
|
|
52
|
-
onChange(null);
|
|
53
|
-
}
|
|
54
|
-
onChange(value);
|
|
55
|
-
}}
|
|
56
|
-
onBlur={onBlur}
|
|
57
|
-
value={value || null}
|
|
58
|
-
/>
|
|
59
|
-
)}
|
|
57
|
+
value={value}
|
|
58
|
+
FieldProps={FieldProps}
|
|
59
|
+
getOptionLabel={handleGetCodesOptionLabel}
|
|
60
|
+
queryKey={queryKey}
|
|
61
|
+
queryOptions={{ enabled: !!list, ...queryOptions }}
|
|
62
|
+
watchParams={{ list, ...watchParams }}
|
|
63
|
+
{...rest}
|
|
64
|
+
loadOptions={handleLoadOptions}
|
|
60
65
|
/>
|
|
61
66
|
);
|
|
62
67
|
};
|
|
@@ -1,10 +1,23 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import type { Organization } from '@availity/mui-autocomplete';
|
|
2
|
+
import { handleGetOrgOptionLabel, fetchOrgs } from '@availity/mui-autocomplete';
|
|
3
|
+
import type { ChipTypeMap } from '@mui/material/Chip';
|
|
4
|
+
import type { ApiConfig } from '@availity/api-axios';
|
|
5
|
+
import type { Optional } from './utils';
|
|
6
|
+
import { ControlledAsyncAutocomplete, ControlledAsyncAutocompleteProps } from './AsyncAutocomplete';
|
|
4
7
|
|
|
5
|
-
export
|
|
6
|
-
|
|
7
|
-
|
|
8
|
+
export interface ControlledOrgAutocompleteProps<
|
|
9
|
+
Option = Organization,
|
|
10
|
+
Multiple extends boolean | undefined = false,
|
|
11
|
+
DisableClearable extends boolean | undefined = false,
|
|
12
|
+
FreeSolo extends boolean | undefined = false,
|
|
13
|
+
ChipComponent extends React.ElementType = ChipTypeMap['defaultComponent'],
|
|
14
|
+
> extends Omit<
|
|
15
|
+
Optional<ControlledAsyncAutocompleteProps<Option, Multiple, DisableClearable, FreeSolo, ChipComponent>, 'queryKey'>,
|
|
16
|
+
'loadOptions'
|
|
17
|
+
> {
|
|
18
|
+
/** Axios ApiConfig */
|
|
19
|
+
apiConfig?: ApiConfig;
|
|
20
|
+
}
|
|
8
21
|
|
|
9
22
|
export const ControlledOrganizationAutocomplete = ({
|
|
10
23
|
name,
|
|
@@ -15,48 +28,29 @@ export const ControlledOrganizationAutocomplete = ({
|
|
|
15
28
|
shouldUnregister,
|
|
16
29
|
value,
|
|
17
30
|
FieldProps,
|
|
31
|
+
queryKey = 'org-autocomplete',
|
|
32
|
+
apiConfig = {},
|
|
18
33
|
...rest
|
|
19
34
|
}: ControlledOrgAutocompleteProps) => {
|
|
35
|
+
const handleLoadOptions = async (offset: number, limit: number) => {
|
|
36
|
+
const resp = await fetchOrgs({ ...apiConfig, params: { dropdown: true, ...apiConfig.params, offset, limit } });
|
|
37
|
+
|
|
38
|
+
return resp;
|
|
39
|
+
};
|
|
20
40
|
return (
|
|
21
|
-
<
|
|
41
|
+
<ControlledAsyncAutocomplete
|
|
22
42
|
name={name}
|
|
23
43
|
defaultValue={defaultValue}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
shouldUnregister,
|
|
28
|
-
value,
|
|
29
|
-
...rules,
|
|
30
|
-
}}
|
|
44
|
+
onBlur={onBlur}
|
|
45
|
+
onChange={onChange}
|
|
46
|
+
rules={rules}
|
|
31
47
|
shouldUnregister={shouldUnregister}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
error: !!error,
|
|
39
|
-
helperText: error?.message ? (
|
|
40
|
-
<>
|
|
41
|
-
{error.message}
|
|
42
|
-
<br />
|
|
43
|
-
{FieldProps?.helperText}
|
|
44
|
-
</>
|
|
45
|
-
) : (
|
|
46
|
-
FieldProps?.helperText
|
|
47
|
-
),
|
|
48
|
-
inputRef: ref,
|
|
49
|
-
}}
|
|
50
|
-
onChange={(event, value, reason) => {
|
|
51
|
-
if (reason === 'clear') {
|
|
52
|
-
onChange(null);
|
|
53
|
-
}
|
|
54
|
-
onChange(value);
|
|
55
|
-
}}
|
|
56
|
-
onBlur={onBlur}
|
|
57
|
-
value={value || null}
|
|
58
|
-
/>
|
|
59
|
-
)}
|
|
48
|
+
value={value}
|
|
49
|
+
FieldProps={FieldProps}
|
|
50
|
+
getOptionLabel={handleGetOrgOptionLabel}
|
|
51
|
+
queryKey={queryKey}
|
|
52
|
+
{...rest}
|
|
53
|
+
loadOptions={handleLoadOptions}
|
|
60
54
|
/>
|
|
61
55
|
);
|
|
62
56
|
};
|
|
@@ -1,13 +1,25 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import type { Provider } from '@availity/mui-autocomplete';
|
|
2
|
+
import { handleGetProviderOptionLabel, fetchProviders } from '@availity/mui-autocomplete';
|
|
3
|
+
import type { ChipTypeMap } from '@mui/material/Chip';
|
|
4
|
+
import type { Optional } from './utils';
|
|
5
|
+
import type { ApiConfig } from '@availity/api-axios';
|
|
6
|
+
import { ControlledAsyncAutocomplete, type ControlledAsyncAutocompleteProps } from './AsyncAutocomplete';
|
|
4
7
|
|
|
5
|
-
export
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
export interface ControlledProviderAutocompleteProps<
|
|
9
|
+
Option = Provider,
|
|
10
|
+
Multiple extends boolean | undefined = false,
|
|
11
|
+
DisableClearable extends boolean | undefined = false,
|
|
12
|
+
FreeSolo extends boolean | undefined = false,
|
|
13
|
+
ChipComponent extends React.ElementType = ChipTypeMap['defaultComponent'],
|
|
14
|
+
> extends Omit<
|
|
15
|
+
Optional<ControlledAsyncAutocompleteProps<Option, Multiple, DisableClearable, FreeSolo, ChipComponent>, 'queryKey'>,
|
|
16
|
+
'loadOptions'
|
|
17
|
+
> {
|
|
18
|
+
/** Customer ID of the Organization you are requesting the providers for */
|
|
19
|
+
customerId: string;
|
|
20
|
+
/** Config passed to the AvProvidersApi.getProviders function */
|
|
21
|
+
apiConfig?: ApiConfig;
|
|
22
|
+
}
|
|
11
23
|
|
|
12
24
|
export const ControlledProviderAutocomplete = ({
|
|
13
25
|
name,
|
|
@@ -18,47 +30,35 @@ export const ControlledProviderAutocomplete = ({
|
|
|
18
30
|
shouldUnregister,
|
|
19
31
|
value,
|
|
20
32
|
FieldProps,
|
|
33
|
+
apiConfig = {},
|
|
34
|
+
customerId,
|
|
35
|
+
queryKey = 'prov-autocomplete',
|
|
21
36
|
...rest
|
|
22
37
|
}: ControlledProviderAutocompleteProps) => {
|
|
38
|
+
const handleLoadOptions = async (offset: number, limit: number, inputValue: string) => {
|
|
39
|
+
const resp = await fetchProviders(customerId, {
|
|
40
|
+
...apiConfig,
|
|
41
|
+
params: { ...apiConfig.params, offset, limit, q: inputValue },
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
return resp;
|
|
45
|
+
};
|
|
23
46
|
return (
|
|
24
|
-
<
|
|
47
|
+
<ControlledAsyncAutocomplete
|
|
25
48
|
name={name}
|
|
26
49
|
defaultValue={defaultValue}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
shouldUnregister,
|
|
31
|
-
value,
|
|
32
|
-
...rules,
|
|
33
|
-
}}
|
|
50
|
+
onBlur={onBlur}
|
|
51
|
+
onChange={onChange}
|
|
52
|
+
rules={rules}
|
|
34
53
|
shouldUnregister={shouldUnregister}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
<>
|
|
44
|
-
{error.message}
|
|
45
|
-
<br />
|
|
46
|
-
{FieldProps?.helperText}
|
|
47
|
-
</>
|
|
48
|
-
) : (
|
|
49
|
-
FieldProps?.helperText
|
|
50
|
-
),
|
|
51
|
-
}}
|
|
52
|
-
onChange={(event, value, reason) => {
|
|
53
|
-
if (reason === 'clear') {
|
|
54
|
-
onChange(null);
|
|
55
|
-
}
|
|
56
|
-
onChange(value);
|
|
57
|
-
}}
|
|
58
|
-
onBlur={onBlur}
|
|
59
|
-
value={value || null}
|
|
60
|
-
/>
|
|
61
|
-
)}
|
|
54
|
+
value={value}
|
|
55
|
+
FieldProps={FieldProps}
|
|
56
|
+
getOptionLabel={handleGetProviderOptionLabel}
|
|
57
|
+
queryOptions={{ enabled: !!customerId }}
|
|
58
|
+
queryKey={queryKey}
|
|
59
|
+
watchParams={{ customerId }}
|
|
60
|
+
{...rest}
|
|
61
|
+
loadOptions={handleLoadOptions}
|
|
62
62
|
/>
|
|
63
63
|
);
|
|
64
64
|
};
|
package/src/lib/Types.tsx
CHANGED
|
@@ -242,6 +242,8 @@ export const RadioGroupPropsCategorized: RadioGroupPropsObject = {
|
|
|
242
242
|
|
|
243
243
|
export const ProviderAutocompletePropsCategorized: ProviderAutocompletePropsObject = {
|
|
244
244
|
classes: { table: { category: 'Input Props' } },
|
|
245
|
+
defaultToFirstOption: { table: { category: 'Input Props' } },
|
|
246
|
+
defaultToOnlyOption: { table: { category: 'Input Props' } },
|
|
245
247
|
id: { table: { category: 'Input Props' } },
|
|
246
248
|
onKeyDown: { table: { category: 'Input Props' } },
|
|
247
249
|
sx: { table: { category: 'Input Props' } },
|
|
@@ -297,6 +299,8 @@ export const ProviderAutocompletePropsCategorized: ProviderAutocompletePropsObje
|
|
|
297
299
|
|
|
298
300
|
export const OrganizationAutocompletePropsCategorized: OrganizationAutocompletePropsObject = {
|
|
299
301
|
classes: { table: { category: 'Input Props' } },
|
|
302
|
+
defaultToFirstOption: { table: { category: 'Input Props' } },
|
|
303
|
+
defaultToOnlyOption: { table: { category: 'Input Props' } },
|
|
300
304
|
id: { table: { category: 'Input Props' } },
|
|
301
305
|
onKeyDown: { table: { category: 'Input Props' } },
|
|
302
306
|
sx: { table: { category: 'Input Props' } },
|
|
@@ -400,6 +404,8 @@ export const DatepickerPropsCategorized: DatepickerPropsObject = {
|
|
|
400
404
|
|
|
401
405
|
export const CodesAutocompletePropsCategorized: CodesAutocompletePropsObject = {
|
|
402
406
|
classes: { table: { category: 'Input Props' } },
|
|
407
|
+
defaultToFirstOption: { table: { category: 'Input Props' } },
|
|
408
|
+
defaultToOnlyOption: { table: { category: 'Input Props' } },
|
|
403
409
|
id: { table: { category: 'Input Props' } },
|
|
404
410
|
onKeyDown: { table: { category: 'Input Props' } },
|
|
405
411
|
sx: { table: { category: 'Input Props' } },
|
|
@@ -455,6 +461,8 @@ export const CodesAutocompletePropsCategorized: CodesAutocompletePropsObject = {
|
|
|
455
461
|
|
|
456
462
|
export const AsyncAutocompletePropsCategorized: AsyncAutocompletePropsObject = {
|
|
457
463
|
classes: { table: { category: 'Input Props' } },
|
|
464
|
+
defaultToFirstOption: { table: { category: 'Input Props' } },
|
|
465
|
+
defaultToOnlyOption: { table: { category: 'Input Props' } },
|
|
458
466
|
id: { table: { category: 'Input Props' } },
|
|
459
467
|
onKeyDown: { table: { category: 'Input Props' } },
|
|
460
468
|
sx: { table: { category: 'Input Props' } },
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type Optional<T, K extends keyof T> = Pick<Partial<T>, K> & Omit<T, K>;
|