@aws-amplify/ui-react-core 2.1.33 → 3.0.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.
Files changed (82) hide show
  1. package/dist/esm/Authenticator/context/AuthenticatorProvider.mjs +5 -6
  2. package/dist/esm/Authenticator/hooks/constants.mjs +4 -4
  3. package/dist/esm/Authenticator/hooks/useAuthenticator/useAuthenticator.mjs +14 -11
  4. package/dist/esm/Authenticator/hooks/useAuthenticator/utils.mjs +10 -18
  5. package/dist/esm/Authenticator/hooks/useAuthenticatorRoute/constants.mjs +7 -4
  6. package/dist/esm/Authenticator/hooks/useAuthenticatorRoute/useAuthenticatorRoute.mjs +6 -6
  7. package/dist/esm/Authenticator/hooks/useAuthenticatorRoute/utils.mjs +47 -18
  8. package/dist/esm/Authenticator/hooks/utils.mjs +2 -2
  9. package/dist/esm/components/FormCore/FormProvider.mjs +15 -0
  10. package/dist/esm/components/FormCore/useField.mjs +20 -0
  11. package/dist/esm/components/FormCore/useForm.mjs +51 -0
  12. package/dist/esm/components/FormCore/withFormProvider.mjs +15 -0
  13. package/dist/esm/hooks/useSetUserAgent.mjs +15 -0
  14. package/dist/esm/hooks/useTimeout.mjs +22 -0
  15. package/dist/esm/index.mjs +7 -0
  16. package/dist/esm/utils/createContextUtilities.mjs +80 -0
  17. package/dist/index.js +284 -96
  18. package/dist/types/Authenticator/hooks/types.d.ts +10 -7
  19. package/dist/types/Authenticator/hooks/useAuthenticator/types.d.ts +1 -3
  20. package/dist/types/Authenticator/hooks/useAuthenticator/utils.d.ts +2 -3
  21. package/dist/types/Authenticator/hooks/useAuthenticatorRoute/types.d.ts +3 -3
  22. package/dist/types/Authenticator/hooks/useAuthenticatorRoute/useAuthenticatorRoute.d.ts +2 -2
  23. package/dist/types/Authenticator/hooks/useAuthenticatorRoute/utils.d.ts +2 -2
  24. package/dist/types/components/FormCore/FormProvider.d.ts +4 -0
  25. package/dist/types/components/FormCore/index.d.ts +5 -0
  26. package/dist/types/components/FormCore/types.d.ts +217 -0
  27. package/dist/types/components/FormCore/useControlledField.d.ts +9 -0
  28. package/dist/types/components/FormCore/useField.d.ts +9 -0
  29. package/dist/types/components/FormCore/useForm.d.ts +12 -0
  30. package/dist/types/components/FormCore/withFormProvider.d.ts +8 -0
  31. package/dist/types/components/index.d.ts +1 -0
  32. package/dist/types/hooks/index.d.ts +2 -0
  33. package/dist/types/hooks/useSetUserAgent.d.ts +2 -0
  34. package/dist/types/hooks/useTimeout.d.ts +4 -0
  35. package/dist/types/index.d.ts +3 -2
  36. package/dist/types/types/index.d.ts +1 -1
  37. package/dist/types/types/types.d.ts +2 -0
  38. package/dist/types/utils/createContextUtilities.d.ts +26 -18
  39. package/package.json +11 -29
  40. package/src/Authenticator/context/AuthenticatorContext.tsx +17 -0
  41. package/src/Authenticator/context/AuthenticatorProvider.tsx +82 -0
  42. package/src/Authenticator/context/index.ts +2 -0
  43. package/src/Authenticator/hooks/constants.ts +30 -0
  44. package/src/Authenticator/hooks/index.ts +5 -0
  45. package/src/Authenticator/hooks/types.ts +218 -0
  46. package/src/Authenticator/hooks/useAuthenticator/__mock__/useAuthenticator.ts +66 -0
  47. package/src/Authenticator/hooks/useAuthenticator/constants.ts +2 -0
  48. package/src/Authenticator/hooks/useAuthenticator/index.ts +2 -0
  49. package/src/Authenticator/hooks/useAuthenticator/types.ts +48 -0
  50. package/src/Authenticator/hooks/useAuthenticator/useAuthenticator.ts +72 -0
  51. package/src/Authenticator/hooks/useAuthenticator/utils.ts +97 -0
  52. package/src/Authenticator/hooks/useAuthenticatorInitMachine/index.ts +1 -0
  53. package/src/Authenticator/hooks/useAuthenticatorInitMachine/useAuthenticatorInitMachine.tsx +25 -0
  54. package/src/Authenticator/hooks/useAuthenticatorRoute/constants.ts +107 -0
  55. package/src/Authenticator/hooks/useAuthenticatorRoute/index.ts +2 -0
  56. package/src/Authenticator/hooks/useAuthenticatorRoute/types.ts +111 -0
  57. package/src/Authenticator/hooks/useAuthenticatorRoute/useAuthenticatorRoute.ts +126 -0
  58. package/src/Authenticator/hooks/useAuthenticatorRoute/utils.ts +204 -0
  59. package/src/Authenticator/hooks/utils.ts +38 -0
  60. package/src/Authenticator/index.ts +23 -0
  61. package/src/components/FormCore/FormProvider.tsx +37 -0
  62. package/src/components/FormCore/index.ts +13 -0
  63. package/src/components/FormCore/types.ts +277 -0
  64. package/src/components/FormCore/useControlledField.ts +73 -0
  65. package/src/components/FormCore/useField.ts +25 -0
  66. package/src/components/FormCore/useForm.ts +84 -0
  67. package/src/components/FormCore/withFormProvider.tsx +31 -0
  68. package/src/components/RenderNothing/RenderNothing.tsx +6 -0
  69. package/src/components/RenderNothing/index.ts +1 -0
  70. package/src/components/index.ts +15 -0
  71. package/src/hooks/index.ts +8 -0
  72. package/src/hooks/useDeprecationWarning.ts +27 -0
  73. package/src/hooks/useHasValueUpdated.ts +28 -0
  74. package/src/hooks/usePreviousValue.ts +15 -0
  75. package/src/hooks/useSetUserAgent.ts +18 -0
  76. package/src/hooks/useTimeout.ts +30 -0
  77. package/src/index.ts +48 -0
  78. package/src/types/index.ts +1 -0
  79. package/src/types/types.ts +3 -0
  80. package/src/utils/createContextUtilities.tsx +131 -0
  81. package/src/utils/index.ts +1 -0
  82. package/dist/esm/node_modules/tslib/tslib.es6.mjs +0 -38
