@aws-amplify/ui-react-native 1.2.20 → 1.2.22

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 (113) hide show
  1. package/CHANGELOG.md +57 -0
  2. package/dist/Authenticator/Authenticator.d.ts +101 -148
  3. package/dist/Authenticator/Authenticator.js +2 -3
  4. package/dist/Authenticator/Defaults/ConfirmResetPassword/ConfirmResetPassword.d.ts +13 -2
  5. package/dist/Authenticator/Defaults/ConfirmResetPassword/ConfirmResetPassword.js +4 -3
  6. package/dist/Authenticator/Defaults/ConfirmSignIn/ConfirmSignIn.d.ts +13 -2
  7. package/dist/Authenticator/Defaults/ConfirmSignIn/ConfirmSignIn.js +4 -3
  8. package/dist/Authenticator/Defaults/ConfirmSignUp/ConfirmSignUp.d.ts +13 -2
  9. package/dist/Authenticator/Defaults/ConfirmSignUp/ConfirmSignUp.js +4 -3
  10. package/dist/Authenticator/Defaults/ConfirmVerifyUser/ConfirmVerifyUser.d.ts +13 -2
  11. package/dist/Authenticator/Defaults/ConfirmVerifyUser/ConfirmVerifyUser.js +4 -3
  12. package/dist/Authenticator/Defaults/ForceNewPassword/ForceNewPassword.d.ts +13 -2
  13. package/dist/Authenticator/Defaults/ForceNewPassword/ForceNewPassword.js +4 -3
  14. package/dist/Authenticator/Defaults/ResetPassword/ResetPassword.d.ts +13 -2
  15. package/dist/Authenticator/Defaults/ResetPassword/ResetPassword.js +4 -3
  16. package/dist/Authenticator/Defaults/SetupTOTP/SetupTOTP.d.ts +13 -2
  17. package/dist/Authenticator/Defaults/SetupTOTP/SetupTOTP.js +4 -3
  18. package/dist/Authenticator/Defaults/SignIn/SignIn.d.ts +13 -2
  19. package/dist/Authenticator/Defaults/SignIn/SignIn.js +4 -3
  20. package/dist/Authenticator/Defaults/SignUp/SignUp.d.ts +13 -2
  21. package/dist/Authenticator/Defaults/SignUp/SignUp.js +4 -3
  22. package/dist/Authenticator/Defaults/VerifyUser/VerifyUser.d.ts +13 -2
  23. package/dist/Authenticator/Defaults/VerifyUser/VerifyUser.js +4 -3
  24. package/dist/Authenticator/Defaults/types.d.ts +21 -20
  25. package/dist/Authenticator/common/DefaultContent/styles.js +1 -2
  26. package/dist/Authenticator/common/DefaultContent/types.d.ts +1 -1
  27. package/dist/Authenticator/common/DefaultFormFields/DefaultRadioFormFields.d.ts +7 -3
  28. package/dist/Authenticator/common/DefaultFormFields/DefaultRadioFormFields.js +4 -3
  29. package/dist/Authenticator/common/DefaultFormFields/DefaultTextFormFields.d.ts +6 -2
  30. package/dist/Authenticator/common/DefaultFormFields/DefaultTextFormFields.js +3 -3
  31. package/dist/Authenticator/common/DefaultFormFields/types.d.ts +12 -3
  32. package/dist/Authenticator/hooks/types.d.ts +3 -2
  33. package/dist/Authenticator/hooks/useFieldValues/types.d.ts +4 -1
  34. package/dist/Authenticator/hooks/useFieldValues/useFieldValues.d.ts +1 -1
  35. package/dist/Authenticator/hooks/useFieldValues/useFieldValues.js +21 -3
  36. package/dist/Authenticator/hooks/useFieldValues/utils.d.ts +10 -1
  37. package/dist/Authenticator/hooks/useFieldValues/utils.js +32 -2
  38. package/dist/primitives/Heading/styles.js +5 -5
  39. package/dist/primitives/Label/styles.js +2 -2
  40. package/dist/primitives/TextField/TextField.js +2 -1
  41. package/dist/primitives/TextField/styles.js +6 -3
  42. package/dist/primitives/TextField/types.d.ts +1 -0
  43. package/dist/theme/createTheme.js +24 -18
  44. package/dist/theme/types.d.ts +1 -1
  45. package/dist/version.d.ts +1 -1
  46. package/dist/version.js +1 -1
  47. package/jest.config.js +1 -0
  48. package/package.json +5 -5
  49. package/src/Authenticator/Authenticator.tsx +2 -6
  50. package/src/Authenticator/Defaults/ConfirmResetPassword/ConfirmResetPassword.tsx +7 -3
  51. package/src/Authenticator/Defaults/ConfirmResetPassword/__tests__/__snapshots__/ConfirmResetPassword.spec.tsx.snap +34 -30
  52. package/src/Authenticator/Defaults/ConfirmSignIn/ConfirmSignIn.tsx +7 -3
  53. package/src/Authenticator/Defaults/ConfirmSignIn/__tests__/ConfirmSignIn.spec.tsx +1 -0
  54. package/src/Authenticator/Defaults/ConfirmSignIn/__tests__/__snapshots__/ConfirmSignIn.spec.tsx.snap +14 -14
  55. package/src/Authenticator/Defaults/ConfirmSignUp/ConfirmSignUp.tsx +7 -3
  56. package/src/Authenticator/Defaults/ConfirmSignUp/__tests__/ConfirmSignUp.spec.tsx +1 -0
  57. package/src/Authenticator/Defaults/ConfirmSignUp/__tests__/__snapshots__/ConfirmSignUp.spec.tsx.snap +12 -15
  58. package/src/Authenticator/Defaults/ConfirmVerifyUser/ConfirmVerifyUser.tsx +7 -3
  59. package/src/Authenticator/Defaults/ConfirmVerifyUser/__tests__/ConfirmVerifyUser.spec.tsx +1 -0
  60. package/src/Authenticator/Defaults/ConfirmVerifyUser/__tests__/__snapshots__/ConfirmVerifyUser.spec.tsx.snap +6 -9
  61. package/src/Authenticator/Defaults/ForceNewPassword/ForceNewPassword.tsx +7 -3
  62. package/src/Authenticator/Defaults/ForceNewPassword/__tests__/__snapshots__/ForceNewPassword.spec.tsx.snap +13 -10
  63. package/src/Authenticator/Defaults/ResetPassword/ResetPassword.tsx +7 -3
  64. package/src/Authenticator/Defaults/ResetPassword/__tests__/ResetPassword.spec.tsx +1 -0
  65. package/src/Authenticator/Defaults/ResetPassword/__tests__/__snapshots__/ResetPassword.spec.tsx.snap +14 -14
  66. package/src/Authenticator/Defaults/SetupTOTP/SetupTOTP.tsx +7 -3
  67. package/src/Authenticator/Defaults/SetupTOTP/__tests__/SetupTOTP.spec.tsx +1 -0
  68. package/src/Authenticator/Defaults/SetupTOTP/__tests__/__snapshots__/SetupTOTP.spec.tsx.snap +22 -22
  69. package/src/Authenticator/Defaults/SignIn/SignIn.tsx +7 -3
  70. package/src/Authenticator/Defaults/SignIn/__tests__/SignIn.spec.tsx +1 -0
  71. package/src/Authenticator/Defaults/SignIn/__tests__/__snapshots__/SignIn.spec.tsx.snap +36 -33
  72. package/src/Authenticator/Defaults/SignUp/SignUp.tsx +7 -3
  73. package/src/Authenticator/Defaults/SignUp/__tests__/__snapshots__/SignUp.spec.tsx.snap +111 -96
  74. package/src/Authenticator/Defaults/VerifyUser/VerifyUser.tsx +7 -3
  75. package/src/Authenticator/Defaults/VerifyUser/__tests__/VerifyUser.spec.tsx +1 -0
  76. package/src/Authenticator/Defaults/VerifyUser/__tests__/__snapshots__/VerifyUser.spec.tsx.snap +16 -18
  77. package/src/Authenticator/Defaults/types.ts +63 -49
  78. package/src/Authenticator/__tests__/Authenticator.spec.tsx +16 -19
  79. package/src/Authenticator/__tests__/__snapshots__/Authenticator.spec.tsx.snap +1 -9
  80. package/src/Authenticator/__tests__/withAuthenticator.spec.tsx +1 -1
  81. package/src/Authenticator/common/DefaultContent/styles.ts +1 -2
  82. package/src/Authenticator/common/DefaultContent/types.ts +1 -4
  83. package/src/Authenticator/common/DefaultFormFields/DefaultRadioFormFields.tsx +8 -6
  84. package/src/Authenticator/common/DefaultFormFields/DefaultTextFormFields.tsx +10 -7
  85. package/src/Authenticator/common/DefaultFormFields/types.ts +15 -5
  86. package/src/Authenticator/common/DefaultHeader/__tests__/__snapshots__/DefaultHeader.spec.tsx.snap +1 -1
  87. package/src/Authenticator/common/FederatedProviderButton/__tests__/__snapshots__/FederatedProviderButton.spec.tsx.snap +4 -4
  88. package/src/Authenticator/common/FederatedProviderButtons/__tests__/__snapshots__/FederatedProviderButtons.spec.tsx.snap +4 -4
  89. package/src/Authenticator/hooks/types.ts +3 -0
  90. package/src/Authenticator/hooks/useFieldValues/__tests__/useFieldValues.spec.ts +75 -2
  91. package/src/Authenticator/hooks/useFieldValues/__tests__/utils.spec.ts +67 -1
  92. package/src/Authenticator/hooks/useFieldValues/types.ts +5 -0
  93. package/src/Authenticator/hooks/useFieldValues/useFieldValues.ts +26 -1
  94. package/src/Authenticator/hooks/useFieldValues/utils.ts +44 -1
  95. package/src/primitives/Checkbox/__tests__/__snapshots__/Checkbox.spec.tsx.snap +14 -14
  96. package/src/primitives/Divider/__tests__/__snapshots__/Divider.spec.tsx.snap +4 -4
  97. package/src/primitives/Heading/__tests__/__snapshots__/Heading.spec.tsx.snap +7 -7
  98. package/src/primitives/Heading/styles.ts +5 -5
  99. package/src/primitives/Label/__tests__/__snapshots__/Label.spec.tsx.snap +8 -8
  100. package/src/primitives/Label/styles.ts +2 -2
  101. package/src/primitives/PasswordField/__tests__/__snapshots__/PasswordField.spec.tsx.snap +25 -20
  102. package/src/primitives/PhoneNumberField/__tests__/__snapshots__/PhoneNumberField.spec.tsx.snap +6 -0
  103. package/src/primitives/Radio/__tests__/__snapshots__/Radio.spec.tsx.snap +14 -14
  104. package/src/primitives/RadioGroup/__tests__/__snapshots__/RadioGroup.spec.tsx.snap +48 -48
  105. package/src/primitives/TextField/TextField.tsx +2 -1
  106. package/src/primitives/TextField/__tests__/TextField.spec.tsx +57 -8
  107. package/src/primitives/TextField/__tests__/__snapshots__/TextField.spec.tsx.snap +61 -55
  108. package/src/primitives/TextField/styles.ts +6 -3
  109. package/src/primitives/TextField/types.ts +1 -0
  110. package/src/theme/__tests__/createTheme.spec.ts +48 -0
  111. package/src/theme/createTheme.ts +44 -21
  112. package/src/theme/types.ts +17 -16
  113. package/src/version.ts +1 -1
