@aws-amplify/ui-react-core 2.0.0 → 2.1.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 (46) hide show
  1. package/dist/esm/Authenticator/hooks/constants.js +26 -0
  2. package/dist/esm/Authenticator/hooks/useAuthenticator/constants.js +1 -13
  3. package/dist/esm/Authenticator/hooks/useAuthenticator/useAuthenticator.js +4 -3
  4. package/dist/esm/Authenticator/hooks/useAuthenticator/utils.js +23 -9
  5. package/dist/esm/Authenticator/hooks/useAuthenticatorInitMachine/useAuthenticatorInitMachine.js +17 -0
  6. package/dist/esm/Authenticator/hooks/useAuthenticatorRoute/constants.js +73 -0
  7. package/dist/esm/Authenticator/hooks/useAuthenticatorRoute/useAuthenticatorRoute.js +52 -0
  8. package/dist/esm/Authenticator/hooks/useAuthenticatorRoute/utils.js +89 -0
  9. package/dist/esm/Authenticator/hooks/utils.js +24 -0
  10. package/dist/esm/InAppMessaging/hooks/useMessage/useMessage.js +3 -3
  11. package/dist/esm/components/RenderNothing/RenderNothing.js +2 -2
  12. package/dist/esm/hooks/useHasValueUpdated.js +13 -0
  13. package/dist/esm/hooks/usePreviousValue.js +13 -0
  14. package/dist/esm/index.js +5 -0
  15. package/dist/index.js +322 -32
  16. package/dist/types/Authenticator/hooks/__mock__/components.d.ts +7 -0
  17. package/dist/types/Authenticator/hooks/__tests__/utils.spec.d.ts +1 -0
  18. package/dist/types/Authenticator/hooks/constants.d.ts +3 -0
  19. package/dist/types/Authenticator/hooks/index.d.ts +4 -0
  20. package/dist/types/Authenticator/hooks/types.d.ts +123 -0
  21. package/dist/types/Authenticator/hooks/useAuthenticator/__mock__/useAuthenticator.d.ts +4 -0
  22. package/dist/types/Authenticator/hooks/useAuthenticator/constants.d.ts +0 -2
  23. package/dist/types/Authenticator/hooks/useAuthenticator/index.d.ts +1 -1
  24. package/dist/types/Authenticator/hooks/useAuthenticator/types.d.ts +2 -2
  25. package/dist/types/Authenticator/hooks/useAuthenticator/useAuthenticator.d.ts +2 -2
  26. package/dist/types/Authenticator/hooks/useAuthenticator/utils.d.ts +7 -6
  27. package/dist/types/Authenticator/hooks/useAuthenticatorInitMachine/__tests__/useAuthenticatorInitMachine.spec.d.ts +1 -0
  28. package/dist/types/Authenticator/hooks/useAuthenticatorInitMachine/index.d.ts +1 -0
  29. package/dist/types/Authenticator/hooks/useAuthenticatorInitMachine/useAuthenticatorInitMachine.d.ts +4 -0
  30. package/dist/types/Authenticator/hooks/useAuthenticatorRoute/__tests__/useAuthenticatorRoute.spec.d.ts +1 -0
  31. package/dist/types/Authenticator/hooks/useAuthenticatorRoute/__tests__/utils.spec.d.ts +1 -0
  32. package/dist/types/Authenticator/hooks/useAuthenticatorRoute/constants.d.ts +4 -0
  33. package/dist/types/Authenticator/hooks/useAuthenticatorRoute/index.d.ts +2 -0
  34. package/dist/types/Authenticator/hooks/useAuthenticatorRoute/types.d.ts +38 -0
  35. package/dist/types/Authenticator/hooks/useAuthenticatorRoute/useAuthenticatorRoute.d.ts +11 -0
  36. package/dist/types/Authenticator/hooks/useAuthenticatorRoute/utils.d.ts +17 -0
  37. package/dist/types/Authenticator/hooks/utils.d.ts +4 -0
  38. package/dist/types/Authenticator/index.d.ts +3 -2
  39. package/dist/types/components/RenderNothing/RenderNothing.d.ts +1 -1
  40. package/dist/types/hooks/__tests__/useHasValueUpdated.spec.d.ts +1 -0
  41. package/dist/types/hooks/__tests__/usePreviousValue.spec.d.ts +1 -0
  42. package/dist/types/hooks/index.d.ts +2 -0
  43. package/dist/types/hooks/useHasValueUpdated.d.ts +1 -0
  44. package/dist/types/hooks/usePreviousValue.d.ts +1 -0
  45. package/dist/types/index.d.ts +2 -1
  46. package/package.json +5 -5
