@aws-amplify/ui-react-native 2.4.5 → 2.5.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/dist/Authenticator/Authenticator.d.ts +33 -0
- package/dist/Authenticator/Authenticator.js +5 -1
- package/dist/Authenticator/Defaults/SelectMfaType/SelectMfaType.d.ts +14 -0
- package/dist/Authenticator/Defaults/SelectMfaType/SelectMfaType.js +39 -0
- package/dist/Authenticator/Defaults/SelectMfaType/index.d.ts +1 -0
- package/dist/Authenticator/Defaults/SelectMfaType/index.js +1 -0
- package/dist/Authenticator/Defaults/SetupEmail/SetupEmail.d.ts +14 -0
- package/dist/Authenticator/Defaults/SetupEmail/SetupEmail.js +39 -0
- package/dist/Authenticator/Defaults/SetupEmail/index.d.ts +1 -0
- package/dist/Authenticator/Defaults/SetupEmail/index.js +1 -0
- package/dist/Authenticator/Defaults/VerifyUser/VerifyUser.js +2 -2
- package/dist/Authenticator/Defaults/index.d.ts +3 -1
- package/dist/Authenticator/Defaults/index.js +2 -0
- package/dist/Authenticator/Defaults/types.d.ts +22 -0
- package/dist/Authenticator/common/DefaultFormFields/DefaultSelectMfaTypeFormFields.d.ts +7 -0
- package/dist/Authenticator/common/DefaultFormFields/DefaultSelectMfaTypeFormFields.js +12 -0
- package/dist/Authenticator/common/DefaultFormFields/{DefaultRadioFormFields.d.ts → DefaultVerifyUserFormFields.d.ts} +2 -2
- package/dist/Authenticator/common/DefaultFormFields/{DefaultRadioFormFields.js → DefaultVerifyUserFormFields.js} +7 -5
- package/dist/Authenticator/common/DefaultFormFields/index.d.ts +2 -1
- package/dist/Authenticator/common/DefaultFormFields/index.js +2 -1
- package/dist/Authenticator/hooks/useFieldValues/useFieldValues.js +52 -19
- package/dist/Authenticator/hooks/useFieldValues/utils.d.ts +2 -1
- package/dist/Authenticator/hooks/useFieldValues/utils.js +26 -3
- package/dist/Authenticator/index.d.ts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/primitives/RadioGroup/RadioGroup.d.ts +1 -0
- package/dist/primitives/RadioGroup/RadioGroup.js +2 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/lib/Authenticator/Authenticator.js +4 -0
- package/lib/Authenticator/Defaults/SelectMfaType/SelectMfaType.js +42 -0
- package/lib/Authenticator/Defaults/SelectMfaType/index.js +8 -0
- package/lib/Authenticator/Defaults/SetupEmail/SetupEmail.js +42 -0
- package/lib/Authenticator/Defaults/SetupEmail/index.js +8 -0
- package/lib/Authenticator/Defaults/VerifyUser/VerifyUser.js +1 -1
- package/lib/Authenticator/Defaults/index.js +5 -1
- package/lib/Authenticator/common/DefaultFormFields/DefaultSelectMfaTypeFormFields.js +15 -0
- package/lib/Authenticator/common/DefaultFormFields/{DefaultRadioFormFields.js → DefaultVerifyUserFormFields.js} +7 -5
- package/lib/Authenticator/common/DefaultFormFields/index.js +5 -3
- package/lib/Authenticator/hooks/useFieldValues/useFieldValues.js +51 -18
- package/lib/Authenticator/hooks/useFieldValues/utils.js +29 -5
- package/lib/primitives/RadioGroup/RadioGroup.js +3 -1
- package/lib/version.js +1 -1
- package/package.json +4 -4
- package/src/Authenticator/Authenticator.tsx +6 -0
- package/src/Authenticator/Defaults/SelectMfaType/SelectMfaType.tsx +87 -0
- package/src/Authenticator/Defaults/SelectMfaType/index.ts +1 -0
- package/src/Authenticator/Defaults/SetupEmail/SetupEmail.tsx +86 -0
- package/src/Authenticator/Defaults/SetupEmail/index.ts +1 -0
- package/src/Authenticator/Defaults/VerifyUser/VerifyUser.tsx +2 -2
- package/src/Authenticator/Defaults/index.ts +4 -0
- package/src/Authenticator/Defaults/types.ts +30 -0
- package/src/Authenticator/common/DefaultFormFields/DefaultSelectMfaTypeFormFields.tsx +35 -0
- package/src/Authenticator/common/DefaultFormFields/{DefaultRadioFormFields.tsx → DefaultVerifyUserFormFields.tsx} +8 -7
- package/src/Authenticator/common/DefaultFormFields/index.ts +2 -1
- package/src/Authenticator/hooks/useFieldValues/useFieldValues.ts +65 -21
- package/src/Authenticator/hooks/useFieldValues/utils.ts +40 -5
- package/src/Authenticator/index.ts +2 -0
- package/src/index.ts +2 -0
- package/src/primitives/RadioGroup/RadioGroup.tsx +7 -1
- package/src/version.ts +1 -1
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
import { DefaultRadioFormFieldsProps } from './types';
|
|
4
|
+
|
|
5
|
+
import { RadioGroup } from '../../../primitives/RadioGroup';
|
|
6
|
+
import { Radio } from '../../../primitives/Radio';
|
|
7
|
+
|
|
8
|
+
const DefaultSelectMfaTypeFormFields = ({
|
|
9
|
+
fields = [],
|
|
10
|
+
fieldContainerStyle,
|
|
11
|
+
fieldLabelStyle,
|
|
12
|
+
isPending,
|
|
13
|
+
style,
|
|
14
|
+
}: DefaultRadioFormFieldsProps): React.JSX.Element => {
|
|
15
|
+
// set initial value for radio field based on selected bool
|
|
16
|
+
const initialValue = fields.find((field) => !!field.selected)?.value;
|
|
17
|
+
return (
|
|
18
|
+
<RadioGroup disabled={isPending} style={style} initialValue={initialValue}>
|
|
19
|
+
{fields.map(({ value, label, ...props }) => (
|
|
20
|
+
<Radio
|
|
21
|
+
{...props}
|
|
22
|
+
key={value}
|
|
23
|
+
value={value}
|
|
24
|
+
label={label}
|
|
25
|
+
labelStyle={fieldLabelStyle}
|
|
26
|
+
style={fieldContainerStyle}
|
|
27
|
+
/>
|
|
28
|
+
))}
|
|
29
|
+
</RadioGroup>
|
|
30
|
+
);
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
DefaultSelectMfaTypeFormFields.displayName = 'FormFields';
|
|
34
|
+
|
|
35
|
+
export default DefaultSelectMfaTypeFormFields;
|
|
@@ -14,18 +14,19 @@ const attributeMap: AttributeMap = {
|
|
|
14
14
|
phone_number: 'Phone Number',
|
|
15
15
|
};
|
|
16
16
|
|
|
17
|
-
const
|
|
18
|
-
fields,
|
|
17
|
+
const DefaultVerifyUserFormFields = ({
|
|
18
|
+
fields = [],
|
|
19
19
|
fieldContainerStyle,
|
|
20
20
|
fieldLabelStyle,
|
|
21
21
|
isPending,
|
|
22
22
|
style,
|
|
23
23
|
}: DefaultRadioFormFieldsProps): React.JSX.Element => {
|
|
24
|
+
// set initial value for radio field based on selected bool
|
|
25
|
+
const initialValue = fields.find((field) => !!field.selected)?.name;
|
|
24
26
|
return (
|
|
25
|
-
<RadioGroup disabled={isPending} style={style}>
|
|
26
|
-
{
|
|
27
|
+
<RadioGroup disabled={isPending} style={style} initialValue={initialValue}>
|
|
28
|
+
{fields.map(({ name, value, ...props }) => {
|
|
27
29
|
const attributeType = attributeMap[name as keyof AttributeMap];
|
|
28
|
-
|
|
29
30
|
return (
|
|
30
31
|
<Radio
|
|
31
32
|
{...props}
|
|
@@ -43,6 +44,6 @@ const DefaultRadioFormFields = ({
|
|
|
43
44
|
);
|
|
44
45
|
};
|
|
45
46
|
|
|
46
|
-
|
|
47
|
+
DefaultVerifyUserFormFields.displayName = 'FormFields';
|
|
47
48
|
|
|
48
|
-
export default
|
|
49
|
+
export default DefaultVerifyUserFormFields;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
export { default as DefaultRadioFormFields } from './DefaultRadioFormFields';
|
|
2
1
|
export { default as DefaultTextFormFields } from './DefaultTextFormFields';
|
|
2
|
+
export { default as DefaultVerifyUserFormFields } from './DefaultVerifyUserFormFields';
|
|
3
|
+
export { default as DefaultSelectMfaTypeFormFields } from './DefaultSelectMfaTypeFormFields';
|
|
3
4
|
export { DefaultFormFieldsComponent, DefaultFormFieldsStyle } from './types';
|
|
@@ -2,14 +2,20 @@ import { useMemo, useState } from 'react';
|
|
|
2
2
|
import { ConsoleLogger as Logger } from 'aws-amplify/utils';
|
|
3
3
|
import { ValidationError } from '@aws-amplify/ui';
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
OnChangeText,
|
|
7
|
+
RadioFieldOptions,
|
|
8
|
+
TextFieldOnBlur,
|
|
9
|
+
TypedField,
|
|
10
|
+
} from '../types';
|
|
6
11
|
|
|
7
12
|
import { UseFieldValues, UseFieldValuesParams } from './types';
|
|
8
13
|
import {
|
|
9
14
|
getSanitizedTextFields,
|
|
10
|
-
getSanitizedRadioFields,
|
|
11
15
|
isRadioFieldOptions,
|
|
12
16
|
runFieldValidation,
|
|
17
|
+
getSanitizedVerifyUserFields,
|
|
18
|
+
getSanitizedSelectMfaTypeFields,
|
|
13
19
|
} from './utils';
|
|
14
20
|
|
|
15
21
|
const logger = new Logger('Authenticator');
|
|
@@ -22,11 +28,32 @@ export default function useFieldValues<FieldType extends TypedField>({
|
|
|
22
28
|
handleSubmit,
|
|
23
29
|
validationErrors,
|
|
24
30
|
}: UseFieldValuesParams<FieldType>): UseFieldValues<FieldType> {
|
|
25
|
-
const [values, setValues] = useState<Record<string, string>>({});
|
|
26
31
|
const [touched, setTouched] = useState<Record<string, boolean>>({});
|
|
27
32
|
const [fieldValidationErrors, setFieldValidationErrors] =
|
|
28
33
|
useState<ValidationError>({});
|
|
29
|
-
const
|
|
34
|
+
const isVerifyUserRoute = componentName === 'VerifyUser';
|
|
35
|
+
const isSelectMfaTypeRoute = componentName === 'SelectMfaType';
|
|
36
|
+
const isRadioFieldComponent = isVerifyUserRoute || isSelectMfaTypeRoute;
|
|
37
|
+
|
|
38
|
+
// initialize values based on route
|
|
39
|
+
// select mfa type screen should auto select first radio option
|
|
40
|
+
const [values, setValues] = useState(() => {
|
|
41
|
+
const result: Record<string, string> = {};
|
|
42
|
+
if (isSelectMfaTypeRoute) {
|
|
43
|
+
const initialValue = fields[0]?.value;
|
|
44
|
+
if (initialValue) {
|
|
45
|
+
result.mfa_type = initialValue;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
if (isVerifyUserRoute) {
|
|
49
|
+
const initialValue = fields[0]?.name;
|
|
50
|
+
if (initialValue) {
|
|
51
|
+
result.unverifiedAttr = initialValue;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return result;
|
|
56
|
+
});
|
|
30
57
|
|
|
31
58
|
const sanitizedFields = useMemo(() => {
|
|
32
59
|
if (!Array.isArray(fields)) {
|
|
@@ -36,12 +63,16 @@ export default function useFieldValues<FieldType extends TypedField>({
|
|
|
36
63
|
return [];
|
|
37
64
|
}
|
|
38
65
|
|
|
39
|
-
if (
|
|
40
|
-
return
|
|
66
|
+
if (isVerifyUserRoute) {
|
|
67
|
+
return getSanitizedVerifyUserFields(fields);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (isSelectMfaTypeRoute) {
|
|
71
|
+
return getSanitizedSelectMfaTypeFields(fields);
|
|
41
72
|
}
|
|
42
73
|
|
|
43
74
|
return getSanitizedTextFields(fields, componentName);
|
|
44
|
-
}, [componentName, fields,
|
|
75
|
+
}, [componentName, fields, isVerifyUserRoute, isSelectMfaTypeRoute]);
|
|
45
76
|
|
|
46
77
|
const fieldsWithHandlers = sanitizedFields.map((field) => {
|
|
47
78
|
if (isRadioFieldOptions(field)) {
|
|
@@ -49,11 +80,31 @@ export default function useFieldValues<FieldType extends TypedField>({
|
|
|
49
80
|
// call `onChange` passed as radio `field` option
|
|
50
81
|
field.onChange?.(value);
|
|
51
82
|
|
|
52
|
-
// set `name` as value of 'unverifiedAttr'
|
|
53
|
-
|
|
83
|
+
// on VerifyUser route, set `name` as value of 'unverifiedAttr'
|
|
84
|
+
// on SelectMfaTYpe route, set `name` as value of 'mfa_type'
|
|
85
|
+
const fieldName = isVerifyUserRoute
|
|
86
|
+
? 'unverifiedAttr'
|
|
87
|
+
: isSelectMfaTypeRoute
|
|
88
|
+
? 'mfa_type'
|
|
89
|
+
: field.name;
|
|
90
|
+
|
|
91
|
+
setValues((prev) => ({ ...prev, [fieldName]: value }));
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
const result: RadioFieldOptions = {
|
|
95
|
+
...field,
|
|
96
|
+
onChange,
|
|
54
97
|
};
|
|
55
98
|
|
|
56
|
-
|
|
99
|
+
// bind selected boolean attribute for radio field
|
|
100
|
+
if (isSelectMfaTypeRoute) {
|
|
101
|
+
result.selected = values.mfa_type === field.value;
|
|
102
|
+
}
|
|
103
|
+
if (isVerifyUserRoute) {
|
|
104
|
+
result.selected = values.unverifiedAttr === field.name;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return result;
|
|
57
108
|
}
|
|
58
109
|
|
|
59
110
|
const { name, label, labelHidden, ...rest } = field;
|
|
@@ -100,18 +151,11 @@ export default function useFieldValues<FieldType extends TypedField>({
|
|
|
100
151
|
};
|
|
101
152
|
}) as FieldType[];
|
|
102
153
|
|
|
103
|
-
const disableFormSubmit =
|
|
154
|
+
const disableFormSubmit = isVerifyUserRoute
|
|
104
155
|
? !values.unverifiedAttr
|
|
105
|
-
:
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
if (value) {
|
|
111
|
-
return false;
|
|
112
|
-
}
|
|
113
|
-
return true;
|
|
114
|
-
});
|
|
156
|
+
: isSelectMfaTypeRoute
|
|
157
|
+
? !values.mfa_type
|
|
158
|
+
: fieldsWithHandlers.some(({ required, value }) => required && !value);
|
|
115
159
|
|
|
116
160
|
const handleFormSubmit = () => {
|
|
117
161
|
const submitValue = isRadioFieldComponent
|
|
@@ -31,16 +31,15 @@ export const isRadioFieldOptions = (
|
|
|
31
31
|
field: TypedField
|
|
32
32
|
): field is RadioFieldOptions => field?.type === 'radio';
|
|
33
33
|
|
|
34
|
-
export const
|
|
35
|
-
fields: TypedField[]
|
|
36
|
-
componentName: AuthenticatorRouteComponentName
|
|
34
|
+
export const getSanitizedVerifyUserFields = (
|
|
35
|
+
fields: TypedField[]
|
|
37
36
|
): TypedField[] => {
|
|
38
37
|
const values: Record<string, boolean> = {};
|
|
39
38
|
|
|
40
39
|
return fields.filter((field) => {
|
|
41
40
|
if (!isRadioFieldOptions(field)) {
|
|
42
41
|
logger.warn(
|
|
43
|
-
|
|
42
|
+
`VerifyUser component does not support text fields. field with type ${field.type} has been ignored.`
|
|
44
43
|
);
|
|
45
44
|
return false;
|
|
46
45
|
}
|
|
@@ -77,6 +76,39 @@ export const getSanitizedRadioFields = (
|
|
|
77
76
|
});
|
|
78
77
|
};
|
|
79
78
|
|
|
79
|
+
export const getSanitizedSelectMfaTypeFields = (
|
|
80
|
+
fields: TypedField[]
|
|
81
|
+
): TypedField[] => {
|
|
82
|
+
const values: Record<string, boolean> = {};
|
|
83
|
+
|
|
84
|
+
return fields.filter((field) => {
|
|
85
|
+
const { value } = field;
|
|
86
|
+
|
|
87
|
+
if (!isRadioFieldOptions(field)) {
|
|
88
|
+
logger.warn(
|
|
89
|
+
`SelectMfaType component does not support non-radio fields; field with type "${field.type}" has been ignored.`
|
|
90
|
+
);
|
|
91
|
+
return false;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (!value) {
|
|
95
|
+
logger.warn('Each field must have a value; field has been ignored.');
|
|
96
|
+
return false;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (values[value]) {
|
|
100
|
+
logger.warn(
|
|
101
|
+
`Each field value must be unique; field with duplicate value of "${value}" has been ignored.`
|
|
102
|
+
);
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
values[value] = true;
|
|
107
|
+
|
|
108
|
+
return true;
|
|
109
|
+
});
|
|
110
|
+
};
|
|
111
|
+
|
|
80
112
|
export const getSanitizedTextFields = (
|
|
81
113
|
fields: TypedField[],
|
|
82
114
|
componentName: AuthenticatorRouteComponentName
|
|
@@ -180,9 +212,12 @@ export function getRouteTypedFields({
|
|
|
180
212
|
|
|
181
213
|
// `VerifyUser` does not require additional updates to the shape of `fields`
|
|
182
214
|
const isVerifyUserRoute = route === 'verifyUser';
|
|
215
|
+
const isSelectMfaTypeRoute = route === 'selectMfaType';
|
|
183
216
|
const radioFields = fields as TypedField[];
|
|
184
217
|
|
|
185
|
-
return isVerifyUserRoute
|
|
218
|
+
return isVerifyUserRoute || isSelectMfaTypeRoute
|
|
219
|
+
? radioFields
|
|
220
|
+
: getTypedFields(fields);
|
|
186
221
|
}
|
|
187
222
|
|
|
188
223
|
/**
|
package/src/index.ts
CHANGED
|
@@ -19,6 +19,8 @@ import { RadioProps } from '../Radio';
|
|
|
19
19
|
import { getThemedStyles } from './styles';
|
|
20
20
|
import { RadioGroupProps } from './types';
|
|
21
21
|
|
|
22
|
+
export const RADIO_GROUP_CONTAINER_TEST_ID = 'amplify__radio-group__container';
|
|
23
|
+
|
|
22
24
|
export default function RadioGroup<T>({
|
|
23
25
|
accessible = true,
|
|
24
26
|
accessibilityRole = 'radiogroup',
|
|
@@ -73,7 +75,11 @@ export default function RadioGroup<T>({
|
|
|
73
75
|
);
|
|
74
76
|
|
|
75
77
|
return (
|
|
76
|
-
<View
|
|
78
|
+
<View
|
|
79
|
+
{...rest}
|
|
80
|
+
style={[themedStyle.container, containerStyle, style]}
|
|
81
|
+
testID={RADIO_GROUP_CONTAINER_TEST_ID}
|
|
82
|
+
>
|
|
77
83
|
<View
|
|
78
84
|
accessible={accessible}
|
|
79
85
|
accessibilityRole={accessibilityRole}
|
package/src/version.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const VERSION = '2.
|
|
1
|
+
export const VERSION = '2.5.0';
|