@dynamic-labs/sdk-react-core 0.19.4 → 0.19.5

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 (31) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/package.cjs +1 -1
  3. package/package.js +1 -1
  4. package/package.json +9 -9
  5. package/src/index.cjs +4 -2
  6. package/src/index.d.ts +1 -1
  7. package/src/index.js +2 -1
  8. package/src/lib/components/NeedHelpSection/NeedHelpSection.cjs +84 -5
  9. package/src/lib/components/NeedHelpSection/NeedHelpSection.js +85 -6
  10. package/src/lib/layout/DynamicAuthLayout/Header/header.cjs +9 -11
  11. package/src/lib/layout/DynamicAuthLayout/Header/header.js +10 -12
  12. package/src/lib/locale/en/translation.cjs +7 -3
  13. package/src/lib/locale/en/translation.d.ts +6 -2
  14. package/src/lib/locale/en/translation.js +7 -3
  15. package/src/lib/modals/SignMessageConfirmationModal/getProperErrorMessage.cjs +1 -1
  16. package/src/lib/modals/SignMessageConfirmationModal/getProperErrorMessage.js +1 -1
  17. package/src/lib/styles/index.shadow.cjs +1 -1
  18. package/src/lib/styles/index.shadow.js +1 -1
  19. package/src/lib/utils/hooks/index.d.ts +1 -0
  20. package/src/lib/utils/hooks/useFetchProjectSettings/useFetchProjectSettings.cjs +8 -1
  21. package/src/lib/utils/hooks/useFetchProjectSettings/useFetchProjectSettings.js +9 -2
  22. package/src/lib/utils/hooks/useWalletConnectors/useWalletConnectors.cjs +8 -0
  23. package/src/lib/utils/hooks/useWalletConnectors/useWalletConnectors.js +9 -1
  24. package/src/lib/views/LoginView/sections/SocialSignInSection/SocialSignInSection.cjs +2 -5
  25. package/src/lib/views/LoginView/sections/SocialSignInSection/SocialSignInSection.js +2 -5
  26. package/src/lib/views/LoginView/useLoginView.cjs +101 -84
  27. package/src/lib/views/LoginView/useLoginView.js +102 -85
  28. package/src/lib/widgets/DynamicWidget/views/ManagePasskeysWidgetView/PasskeyCard/PasskeyCard.cjs +16 -6
  29. package/src/lib/widgets/DynamicWidget/views/ManagePasskeysWidgetView/PasskeyCard/PasskeyCard.js +16 -6
  30. package/src/lib/utils/functions/getEnabledProviders/index.cjs +0 -7
  31. package/src/lib/utils/functions/getEnabledProviders/index.js +0 -3
@@ -20,14 +20,19 @@ require('@dynamic-labs/utils');
20
20
  require('../../shared/consts/index.cjs');
21
21
  require('@dynamic-labs/multi-wallet');
22
22
  var isEmailProviderEnabled = require('../../utils/functions/isEmailProviderEnabled/isEmailProviderEnabled.cjs');
23
- var index = require('../../utils/functions/getEnabledProviders/index.cjs');
24
23
 
25
24
  /* eslint-disable multiline-comment-style */
26
25
  const NUMBER_OF_WALLETS = 3;
27
26
  const useLoginView = () => {
28
- var _a, _b, _c, _d;
27
+ var _a, _b, _c, _d, _e, _f;
29
28
  const { projectSettings, authorizationViewDisplayOrder, loginWithEmail, wallets, walletsFilter, } = useInternalDynamicContext.useInternalDynamicContext();
29
+ const { t } = reactI18next.useTranslation();
30
30
  const { enabledSocialProviders } = SocialRedirectContext.useSocialRedirectContext();
31
+ const hasSocialProvidersEnabled = Boolean(enabledSocialProviders === null || enabledSocialProviders === void 0 ? void 0 : enabledSocialProviders.length);
32
+ const hasEmailProviderEnabled = ((_a = projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.providers) === null || _a === void 0 ? void 0 : _a.length) &&
33
+ isEmailProviderEnabled.isEmailProviderEnabled(projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.providers);
34
+ // is email only is set in the project settings when the "Email (Web2) only" is toggled on in the dashboard
35
+ const isEmailOnly = (_c = (_b = projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.design) === null || _b === void 0 ? void 0 : _b.modal) === null || _c === void 0 ? void 0 : _c.emailOnly;
31
36
  /** Takes from wallets only those that can be selected in the wallet list by the user.
32
37
  * Should filter out embedded wallets
33
38
  * WHY: when we decide whether to show wallets or not, we need to know how many wallets
@@ -35,61 +40,91 @@ const useLoginView = () => {
35
40
  * wallets and then display an empty wallet list (since turnkey doesn't render)
36
41
  */
37
42
  const selectableWallets = (walletsFilter ? walletsFilter(wallets) : wallets).filter(({ key }) => key !== 'turnkey');
38
- const { t } = reactI18next.useTranslation();
39
- const hasEnabledProviders = Boolean(index.getEnabledProviders(projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.providers).length);
43
+ const separator = React.useMemo(() => ({
44
+ label: t('dyn_login.separators.default'),
45
+ type: sdkApi.SdkViewSectionType.Separator,
46
+ }), [t]);
40
47
  const isWalletOnly = React.useMemo(() => {
41
- var _a, _b, _c, _d;
48
+ var _a, _b, _c;
42
49
  if (!projectSettings) {
43
50
  return false;
44
51
  }
45
- // toolkit functionality overrides whatever is defined
46
- if (!loginWithEmail) {
52
+ // if both loginWithEmail AND hasSocialProvidersEnabled are false, it's wallet only
53
+ if (!loginWithEmail && !hasSocialProvidersEnabled) {
47
54
  return true;
48
55
  }
49
56
  const loginView = (_b = (_a = projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.sdk) === null || _a === void 0 ? void 0 : _a.views) === null || _b === void 0 ? void 0 : _b.find((view) => view.type === sdkApi.SdkViewType.Login);
50
- // backwards compatibility for those that didn't set up login view sessions
57
+ // backwards compatibility for those that didn't set up login view sections
51
58
  if (!((_c = loginView === null || loginView === void 0 ? void 0 : loginView.sections) === null || _c === void 0 ? void 0 : _c.length)) {
52
- return (!((_d = projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.providers) === null || _d === void 0 ? void 0 : _d.length) ||
53
- !isEmailProviderEnabled.isEmailProviderEnabled(projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.providers));
59
+ return !hasEmailProviderEnabled && !hasSocialProvidersEnabled;
54
60
  }
55
61
  return (loginView.sections.length === 1 && loginView.sections[0].type === 'wallet');
56
- }, [projectSettings, loginWithEmail]);
62
+ }, [
63
+ projectSettings,
64
+ loginWithEmail,
65
+ hasSocialProvidersEnabled,
66
+ hasEmailProviderEnabled,
67
+ enabledSocialProviders === null || enabledSocialProviders === void 0 ? void 0 : enabledSocialProviders.length,
68
+ ]);
57
69
  /**
58
- * build email and social view sections from project settings design.modal props - backwards compatibility
70
+ * build email from project settings design.modal props
59
71
  * @returns SdkViewSection[]
60
72
  */