@@ -0,0 +1,26 @@
1
+ const COMPONENT_ROUTE_KEYS = [
2
+ 'confirmResetPassword',
3
+ 'confirmSignIn',
4
+ 'confirmSignUp',
5
+ 'confirmVerifyUser',
6
+ 'forceNewPassword',
7
+ 'resetPassword',
8
+ 'setupTOTP',
9
+ 'signIn',
10
+ 'signUp',
11
+ 'verifyUser',
12
+ ];
13
+ const COMPONENT_ROUTE_NAMES = [
14
+ 'ConfirmResetPassword',
15
+ 'ConfirmSignIn',
16
+ 'ConfirmSignUp',
17
+ 'ConfirmVerifyUser',
18
+ 'ForceNewPassword',
19
+ 'ResetPassword',
20
+ 'SetupTOTP',
21
+ 'SignIn',
22
+ 'SignUp',
23
+ 'VerifyUser',
24
+ ];
25
+
26
+ export { COMPONENT_ROUTE_KEYS, COMPONENT_ROUTE_NAMES };
@@ -1,15 +1,3 @@
1
1
  const USE_AUTHENTICATOR_ERROR = '`useAuthenticator` must be used inside an `Authenticator.Provider`.';
2
- const COMPONENT_ROUTE_KEYS = [
3
- 'signIn',
4
- 'signUp',
5
- 'forceNewPassword',
6
- 'confirmResetPassword',
7
- 'confirmSignIn',
8
- 'confirmSignUp',
9
- 'confirmVerifyUser',
10
- 'resetPassword',
11
- 'setupTOTP',
12
- 'verifyUser',
13
- ];
14
2
 
15
- export { COMPONENT_ROUTE_KEYS, USE_AUTHENTICATOR_ERROR };
3
+ export { USE_AUTHENTICATOR_ERROR };
@@ -5,7 +5,7 @@ import { getServiceFacade } from '@aws-amplify/ui';
5
5
  import 'react/jsx-runtime';
6
6
  import { AuthenticatorContext } from '../../context/AuthenticatorContext.js';
7
7
  import { USE_AUTHENTICATOR_ERROR } from './constants.js';
8
- import { getLegacyFields, getTotpSecretCodeCallback, getComparator, defaultComparator } from './utils.js';
8
+ import { getMachineFields, getTotpSecretCodeCallback, getComparator, defaultComparator } from './utils.js';
9
9
 
10
10
  /**
11
11
  * [📖 Docs](https://ui.docs.amplify.aws/react/connected-components/authenticator/headless#useauthenticator-hook)
@@ -20,13 +20,14 @@ function useAuthenticator(selector) {
20
20
  const xstateSelector = useCallback((state) => (Object.assign({}, getServiceFacade({ send, state }))), [send]);
21
21
  const comparator = selector ? getComparator(selector) : defaultComparator;
22
22
  const facade = useSelector(service, xstateSelector, comparator);
23
- const { route, user } = facade, rest = __rest(facade, ["route", "user"]);
23
+ const { route, unverifiedContactMethods, user } = facade, rest = __rest(facade, ["route", "unverifiedContactMethods", "user"]);
24
24
  // do not memoize output. `service.getSnapshot` reference remains stable preventing
25
25
  // `fields` from updating with current form state on value changes
26
26
  const serviceSnapshot = service.getSnapshot();
27
27
  // legacy `formFields` values required until form state is removed from state machine
28
- const fields = useMemo(() => getLegacyFields(route, serviceSnapshot), [route, serviceSnapshot]);
28
+ const fields = useMemo(() => getMachineFields(route, serviceSnapshot, unverifiedContactMethods), [route, serviceSnapshot, unverifiedContactMethods]);
29
29
  return Object.assign(Object.assign({}, rest), { getTotpSecretCode: getTotpSecretCodeCallback(user), route,
30
+ unverifiedContactMethods,
30
31
  user,
31
32
  /** @deprecated For internal use only */
