@availity/mui-controlled-form 1.1.2 → 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 +17 -0
- package/dist/index.d.mts +28 -9
- package/dist/index.d.ts +28 -9
- package/dist/index.js +136 -131
- package/dist/index.mjs +148 -143
- package/package.json +5 -4
- 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/TextField.stories.tsx +53 -6
- package/src/lib/TextField.test.tsx +8 -4
- package/src/lib/TextField.tsx +1 -1
- package/src/lib/Types.tsx +9 -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
|
};
|
|
@@ -16,7 +16,7 @@ const meta: Meta<typeof ControlledTextField> = {
|
|
|
16
16
|
...TextFieldPropsCategorized,
|
|
17
17
|
helperText: {
|
|
18
18
|
type: 'string',
|
|
19
|
-
table: { category: 'Input Props' }
|
|
19
|
+
table: { category: 'Input Props' },
|
|
20
20
|
},
|
|
21
21
|
},
|
|
22
22
|
};
|
|
@@ -25,22 +25,67 @@ export default meta;
|
|
|
25
25
|
|
|
26
26
|
export const _ControlledTextField: StoryObj<typeof ControlledTextField> = {
|
|
27
27
|
render: (args: ControlledTextFieldProps) => {
|
|
28
|
-
const methods = useForm({values:{ [args.name]: '' }});
|
|
28
|
+
const methods = useForm({ values: { [args.name]: '' } });
|
|
29
29
|
|
|
30
30
|
return (
|
|
31
31
|
<FormProvider {...methods}>
|
|
32
32
|
<form onSubmit={methods.handleSubmit((data) => data)}>
|
|
33
33
|
<ControlledTextField {...args} />
|
|
34
34
|
<Grid container direction="row" justifyContent="space-between" marginTop={1}>
|
|
35
|
-
<Button
|
|
35
|
+
<Button
|
|
36
|
+
disabled={!methods?.formState?.isSubmitSuccessful}
|
|
37
|
+
children="Reset"
|
|
38
|
+
color="secondary"
|
|
39
|
+
onClick={() => methods.reset()}
|
|
40
|
+
/>
|
|
36
41
|
<Button type="submit" disabled={methods?.formState?.isSubmitSuccessful} children="Submit" />
|
|
37
42
|
</Grid>
|
|
38
|
-
{
|
|
43
|
+
{methods?.formState?.isSubmitSuccessful ? (
|
|
39
44
|
<Paper sx={{ padding: '1.5rem', marginTop: '1.5rem' }}>
|
|
40
45
|
<Typography variant="h2">Submitted Values</Typography>
|
|
41
46
|
<pre data-testid="result">{JSON.stringify(methods.getValues(), null, 2)}</pre>
|
|
42
47
|
</Paper>
|
|
43
|
-
) : null
|
|
48
|
+
) : null}
|
|
49
|
+
</form>
|
|
50
|
+
</FormProvider>
|
|
51
|
+
);
|
|
52
|
+
},
|
|
53
|
+
args: {
|
|
54
|
+
name: 'controlledTextField',
|
|
55
|
+
placeholder: 'Name',
|
|
56
|
+
required: true,
|
|
57
|
+
rules: {
|
|
58
|
+
required: 'This field is required.',
|
|
59
|
+
maxLength: { value: 10, message: 'Too long' },
|
|
60
|
+
},
|
|
61
|
+
label: 'TextField Label',
|
|
62
|
+
showCharacterCount: true,
|
|
63
|
+
},
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
export const _ControlledTextFieldDisplayOverflow: StoryObj<typeof ControlledTextField> = {
|
|
67
|
+
render: (args: ControlledTextFieldProps) => {
|
|
68
|
+
const methods = useForm({ values: { [args.name]: '' } });
|
|
69
|
+
|
|
70
|
+
return (
|
|
71
|
+
<FormProvider {...methods}>
|
|
72
|
+
<form onSubmit={methods.handleSubmit((data) => data)}>
|
|
73
|
+
<ControlledTextField {...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}
|
|
44
89
|
</form>
|
|
45
90
|
</FormProvider>
|
|
46
91
|
);
|
|
@@ -52,8 +97,10 @@ export const _ControlledTextField: StoryObj<typeof ControlledTextField> = {
|
|
|
52
97
|
required: true,
|
|
53
98
|
rules: {
|
|
54
99
|
required: 'This field is required.',
|
|
55
|
-
maxLength: { value: 10, message: 'Too long' }
|
|
100
|
+
maxLength: { value: 10, message: 'Too long' },
|
|
56
101
|
},
|
|
57
102
|
label: 'TextField Label',
|
|
103
|
+
displayOverflowMaxLength: true,
|
|
104
|
+
showCharacterCount: true,
|
|
58
105
|
},
|
|
59
106
|
};
|
|
@@ -80,12 +80,14 @@ describe('ControlledTextField', () => {
|
|
|
80
80
|
</TestForm>
|
|
81
81
|
);
|
|
82
82
|
|
|
83
|
-
expect(getByText('0
|
|
83
|
+
expect(getByText('0')).toBeTruthy();
|
|
84
|
+
expect(getByText('/20')).toBeTruthy();
|
|
84
85
|
|
|
85
86
|
const input = getByTestId('testTextField');
|
|
86
87
|
fireEvent.change(input, { target: { value: 'Some Text' } });
|
|
87
88
|
|
|
88
|
-
expect(getByText('9
|
|
89
|
+
expect(getByText('9')).toBeTruthy();
|
|
90
|
+
expect(getByText('/20')).toBeTruthy();
|
|
89
91
|
|
|
90
92
|
fireEvent.change(input, { target: { value: "Some More Text that doesn't fit" } });
|
|
91
93
|
|
|
@@ -103,12 +105,14 @@ describe('ControlledTextField', () => {
|
|
|
103
105
|
/>
|
|
104
106
|
</TestForm>
|
|
105
107
|
);
|
|
106
|
-
expect(getByText('0
|
|
108
|
+
expect(getByText('0')).toBeTruthy();
|
|
109
|
+
expect(getByText('/20')).toBeTruthy();
|
|
107
110
|
|
|
108
111
|
const input = getByTestId('testTextField');
|
|
109
112
|
fireEvent.change(input, { target: { value: 'Some Text' } });
|
|
110
113
|
|
|
111
|
-
expect(getByText('9
|
|
114
|
+
expect(getByText('9')).toBeTruthy();
|
|
115
|
+
expect(getByText('/20')).toBeTruthy();
|
|
112
116
|
|
|
113
117
|
fireEvent.change(input, { target: { value: "Some More Text that doesn't fit" } });
|
|
114
118
|
|
package/src/lib/TextField.tsx
CHANGED
|
@@ -39,7 +39,7 @@ export const ControlledTextField = ({
|
|
|
39
39
|
slotProps={{
|
|
40
40
|
...rest.slotProps,
|
|
41
41
|
htmlInput: {
|
|
42
|
-
maxLength: rules.maxLength,
|
|
42
|
+
maxLength: typeof rules.maxLength === 'object' ? rules.maxLength.value : rules.maxLength,
|
|
43
43
|
...rest.slotProps?.htmlInput,
|
|
44
44
|
},
|
|
45
45
|
}}
|
package/src/lib/Types.tsx
CHANGED
|
@@ -188,6 +188,7 @@ export const AllControllerPropertiesCategorized: CategorizedControllerPropsObjec
|
|
|
188
188
|
};
|
|
189
189
|
|
|
190
190
|
export const TextFieldPropsCategorized: TextFieldPropsObject = {
|
|
191
|
+
displayOverflowMaxLength: { table: { category: 'Input Props' } },
|
|
191
192
|
slotProps: { table: { category: 'Input Props' } },
|
|
192
193
|
className: { table: { category: 'Input Props' } },
|
|
193
194
|
style: { table: { category: 'Input Props' } },
|
|
@@ -241,6 +242,8 @@ export const RadioGroupPropsCategorized: RadioGroupPropsObject = {
|
|
|
241
242
|
|
|
242
243
|
export const ProviderAutocompletePropsCategorized: ProviderAutocompletePropsObject = {
|
|
243
244
|
classes: { table: { category: 'Input Props' } },
|
|
245
|
+
defaultToFirstOption: { table: { category: 'Input Props' } },
|
|
246
|
+
defaultToOnlyOption: { table: { category: 'Input Props' } },
|
|
244
247
|
id: { table: { category: 'Input Props' } },
|
|
245
248
|
onKeyDown: { table: { category: 'Input Props' } },
|
|
246
249
|
sx: { table: { category: 'Input Props' } },
|
|
@@ -296,6 +299,8 @@ export const ProviderAutocompletePropsCategorized: ProviderAutocompletePropsObje
|
|
|
296
299
|
|
|
297
300
|
export const OrganizationAutocompletePropsCategorized: OrganizationAutocompletePropsObject = {
|
|
298
301
|
classes: { table: { category: 'Input Props' } },
|
|
302
|
+
defaultToFirstOption: { table: { category: 'Input Props' } },
|
|
303
|
+
defaultToOnlyOption: { table: { category: 'Input Props' } },
|
|
299
304
|
id: { table: { category: 'Input Props' } },
|
|
300
305
|
onKeyDown: { table: { category: 'Input Props' } },
|
|
301
306
|
sx: { table: { category: 'Input Props' } },
|
|
@@ -399,6 +404,8 @@ export const DatepickerPropsCategorized: DatepickerPropsObject = {
|
|
|
399
404
|
|
|
400
405
|
export const CodesAutocompletePropsCategorized: CodesAutocompletePropsObject = {
|
|
401
406
|
classes: { table: { category: 'Input Props' } },
|
|
407
|
+
defaultToFirstOption: { table: { category: 'Input Props' } },
|
|
408
|
+
defaultToOnlyOption: { table: { category: 'Input Props' } },
|
|
402
409
|
id: { table: { category: 'Input Props' } },
|
|
403
410
|
onKeyDown: { table: { category: 'Input Props' } },
|
|
404
411
|
sx: { table: { category: 'Input Props' } },
|
|
@@ -454,6 +461,8 @@ export const CodesAutocompletePropsCategorized: CodesAutocompletePropsObject = {
|
|
|
454
461
|
|
|
455
462
|
export const AsyncAutocompletePropsCategorized: AsyncAutocompletePropsObject = {
|
|
456
463
|
classes: { table: { category: 'Input Props' } },
|
|
464
|
+
defaultToFirstOption: { table: { category: 'Input Props' } },
|
|
465
|
+
defaultToOnlyOption: { table: { category: 'Input Props' } },
|
|
457
466
|
id: { table: { category: 'Input Props' } },
|
|
458
467
|
onKeyDown: { table: { category: 'Input Props' } },
|
|
459
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>;
|