@@ -1,13 +1,12 @@
1
- import { __awaiter } from '../../node_modules/tslib/tslib.es6.mjs';
2
1
  import React__default, { useContext, useMemo, useEffect } from 'react';
3
2
  import { useInterpret } from '@xstate/react';
4
- import { Auth } from 'aws-amplify';
3
+ import { getCurrentUser } from 'aws-amplify/auth';
5
4
  import { createAuthenticatorMachine, listenToAuthHub, defaultAuthHubHandler } from '@aws-amplify/ui';
6
5
  import { AuthenticatorContext } from './AuthenticatorContext.mjs';
7
6
 
8
- const createHubHandler = (options) => (data, service) => __awaiter(void 0, void 0, void 0, function* () {
9
- yield defaultAuthHubHandler(data, service, options);
10
- });
7
+ const createHubHandler = (options) => async (data, service) => {
8
+ await defaultAuthHubHandler(data, service, options);
9
+ };
11
10
  function AuthenticatorProvider({ children, }) {
12
11
  // `authStatus` is exposed by `useAuthenticator` but should not be derived directly from the
13
12
  // state machine as the machine only updates on `Authenticator` initiated events, which
@@ -16,7 +15,7 @@ function AuthenticatorProvider({ children, }) {
16
15
  const [authStatus, setAuthStatus] = React__default.useState('configuring');
17
16
  // only run on first render
18
17
  React__default.useEffect(() => {
19
- Auth.currentAuthenticatedUser()
18
+ getCurrentUser()
20
19
  .then(() => {
21
20
  setAuthStatus('authenticated');
22
21
  })
@@ -4,8 +4,8 @@ const COMPONENT_ROUTE_KEYS = [
4
4
  'confirmSignUp',
5
5
  'confirmVerifyUser',
6
6
  'forceNewPassword',
7
- 'resetPassword',
8
- 'setupTOTP',
7
+ 'forgotPassword',
8
+ 'setupTotp',
9
9
  'signIn',
10
10
  'signUp',
11
11
  'verifyUser',
@@ -16,8 +16,8 @@ const COMPONENT_ROUTE_NAMES = [
16
16
  'ConfirmSignUp',
17
17
  'ConfirmVerifyUser',
18
18
  'ForceNewPassword',
19
- 'ResetPassword',
20
- 'SetupTOTP',
19
+ 'ForgotPassword',
20
+ 'SetupTotp',
21
21
  'SignIn',
22
22
  'SignUp',
23
23
  'VerifyUser',
@@ -1,11 +1,10 @@
1
- import { __rest } from '../../../node_modules/tslib/tslib.es6.mjs';
2
1
  import React__default, { useCallback } from 'react';
3
2
  import { useSelector } from '@xstate/react';
4
3
  import { getServiceFacade } from '@aws-amplify/ui';
5
- import 'aws-amplify';
4
+ import 'aws-amplify/auth';
6
5
  import { AuthenticatorContext } from '../../context/AuthenticatorContext.mjs';
7
6
  import { USE_AUTHENTICATOR_ERROR } from './constants.mjs';
8
- import { getQRFields, getMachineFields, getTotpSecretCodeCallback, getComparator, defaultComparator } from './utils.mjs';
7
+ import { getQRFields, getMachineFields, getComparator, defaultComparator } from './utils.mjs';
9
8
 
10
9
  /**
11
10
  * [📖 Docs](https://ui.docs.amplify.aws/react/connected-components/authenticator/headless#useauthenticator-hook)
@@ -17,27 +16,31 @@ function useAuthenticator(selector) {
17
16
  }
18
17
  const { service } = context;
19
18
  const { send } = service;
20
- const xstateSelector = useCallback((state) => (Object.assign({}, getServiceFacade({ send, state }))), [send]);
19
+ const xstateSelector = useCallback((state) => ({ ...getServiceFacade({ send, state }) }), [send]);
21
20
  const comparator = selector ? getComparator(selector) : defaultComparator;
22
21
  // the purpose of `context.authStatus`is to intentionally override `facade.authStatus`. `facade.authStatus` does
23
22
  // not update on external sign in events (for example when a user is not using the `Authenticator`).
24
23
  const { authStatus } = context;
25
24
  const facade = useSelector(service, xstateSelector, comparator);
26
- const { route, totpSecretCode, unverifiedContactMethods, user } = facade, rest = __rest(facade, ["route", "totpSecretCode", "unverifiedContactMethods", "user"]);
25
+ const { route, totpSecretCode, unverifiedUserAttributes, user, ...rest } = facade;
27
26
  // do not memoize output. `service.getSnapshot` reference remains stable preventing
28
27
  // `fields` from updating with current form state on value changes
29
28
  const serviceSnapshot = service.getSnapshot();
30
- // legacy `QRFields` values only used for SetupTOTP page to retrieve issuer information, will be removed in future
31
- const QRFields = route === 'setupTOTP' ? getQRFields(serviceSnapshot) : null;
29
+ // legacy `QRFields` values only used for SetupTotp page to retrieve issuer information, will be removed in future
30
+ const QRFields = route === 'setupTotp' ? getQRFields(serviceSnapshot) : null;
32
31
  // legacy `formFields` values required until form state is removed from state machine
33
- const fields = getMachineFields(route, serviceSnapshot, unverifiedContactMethods);
34
- return Object.assign(Object.assign({}, rest), { authStatus,
32
+ const fields = getMachineFields(route, serviceSnapshot, unverifiedUserAttributes);
33
+ return {
34
+ ...rest,
35
+ authStatus,
35
36
  route,
36
37
  totpSecretCode,
37
- unverifiedContactMethods,
38
+ unverifiedUserAttributes,
38
39
  user,
39
40
  /** @deprecated For internal use only */
40
- fields, getTotpSecretCode: getTotpSecretCodeCallback(user), QRFields });
41
+ fields,
42
+ QRFields,
43
+ };
41
44
  }
42
45
 
43
46
  export { useAuthenticator as default };
@@ -1,5 +1,3 @@
1
- import { __awaiter } from '../../../node_modules/tslib/tslib.es6.mjs';
2
- import { Auth } from 'aws-amplify';
3
1
  import { getActorContext, getSortedFormFields, isString, areEmptyArrays, areEmptyObjects } from '@aws-amplify/ui';
4
2
  import { isComponentRouteKey } from '../utils.mjs';
5
3
 
@@ -27,19 +25,13 @@ const getComparator = (selector) => (currentFacade, nextFacade) => {
27
25
  // Shallow compare the array values
28
26
  return areSelectorDepsEqual(currentSelectorDeps, nextSelectorDeps);
29
27
  };
30
- const getQRFields = (state) => {
31
- var _a, _b, _c;
32
- return (Object.assign({}, (_c = (_b = (_a = getActorContext(state)) === null || _a === void 0 ? void 0 : _a.formFields) === null || _b === void 0 ? void 0 : _b.setupTOTP) === null || _c === void 0 ? void 0 : _c.QR));
33
- };
34
- const getTotpSecretCodeCallback = (user) => function getTotpSecretCode() {
35
- return __awaiter(this, void 0, void 0, function* () {
36
- return yield Auth.setupTOTP(user);
37
- });
38
- };
39
- const flattenFormFields = (fields) => fields.flatMap(([name, options]) => (Object.assign({ name }, options)));
40
- const convertContactMethodsToFields = (unverifiedContactMethods) => {
41
- return (unverifiedContactMethods &&
42
- Object.entries(unverifiedContactMethods).map(([name, value]) => {
28
+ const getQRFields = (state) => ({
29
+ ...getActorContext(state)?.formFields?.setupTotp?.QR,
30
+ });
31
+ const flattenFormFields = (fields) => fields.flatMap(([name, options]) => ({ name, ...options }));
32
+ const convertContactMethodsToFields = (unverifiedUserAttributes) => {
33
+ return (unverifiedUserAttributes &&
34
+ Object.entries(unverifiedUserAttributes).map(([name, value]) => {
43
35
  const valueIsString = isString(value);
44
36
  if (!valueIsString || !name) {
45
37
  return {};
@@ -51,13 +43,13 @@ const convertContactMethodsToFields = (unverifiedContactMethods) => {
51
43
  * Retrieves default and custom (RWA only, to be updated) form field values from state machine
52
44
  * for subcomponent routes that render fields
53
45
  */
54
- const getMachineFields = (route, state, unverifiedContactMethods) => {
46
+ const getMachineFields = (route, state, unverifiedUserAttributes) => {
55
47
  if (isComponentRouteKey(route)) {
56
48
  return route === 'verifyUser'
57
- ? convertContactMethodsToFields(unverifiedContactMethods)
49
+ ? convertContactMethodsToFields(unverifiedUserAttributes)
58
50
  : flattenFormFields(getSortedFormFields(route, state));
59
51
  }
60
52
  return [];
61
53
  };
62
54
 
63
- export { areSelectorDepsEqual, defaultComparator, getComparator, getMachineFields, getQRFields, getTotpSecretCodeCallback };
55
+ export { areSelectorDepsEqual, defaultComparator, getComparator, getMachineFields, getQRFields };
@@ -18,8 +18,8 @@ const CONFIRM_RESET_PASSWORD_MACHINE_KEYS = [
18
18
  ];
19
19
  const CONFIRM_SIGN_IN_MACHINE_KEYS = [
20
20
  ...COMMON_ROUTE_MACHINE_KEYS,
21
+ 'challengeName',
21
22
  'toSignIn',
22
- 'user',
23
23
  ];
24
24
  const CONFIRM_SIGN_UP_MACHINE_KEYS = [
25
25
  ...COMMON_ROUTE_MACHINE_KEYS,
@@ -42,13 +42,15 @@ const RESET_PASSWORD_MACHINE_KEYS = [
42
42
  ];
43
43
  const SIGN_IN_MACHINE_KEYS = [
44
44
  ...COMMON_ROUTE_MACHINE_KEYS,
45
+ 'socialProviders',
45
46
  'toFederatedSignIn',
46
- 'toResetPassword',
47
+ 'toForgotPassword',
47
48
  'toSignUp',
48
49
  ];
49
50
  const SIGN_UP_MACHINE_KEYS = [
50
51
  ...COMMON_ROUTE_MACHINE_KEYS,
51
52
  'hasValidationErrors',
53
+ 'socialProviders',
52
54
  'toSignIn',
53
55
  'validationErrors',
54
56
  ];
@@ -56,6 +58,7 @@ const SETUP_TOTP_MACHINE_KEYS = [
56
58
  ...COMMON_ROUTE_MACHINE_KEYS,
57
59
  'toSignIn',
58
60
  'totpSecretCode',
61
+ 'username',
59
62
  ];
60
63
  const VERIFY_USER_MACHINE_KEYS = [
61
64
  ...COMMON_ROUTE_MACHINE_KEYS,
@@ -69,8 +72,8 @@ const MACHINE_PROP_KEYS = {
69
72
  forceNewPassword: FORCE_NEW_PASSWORD_MACHINE_KEYS,
70
73
  signIn: SIGN_IN_MACHINE_KEYS,
71
74
  signUp: SIGN_UP_MACHINE_KEYS,
72
- resetPassword: RESET_PASSWORD_MACHINE_KEYS,
73
- setupTOTP: SETUP_TOTP_MACHINE_KEYS,
75
+ forgotPassword: RESET_PASSWORD_MACHINE_KEYS,
76
+ setupTotp: SETUP_TOTP_MACHINE_KEYS,
74
77
  verifyUser: VERIFY_USER_MACHINE_KEYS,
75
78
  };
76
79
 
@@ -1,6 +1,6 @@
1
1
  import { useMemo } from 'react';
2
2
  import useAuthenticator from '../useAuthenticator/useAuthenticator.mjs';
3
- import { getRouteMachineSelector, resolveDefault, resolveVerifyUserRoute, resolveSignUpRoute, resolveSignInRoute, resolveSetupTOTPRoute, resolveResetPasswordRoute, resolveForceNewPasswordRoute, resolveConfirmVerifyUserRoute, resolveConfirmSignUpRoute, resolveConfirmSignInRoute, resolveConfirmResetPasswordRoute, routeSelector } from './utils.mjs';
3
+ import { getRouteMachineSelector, resolveDefault, resolveVerifyUserRoute, resolveSignUpRoute, resolveSignInRoute, resolveSetupTotpRoute, resolveForgotPasswordRoute, resolveForceNewPasswordRoute, resolveConfirmVerifyUserRoute, resolveConfirmSignUpRoute, resolveConfirmSignInRoute, resolveConfirmResetPasswordRoute, routeSelector } from './utils.mjs';
4
4
 
5
5
  function useAuthenticatorRoute({ components, }) {
6
6
  const { route } = useAuthenticator(routeSelector);
@@ -11,7 +11,7 @@ function useAuthenticatorRoute({ components, }) {
11
11
  // Only state machine props specified by the current `routeSelector` will have their current value
12
12
  // returned by `useAuthenticator`, non-machine props returned will always be the current value
13
13
  const routeSelectorProps = useAuthenticator(routeMachineSelector);
14
- const { ConfirmResetPassword, ConfirmSignIn, ConfirmSignUp, ConfirmVerifyUser, ForceNewPassword, ResetPassword, SetupTOTP, SignIn, SignUp, VerifyUser, } = components;
14
+ const { ConfirmResetPassword, ConfirmSignIn, ConfirmSignUp, ConfirmVerifyUser, ForceNewPassword, ForgotPassword, SetupTotp, SignIn, SignUp, VerifyUser, } = components;
15
15
  switch (route) {
16
16
  case 'confirmResetPassword': {
17
17
  return resolveConfirmResetPasswordRoute(ConfirmResetPassword, routeSelectorProps);
@@ -28,11 +28,11 @@ function useAuthenticatorRoute({ components, }) {
28
28
  case 'forceNewPassword': {
29
29
  return resolveForceNewPasswordRoute(ForceNewPassword, routeSelectorProps);
30
30
  }
31
- case 'resetPassword': {
32
- return resolveResetPasswordRoute(ResetPassword, routeSelectorProps);
31
+ case 'forgotPassword': {
32
+ return resolveForgotPasswordRoute(ForgotPassword, routeSelectorProps);
33
33
  }
34
- case 'setupTOTP': {
35
- return resolveSetupTOTPRoute(SetupTOTP, routeSelectorProps);
34
+ case 'setupTotp': {
35
+ return resolveSetupTotpRoute(SetupTotp, routeSelectorProps);
36
36
  }
37
37
  case 'signIn': {
38
38
  return resolveSignInRoute(SignIn, routeSelectorProps);
@@ -1,4 +1,7 @@
1
- import { __rest } from '../../../node_modules/tslib/tslib.es6.mjs';
1
+ import 'react';
2
+ import 'react-hook-form';
3
+ import '@aws-amplify/ui';
4
+ import '../../../components/FormCore/FormProvider.mjs';
2
5
  import RenderNothing from '../../../components/RenderNothing/RenderNothing.mjs';
3
6
  import { isComponentRouteKey } from '../utils.mjs';
4
7
  import { MACHINE_PROP_KEYS, EVENT_HANDLER_KEY_MAP } from './constants.mjs';
@@ -15,47 +18,66 @@ const getRouteMachineSelector = (route) => isComponentRouteKey(route)
15
18
  : routeSelector;
16
19
  const isFormEventHandlerKey = (key) => ['updateBlur', 'updateForm', 'submitForm'].includes(key);
17
20
  const convertEventHandlerKey = (key) => EVENT_HANDLER_KEY_MAP[key];
18
- const getConvertedMachineProps = (route, context) => MACHINE_PROP_KEYS[route].reduce((acc, key) => (Object.assign(Object.assign({}, acc), { [isFormEventHandlerKey(key) ? convertEventHandlerKey(key) : key]: context[key] })), {});
21
+ const getConvertedMachineProps = (route, context) => MACHINE_PROP_KEYS[route].reduce((acc, key) => ({
22
+ ...acc,
23
+ [isFormEventHandlerKey(key) ? convertEventHandlerKey(key) : key]: context[key],
24
+ }), {});
19
25
  function resolveConfirmResetPasswordRoute(Component, props) {
20
26
  return {
21
27
  Component,
22
- props: Object.assign(Object.assign({}, Component), getConvertedMachineProps('confirmResetPassword', props)),
28
+ props: {
29
+ ...Component,
30
+ ...getConvertedMachineProps('confirmResetPassword', props),
31
+ },
23
32
  };
24
33
  }
25
34
  function resolveConfirmSignInRoute(Component, props) {
26
- const _a = getConvertedMachineProps('confirmSignIn', props), { user } = _a, machineProps = __rest(_a, ["user"]);
27
- // prior to the `confirmSignIn` route, `user.username` is populated
28
- const challengeName = user.challengeName;
29
- return { Component, props: Object.assign(Object.assign(Object.assign({}, Component), machineProps), { challengeName }) };
35
+ const { challengeName, ...machineProps } = getConvertedMachineProps('confirmSignIn', props);
36
+ return { Component, props: { ...Component, ...machineProps, challengeName } };
30
37
  }
31
38
  function resolveConfirmSignUpRoute(Component, props) {
32
39
  return {
33
40
  Component,
34
- props: Object.assign(Object.assign({}, Component), getConvertedMachineProps('confirmSignUp', props)),
41
+ props: {
42
+ ...Component,
43
+ ...getConvertedMachineProps('confirmSignUp', props),
44
+ },
35
45
  };
36
46
  }
37
47
  function resolveConfirmVerifyUserRoute(Component, props) {
38
48
  return {
39
49
  Component,
40
- props: Object.assign(Object.assign({}, Component), getConvertedMachineProps('confirmVerifyUser', props)),
50
+ props: {
51
+ ...Component,
52
+ ...getConvertedMachineProps('confirmVerifyUser', props),
53
+ },
41
54
  };
42
55
  }
43
56
  function resolveForceNewPasswordRoute(Component, props) {
44
57
  return {
45
58
  Component,
46
- props: Object.assign(Object.assign({}, Component), getConvertedMachineProps('forceNewPassword', props)),
59
+ props: {
60
+ ...Component,
61
+ ...getConvertedMachineProps('forceNewPassword', props),
62
+ },
47
63
  };
48
64
  }
49
- function resolveResetPasswordRoute(Component, props) {
65
+ function resolveForgotPasswordRoute(Component, props) {
50
66
  return {
51
67
  Component,
52
- props: Object.assign(Object.assign({}, Component), getConvertedMachineProps('resetPassword', props)),
68
+ props: {
69
+ ...Component,
70
+ ...getConvertedMachineProps('forgotPassword', props),
71
+ },
53
72
  };
54
73
  }
55
- function resolveSetupTOTPRoute(Component, props) {
74
+ function resolveSetupTotpRoute(Component, props) {
56
75
  return {
57
76
  Component,
58
- props: Object.assign(Object.assign({}, Component), getConvertedMachineProps('setupTOTP', props)),
77
+ props: {
78
+ ...Component,
79
+ ...getConvertedMachineProps('setupTotp', props),
80
+ },
59
81
  };
60
82
  }
61
83
  function resolveSignInRoute(Component, props) {
@@ -63,19 +85,26 @@ function resolveSignInRoute(Component, props) {
63
85
  const hideSignUp = false;
64
86
  return {
65
87
  Component,
66
- props: Object.assign(Object.assign(Object.assign({}, Component), getConvertedMachineProps('signIn', props)), { hideSignUp }),
88
+ props: {
89
+ ...Component,
90
+ ...getConvertedMachineProps('signIn', props),
91
+ hideSignUp,
92
+ },
67
93
  };
68
94
  }
69
95
  function resolveSignUpRoute(Component, props) {
70
96
  return {
71
97
  Component,
72
- props: Object.assign(Object.assign({}, Component), getConvertedMachineProps('signUp', props)),
98
+ props: { ...Component, ...getConvertedMachineProps('signUp', props) },
73
99
  };
74
100
  }
75
101
  function resolveVerifyUserRoute(Component, props) {
76
102
  return {
77
103
  Component,
78
- props: Object.assign(Object.assign({}, Component), getConvertedMachineProps('verifyUser', props)),
104
+ props: {
105
+ ...Component,
106
+ ...getConvertedMachineProps('verifyUser', props),
107
+ },
79
108
  };
80
109
  }
81
110
  function resolveDefault() {
@@ -85,4 +114,4 @@ function resolveDefault() {
85
114
  };
86
115
  }
87
116
 
88
- export { getRouteMachineSelector, resolveConfirmResetPasswordRoute, resolveConfirmSignInRoute, resolveConfirmSignUpRoute, resolveConfirmVerifyUserRoute, resolveDefault, resolveForceNewPasswordRoute, resolveResetPasswordRoute, resolveSetupTOTPRoute, resolveSignInRoute, resolveSignUpRoute, resolveVerifyUserRoute, routeSelector };
117
+ export { getRouteMachineSelector, resolveConfirmResetPasswordRoute, resolveConfirmSignInRoute, resolveConfirmSignUpRoute, resolveConfirmVerifyUserRoute, resolveDefault, resolveForceNewPasswordRoute, resolveForgotPasswordRoute, resolveSetupTotpRoute, resolveSignInRoute, resolveSignUpRoute, resolveVerifyUserRoute, routeSelector };
@@ -9,7 +9,7 @@ function resolveAuthenticatorComponents(defaults, overrides) {
9
9
  const Default = defaults[route];
10
10
  const Override = overrides[route];
11
11
  if (typeof Override !== 'function') {
12
- return Object.assign(Object.assign({}, components), { [route]: Default });
12
+ return { ...components, [route]: Default };
13
13
  }
14
14
  const { Footer, FormFields, Header } = Default;
15
15
  // cast to allow assigning of component slots
@@ -17,7 +17,7 @@ function resolveAuthenticatorComponents(defaults, overrides) {
17
17
  Component.Footer = Footer;
18
18
  Component.FormFields = FormFields;
19
19
  Component.Header = Header;
20
- return Object.assign(Object.assign({}, components), { [route]: Component });
20
+ return { ...components, [route]: Component };
21
21
  }, {});
22
22
  }
23
23
 
@@ -0,0 +1,15 @@
1
+ import React__default from 'react';
2
+ import { useForm, FormProvider as FormProvider$1 } from 'react-hook-form';
3
+
4
+ const DEFAULT_MODE = 'onTouched';
5
+ const FormProvider = React__default.forwardRef(function FormProvider({ children, defaultValues, mode = DEFAULT_MODE }, ref) {
6
+ const formProviderProps = useForm({
7
+ defaultValues,
8
+ mode,
9
+ });
10
+ const { getValues, reset } = formProviderProps;
11
+ React__default.useImperativeHandle(ref, () => ({ getValues, reset: () => reset(defaultValues) }), [defaultValues, getValues, reset]);
12
+ return (React__default.createElement(FormProvider$1, { ...formProviderProps }, children));
13
+ });
14
+
15
+ export { FormProvider as default };
@@ -0,0 +1,20 @@
1
+ import useForm from './useForm.mjs';
2
+
3
+ const DEFAULT_ERROR_MESSAGE = '`useField` must be used within a `FormProvider`';
4
+ /**
5
+ * `Field` integration hook for usage with React `Field` components.
6
+ *
7
+ * @param params Requires `name`, all additional params optional
8
+ * @returns `Form` aware `Field` event handlers and state values
9
+ */
10
+ function useField(params) {
11
+ const { getFieldState, registerField } = useForm({
12
+ errorMessage: DEFAULT_ERROR_MESSAGE,
13
+ });
14
+ return {
15
+ ...registerField(params),
16
+ ...getFieldState(params.name),
17
+ };
18
+ }
19
+
20
+ export { DEFAULT_ERROR_MESSAGE, useField as default };
@@ -0,0 +1,51 @@
1
+ import React__default from 'react';
2
+ import { useFormContext } from 'react-hook-form';
3
+ import { noop } from '@aws-amplify/ui';
4
+
5
+ const DEFAULT_ERROR_MESSAGE = '`useForm` must be called inside a `FormProvider`';
6
+ /**
7
+ * Utility hook corresponding to `FormProvider`, must be used within a `FormProvider`
8
+ *
9
+ * @internal Extend for public export. `useForm` and `UseForm` are an abstraction layer
10
+ * on top of `useFormContext` and `UseFormReturn`, imported from `react-hook-form`
11
+ *
12
+ * @param options optional parameters
13
+ * @returns `Form` utilities
14
+ */
15
+ function useForm(options = {}) {
16
+ const formContext = useFormContext();
17
+ const { errorMessage, onSubmit: _onSubmit } = options;
18
+ if (!formContext) {
19
+ throw new Error(errorMessage ?? DEFAULT_ERROR_MESSAGE);
20
+ }
21
+ const { formState, getFieldState: _getFieldState, getValues, handleSubmit, register, reset, setValue, } = formContext;
22
+ // Do not memoize, `formState` updates on all events
23
+ const getFieldState = (name) => {
24
+ const { error, ...fieldState } = _getFieldState(name, formState);
25
+ const { message: errorMessage } = error ?? {};
26
+ return { ...fieldState, errorMessage, hasError: !!errorMessage };
27
+ };
28
+ // memoize `registerField` and `setFormValue` together,
29
+ // `register` and `setValue` maintain stable references
30
+ const { registerField, setFormValue } = React__default.useMemo(() => {
31
+ return {
32
+ registerField: ({ name, ...options }) => register(name, options),
33
+ setFormValue: ({ name, value, ...options }) => setValue(name, value, options),
34
+ };
35
+ }, [register, setValue]);
36
+ const onSubmit = React__default.useCallback((event) => {
37
+ const handler = _onSubmit ? handleSubmit(_onSubmit) : noop;
38
+ handler(event);
39
+ }, [_onSubmit, handleSubmit]);
40
+ return {
41
+ getFieldState,
42
+ getValues,
43
+ isValid: formState.isValid,
44
+ onSubmit,
45
+ registerField,
46
+ reset,
47
+ setFormValue,
48
+ };
49
+ }
50
+
51
+ export { DEFAULT_ERROR_MESSAGE, useForm as default };
@@ -0,0 +1,15 @@
1
+ import React__default from 'react';
2
+ import FormProvider from './FormProvider.mjs';
3
+
4
+ /**
5
+ * @param Child `Form` base component wrapped inside `FormProvider`
6
+ * @returns Composed `Form` component exposing `FormContext` values to descendents
7
+ */
8
+ function withFormProvider(Child) {
9
+ return React__default.forwardRef(function Form({ defaultValues, mode, ...props }, ref) {
10
+ return (React__default.createElement(FormProvider, { defaultValues: defaultValues, mode: mode, ref: ref },
11
+ React__default.createElement(Child, { ...props })));
12
+ });
13
+ }
14
+
15
+ export { withFormProvider as default };
@@ -0,0 +1,15 @@
1
+ import { useEffect } from 'react';
2
+ import { setUserAgent } from '@aws-amplify/ui';
3
+
4
+ function useSetUserAgent({ componentName, packageName, version, }) {
5
+ useEffect(() => {
6
+ const clearUserAgent = setUserAgent({
7
+ componentName,
8
+ packageName,
9
+ version,
10
+ });
11
+ return clearUserAgent;
12
+ }, [componentName, packageName, version]);
13
+ }
14
+
15
+ export { useSetUserAgent as default };
@@ -0,0 +1,22 @@
1
+ import React__default from 'react';
2
+ import { isTypedFunction } from '@aws-amplify/ui';
3
+
4
+ function useTimeout({ callback, delay, }) {
5
+ const storedCallback = React__default.useRef(callback);
6
+ React__default.useLayoutEffect(() => {
7
+ storedCallback.current = callback;
8
+ }, [callback]);
9
+ React__default.useEffect(() => {
10
+ if (!isTypedFunction(storedCallback.current) || !delay) {
11
+ return;
12
+ }
13
+ const timeoutId = setTimeout(() => {
14
+ storedCallback.current?.();
15
+ }, delay);
16
+ return () => {
17
+ clearTimeout(timeoutId);
18
+ };
19
+ }, [delay]);
20
+ }
21
+
22
+ export { useTimeout as default };
@@ -4,7 +4,14 @@ export { default as useAuthenticator } from './Authenticator/hooks/useAuthentica
4
4
  export { default as useAuthenticatorRoute } from './Authenticator/hooks/useAuthenticatorRoute/useAuthenticatorRoute.mjs';
5
5
  export { default as useAuthenticatorInitMachine } from './Authenticator/hooks/useAuthenticatorInitMachine/useAuthenticatorInitMachine.mjs';
6
6
  export { isComponentRouteKey as isAuthenticatorComponentRouteKey, resolveAuthenticatorComponents } from './Authenticator/hooks/utils.mjs';
7
+ export { default as useField } from './components/FormCore/useField.mjs';
8
+ export { default as useForm } from './components/FormCore/useForm.mjs';
9
+ export { default as FormProvider } from './components/FormCore/FormProvider.mjs';
10
+ export { default as withFormProvider } from './components/FormCore/withFormProvider.mjs';
7
11
  export { default as RenderNothing } from './components/RenderNothing/RenderNothing.mjs';
8
12
  export { default as useDeprecationWarning } from './hooks/useDeprecationWarning.mjs';
9
13
  export { default as useHasValueUpdated } from './hooks/useHasValueUpdated.mjs';
10
14
  export { default as usePreviousValue } from './hooks/usePreviousValue.mjs';
15
+ export { default as useSetUserAgent } from './hooks/useSetUserAgent.mjs';
16
+ export { default as useTimeout } from './hooks/useTimeout.mjs';
17
+ export { default as createContextUtilities } from './utils/createContextUtilities.mjs';
@@ -0,0 +1,80 @@
1
+ import React__default from 'react';
2
+ import { isUndefined, isString } from '@aws-amplify/ui';
3
+
4
+ const INVALID_OPTIONS_MESSAGE = 'an `errorMessage` or a `defaultValue` must be provided in `options`';
5
+ /**
6
+ * Uses `ContextType`/`Name` generics and `options` to create:
7
+ * - `${Name}Context`: React Context of type `ContextType`
8
+ * - `Provider${Name}`: React Context `Provider` component exposing the `ContextType`
9
+ * as optional props
10
+ * - `use${Name}`: Utility Hook exposing the values of `ContextType`. Allows
11
+ * params with `errorMessage` for granular error messaging
12
+ *
13
+ * @template ContextType Type definition of the Context.
14
+ * > For most use cases the keys of `ContextType` should not be optional in
15
+ * preference of explicit `undefined` to avoid optional types on the
16
+ * Utility Hook return
17
+ *
18
+ * @param options Context utility options. Requires a `contextName`, and
19
+ * either a `defaultValue` of `ContextType` **or** an `errorMessage`
20
+ * allowing for differing behaviors of the Utility Hook when used outside a
21
+ * parent `Provider`:
22
+ *
23
+ * - `defaultValue`: Ensures the Utility Hook returns a default value for
24
+ * scenarios **where the missing context values should not impact usage**
25
+ * - `errorMessage`: Ensures the Utility Hook throws an error for
26
+ * scenarios **where the missing context values should prevent** usage
27
+ *
28
+ * @returns `Context`, `Provider` Component and `useContext` Utility Hook
29
+ *
30
+ * @usage
31
+ * ```ts
32
+ * interface StuffContextType {
33
+ * things: number;
34
+ * }
35
+ *
36
+ * // with `defaultValue`
37
+ * const defaultValue: StuffContextType = { things: 7 };
38
+ *
39
+ * const { StuffProvider, useStuff } = createContextUtilities({
40
+ * contextName: 'Stuff',
41
+ * defaultValue,
42
+ * });
43
+ *
44
+ * // with `errorMessage`
45
+ * const { StuffProvider, useStuff } = createContextUtilities<StuffContextType>({
46
+ * contextName: 'Stuff',
47
+ * errorMessage: '`useStuff` must be used in a `StuffProvider`'
48
+ * });
49
+ * ```
50
+ */
51
+ function createContextUtilities(options) {
52
+ const { contextName, defaultValue, errorMessage } = options ?? {};
53
+ if (isUndefined(defaultValue) && !isString(errorMessage)) {
54
+ throw new Error(INVALID_OPTIONS_MESSAGE);
55
+ }
56
+ const Context = React__default.createContext(defaultValue);
57
+ function Provider(props) {
58
+ const { children, ...context } = props;
59
+ const value = React__default.useMemo(() => context,
60
+ // Unpack `context` for the dep array; using `[context]` results in
61
+ // evaluation on every render
62
+ // eslint-disable-next-line react-hooks/exhaustive-deps
63
+ Object.values(context));
64
+ return React__default.createElement(Context.Provider, { value: value }, children);
65
+ }
66
+ Provider.displayName = `${contextName}Provider`;
67
+ return {
68
+ [`use${contextName}`]: function (params) {
69
+ const context = React__default.useContext(Context);
70
+ if (isUndefined(context)) {
71
+ throw new Error(params?.errorMessage ?? errorMessage);
72
+ }
73
+ return context;
74
+ },
75
+ [`${contextName}Provider`]: Provider,
76
+ [`${contextName}Context`]: Context,
77
+ };
78
+ }
79
+
80
+ export { INVALID_OPTIONS_MESSAGE, createContextUtilities as default };