32
33
  fields });
@@ -1,8 +1,9 @@
1
1
  import { __awaiter } from '../../../node_modules/tslib/tslib.es6.js';
2
2
  import { Auth } from 'aws-amplify';
3
3
  import { getSortedFormFields } from '@aws-amplify/ui';
4
+ import isString from 'lodash/isString';
4
5
  import { areEmptyArrays, areEmptyObjects } from '../../../utils/index.js';
5
- import { COMPONENT_ROUTE_KEYS } from './constants.js';
6
+ import { isComponentRouteKey } from '../utils.js';
6
7
 
7
8
  const defaultComparator = () => false;
8
9
  /**
@@ -33,15 +34,28 @@ const getTotpSecretCodeCallback = (user) => function getTotpSecretCode() {
33
34
  return yield Auth.setupTOTP(user);
34
35
  });
35
36
  };
36
- const isComponentRouteKey = (route) => COMPONENT_ROUTE_KEYS.some((componentRoute) => componentRoute === route);
37
37
  const flattenFormFields = (fields) => fields.flatMap(([name, options]) => (Object.assign({ name }, options)));
38
+ const convertContactMethodsToFields = (unverifiedContactMethods) => {
39
+ return (unverifiedContactMethods &&
40
+ Object.entries(unverifiedContactMethods).map(([name, value]) => {
41
+ const valueIsString = isString(value);
42
+ if (!valueIsString || !name) {
43
+ return {};
44
+ }
45
+ return { name, label: value, type: 'radio', value };
46
+ }));
47
+ };
38
48
  /**
39
- * Retrieves legacy form field values from state machine for routes that have fields
49
+ * Retrieves default and custom (RWA only, to be updated) form field values from state machine
50
+ * for subcomponent routes that render fields
40
51
  */
41
- const getLegacyFields = (route, state) =>
42
- // verifyUser is a component route, but does not have form fields
43
- isComponentRouteKey(route) && route !== 'verifyUser'
44
- ? flattenFormFields(getSortedFormFields(route, state))
45
- : [];
52
+ const getMachineFields = (route, state, unverifiedContactMethods) => {
53
+ if (isComponentRouteKey(route)) {
54
+ return route === 'verifyUser'
55
+ ? convertContactMethodsToFields(unverifiedContactMethods)
56
+ : flattenFormFields(getSortedFormFields(route, state));
57
+ }
58
+ return [];
59
+ };
46
60
 