61
73
  const getEmailViewSectionDefinition = React.useCallback(() => {
62
- var _a, _b;
63
- const loginViewSections = [
74
+ if (!hasEmailProviderEnabled)
75
+ return [];
76
+ return [
64
77
  {
65
78
  type: sdkApi.SdkViewSectionType.Email,
66
79
  },
67
80
  ];
68
- if (enabledSocialProviders === null || enabledSocialProviders === void 0 ? void 0 : enabledSocialProviders.length) {
69
- const socialSection = {
81
+ }, [hasEmailProviderEnabled]);
82
+ /**
83
+ * build social from project settings design.modal props
84
+ * @returns SdkViewSection[]
85
+ */
86
+ const getSocialViewSectionDefinition = React.useCallback(() => {
87
+ if (!(enabledSocialProviders === null || enabledSocialProviders === void 0 ? void 0 : enabledSocialProviders.length))
88
+ return [];
89
+ return [
90
+ {
70
91
  numOfItemsToDisplay: 5,
71
92
  type: sdkApi.SdkViewSectionType.Social,
72
- };
73
- loginViewSections.push(socialSection);
74
- if ((_a = projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.design.modal) === null || _a === void 0 ? void 0 : _a.splitEmailAndSocial) {
75
- loginViewSections.splice(1, 0, {
76
- label: t('dyn_login.separators.default'),
77
- type: sdkApi.SdkViewSectionType.Separator,
78
- });
79
- // eslint-disable-next-line prefer-destructuring
80
- socialSection.defaultItem = enabledSocialProviders[0];
81
- }
82
- }
83
- if ((_b = projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.design.modal) === null || _b === void 0 ? void 0 : _b.socialAboveEmail) {
84
- loginViewSections.reverse();
85
- }
86
- return loginViewSections;
93
+ },
94
+ ];
95
+ }, [enabledSocialProviders === null || enabledSocialProviders === void 0 ? void 0 : enabledSocialProviders.length]);
96
+ const getWalletViewSectionDefinition = React.useCallback(() => {
97
+ var _a, _b;
98
+ if (!(selectableWallets === null || selectableWallets === void 0 ? void 0 : selectableWallets.length))
99
+ return [];
100
+ const numOfItemsToDisplay = ((_b = (_a = projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.design) === null || _a === void 0 ? void 0 : _a.modal) === null || _b === void 0 ? void 0 : _b.showWalletsButton)
101
+ ? 0
102
+ : NUMBER_OF_WALLETS;
103
+ return [
104
+ {
105
+ numOfItemsToDisplay,
106
+ type: sdkApi.SdkViewSectionType.Wallet,
107
+ },
108
+ ];
87
109
  }, [
88
- enabledSocialProviders,
89
- (_a = projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.design.modal) === null || _a === void 0 ? void 0 : _a.socialAboveEmail,
90
- (_b = projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.design.modal) === null || _b === void 0 ? void 0 : _b.splitEmailAndSocial,
91
- t,
110
+ (_e = (_d = projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.design) === null || _d === void 0 ? void 0 : _d.modal) === null || _e === void 0 ? void 0 : _e.showWalletsButton,
111
+ selectableWallets === null || selectableWallets === void 0 ? void 0 : selectableWallets.length,
92
112
  ]);
113
+ const applyLoginModalSettings = React.useCallback((emailAndSocialSections) => {
114
+ if (emailAndSocialSections.length < 2) {
115
+ return emailAndSocialSections;
116
+ }
117
+ const { splitEmailAndSocial, socialAboveEmail } = (projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.design.modal) || {};
118
+ if (splitEmailAndSocial) {
119
+ emailAndSocialSections.splice(1, 0, separator);
120
+ // eslint-disable-next-line prefer-destructuring
121
+ emailAndSocialSections[2].defaultItem = enabledSocialProviders[0];
122
+ }
123
+ if (socialAboveEmail) {
124
+ emailAndSocialSections.reverse();
125
+ }
126
+ return emailAndSocialSections;
127
+ }, [enabledSocialProviders, projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.design.modal, separator]);
93
128
  // TODO: https://linear.app/dynamic-labs/issue/GVTY-212/rethink-or-implement-toolkit-template-for-email-wallet-order
94
129
  /**
95
130
  * remove wallet view section from projectSettings?.sdk?.views if no wallet defined
@@ -102,78 +137,60 @@ const useLoginView = () => {
102
137
  }
103
138
  return sections.filter((section) => section.type !== 'wallet');
104
139
  }, [selectableWallets === null || selectableWallets === void 0 ? void 0 : selectableWallets.length]);
105
- const addSeparator = React.useCallback((index) => {
106
- // if not the first index, no separator is needed
107
- // if the first index but does not have wallets or providers,
108
- // it'll show only one view section - no separator is needed
109
- if (index !== 0 || !(selectableWallets === null || selectableWallets === void 0 ? void 0 : selectableWallets.length) || !hasEnabledProviders) {
110
- return [];
111
- }
112
- return [
113
- {
114
- label: t('dyn_login.separators.default'),
115
- type: sdkApi.SdkViewSectionType.Separator,
116
- },
117
- ];
118
- }, [hasEnabledProviders, selectableWallets === null || selectableWallets === void 0 ? void 0 : selectableWallets.length, t]);
119
140
  /**
120
141
  * build login view sections array from project settings design.modal props - backwards compatibility
121
142
  * @returns SdkViewSection[]
122
143
  */
123
- const buildLoginSections = React.useCallback(() => {
124
- let loginViewSections = [];
125
- authorizationViewDisplayOrder === null || authorizationViewDisplayOrder === void 0 ? void 0 : authorizationViewDisplayOrder.forEach((loginItem, index) => {
126
- var _a, _b;
127
- if (loginItem === 'email' &&
128
- (projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.providers) &&
129
- isEmailProviderEnabled.isEmailProviderEnabled(projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.providers)) {
130
- loginViewSections = loginViewSections.concat(getEmailViewSectionDefinition(),
131
- // add separator if wallets defined
132
- addSeparator(index));
144
+ const buildLoginSections = React.useCallback((buildOrder) => {
145
+ const loginViewSections = [];
146
+ buildOrder === null || buildOrder === void 0 ? void 0 : buildOrder.forEach((loginItem) => {
147
+ // Add a separator if there are sections already
148
+ if (loginViewSections.length)
149
+ loginViewSections.push(separator);
150
+ if (loginItem === 'email') {
151
+ // In the past, the email and social sections were combined into one section,
152
+ // so we need to check for that case and add the social section if needed for backwards compatibility
153
+ // if email was just pushed to the loginViewSections array and social is not defined in the buildOrder,
154
+ // then we need to add social (if social is enabled)
155
+ const emailAndSocialSections = [
156
+ ...getEmailViewSectionDefinition(),
157
+ ...getSocialViewSectionDefinition(),
158
+ ];
159
+ loginViewSections.push(...applyLoginModalSettings(emailAndSocialSections));
133
160
  }
134
- if (loginItem === 'wallet' && (selectableWallets === null || selectableWallets === void 0 ? void 0 : selectableWallets.length)) {
135
- // if showWalletsButton is true, it should show "Connec with Wallet" button
136
- const numOfItemsToDisplay = ((_b = (_a = projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.design) === null || _a === void 0 ? void 0 : _a.modal) === null || _b === void 0 ? void 0 : _b.showWalletsButton)
137
- ? 0
138
- : NUMBER_OF_WALLETS;
139
- loginViewSections = loginViewSections.concat([
140
- {
141
- numOfItemsToDisplay,
142
- type: sdkApi.SdkViewSectionType.Wallet,
143
- },
144
- ],
145
- // add separator if email providers defined
146
- addSeparator(index));
161
+ if (loginItem === 'wallet') {
162
+ loginViewSections.push(...getWalletViewSectionDefinition());
147
163
  }
148
164
  });
149
165
  return loginViewSections;
150
166
  }, [
151
- addSeparator,
152
- authorizationViewDisplayOrder,
167
+ applyLoginModalSettings,
153
168
  getEmailViewSectionDefinition,
154
- (_d = (_c = projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.design) === null || _c === void 0 ? void 0 : _c.modal) === null || _d === void 0 ? void 0 : _d.showWalletsButton,
155
- projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.providers,
156
- selectableWallets === null || selectableWallets === void 0 ? void 0 : selectableWallets.length,
169
+ getSocialViewSectionDefinition,
170
+ getWalletViewSectionDefinition,
171
+ separator,
157
172
  ]);
158
173
  /**
159
174
  * returns the login view sections to be displayed in order from projectSettings?.sdk?.views
160
175
  * and has backwards compatibility with project settings design.modal props
161
176
  */
162
177
  const logingViewSections = React.useMemo(() => {
163
- var _a, _b, _c, _d, _e;
178
+ var _a, _b, _c;
164
179
  const loginView = (_b = (_a = projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.sdk) === null || _a === void 0 ? void 0 : _a.views) === null || _b === void 0 ? void 0 : _b.find((view) => view.type === sdkApi.SdkViewType.Login);
165
180
  if ((_c = loginView === null || loginView === void 0 ? void 0 : loginView.sections) === null || _c === void 0 ? void 0 : _c.length) {
166
181
  return filterLoginViewSections(loginView === null || loginView === void 0 ? void 0 : loginView.sections);
167
182
  }
168
- if ((_e = (_d = projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.design) === null || _d === void 0 ? void 0 : _d.modal) === null || _e === void 0 ? void 0 : _e.emailOnly) {
169
- return getEmailViewSectionDefinition();
183
+ let viewOrder = authorizationViewDisplayOrder;
184
+ if (isEmailOnly) {
185
+ viewOrder = ['email'];
170
186
  }
171
- return buildLoginSections();
187
+ return buildLoginSections(viewOrder);
172
188
  }, [
173
- projectSettings,
174
- getEmailViewSectionDefinition,
175
- filterLoginViewSections,
189
+ (_f = projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.sdk) === null || _f === void 0 ? void 0 : _f.views,
190
+ authorizationViewDisplayOrder,
191
+ isEmailOnly,
176
192
  buildLoginSections,
193
+ filterLoginViewSections,
177
194
  ]);
178
195
  return {
179
196
  isWalletOnly,
@@ -1,6 +1,6 @@
1
1
  import { useMemo, useCallback } from 'react';
2
2
  import { useTranslation } from 'react-i18next';
3
- import { SdkViewType, SdkViewSectionType } from '@dynamic-labs/sdk-api';
3
+ import { SdkViewSectionType, SdkViewType } from '@dynamic-labs/sdk-api';
4
4
  import { useInternalDynamicContext } from '../../context/DynamicContext/useInternalDynamicContext.js';
5
5
  import { useSocialRedirectContext } from '../../context/SocialRedirectContext/SocialRedirectContext.js';
6
6
  import '../../shared/logger.js';
@@ -16,14 +16,19 @@ import '@dynamic-labs/utils';
16
16
  import '../../shared/consts/index.js';
17
17
  import '@dynamic-labs/multi-wallet';
18
18
  import { isEmailProviderEnabled } from '../../utils/functions/isEmailProviderEnabled/isEmailProviderEnabled.js';
19
- import { getEnabledProviders } from '../../utils/functions/getEnabledProviders/index.js';
20
19
 
21
20
  /* eslint-disable multiline-comment-style */
22
21
  const NUMBER_OF_WALLETS = 3;
23
22
  const useLoginView = () => {
24
- var _a, _b, _c, _d;
23
+ var _a, _b, _c, _d, _e, _f;
25
24
  const { projectSettings, authorizationViewDisplayOrder, loginWithEmail, wallets, walletsFilter, } = useInternalDynamicContext();
25
+ const { t } = useTranslation();
26
26
  const { enabledSocialProviders } = useSocialRedirectContext();
27
+ const hasSocialProvidersEnabled = Boolean(enabledSocialProviders === null || enabledSocialProviders === void 0 ? void 0 : enabledSocialProviders.length);
28
+ const hasEmailProviderEnabled = ((_a = projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.providers) === null || _a === void 0 ? void 0 : _a.length) &&
29
+ isEmailProviderEnabled(projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.providers);
30
+ // is email only is set in the project settings when the "Email (Web2) only" is toggled on in the dashboard
31
+ const isEmailOnly = (_c = (_b = projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.design) === null || _b === void 0 ? void 0 : _b.modal) === null || _c === void 0 ? void 0 : _c.emailOnly;
27
32
  /** Takes from wallets only those that can be selected in the wallet list by the user.
28
33
  * Should filter out embedded wallets
29
34
  * WHY: when we decide whether to show wallets or not, we need to know how many wallets
@@ -31,61 +36,91 @@ const useLoginView = () => {
31
36
  * wallets and then display an empty wallet list (since turnkey doesn't render)
32
37
  */
33
38
  const selectableWallets = (walletsFilter ? walletsFilter(wallets) : wallets).filter(({ key }) => key !== 'turnkey');
34
- const { t } = useTranslation();
35
- const hasEnabledProviders = Boolean(getEnabledProviders(projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.providers).length);
39
+ const separator = useMemo(() => ({
40
+ label: t('dyn_login.separators.default'),
41
+ type: SdkViewSectionType.Separator,
42
+ }), [t]);
36
43
  const isWalletOnly = useMemo(() => {
37
- var _a, _b, _c, _d;
44
+ var _a, _b, _c;
38
45
  if (!projectSettings) {
39
46
  return false;
40
47
  }
41
- // toolkit functionality overrides whatever is defined
42
- if (!loginWithEmail) {
48
+ // if both loginWithEmail AND hasSocialProvidersEnabled are false, it's wallet only
49
+ if (!loginWithEmail && !hasSocialProvidersEnabled) {
43
50
  return true;
44
51
  }
45
52
  const loginView = (_b = (_a = projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.sdk) === null || _a === void 0 ? void 0 : _a.views) === null || _b === void 0 ? void 0 : _b.find((view) => view.type === SdkViewType.Login);
46
- // backwards compatibility for those that didn't set up login view sessions
53
+ // backwards compatibility for those that didn't set up login view sections
47
54
  if (!((_c = loginView === null || loginView === void 0 ? void 0 : loginView.sections) === null || _c === void 0 ? void 0 : _c.length)) {
48
- return (!((_d = projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.providers) === null || _d === void 0 ? void 0 : _d.length) ||
49
- !isEmailProviderEnabled(projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.providers));
55
+ return !hasEmailProviderEnabled && !hasSocialProvidersEnabled;
50
56
  }
51
57
  return (loginView.sections.length === 1 && loginView.sections[0].type === 'wallet');
52
- }, [projectSettings, loginWithEmail]);
58
+ }, [
59
+ projectSettings,
60
+ loginWithEmail,
61
+ hasSocialProvidersEnabled,
62
+ hasEmailProviderEnabled,
63
+ enabledSocialProviders === null || enabledSocialProviders === void 0 ? void 0 : enabledSocialProviders.length,
64
+ ]);
53
65
  /**
54
- * build email and social view sections from project settings design.modal props - backwards compatibility
66
+ * build email from project settings design.modal props
55
67
  * @returns SdkViewSection[]
56
68
  */
57
69
  const getEmailViewSectionDefinition = useCallback(() => {
58
- var _a, _b;
59
- const loginViewSections = [
70
+ if (!hasEmailProviderEnabled)
71
+ return [];
72
+ return [
60
73
  {
61
74
  type: SdkViewSectionType.Email,
62
75
  },
63
76
  ];
64
- if (enabledSocialProviders === null || enabledSocialProviders === void 0 ? void 0 : enabledSocialProviders.length) {
65
- const socialSection = {
77
+ }, [hasEmailProviderEnabled]);
78
+ /**
79
+ * build social from project settings design.modal props
80
+ * @returns SdkViewSection[]
81
+ */
82
+ const getSocialViewSectionDefinition = useCallback(() => {
83
+ if (!(enabledSocialProviders === null || enabledSocialProviders === void 0 ? void 0 : enabledSocialProviders.length))
84
+ return [];
85
+ return [
86
+ {
66
87
  numOfItemsToDisplay: 5,
67
88
  type: SdkViewSectionType.Social,
68
- };
69
- loginViewSections.push(socialSection);
70
- if ((_a = projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.design.modal) === null || _a === void 0 ? void 0 : _a.splitEmailAndSocial) {
71
- loginViewSections.splice(1, 0, {
72
- label: t('dyn_login.separators.default'),
73
- type: SdkViewSectionType.Separator,
74
- });
75
- // eslint-disable-next-line prefer-destructuring
76
- socialSection.defaultItem = enabledSocialProviders[0];
77
- }
78
- }
79
- if ((_b = projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.design.modal) === null || _b === void 0 ? void 0 : _b.socialAboveEmail) {
80
- loginViewSections.reverse();
81
- }
82
- return loginViewSections;
89
+ },
90
+ ];
91
+ }, [enabledSocialProviders === null || enabledSocialProviders === void 0 ? void 0 : enabledSocialProviders.length]);
92
+ const getWalletViewSectionDefinition = useCallback(() => {
93
+ var _a, _b;
94
+ if (!(selectableWallets === null || selectableWallets === void 0 ? void 0 : selectableWallets.length))
95
+ return [];
96
+ const numOfItemsToDisplay = ((_b = (_a = projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.design) === null || _a === void 0 ? void 0 : _a.modal) === null || _b === void 0 ? void 0 : _b.showWalletsButton)
97
+ ? 0
98
+ : NUMBER_OF_WALLETS;
99
+ return [
100
+ {
101
+ numOfItemsToDisplay,
102
+ type: SdkViewSectionType.Wallet,
103
+ },
104
+ ];
83
105
  }, [
84
- enabledSocialProviders,
85
- (_a = projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.design.modal) === null || _a === void 0 ? void 0 : _a.socialAboveEmail,
86
- (_b = projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.design.modal) === null || _b === void 0 ? void 0 : _b.splitEmailAndSocial,
87
- t,
106
+ (_e = (_d = projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.design) === null || _d === void 0 ? void 0 : _d.modal) === null || _e === void 0 ? void 0 : _e.showWalletsButton,
107
+ selectableWallets === null || selectableWallets === void 0 ? void 0 : selectableWallets.length,
88
108
  ]);
109
+ const applyLoginModalSettings = useCallback((emailAndSocialSections) => {
110
+ if (emailAndSocialSections.length < 2) {
111
+ return emailAndSocialSections;
112
+ }
113
+ const { splitEmailAndSocial, socialAboveEmail } = (projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.design.modal) || {};
114
+ if (splitEmailAndSocial) {
115
+ emailAndSocialSections.splice(1, 0, separator);
116
+ // eslint-disable-next-line prefer-destructuring
117
+ emailAndSocialSections[2].defaultItem = enabledSocialProviders[0];
118
+ }
119
+ if (socialAboveEmail) {
120
+ emailAndSocialSections.reverse();
121
+ }
122
+ return emailAndSocialSections;
123
+ }, [enabledSocialProviders, projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.design.modal, separator]);
89
124
  // TODO: https://linear.app/dynamic-labs/issue/GVTY-212/rethink-or-implement-toolkit-template-for-email-wallet-order
90
125
  /**
91
126
  * remove wallet view section from projectSettings?.sdk?.views if no wallet defined
@@ -98,78 +133,60 @@ const useLoginView = () => {
98
133
  }
99
134
  return sections.filter((section) => section.type !== 'wallet');
100
135
  }, [selectableWallets === null || selectableWallets === void 0 ? void 0 : selectableWallets.length]);
101
- const addSeparator = useCallback((index) => {
102
- // if not the first index, no separator is needed
103
- // if the first index but does not have wallets or providers,
104
- // it'll show only one view section - no separator is needed
105
- if (index !== 0 || !(selectableWallets === null || selectableWallets === void 0 ? void 0 : selectableWallets.length) || !hasEnabledProviders) {
106
- return [];
107
- }
108
- return [
109
- {
110
- label: t('dyn_login.separators.default'),
111
- type: SdkViewSectionType.Separator,
112
- },
113
- ];
114
- }, [hasEnabledProviders, selectableWallets === null || selectableWallets === void 0 ? void 0 : selectableWallets.length, t]);
115
136
  /**
116
137
  * build login view sections array from project settings design.modal props - backwards compatibility
117
138
  * @returns SdkViewSection[]
118
139
  */
119
- const buildLoginSections = useCallback(() => {
120
- let loginViewSections = [];
121
- authorizationViewDisplayOrder === null || authorizationViewDisplayOrder === void 0 ? void 0 : authorizationViewDisplayOrder.forEach((loginItem, index) => {
122
- var _a, _b;
123
- if (loginItem === 'email' &&
124
- (projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.providers) &&
125
- isEmailProviderEnabled(projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.providers)) {
126
- loginViewSections = loginViewSections.concat(getEmailViewSectionDefinition(),
127
- // add separator if wallets defined
128
- addSeparator(index));
140
+ const buildLoginSections = useCallback((buildOrder) => {
141
+ const loginViewSections = [];
142
+ buildOrder === null || buildOrder === void 0 ? void 0 : buildOrder.forEach((loginItem) => {
143
+ // Add a separator if there are sections already
144
+ if (loginViewSections.length)
145
+ loginViewSections.push(separator);
146
+ if (loginItem === 'email') {
147
+ // In the past, the email and social sections were combined into one section,
148
+ // so we need to check for that case and add the social section if needed for backwards compatibility
149
+ // if email was just pushed to the loginViewSections array and social is not defined in the buildOrder,
150
+ // then we need to add social (if social is enabled)
151
+ const emailAndSocialSections = [
152
+ ...getEmailViewSectionDefinition(),
153
+ ...getSocialViewSectionDefinition(),
154
+ ];
155
+ loginViewSections.push(...applyLoginModalSettings(emailAndSocialSections));
129
156
  }
130
- if (loginItem === 'wallet' && (selectableWallets === null || selectableWallets === void 0 ? void 0 : selectableWallets.length)) {
131
- // if showWalletsButton is true, it should show "Connec with Wallet" button
132
- const numOfItemsToDisplay = ((_b = (_a = projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.design) === null || _a === void 0 ? void 0 : _a.modal) === null || _b === void 0 ? void 0 : _b.showWalletsButton)
133
- ? 0
134
- : NUMBER_OF_WALLETS;
135
- loginViewSections = loginViewSections.concat([
136
- {
137
- numOfItemsToDisplay,
138
- type: SdkViewSectionType.Wallet,
139
- },
140
- ],
141
- // add separator if email providers defined
142
- addSeparator(index));
157
+ if (loginItem === 'wallet') {
158
+ loginViewSections.push(...getWalletViewSectionDefinition());
143
159
  }
144
160
  });
145
161
  return loginViewSections;
146
162
  }, [
147
- addSeparator,
148
- authorizationViewDisplayOrder,
163
+ applyLoginModalSettings,
149
164
  getEmailViewSectionDefinition,
150
- (_d = (_c = projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.design) === null || _c === void 0 ? void 0 : _c.modal) === null || _d === void 0 ? void 0 : _d.showWalletsButton,
151
- projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.providers,
152
- selectableWallets === null || selectableWallets === void 0 ? void 0 : selectableWallets.length,
165
+ getSocialViewSectionDefinition,
166
+ getWalletViewSectionDefinition,
167
+ separator,
153
168
  ]);
154
169
  /**
155
170
  * returns the login view sections to be displayed in order from projectSettings?.sdk?.views
156
171
  * and has backwards compatibility with project settings design.modal props
157
172
  */
158
173
  const logingViewSections = useMemo(() => {
159
- var _a, _b, _c, _d, _e;
174
+ var _a, _b, _c;
160
175
  const loginView = (_b = (_a = projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.sdk) === null || _a === void 0 ? void 0 : _a.views) === null || _b === void 0 ? void 0 : _b.find((view) => view.type === SdkViewType.Login);
161
176
  if ((_c = loginView === null || loginView === void 0 ? void 0 : loginView.sections) === null || _c === void 0 ? void 0 : _c.length) {
162
177
  return filterLoginViewSections(loginView === null || loginView === void 0 ? void 0 : loginView.sections);
163
178
  }
164
- if ((_e = (_d = projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.design) === null || _d === void 0 ? void 0 : _d.modal) === null || _e === void 0 ? void 0 : _e.emailOnly) {
165
- return getEmailViewSectionDefinition();
179
+ let viewOrder = authorizationViewDisplayOrder;
180
+ if (isEmailOnly) {
181
+ viewOrder = ['email'];
166
182
  }
167
- return buildLoginSections();
183
+ return buildLoginSections(viewOrder);
168
184
  }, [
169
- projectSettings,
170
- getEmailViewSectionDefinition,
171
- filterLoginViewSections,
185
+ (_f = projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.sdk) === null || _f === void 0 ? void 0 : _f.views,
186
+ authorizationViewDisplayOrder,
187
+ isEmailOnly,
172
188
  buildLoginSections,
189
+ filterLoginViewSections,
173
190
  ]);
174
191
  return {
175
192
  isWalletOnly,
@@ -3,9 +3,9 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var jsxRuntime = require('react/jsx-runtime');
6
+ var React = require('react');
6
7
  var reactI18next = require('react-i18next');
7
8
  var iconic = require('@dynamic-labs/iconic');
8
- require('react');
9
9
  var Typography = require('../../../../../components/Typography/Typography.cjs');
10
10
  require('@dynamic-labs/sdk-api');
11
11
  require('../../../../../shared/logger.cjs');
@@ -21,6 +21,7 @@ require('../../../../../context/DynamicContext/DynamicContext.cjs');
21
21
  require('@dynamic-labs/multi-wallet');
22
22
  require('../../../../../components/ShadowDOM/ShadowDOM.cjs');
23
23
  require('../../../../../context/ThemeContext/ThemeContext.cjs');
24
+ var classNames = require('../../../../../utils/functions/classNames/classNames.cjs');
24
25
  require('react-dom');
25
26
  require('react-focus-lock');
26
27
  require('../../../../../components/Transition/ZoomTransition/ZoomTransition.cjs');
@@ -71,6 +72,7 @@ const mapPasskeyProviderToIcon = {
71
72
  };
72
73
  const PasskeyCard = ({ passkey }) => {
73
74
  const { t } = reactI18next.useTranslation();
75
+ const [showTooltip, setShowTooltip] = React.useState(false);
74
76
  const { value: timeSinceValue, unit: timeSinceUnit } = getTimeSince.getTimeSince(passkey.createdAt);
75
77
  const PasskeyProviderIcon = () => {
76
78
  if (!passkey.userAgent)
@@ -88,11 +90,19 @@ const PasskeyCard = ({ passkey }) => {
88
90
  return null;
89
91
  return t(`dyn_manage_passkeys.passkey_providers.${provider}`);
90
92
  };
91
- return (jsxRuntime.jsxs("div", { className: 'passkey-card', children: [jsxRuntime.jsxs("div", { className: 'passkey-card__info', children: [jsxRuntime.jsx("div", { className: 'passkey-card__info__icon', children: jsxRuntime.jsx(PasskeyProviderIcon, {}) }), jsxRuntime.jsxs("div", { className: 'passkey-card__info__text', children: [jsxRuntime.jsx(Typography.Typography, { variant: 'body_normal', color: 'primary', children: shortenEmail.shortenEmail(passkey.alias, {
92
- breakpoint: 12,
93
- cutEnd: 4,
94
- cutStart: 4,
95
- }) }), getPasskeyProviderName() && (jsxRuntime.jsxs(Typography.Typography, { variant: 'body_small', color: 'secondary', children: [t('dyn_manage_passkeys.passkey_from'), " ", getPasskeyProviderName()] }))] })] }), jsxRuntime.jsx("div", { className: 'passkey-card__date', children: jsxRuntime.jsxs(Typography.Typography, { variant: 'body_small', color: 'secondary', children: [t('dyn_time_since.created'), ' ', `${timeSinceValue} ${timeSinceUnit} ${t('dyn_time_since.ago')}`] }) })] }));
93
+ const handleShowTooltip = () => {
94
+ setShowTooltip(true);
95
+ setTimeout(() => {
96
+ setShowTooltip(false);
97
+ }, 2000);
98
+ };
99
+ return (jsxRuntime.jsxs("div", { className: 'passkey-card', children: [jsxRuntime.jsxs("div", { className: 'passkey-card__info', children: [jsxRuntime.jsx("div", { className: 'passkey-card__info__icon', "data-testId": 'provider-icon', children: jsxRuntime.jsx(PasskeyProviderIcon, {}) }), jsxRuntime.jsxs("div", { className: 'passkey-card__info__text', children: [jsxRuntime.jsxs(Typography.Typography, { "data-testid": 'passkey-alias', variant: 'body_normal', color: 'primary', title: passkey.alias, onClick: handleShowTooltip, children: [shortenEmail.shortenEmail(passkey.alias, {
100
+ breakpoint: 12,
101
+ cutEnd: 4,
102
+ cutStart: 4,
103
+ }), jsxRuntime.jsx("p", { className: classNames.classNames('passkey-card__info__tooltip', {
104
+ 'passkey-card__info__tooltip--visible': showTooltip,
105
+ }), children: passkey.alias })] }), getPasskeyProviderName() && (jsxRuntime.jsxs(Typography.Typography, { variant: 'body_small', color: 'secondary', children: [t('dyn_manage_passkeys.passkey_from'), " ", getPasskeyProviderName()] }))] })] }), jsxRuntime.jsx("div", { className: 'passkey-card__date', children: jsxRuntime.jsxs(Typography.Typography, { variant: 'body_small', color: 'secondary', children: [t('dyn_time_since.created'), ' ', `${timeSinceValue} ${timeSinceUnit} ${t('dyn_time_since.ago')}`] }) })] }));
96
106
  };
97
107
 
98
108
  exports.PasskeyCard = PasskeyCard;
@@ -1,7 +1,7 @@
1
1
  import { jsx, jsxs } from 'react/jsx-runtime';
2
+ import { useState } from 'react';
2
3
  import { useTranslation } from 'react-i18next';
3
4
  import { AndroidIcon, BraveIcon, ChromeIcon, EdgeIcon, FirefoxIcon, AppleIcon, OperaIcon, SafariIcon } from '@dynamic-labs/iconic';
4
- import 'react';
5
5
  import { Typography } from '../../../../../components/Typography/Typography.js';
6
6
  import '@dynamic-labs/sdk-api';
7
7
  import '../../../../../shared/logger.js';
@@ -17,6 +17,7 @@ import '../../../../../context/DynamicContext/DynamicContext.js';
17
17
  import '@dynamic-labs/multi-wallet';
18
18
  import '../../../../../components/ShadowDOM/ShadowDOM.js';
19
19
  import '../../../../../context/ThemeContext/ThemeContext.js';
20
+ import { classNames } from '../../../../../utils/functions/classNames/classNames.js';
20
21
  import 'react-dom';
21
22
  import 'react-focus-lock';
22
23
  import '../../../../../components/Transition/ZoomTransition/ZoomTransition.js';
@@ -67,6 +68,7 @@ const mapPasskeyProviderToIcon = {
67
68
  };
68
69
  const PasskeyCard = ({ passkey }) => {
69
70
  const { t } = useTranslation();
71
+ const [showTooltip, setShowTooltip] = useState(false);
70
72
  const { value: timeSinceValue, unit: timeSinceUnit } = getTimeSince(passkey.createdAt);
71
73
  const PasskeyProviderIcon = () => {
72
74
  if (!passkey.userAgent)
@@ -84,11 +86,19 @@ const PasskeyCard = ({ passkey }) => {
84
86
  return null;
85
87
  return t(`dyn_manage_passkeys.passkey_providers.${provider}`);
86
88
  };
87
- return (jsxs("div", { className: 'passkey-card', children: [jsxs("div", { className: 'passkey-card__info', children: [jsx("div", { className: 'passkey-card__info__icon', children: jsx(PasskeyProviderIcon, {}) }), jsxs("div", { className: 'passkey-card__info__text', children: [jsx(Typography, { variant: 'body_normal', color: 'primary', children: shortenEmail(passkey.alias, {
88
- breakpoint: 12,
89
- cutEnd: 4,
90
- cutStart: 4,
91
- }) }), getPasskeyProviderName() && (jsxs(Typography, { variant: 'body_small', color: 'secondary', children: [t('dyn_manage_passkeys.passkey_from'), " ", getPasskeyProviderName()] }))] })] }), jsx("div", { className: 'passkey-card__date', children: jsxs(Typography, { variant: 'body_small', color: 'secondary', children: [t('dyn_time_since.created'), ' ', `${timeSinceValue} ${timeSinceUnit} ${t('dyn_time_since.ago')}`] }) })] }));
89
+ const handleShowTooltip = () => {
90
+ setShowTooltip(true);
91
+ setTimeout(() => {
92
+ setShowTooltip(false);
93
+ }, 2000);
94
+ };
95
+ return (jsxs("div", { className: 'passkey-card', children: [jsxs("div", { className: 'passkey-card__info', children: [jsx("div", { className: 'passkey-card__info__icon', "data-testId": 'provider-icon', children: jsx(PasskeyProviderIcon, {}) }), jsxs("div", { className: 'passkey-card__info__text', children: [jsxs(Typography, { "data-testid": 'passkey-alias', variant: 'body_normal', color: 'primary', title: passkey.alias, onClick: handleShowTooltip, children: [shortenEmail(passkey.alias, {
96
+ breakpoint: 12,
97
+ cutEnd: 4,
98
+ cutStart: 4,
99
+ }), jsx("p", { className: classNames('passkey-card__info__tooltip', {
100
+ 'passkey-card__info__tooltip--visible': showTooltip,
101
+ }), children: passkey.alias })] }), getPasskeyProviderName() && (jsxs(Typography, { variant: 'body_small', color: 'secondary', children: [t('dyn_manage_passkeys.passkey_from'), " ", getPasskeyProviderName()] }))] })] }), jsx("div", { className: 'passkey-card__date', children: jsxs(Typography, { variant: 'body_small', color: 'secondary', children: [t('dyn_time_since.created'), ' ', `${timeSinceValue} ${timeSinceUnit} ${t('dyn_time_since.ago')}`] }) })] }));
92
102
  };
93
103
 
94
104
  export { PasskeyCard };