@@ -4,13 +4,14 @@ import { DefaultContent, DefaultFooter, DefaultTextFormFields, DefaultHeader, }
4
4
  import { useFieldValues } from '../../hooks';
5
5
  const COMPONENT_NAME = 'ResetPassword';
6
6
  const { getResetYourPasswordText, getSendCodeText, getSendingText, getBackToSignInText, } = authenticatorTextUtil;
7
- const ResetPassword = ({ fields, handleBlur, handleChange, handleSubmit, isPending, toSignIn, ...rest }) => {
8
- const { disableFormSubmit: disabled, fields: fieldsWithHandlers, handleFormSubmit, } = useFieldValues({
7
+ const ResetPassword = ({ fields, handleBlur, handleChange, handleSubmit, isPending, toSignIn, validationErrors, ...rest }) => {
8
+ const { disableFormSubmit: disabled, fields: fieldsWithHandlers, fieldValidationErrors, handleFormSubmit, } = useFieldValues({
9
9
  componentName: COMPONENT_NAME,
10
10
  fields,
11
11
  handleBlur,
12
12
  handleChange,
13
13
  handleSubmit,
14
+ validationErrors,
14
15
  });
15
16
  const headerText = getResetYourPasswordText();
16
17
  const primaryButtonText = isPending ? getSendingText() : getSendCodeText();
@@ -29,7 +30,7 @@ const ResetPassword = ({ fields, handleBlur, handleChange, handleSubmit, isPendi
29
30
  secondaryButtonText,
30
31
  toSignIn,
31
32
  ]);
32
- return (<DefaultContent {...rest} buttons={buttons} headerText={headerText} fields={fieldsWithHandlers} isPending={isPending}/>);
33
+ return (<DefaultContent {...rest} buttons={buttons} headerText={headerText} fields={fieldsWithHandlers} isPending={isPending} validationErrors={fieldValidationErrors}/>);
33
34
  };
34
35
  ResetPassword.Footer = DefaultFooter;
35
36
  ResetPassword.FormFields = DefaultTextFormFields;
@@ -1,3 +1,14 @@
1
- import { DefaultSetupTOTPComponent } from '../types';
2
- declare const SetupTOTP: DefaultSetupTOTPComponent;
1
+ /// <reference types="react" />
2
+ import { DefaultFooter, DefaultHeader } from '../../common';
3
+ import { DefaultSetupTOTPProps } from '../types';
4
+ declare const SetupTOTP: {
5
+ ({ fields, handleBlur, handleChange, handleSubmit, isPending, toSignIn, totpSecretCode, validationErrors, ...rest }: DefaultSetupTOTPProps): JSX.Element;
6
+ Footer: typeof DefaultFooter;
7
+ FormFields: {
8
+ ({ fieldContainerStyle, fieldErrorsContainer, fieldErrorStyle, fieldStyle, fields, isPending, style, validationErrors, }: import("../../common/DefaultFormFields/types").DefaultTextFormFieldsProps): JSX.Element;
9
+ displayName: string;
10
+ };
11
+ Header: typeof DefaultHeader;
12
+ displayName: string;
13
+ };
3
14
  export default SetupTOTP;
@@ -6,13 +6,14 @@ import { useFieldValues } from '../../hooks';
6
6
  import { styles } from './styles';
7
7
  const COMPONENT_NAME = 'SetupTOTP';
8
8
  const { getBackToSignInText, getConfirmingText, getConfirmText, getSetupTOTPText, getSetupTOTPInstructionsText, } = authenticatorTextUtil;
9
- const SetupTOTP = ({ fields, handleBlur, handleChange, handleSubmit, isPending, toSignIn, totpSecretCode, ...rest }) => {
10
- const { disableFormSubmit: disabled, fields: fieldsWithHandlers, handleFormSubmit, } = useFieldValues({
9
+ const SetupTOTP = ({ fields, handleBlur, handleChange, handleSubmit, isPending, toSignIn, totpSecretCode, validationErrors, ...rest }) => {
10
+ const { disableFormSubmit: disabled, fields: fieldsWithHandlers, fieldValidationErrors, handleFormSubmit, } = useFieldValues({
11
11
  componentName: COMPONENT_NAME,
12
12
  fields,
13
13
  handleBlur,
14
14
  handleChange,
15
15
  handleSubmit,
16
+ validationErrors,
16
17
  });
17
18
  const headerText = getSetupTOTPText();
18
19
  const primaryButtonText = isPending ? getConfirmingText() : getConfirmText();
@@ -39,7 +40,7 @@ const SetupTOTP = ({ fields, handleBlur, handleChange, handleSubmit, isPending,
39
40
  secondaryButtonText,
40
41
  toSignIn,
41
42
  ]);
42
- return (<DefaultContent {...rest} body={body} buttons={buttons} headerText={headerText} fields={fieldsWithHandlers} isPending={isPending}/>);
43
+ return (<DefaultContent {...rest} body={body} buttons={buttons} headerText={headerText} fields={fieldsWithHandlers} isPending={isPending} validationErrors={fieldValidationErrors}/>);
43
44
  };
44
45
  SetupTOTP.Footer = DefaultFooter;
45
46
  SetupTOTP.FormFields = DefaultTextFormFields;
@@ -1,3 +1,14 @@
1
- import { DefaultSignInComponent } from '../types';
2
- declare const SignIn: DefaultSignInComponent;
1
+ /// <reference types="react" />
2
+ import { DefaultFooter, DefaultHeader } from '../../common';
3
+ import { DefaultSignInProps } from '../types';
4
+ declare const SignIn: {
5
+ ({ fields, handleBlur, handleChange, handleSubmit, hideSignUp, toResetPassword, toSignUp, validationErrors, ...rest }: DefaultSignInProps): JSX.Element;
6
+ Footer: typeof DefaultFooter;
7
+ FormFields: {
8
+ ({ fieldContainerStyle, fieldErrorsContainer, fieldErrorStyle, fieldStyle, fields, isPending, style, validationErrors, }: import("../../common/DefaultFormFields/types").DefaultTextFormFieldsProps): JSX.Element;
9
+ displayName: string;
10
+ };
11
+ Header: typeof DefaultHeader;
12
+ displayName: string;
13
+ };
3
14
  export default SignIn;
@@ -3,14 +3,15 @@ import { authenticatorTextUtil } from '@aws-amplify/ui';
3
3
  import { DefaultFooter, DefaultTextFormFields, DefaultHeader, DefaultContent, } from '../../common';
4
4
  import { useFieldValues } from '../../hooks';
5
5
  const COMPONENT_NAME = 'SignIn';
6
- const SignIn = ({ fields, handleBlur, handleChange, handleSubmit, hideSignUp, toResetPassword, toSignUp, ...rest }) => {
6
+ const SignIn = ({ fields, handleBlur, handleChange, handleSubmit, hideSignUp, toResetPassword, toSignUp, validationErrors, ...rest }) => {
7
7
  const { getSignInTabText, getSignInText, getSignUpTabText, getForgotPasswordText, } = authenticatorTextUtil;
8
- const { disableFormSubmit: disabled, fields: fieldsWithHandlers, handleFormSubmit, } = useFieldValues({
8
+ const { disableFormSubmit: disabled, fields: fieldsWithHandlers, fieldValidationErrors, handleFormSubmit, } = useFieldValues({
9
9
  componentName: COMPONENT_NAME,
10
10
  fields,
11
11
  handleBlur,
12
12
  handleChange,
13
13
  handleSubmit,
14
+ validationErrors,
14
15
  });
15
16
  const headerText = getSignInTabText();
16
17
  const forgotPasswordText = getForgotPasswordText(true);
@@ -37,7 +38,7 @@ const SignIn = ({ fields, handleBlur, handleChange, handleSubmit, hideSignUp, to
37
38
  toResetPassword,
38
39
  toSignUp,
39
40
  ]);
40
- return (<DefaultContent {...rest} buttons={buttons} fields={fieldsWithHandlers} headerText={headerText}/>);
41
+ return (<DefaultContent {...rest} buttons={buttons} fields={fieldsWithHandlers} headerText={headerText} validationErrors={fieldValidationErrors}/>);
41
42
  };
42
43
  SignIn.Footer = DefaultFooter;
43
44
  SignIn.FormFields = DefaultTextFormFields;
@@ -1,3 +1,14 @@
1
- import { DefaultSignUpComponent } from '../types';
2
- declare const SignUp: DefaultSignUpComponent;
1
+ /// <reference types="react" />
2
+ import { DefaultFooter, DefaultHeader } from '../../common';
3
+ import { DefaultSignUpProps } from '../types';
4
+ declare const SignUp: {
5
+ ({ fields, handleBlur, handleChange, handleSubmit, hasValidationErrors, hideSignIn, isPending, toSignIn, validationErrors, ...rest }: DefaultSignUpProps): JSX.Element;
6
+ Footer: typeof DefaultFooter;
7
+ FormFields: {
8
+ ({ fieldContainerStyle, fieldErrorsContainer, fieldErrorStyle, fieldStyle, fields, isPending, style, validationErrors, }: import("../../common/DefaultFormFields/types").DefaultTextFormFieldsProps): JSX.Element;
9
+ displayName: string;
10
+ };
11
+ Header: typeof DefaultHeader;
12
+ displayName: string;
13
+ };
3
14
  export default SignUp;
@@ -4,13 +4,14 @@ import { DefaultContent, DefaultFooter, DefaultTextFormFields, DefaultHeader, }
4
4
  import { useFieldValues } from '../../hooks';
5
5
  const COMPONENT_NAME = 'SignUp';
6
6
  const { getCreateAccountText, getCreatingAccountText, getSignInTabText, getSignUpTabText, } = authenticatorTextUtil;
7
- const SignUp = ({ fields, handleBlur, handleChange, handleSubmit, hasValidationErrors, hideSignIn, isPending, toSignIn, ...rest }) => {
8
- const { disableFormSubmit, fields: fieldsWithHandlers, handleFormSubmit, } = useFieldValues({
7
+ const SignUp = ({ fields, handleBlur, handleChange, handleSubmit, hasValidationErrors, hideSignIn, isPending, toSignIn, validationErrors, ...rest }) => {
8
+ const { disableFormSubmit, fields: fieldsWithHandlers, fieldValidationErrors, handleFormSubmit, } = useFieldValues({
9
9
  componentName: COMPONENT_NAME,
10
10
  fields,
11
11
  handleBlur,
12
12
  handleChange,
13
13
  handleSubmit,
14
+ validationErrors,
14
15
  });
15
16
  const disabled = hasValidationErrors || disableFormSubmit;
16
17
  const headerText = getSignUpTabText();
@@ -35,7 +36,7 @@ const SignUp = ({ fields, handleBlur, handleChange, handleSubmit, hasValidationE
35
36
  secondaryButtonText,
36
37
  toSignIn,
37
38
  ]);
38
- return (<DefaultContent {...rest} buttons={buttons} fields={fieldsWithHandlers} headerText={headerText} isPending={isPending}/>);
39
+ return (<DefaultContent {...rest} buttons={buttons} fields={fieldsWithHandlers} headerText={headerText} isPending={isPending} validationErrors={fieldValidationErrors}/>);
39
40
  };
40
41
  SignUp.Footer = DefaultFooter;
41
42
  SignUp.FormFields = DefaultTextFormFields;
@@ -1,3 +1,14 @@
1
- import { DefaultVerifyUserComponent } from '../types';
2
- declare const VerifyUser: DefaultVerifyUserComponent;
1
+ /// <reference types="react" />
2
+ import { DefaultFooter, DefaultHeader } from '../../common';
3
+ import { DefaultVerifyUserProps } from '../types';
4
+ declare const VerifyUser: {
5
+ ({ fields, handleBlur, handleChange, handleSubmit, skipVerification, validationErrors, ...rest }: DefaultVerifyUserProps): JSX.Element;
6
+ Footer: typeof DefaultFooter;
7
+ FormFields: {
8
+ ({ fields, fieldContainerStyle, fieldLabelStyle, isPending, style, }: import("../../common/DefaultFormFields/types").DefaultRadioFormFieldsProps): JSX.Element;
9
+ displayName: string;
10
+ };
11
+ Header: typeof DefaultHeader;
12
+ displayName: string;
13
+ };
3
14
  export default VerifyUser;
@@ -4,13 +4,14 @@ import { DefaultContent, DefaultFooter, DefaultHeader, DefaultRadioFormFields, }
4
4
  import { useFieldValues } from '../../hooks';
5
5
  const COMPONENT_NAME = 'VerifyUser';
6
6
  const { getSkipText, getVerifyContactText, getVerifyText, getAccountRecoveryInfoText, } = authenticatorTextUtil;
7
- const VerifyUser = ({ fields, handleBlur, handleChange, handleSubmit, skipVerification, ...rest }) => {
8
- const { disableFormSubmit: disabled, fields: fieldsWithHandlers, handleFormSubmit, } = useFieldValues({
7
+ const VerifyUser = ({ fields, handleBlur, handleChange, handleSubmit, skipVerification, validationErrors, ...rest }) => {
8
+ const { disableFormSubmit: disabled, fields: fieldsWithHandlers, fieldValidationErrors, handleFormSubmit, } = useFieldValues({
9
9
  componentName: COMPONENT_NAME,
10
10
  fields,
11
11
  handleBlur,
12
12
  handleChange,
13
13
  handleSubmit,
14
+ validationErrors,
14
15
  });
15
16
  const headerText = getVerifyContactText();
16
17
  const skipText = getSkipText();
@@ -20,7 +21,7 @@ const VerifyUser = ({ fields, handleBlur, handleChange, handleSubmit, skipVerifi
20
21
  primary: { children: verifyText, disabled, onPress: handleFormSubmit },
21
22
  links: [{ children: skipText, onPress: skipVerification }],
22
23
  }), [disabled, handleFormSubmit, skipText, skipVerification, verifyText]);
23
- return (<DefaultContent {...rest} body={bodyText} buttons={buttons} fields={fieldsWithHandlers} headerText={headerText}/>);
24
+ return (<DefaultContent {...rest} body={bodyText} buttons={buttons} fields={fieldsWithHandlers} headerText={headerText} validationErrors={fieldValidationErrors}/>);
24
25
  };
25
26
  VerifyUser.Footer = DefaultFooter;
26
27
  VerifyUser.FormFields = DefaultRadioFormFields;
@@ -1,3 +1,4 @@
1
+ /// <reference types="react" />
1
2
  import { AuthenticatorComponentOverrides, AuthenticatorComponentDefaults } from '@aws-amplify/ui-react-core';
2
3
  import { RadioFieldOptions, TextFieldOptionsType } from '../hooks';
3
4
  export interface ConfirmResetPasswordStyle {
@@ -21,36 +22,36 @@ export interface SignUpStyle {
21
22
  export interface VerifyUserStyle {
22
23
  }
23
24
  export type DefaultComponents<FieldType = {}, Props = {}> = AuthenticatorComponentDefaults<FieldType, Props>;
24
- export type DefaultConfirmResetPasswordComponent = DefaultComponents<TextFieldOptionsType, {
25
+ export type DefaultConfirmResetPasswordProps = React.ComponentPropsWithoutRef<DefaultComponents<TextFieldOptionsType, {
25
26
  style?: ConfirmResetPasswordStyle;
26
- }>['ConfirmResetPassword'];
27
- export type DefaultConfirmSignInComponent = DefaultComponents<TextFieldOptionsType, {
27
+ }>['ConfirmResetPassword']>;
28
+ export type DefaultConfirmSignInProps = React.ComponentPropsWithoutRef<DefaultComponents<TextFieldOptionsType, {
28
29
  style?: ConfirmSignInStyle;
29
- }>['ConfirmSignIn'];
30
- export type DefaultConfirmSignUpComponent = DefaultComponents<TextFieldOptionsType, {
30
+ }>['ConfirmSignIn']>;
31
+ export type DefaultConfirmSignUpProps = React.ComponentPropsWithoutRef<DefaultComponents<TextFieldOptionsType, {
31
32
  style?: ConfirmSignUpStyle;
32
- }>['ConfirmSignUp'];
33
- export type DefaultConfirmVerifyUserComponent = DefaultComponents<TextFieldOptionsType, {
33
+ }>['ConfirmSignUp']>;
34
+ export type DefaultConfirmVerifyUserProps = React.ComponentPropsWithoutRef<DefaultComponents<TextFieldOptionsType, {
34
35
  style?: ConfirmVerifyUserStyle;
35
- }>['ConfirmVerifyUser'];
36
- export type DefaultForceNewPasswordComponent = DefaultComponents<TextFieldOptionsType, {
36
+ }>['ConfirmVerifyUser']>;
37
+ export type DefaultForceNewPasswordProps = React.ComponentPropsWithoutRef<DefaultComponents<TextFieldOptionsType, {
37
38
  style?: ForceNewPasswordStyle;
38
- }>['ForceNewPassword'];
39
- export type DefaultResetPasswordComponent = DefaultComponents<TextFieldOptionsType, {
39
+ }>['ForceNewPassword']>;
40
+ export type DefaultResetPasswordProps = React.ComponentPropsWithoutRef<DefaultComponents<TextFieldOptionsType, {
40
41
  style?: ResetPasswordStyle;
41
- }>['ResetPassword'];
42
- export type DefaultSetupTOTPComponent = DefaultComponents<TextFieldOptionsType, {
42
+ }>['ResetPassword']>;
43
+ export type DefaultSetupTOTPProps = React.ComponentPropsWithoutRef<DefaultComponents<TextFieldOptionsType, {
43
44
  style?: SetupTOTPStyle;
44
- }>['SetupTOTP'];
45
- export type DefaultSignInComponent = DefaultComponents<TextFieldOptionsType, {
45
+ }>['SetupTOTP']>;
46
+ export type DefaultSignInProps = React.ComponentPropsWithoutRef<DefaultComponents<TextFieldOptionsType, {
46
47
  style?: SignInStyle;
47
- }>['SignIn'];
48
- export type DefaultSignUpComponent = DefaultComponents<TextFieldOptionsType, {
48
+ }>['SignIn']>;
49
+ export type DefaultSignUpProps = React.ComponentPropsWithoutRef<DefaultComponents<TextFieldOptionsType, {
49
50
  style?: SignUpStyle;
50
- }>['SignUp'];
51
- export type DefaultVerifyUserComponent = DefaultComponents<RadioFieldOptions, {
51
+ }>['SignUp']>;
52
+ export type DefaultVerifyUserProps = React.ComponentPropsWithoutRef<DefaultComponents<RadioFieldOptions, {
52
53
  style?: VerifyUserStyle;
53
- }>['VerifyUser'];
54
+ }>['VerifyUser']>;
54
55
  /**
55
56
  * Custom Authenticator components
56
57
  */
@@ -5,8 +5,7 @@ export const getDefaultStyle = ({ tokens: { colors, fontSizes, space }, }) => St
5
5
  paddingHorizontal: space.small,
6
6
  },
7
7
  buttonPrimary: {
8
- marginHorizontal: space.medium,
9
- marginVertical: space.small,
8
+ margin: space.small,
10
9
  },
11
10
  buttonPrimaryLabel: {},
12
11
  buttonSecondary: {
@@ -36,7 +36,7 @@ type DefaultButtons = {
36
36
  secondary?: AuthenticatorButtonProps;
37
37
  links?: AuthenticatorButtonProps[];
38
38
  };
39
- export type DefaultContentProps<FieldsType extends TextFieldOptionsType | RadioFieldOptions | unknown = unknown> = Pick<DefaultComponentProps<FieldsType>, 'error' | 'Footer' | 'isPending'> & {
39
+ export type DefaultContentProps<FieldsType extends TextFieldOptionsType | RadioFieldOptions | unknown = unknown> = Pick<DefaultComponentProps<FieldsType>, 'error' | 'isPending'> & {
40
40
  buttons: DefaultButtons;
41
41
  body?: React.ReactNode;
42
42
  fields: FieldsType[];
@@ -1,3 +1,7 @@
1
- import { DefaultRadioFormFieldsComponent } from './types';
2
- declare const DefaultFormFields: DefaultRadioFormFieldsComponent;
3
- export default DefaultFormFields;
1
+ /// <reference types="react" />
2
+ import { DefaultRadioFormFieldsProps } from './types';
3
+ declare const DefaultRadioFormFields: {
4
+ ({ fields, fieldContainerStyle, fieldLabelStyle, isPending, style, }: DefaultRadioFormFieldsProps): JSX.Element;
5
+ displayName: string;
6
+ };
7
+ export default DefaultRadioFormFields;
@@ -13,12 +13,13 @@ const censorContactInformation = (name, value) => {
13
13
  }
14
14
  return censoredVal;
15
15
  };
16
- const DefaultFormFields = ({ fields, isPending, fieldContainerStyle, fieldLabelStyle, style, }) => {
16
+ const DefaultRadioFormFields = ({ fields, fieldContainerStyle, fieldLabelStyle, isPending, style, }) => {
17
17
  return (<RadioGroup disabled={isPending} style={style}>
18
- {fields.map(({ name, value, ...props }) => (<Radio {...props} key={value}
18
+ {(fields ?? []).map(({ name, value, ...props }) => (<Radio {...props} key={value}
19
19
  // value has to be name, because Auth is only interested in the
20
20
  // string "email" or "phone_number", not the actual value
21
21
  value={name} label={censorContactInformation(name, value)} labelStyle={fieldLabelStyle} style={fieldContainerStyle}/>))}
22
22
  </RadioGroup>);
23
23
  };
24
- export default DefaultFormFields;
24
+ DefaultRadioFormFields.displayName = 'FormFields';
25
+ export default DefaultRadioFormFields;
@@ -1,3 +1,7 @@
1
- import { DefaultTextFormFieldsComponent } from './types';
2
- declare const DefaultTextFormFields: DefaultTextFormFieldsComponent;
1
+ /// <reference types="react" />
2
+ import { DefaultTextFormFieldsProps } from './types';
3
+ declare const DefaultTextFormFields: {
4
+ ({ fieldContainerStyle, fieldErrorsContainer, fieldErrorStyle, fieldStyle, fields, isPending, style, validationErrors, }: DefaultTextFormFieldsProps): JSX.Element;
5
+ displayName: string;
6
+ };
3
7
  export default DefaultTextFormFields;
@@ -3,8 +3,8 @@ import { View } from 'react-native';
3
3
  import { getErrors } from '@aws-amplify/ui';
4
4
  import Field from './Field';
5
5
  import { FieldErrors } from './FieldErrors';
6
- const DefaultTextFormFields = ({ fieldContainerStyle, fieldErrorsContainer, fieldErrorStyle, fieldStyle, fields = [], isPending, style, validationErrors, }) => {
7
- const formFields = fields.map(({ name, type, ...field }) => {
6
+ const DefaultTextFormFields = ({ fieldContainerStyle, fieldErrorsContainer, fieldErrorStyle, fieldStyle, fields, isPending = false, style, validationErrors, }) => {
7
+ const formFields = (fields ?? []).map(({ name, type, ...field }) => {
8
8
  const errors = validationErrors ? getErrors(validationErrors?.[name]) : [];
9
9
  const hasError = errors?.length > 0;
10
10
  return (<Fragment key={name}>
@@ -14,5 +14,5 @@ const DefaultTextFormFields = ({ fieldContainerStyle, fieldErrorsContainer, fiel
14
14
  });
15
15
  return <View style={style}>{formFields}</View>;
16
16
  };
17
- DefaultTextFormFields.displayName = 'DefaultTextFormFields';
17
+ DefaultTextFormFields.displayName = 'FormFields';
18
18
  export default DefaultTextFormFields;
@@ -1,5 +1,5 @@
1
1
  import { StyleProp, TextStyle, ViewStyle } from 'react-native';
2
- import { AuthenticatorFormFieldsComponent } from '@aws-amplify/ui-react-core';
2
+ import { AuthenticatorFormFieldsComponent, UseAuthenticator } from '@aws-amplify/ui-react-core';
3
3
  import { RadioFieldOptions, TextFieldOptionsType } from '../../hooks';
4
4
  export type FieldProps = Omit<TextFieldOptionsType, 'name'> & {
5
5
  disabled: boolean;
@@ -18,5 +18,14 @@ export interface DefaultFormFieldsStyle {
18
18
  style?: StyleProp<ViewStyle>;
19
19
  }
20
20
  export type DefaultFormFieldsComponent<FieldsType> = AuthenticatorFormFieldsComponent<FieldsType, DefaultFormFieldsStyle>;
21
- export type DefaultTextFormFieldsComponent = DefaultFormFieldsComponent<TextFieldOptionsType>;
22
- export type DefaultRadioFormFieldsComponent = DefaultFormFieldsComponent<RadioFieldOptions>;
21
+ interface FormFieldsProps extends DefaultFormFieldsStyle {
22
+ isPending?: UseAuthenticator['isPending'];
23
+ validationErrors?: UseAuthenticator['validationErrors'];
24
+ }
25
+ export interface DefaultTextFormFieldsProps extends FormFieldsProps {
26
+ fields?: TextFieldOptionsType[];
27
+ }
28
+ export interface DefaultRadioFormFieldsProps extends FormFieldsProps {
29
+ fields?: RadioFieldOptions[];
30
+ }
31
+ export {};
@@ -1,6 +1,6 @@
1
1
  import { TextFieldProps, PasswordFieldProps, PhoneNumberFieldProps, RadioProps } from '../../primitives';
2
2
  export type MachineFieldTypeKey = 'password' | 'tel';
3
- export type AuthenticatorFieldTypeKey = 'password' | 'phone' | 'default' | 'radio';
3
+ export type AuthenticatorFieldTypeKey = 'email' | 'password' | 'phone' | 'default' | 'radio';
4
4
  type RadioFieldOnBlur = RadioProps<string>['onBlur'];
5
5
  export type TextFieldOnBlur = TextFieldProps['onBlur'];
6
6
  export type OnChangeText = TextFieldProps['onChangeText'];
@@ -10,10 +10,11 @@ type FieldOptions<FieldProps, Type extends AuthenticatorFieldTypeKey> = {
10
10
  required?: boolean;
11
11
  type: Type;
12
12
  } & Omit<FieldProps, 'disabled' | 'onBlur'>;
13
+ type EmailFieldOptions = FieldOptions<PhoneNumberFieldProps, 'email'>;
13
14
  type PasswordFieldOptions = FieldOptions<PasswordFieldProps, 'password'>;
14
15
  type PhoneFieldOptions = FieldOptions<PhoneNumberFieldProps, 'phone'>;
15
16
  type DefaultFieldOptions = FieldOptions<TextFieldProps, 'default'>;
16
- export type TextFieldOptionsType = (PasswordFieldOptions | PhoneFieldOptions | DefaultFieldOptions) & {
17
+ export type TextFieldOptionsType = (EmailFieldOptions | PasswordFieldOptions | PhoneFieldOptions | DefaultFieldOptions) & {
17
18
  labelHidden?: boolean;
18
19
  };
19
20
  export type RadioFieldOptions = FieldOptions<RadioProps<string>, 'radio'>;
@@ -1,4 +1,5 @@
1
- import { AuthenticatorComponentDefaultProps, AuthenticatorRouteComponentName } from '@aws-amplify/ui-react-core';
1
+ import { AuthenticatorComponentDefaultProps, AuthenticatorRouteComponentName, AuthenticatorMachineContext } from '@aws-amplify/ui-react-core';
2
+ import { ValidationError } from '@aws-amplify/ui';
2
3
  import { TypedField } from '../types';
3
4
  export type MachineEventHandlers = Pick<AuthenticatorComponentDefaultProps[AuthenticatorRouteComponentName], 'handleBlur' | 'handleChange' | 'handleSubmit'>;
4
5
  export interface UseFieldValuesParams<FieldType extends TypedField> {
@@ -16,9 +17,11 @@ export interface UseFieldValuesParams<FieldType extends TypedField> {
16
17
  * machine "SUBMIT"" event handler, validates `field` value against machine validation rules
17
18
  */
18
19
  handleSubmit: MachineEventHandlers['handleSubmit'];
20
+ validationErrors?: AuthenticatorMachineContext['validationErrors'];
19
21
  }
20
22
  export interface UseFieldValues<FieldType extends TypedField> {
21
23
  fields: FieldType[];
24
+ fieldValidationErrors: ValidationError | undefined;
22
25
  disableFormSubmit: boolean;
23
26
  handleFormSubmit: () => void;
24
27
  }
@@ -1,3 +1,3 @@
1
1
  import { TypedField } from '../types';
2
2
  import { UseFieldValues, UseFieldValuesParams } from './types';
3
- export default function useFieldValues<FieldType extends TypedField>({ componentName, fields, handleBlur, handleChange, handleSubmit, }: UseFieldValuesParams<FieldType>): UseFieldValues<FieldType>;
3
+ export default function useFieldValues<FieldType extends TypedField>({ componentName, fields, handleBlur, handleChange, handleSubmit, validationErrors, }: UseFieldValuesParams<FieldType>): UseFieldValues<FieldType>;
@@ -1,9 +1,11 @@
1
1
  import { useMemo, useState } from 'react';
2
2
  import { Logger } from 'aws-amplify';
3
- import { getSanitizedTextFields, getSanitizedRadioFields, isRadioFieldOptions, } from './utils';
3
+ import { getSanitizedTextFields, getSanitizedRadioFields, isRadioFieldOptions, runFieldValidation, } from './utils';
4
4
  const logger = new Logger('Authenticator');
5
- export default function useFieldValues({ componentName, fields = [], handleBlur, handleChange, handleSubmit, }) {
5
+ export default function useFieldValues({ componentName, fields = [], handleBlur, handleChange, handleSubmit, validationErrors, }) {
6
6
  const [values, setValues] = useState({});
7
+ const [touched, setTouched] = useState({});
8
+ const [fieldValidationErrors, setFieldValidationErrors] = useState({});
7
9
  const isRadioFieldComponent = componentName === 'VerifyUser';
8
10
  const sanitizedFields = useMemo(() => {
9
11
  if (!Array.isArray(fields)) {
@@ -27,16 +29,27 @@ export default function useFieldValues({ componentName, fields = [], handleBlur,
27
29
  }
28
30
  const { name, label, labelHidden, ...rest } = field;
29
31
  const onBlur = (event) => {
32
+ setTouched({ ...touched, [name]: true });
30
33
  // call `onBlur` passed as text `field` option
31
34
  field.onBlur?.(event);
32
35
  // call machine blur handler
33
36
  handleBlur({ name, value: values[name] });
37
+ setFieldValidationErrors({
38
+ ...fieldValidationErrors,
39
+ [name]: runFieldValidation(field, values[name], validationErrors),
40
+ });
34
41
  };
35
42
  const onChangeText = (value) => {
36
43
  // call `onChangeText` passed as text `field` option
37
44
  field.onChangeText?.(value);
38
45
  // call machine change handler
39
46
  handleChange({ name, value });
47
+ if (touched[name]) {
48
+ setFieldValidationErrors({
49
+ ...fieldValidationErrors,
50
+ [name]: runFieldValidation(field, value, validationErrors),
51
+ });
52
+ }
40
53
  setValues({ ...values, [name]: value });
41
54
  };
42
55
  return {
@@ -76,5 +89,10 @@ export default function useFieldValues({ componentName, fields = [], handleBlur,
76
89
  }, {});
77
90
  handleSubmit?.(submitValue);
78
91
  };
79
- return { fields: fieldsWithHandlers, disableFormSubmit, handleFormSubmit };
92
+ return {
93
+ fields: fieldsWithHandlers,
94
+ disableFormSubmit,
95
+ fieldValidationErrors: { ...fieldValidationErrors, ...validationErrors },
96
+ handleFormSubmit,
97
+ };
80
98
  }
@@ -1,5 +1,6 @@
1
+ import { ValidationError } from '@aws-amplify/ui';
1
2
  import { AuthenticatorLegacyField, AuthenticatorRouteComponentName, UseAuthenticator } from '@aws-amplify/ui-react-core';
2
- import { RadioFieldOptions, TypedField } from '../types';
3
+ import { RadioFieldOptions, TextFieldOptionsType, TypedField } from '../types';
3
4
  export declare const isRadioFieldOptions: (field: TypedField) => field is RadioFieldOptions;
4
5
  export declare const getSanitizedRadioFields: (fields: TypedField[], componentName: AuthenticatorRouteComponentName) => TypedField[];
5
6
  export declare const getSanitizedTextFields: (fields: TypedField[], componentName: AuthenticatorRouteComponentName) => TypedField[];
@@ -16,3 +17,11 @@ export declare const getTypedField: ({ type: machineFieldType, name, ...field }:
16
17
  */
17
18
  export declare const getTypedFields: (fields: AuthenticatorLegacyField[]) => TypedField[];
18
19
  export declare function getRouteTypedFields({ fields, route, }: Pick<UseAuthenticator, 'fields' | 'route'>): TypedField[];
20
+ /**
21
+ *
22
+ * @param {TextFieldOptionsType} field text field type
23
+ * @param {string | undefined} value text field value
24
+ * @param {string[]} stateValidations validation errors array from state machine
25
+ * @returns {string[]} field errors array
26
+ */
27
+ export declare const runFieldValidation: (field: TextFieldOptionsType, value: string | undefined, stateValidations: ValidationError | undefined) => string[];
@@ -1,8 +1,9 @@
1
1
  import { Logger } from 'aws-amplify';
2
- import { isUnverifiedContactMethodType, UnverifiedContactMethodType, } from '@aws-amplify/ui';
2
+ import { authenticatorTextUtil, isString, isUnverifiedContactMethodType, isValidEmail, UnverifiedContactMethodType, } from '@aws-amplify/ui';
3
3
  import { isAuthenticatorComponentRouteKey, } from '@aws-amplify/ui-react-core';
4
4
  import { KEY_ALLOW_LIST } from './constants';
5
5
  const logger = new Logger('Authenticator');
6
+ const { getInvalidEmailText, getRequiredFieldText } = authenticatorTextUtil;
6
7
  export const isRadioFieldOptions = (field) => field?.type === 'radio';
7
8
  export const getSanitizedRadioFields = (fields, componentName) => {
8
9
  const values = {};
@@ -51,7 +52,7 @@ export const getSanitizedTextFields = (fields, componentName) => {
51
52
  };
52
53
  // typed fields utils
53
54
  const isKeyAllowed = (key) => KEY_ALLOW_LIST.some((allowedKey) => allowedKey === key);
54
- const isValidMachineFieldType = (type) => type === 'password' || type === 'tel';
55
+ const isValidMachineFieldType = (type) => type === 'password' || type === 'tel' || type == 'email';
55
56
  const getFieldType = (type) => {
56
57
  if (isValidMachineFieldType(type)) {
57
58
  return type === 'tel' ? 'phone' : type;
@@ -97,3 +98,32 @@ export function getRouteTypedFields({ fields, route, }) {
97
98
  const radioFields = fields;
98
99
  return isVerifyUserRoute ? radioFields : getTypedFields(fields);
99
100
  }
101
+ /**
102
+ *
103
+ * @param {TextFieldOptionsType} field text field type
104
+ * @param {string | undefined} value text field value
105
+ * @param {string[]} stateValidations validation errors array from state machine
106
+ * @returns {string[]} field errors array
107
+ */
108
+ export const runFieldValidation = (field, value, stateValidations) => {
109
+ const fieldErrors = [];
110
+ if (field.required && !value) {
111
+ fieldErrors.push(getRequiredFieldText());
112
+ }
113
+ if (field.type === 'email') {
114
+ if (!isValidEmail(value)) {
115
+ fieldErrors.push(getInvalidEmailText());
116
+ }
117
+ }
118
+ // add state machine validation errors, if any
119
+ const stateFieldValidation = stateValidations?.[field.name];
120
+ if (stateFieldValidation) {
121
+ if (isString(stateFieldValidation)) {
122
+ fieldErrors.push(stateFieldValidation);
123
+ }
124
+ else {
125
+ return fieldErrors.concat(stateFieldValidation);
126
+ }
127
+ }
128
+ return fieldErrors;
129
+ };
@@ -9,19 +9,19 @@ export const getThemedStyles = (theme) => {
9
9
  },
10
10
  1: {
11
11
  fontSize: fontSizes.xxxl,
12
- fontWeight: fontWeights.hairline,
12
+ fontWeight: fontWeights.light,
13
13
  lineHeight: getLineHeight(fontSizes.xxxl),
14
14
  ...components?.heading?.[1],
15
15
  },
16
16
  2: {
17
17
  fontSize: fontSizes.xxl,
18
- fontWeight: fontWeights.thin,
18
+ fontWeight: fontWeights.normal,
19
19
  lineHeight: getLineHeight(fontSizes.xxl),
20
20
  ...components?.heading?.[2],
21
21
  },
22
22
  3: {
23
23
  fontSize: fontSizes.xl,
24
- fontWeight: fontWeights.light,
24
+ fontWeight: fontWeights.medium,
25
25
  lineHeight: getLineHeight(fontSizes.xl),
26
26
  ...components?.heading?.[3],
27
27
  },
@@ -33,13 +33,13 @@ export const getThemedStyles = (theme) => {
33
33
  },
34
34
  5: {
35
35
  fontSize: fontSizes.medium,
36
- fontWeight: fontWeights.bold,
36
+ fontWeight: fontWeights.semibold,
37
37
  lineHeight: getLineHeight(fontSizes.medium),
38
38
  ...components?.heading?.[5],
39
39
  },
40
40
  6: {
41
41
  fontSize: fontSizes.small,
42
- fontWeight: fontWeights.black,
42
+ fontWeight: fontWeights.bold,
43
43
  lineHeight: getLineHeight(fontSizes.small),
44
44
  ...components?.heading?.[6],
45
45
  },
@@ -4,9 +4,9 @@ export const getThemedStyles = (theme) => {
4
4
  const { components, tokens: { colors, fontSizes, fontWeights }, } = theme;
5
5
  return StyleSheet.create({
6
6
  text: {
7
- fontSize: fontSizes.small,
7
+ fontSize: fontSizes.medium,
8
8
  fontWeight: fontWeights.normal,
9
- lineHeight: getLineHeight(fontSizes.small),
9
+ lineHeight: getLineHeight(fontSizes.medium),
10
10
  ...components?.label?.text,
11
11
  },
12
12
  primary: {
@@ -11,7 +11,8 @@ export default function TextField({ accessibilityLabel, accessibilityRole, acces
11
11
  const fieldContainerStyle = useMemo(() => ({
12
12
  ...themedStyle.fieldContainer,
13
13
  ...(disabled && themedStyle.disabled),
14
- }), [disabled, themedStyle]);
14
+ ...(error && themedStyle.error),
15
+ }), [disabled, error, themedStyle]);
15
16
  return (<View testID={TEXTFIELD_CONTAINER_TEST_ID} style={[themedStyle.container, style]}>
16
17
  {label ? (<Label accessibilityLabel={label} style={[themedStyle.label, labelStyle]}>
17
18
  {label}