47
- export { areSelectorDepsEqual, defaultComparator, getComparator, getLegacyFields, getTotpSecretCodeCallback, isComponentRouteKey };
61
+ export { areSelectorDepsEqual, defaultComparator, getComparator, getMachineFields, getTotpSecretCodeCallback };
@@ -0,0 +1,17 @@
1
+ import React from 'react';
2
+ import useAuthenticator from '../useAuthenticator/useAuthenticator.js';
3
+
4
+ // only select `route` from machine context
5
+ const routeSelector = ({ route }) => [route];
6
+ function useAuthenticatorInitMachine(data) {
7
+ const { route, initializeMachine } = useAuthenticator(routeSelector);
8
+ const hasInitialized = React.useRef(false);
9
+ React.useEffect(() => {
10
+ if (!hasInitialized.current && route === 'setup') {
11
+ initializeMachine(data);
12
+ hasInitialized.current = true;
13
+ }
14
+ }, [initializeMachine, route, data]);
15
+ }
16
+
17
+ export { useAuthenticatorInitMachine as default, routeSelector };
@@ -0,0 +1,73 @@
1
+ const EVENT_HANDLER_KEY_MAP = {
2
+ updateBlur: 'handleBlur',
3
+ updateForm: 'handleChange',
4
+ submitForm: 'handleSubmit',
5
+ };
6
+ const COMMON_ROUTE_MACHINE_KEYS = [
7
+ 'error',
8
+ 'isPending',
9
+ 'submitForm',
10
+ 'updateBlur',
11
+ 'updateForm',
12
+ ];
13
+ const CONFIRM_RESET_PASSWORD_MACHINE_KEYS = [
14
+ ...COMMON_ROUTE_MACHINE_KEYS,
15
+ 'resendCode',
16
+ 'validationErrors',
17
+ ];
18
+ const CONFIRM_SIGN_IN_MACHINE_KEYS = [
19
+ ...COMMON_ROUTE_MACHINE_KEYS,
20
+ 'toSignIn',
21
+ 'user',
22
+ ];
23
+ const CONFIRM_SIGN_UP_MACHINE_KEYS = [
24
+ ...COMMON_ROUTE_MACHINE_KEYS,
25
+ 'codeDeliveryDetails',
26
+ 'resendCode',
27
+ ];
28
+ const CONFIRM_VERIFY_USER_MACHINE_KEYS = [
29
+ ...COMMON_ROUTE_MACHINE_KEYS,
30
+ 'skipVerification',
31
+ ];
32
+ const FORCE_NEW_PASSWORD_MACHINE_KEYS = [
33
+ ...COMMON_ROUTE_MACHINE_KEYS,
34
+ 'toSignIn',
35
+ 'validationErrors',
36
+ ];
37
+ const RESET_PASSWORD_MACHINE_KEYS = [
38
+ ...COMMON_ROUTE_MACHINE_KEYS,
39
+ 'toSignIn',
40
+ ];
41
+ const SIGN_IN_MACHINE_KEYS = [
42
+ ...COMMON_ROUTE_MACHINE_KEYS,
43
+ 'toFederatedSignIn',
44
+ 'toResetPassword',
45
+ 'toSignUp',
46
+ ];
47
+ const SIGN_UP_MACHINE_KEYS = [
48
+ ...COMMON_ROUTE_MACHINE_KEYS,
49
+ 'toSignIn',
50
+ 'validationErrors',
51
+ ];
52
+ const SETUP_TOTP_MACHINE_KEYS = [
53
+ ...COMMON_ROUTE_MACHINE_KEYS,
54
+ 'toSignIn',
55
+ ];
56
+ const VERIFY_USER_MACHINE_KEYS = [
57
+ ...COMMON_ROUTE_MACHINE_KEYS,
58
+ 'skipVerification',
59
+ ];
60
+ const MACHINE_PROP_KEYS = {
61
+ confirmResetPassword: CONFIRM_RESET_PASSWORD_MACHINE_KEYS,
62
+ confirmSignIn: CONFIRM_SIGN_IN_MACHINE_KEYS,
63
+ confirmSignUp: CONFIRM_SIGN_UP_MACHINE_KEYS,
64
+ confirmVerifyUser: CONFIRM_VERIFY_USER_MACHINE_KEYS,
65
+ forceNewPassword: FORCE_NEW_PASSWORD_MACHINE_KEYS,
66
+ signIn: SIGN_IN_MACHINE_KEYS,
67
+ signUp: SIGN_UP_MACHINE_KEYS,
68
+ resetPassword: RESET_PASSWORD_MACHINE_KEYS,
69
+ setupTOTP: SETUP_TOTP_MACHINE_KEYS,
70
+ verifyUser: VERIFY_USER_MACHINE_KEYS,
71
+ };
72
+
73
+ export { EVENT_HANDLER_KEY_MAP, MACHINE_PROP_KEYS };
@@ -0,0 +1,52 @@
1
+ import { useMemo } from 'react';
2
+ import useAuthenticator from '../useAuthenticator/useAuthenticator.js';
3
+ import { getRouteMachineSelector, resolveDefault, resolveVerifyUserRoute, resolveSignUpRoute, resolveSignInRoute, resolveSetupTOTPRoute, resolveResetPasswordRoute, resolveForceNewPasswordRoute, resolveConfirmVerifyUserRoute, resolveConfirmSignUpRoute, resolveConfirmSignInRoute, resolveConfirmResetPasswordRoute, routeSelector } from './utils.js';
4
+
5
+ function useAuthenticatorRoute({ components, }) {
6
+ const { route } = useAuthenticator(routeSelector);
7
+ const routeMachineSelector = useMemo(() => getRouteMachineSelector(route), [route]);
8
+ // `useAuthenticator` exposes both state machine (example: `toSignIn`) and non-state machine
9
+ // props (example: `getTotpSecretCode`). `routeSelector` specifies which state machine props
10
+ // should be returned for a specific route.
11
+ // Only state machine props specified by the current `routeSelector` will have their current value
12
+ // returned by `useAuthenticator`, non-machine props returned will always be the current value
13
+ const routeSelectorProps = useAuthenticator(routeMachineSelector);
14
+ const { ConfirmResetPassword, ConfirmSignIn, ConfirmSignUp, ConfirmVerifyUser, ForceNewPassword, ResetPassword, SetupTOTP, SignIn, SignUp, VerifyUser, } = components;
15
+ switch (route) {
16
+ case 'confirmResetPassword': {
17
+ return resolveConfirmResetPasswordRoute(ConfirmResetPassword, routeSelectorProps);
18
+ }
19
+ case 'confirmSignIn': {
20
+ return resolveConfirmSignInRoute(ConfirmSignIn, routeSelectorProps);
21
+ }
22
+ case 'confirmSignUp': {
23
+ return resolveConfirmSignUpRoute(ConfirmSignUp, routeSelectorProps);
24
+ }
25
+ case 'confirmVerifyUser': {
26
+ return resolveConfirmVerifyUserRoute(ConfirmVerifyUser, routeSelectorProps);
27
+ }
28
+ case 'forceNewPassword': {
29
+ return resolveForceNewPasswordRoute(ForceNewPassword, routeSelectorProps);
30
+ }
31
+ case 'resetPassword': {
32
+ return resolveResetPasswordRoute(ResetPassword, routeSelectorProps);
33
+ }
34
+ case 'setupTOTP': {
35
+ return resolveSetupTOTPRoute(SetupTOTP, routeSelectorProps);
36
+ }
37
+ case 'signIn': {
38
+ return resolveSignInRoute(SignIn, routeSelectorProps);
39
+ }
40
+ case 'signUp': {
41
+ return resolveSignUpRoute(SignUp, routeSelectorProps);
42
+ }
43
+ case 'verifyUser': {
44
+ return resolveVerifyUserRoute(VerifyUser, routeSelectorProps);
45
+ }
46
+ default: {
47
+ return resolveDefault();
48
+ }
49
+ }
50
+ }
51
+
52
+ export { useAuthenticatorRoute as default };
@@ -0,0 +1,89 @@
1
+ import { __rest } from '../../../node_modules/tslib/tslib.es6.js';
2
+ import RenderNothing from '../../../components/RenderNothing/RenderNothing.js';
3
+ import { isComponentRouteKey } from '../utils.js';
4
+ import { MACHINE_PROP_KEYS, EVENT_HANDLER_KEY_MAP } from './constants.js';
5
+
6
+ // only select `route` from machine context
7
+ const routeSelector = ({ route }) => [route];
8
+ const createSelector = (selectorKeys) => (context) => {
9
+ const dependencies = selectorKeys.map((key) => context[key]);
10
+ // route should always be part of deps, so hook knows when route changes.
11
+ return [...dependencies, context.route];
12
+ };
13
+ const getRouteMachineSelector = (route) => isComponentRouteKey(route)
14
+ ? createSelector(MACHINE_PROP_KEYS[route])
15
+ : routeSelector;
16
+ const isFormEventHandlerKey = (key) => ['updateBlur', 'updateForm', 'submitForm'].includes(key);
17
+ 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] })), {});
19
+ function resolveConfirmResetPasswordRoute(Component, props) {
20
+ return {
21
+ Component,
22
+ props: Object.assign(Object.assign({}, Component), getConvertedMachineProps('confirmResetPassword', props)),
23
+ };
24
+ }
25
+ 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 }) };
30
+ }
31
+ function resolveConfirmSignUpRoute(Component, props) {
32
+ return {
33
+ Component,
34
+ props: Object.assign(Object.assign({}, Component), getConvertedMachineProps('confirmSignUp', props)),
35
+ };
36
+ }
37
+ function resolveConfirmVerifyUserRoute(Component, props) {
38
+ return {
39
+ Component,
40
+ props: Object.assign(Object.assign({}, Component), getConvertedMachineProps('confirmVerifyUser', props)),
41
+ };
42
+ }
43
+ function resolveForceNewPasswordRoute(Component, props) {
44
+ return {
45
+ Component,
46
+ props: Object.assign(Object.assign({}, Component), getConvertedMachineProps('forceNewPassword', props)),
47
+ };
48
+ }
49
+ function resolveResetPasswordRoute(Component, props) {
50
+ return {
51
+ Component,
52
+ props: Object.assign(Object.assign({}, Component), getConvertedMachineProps('resetPassword', props)),
53
+ };
54
+ }
55
+ function resolveSetupTOTPRoute(Component, _a) {
56
+ var { getTotpSecretCode } = _a, props = __rest(_a, ["getTotpSecretCode"]);
57
+ return {
58
+ Component,
59
+ props: Object.assign(Object.assign(Object.assign({}, Component), getConvertedMachineProps('setupTOTP', props)), { getTotpSecretCode }),
60
+ };
61
+ }
62
+ function resolveSignInRoute(Component, props) {
63
+ // default `hideSignUp` to false
64
+ const hideSignUp = false;
65
+ return {
66
+ Component,
67
+ props: Object.assign(Object.assign(Object.assign({}, Component), getConvertedMachineProps('signIn', props)), { hideSignUp }),
68
+ };
69
+ }
70
+ function resolveSignUpRoute(Component, props) {
71
+ return {
72
+ Component,
73
+ props: Object.assign(Object.assign({}, Component), getConvertedMachineProps('signUp', props)),
74
+ };
75
+ }
76
+ function resolveVerifyUserRoute(Component, props) {
77
+ return {
78
+ Component,
79
+ props: Object.assign(Object.assign({}, Component), getConvertedMachineProps('verifyUser', props)),
80
+ };
81
+ }
82
+ function resolveDefault() {
83
+ return {
84
+ Component: RenderNothing,
85
+ props: {},
86
+ };
87
+ }
88
+
89
+ export { getRouteMachineSelector, resolveConfirmResetPasswordRoute, resolveConfirmSignInRoute, resolveConfirmSignUpRoute, resolveConfirmVerifyUserRoute, resolveDefault, resolveForceNewPasswordRoute, resolveResetPasswordRoute, resolveSetupTOTPRoute, resolveSignInRoute, resolveSignUpRoute, resolveVerifyUserRoute, routeSelector };
@@ -0,0 +1,24 @@
1
+ import { COMPONENT_ROUTE_KEYS, COMPONENT_ROUTE_NAMES } from './constants.js';
2
+
3
+ const isComponentRouteKey = (route) => COMPONENT_ROUTE_KEYS.some((componentRoute) => componentRoute === route);
4
+ function resolveAuthenticatorComponents(defaults, overrides) {
5
+ if (!overrides) {
6
+ return defaults;
7
+ }
8
+ return COMPONENT_ROUTE_NAMES.reduce((components, route) => {
9
+ const Default = defaults[route];
10
+ const Override = overrides[route];
11
+ if (typeof Override !== 'function') {
12
+ return Object.assign(Object.assign({}, components), { [route]: Default });
13
+ }
14
+ const { Footer, FormFields, Header } = Default;
15
+ // cast to allow assigning of component slots
16
+ const Component = Override;
17
+ Component.Footer = Footer;
18
+ Component.FormFields = FormFields;
19
+ Component.Header = Header;
20
+ return Object.assign(Object.assign({}, components), { [route]: Component });
21
+ }, {});
22
+ }
23
+
24
+ export { isComponentRouteKey, resolveAuthenticatorComponents };
@@ -1,7 +1,7 @@
1
1
  import { ConsoleLogger } from '@aws-amplify/core';
2
2
  import { InAppMessageInteractionEvent, Notifications } from '@aws-amplify/notifications';
3
3
  import isNil from 'lodash/isNil';
4
- import RenderNothng from '../../../components/RenderNothing/RenderNothing.js';
4
+ import RenderNothing from '../../../components/RenderNothing/RenderNothing.js';
5
5
  import useInAppMessaging from '../useInAppMessaging/useInAppMessaging.js';
6
6
  import { getContentProps, getPositionProp } from './utils.js';
7
7
 
@@ -19,7 +19,7 @@ function useMessage({ components, onMessageAction, }) {
19
19
  const { BannerMessage, CarouselMessage, FullScreenMessage, ModalMessage } = components;
20
20
  if (isNil(message)) {
21
21
  return {
22
- Component: RenderNothng,
22
+ Component: RenderNothing,
23
23
  props: EMPTY_PROPS,
24
24
  };
25
25
  }
@@ -68,7 +68,7 @@ function useMessage({ components, onMessageAction, }) {
68
68
  default: {
69
69
  logger.info(`Received unknown InAppMessage layout: ${layout}`);
70
70
  return {
71
- Component: RenderNothng,
71
+ Component: RenderNothing,
72
72
  props: EMPTY_PROPS,
73
73
  };
74
74
  }
@@ -1,8 +1,8 @@
1
1
  /**
2
2
  * Utility component for rendering nothing.
3
3
  */
4
- function RenderNothng(_) {
4
+ function RenderNothing(_) {
5
5
  return null;
6
6
  }
7
7
 
8
- export { RenderNothng as default };
8
+ export { RenderNothing as default };
@@ -0,0 +1,13 @@
1
+ import usePreviousValue from './usePreviousValue.js';
2
+ import isUndefined from 'lodash/isUndefined';
3
+
4
+ function useHasValueUpdated(value, ignoreFirstRender = false) {
5
+ const previous = usePreviousValue(value);
6
+ const shouldIgnoreChange = isUndefined(previous) && ignoreFirstRender;
7
+ if (shouldIgnoreChange) {
8
+ return false;
9
+ }
10
+ return previous !== value;
11
+ }
12
+
13
+ export { useHasValueUpdated as default };
@@ -0,0 +1,13 @@
1
+ import { useRef, useEffect } from 'react';
2
+
3
+ function usePreviousValue(value) {
4
+ const previous = useRef();
5
+ // update ref post render
6
+ useEffect(() => {
7
+ previous.current = value;
8
+ }, [value]);
9
+ // return previous ref
10
+ return previous.current;
11
+ }
12
+
13
+ export { usePreviousValue as default };
package/dist/esm/index.js CHANGED
@@ -1,8 +1,13 @@
1
1
  export { default as AuthenticatorProvider } from './Authenticator/context/AuthenticatorProvider.js';
2
2
  import './Authenticator/context/AuthenticatorContext.js';
3
3
  export { default as useAuthenticator } from './Authenticator/hooks/useAuthenticator/useAuthenticator.js';
4
+ export { default as useAuthenticatorRoute } from './Authenticator/hooks/useAuthenticatorRoute/useAuthenticatorRoute.js';
5
+ export { default as useAuthenticatorInitMachine } from './Authenticator/hooks/useAuthenticatorInitMachine/useAuthenticatorInitMachine.js';
6
+ export { isComponentRouteKey as isAuthenticatorComponentRouteKey, resolveAuthenticatorComponents } from './Authenticator/hooks/utils.js';
4
7
  export { default as useInAppMessaging } from './InAppMessaging/hooks/useInAppMessaging/useInAppMessaging.js';
5
8
  export { default as useMessage } from './InAppMessaging/hooks/useMessage/useMessage.js';
6
9
  import './InAppMessaging/context/InAppMessagingContext/InAppMessagingContext.js';
7
10
  export { default as InAppMessagingProvider } from './InAppMessaging/context/InAppMessagingProvider/InAppMessagingProvider.js';
8
11
  export { default as handleMessageAction } from './InAppMessaging/utils/handleMessageAction.js';
12
+ export { default as usePreviousValue } from './hooks/usePreviousValue.js';
13
+ export { default as useHasValueUpdated } from './hooks/useHasValueUpdated.js';