@arcblock/did-connect-react 3.4.15 → 3.5.1

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 (198) hide show
  1. package/dist/standalone/did-connect-react.css +1 -0
  2. package/dist/standalone/index.js +133700 -0
  3. package/lib/package.json.js +1 -1
  4. package/package.json +11 -6
  5. package/.aigne/doc-smith/config.yaml +0 -85
  6. package/.aigne/doc-smith/history.yaml +0 -6
  7. package/.aigne/doc-smith/output/structure-plan.json +0 -204
  8. package/.aigne/doc-smith/translation-cache.yaml +0 -11
  9. package/.aigne/doc-smith/upload-cache.yaml +0 -213
  10. package/docs/_sidebar.md +0 -18
  11. package/docs/advanced-authentication-methods.ja.md +0 -261
  12. package/docs/advanced-authentication-methods.md +0 -261
  13. package/docs/advanced-authentication-methods.zh-TW.md +0 -261
  14. package/docs/advanced-authentication-methods.zh.md +0 -261
  15. package/docs/advanced-utilities.ja.md +0 -132
  16. package/docs/advanced-utilities.md +0 -132
  17. package/docs/advanced-utilities.zh-TW.md +0 -132
  18. package/docs/advanced-utilities.zh.md +0 -132
  19. package/docs/advanced.ja.md +0 -95
  20. package/docs/advanced.md +0 -95
  21. package/docs/advanced.zh-TW.md +0 -95
  22. package/docs/advanced.zh.md +0 -95
  23. package/docs/api-reference.ja.md +0 -178
  24. package/docs/api-reference.md +0 -178
  25. package/docs/api-reference.zh-TW.md +0 -178
  26. package/docs/api-reference.zh.md +0 -178
  27. package/docs/assets/diagram/core-components-session-provider-01.ja.jpg +0 -0
  28. package/docs/assets/diagram/core-components-session-provider-01.jpg +0 -0
  29. package/docs/assets/diagram/core-components-session-provider-01.zh-TW.jpg +0 -0
  30. package/docs/assets/diagram/core-components-session-provider-01.zh.jpg +0 -0
  31. package/docs/assets/diagram/did-connect-diagram-0.ja.jpg +0 -0
  32. package/docs/assets/diagram/did-connect-diagram-0.jpg +0 -0
  33. package/docs/assets/diagram/did-connect-diagram-0.zh-TW.jpg +0 -0
  34. package/docs/assets/diagram/did-connect-diagram-0.zh.jpg +0 -0
  35. package/docs/assets/diagram/overview-01.ja.jpg +0 -0
  36. package/docs/assets/diagram/overview-01.jpg +0 -0
  37. package/docs/assets/diagram/overview-01.zh-TW.jpg +0 -0
  38. package/docs/assets/diagram/overview-01.zh.jpg +0 -0
  39. package/docs/assets/diagram/use-connect-diagram-0.ja.jpg +0 -0
  40. package/docs/assets/diagram/use-connect-diagram-0.jpg +0 -0
  41. package/docs/assets/diagram/use-connect-diagram-0.zh-TW.jpg +0 -0
  42. package/docs/assets/diagram/use-connect-diagram-0.zh.jpg +0 -0
  43. package/docs/core-components-did-connect.ja.md +0 -166
  44. package/docs/core-components-did-connect.md +0 -166
  45. package/docs/core-components-did-connect.zh-TW.md +0 -166
  46. package/docs/core-components-did-connect.zh.md +0 -166
  47. package/docs/core-components-session-provider.ja.md +0 -197
  48. package/docs/core-components-session-provider.md +0 -197
  49. package/docs/core-components-session-provider.zh-TW.md +0 -197
  50. package/docs/core-components-session-provider.zh.md +0 -197
  51. package/docs/core-components.ja.md +0 -16
  52. package/docs/core-components.md +0 -16
  53. package/docs/core-components.zh-TW.md +0 -16
  54. package/docs/core-components.zh.md +0 -16
  55. package/docs/getting-started.ja.md +0 -138
  56. package/docs/getting-started.md +0 -138
  57. package/docs/getting-started.zh-TW.md +0 -138
  58. package/docs/getting-started.zh.md +0 -138
  59. package/docs/hooks-use-connect.ja.md +0 -178
  60. package/docs/hooks-use-connect.md +0 -178
  61. package/docs/hooks-use-connect.zh-TW.md +0 -178
  62. package/docs/hooks-use-connect.zh.md +0 -178
  63. package/docs/hooks-use-did.ja.md +0 -107
  64. package/docs/hooks-use-did.md +0 -107
  65. package/docs/hooks-use-did.zh-TW.md +0 -107
  66. package/docs/hooks-use-did.zh.md +0 -107
  67. package/docs/hooks-use-oauth-passkey.ja.md +0 -188
  68. package/docs/hooks-use-oauth-passkey.md +0 -188
  69. package/docs/hooks-use-oauth-passkey.zh-TW.md +0 -188
  70. package/docs/hooks-use-oauth-passkey.zh.md +0 -188
  71. package/docs/hooks.ja.md +0 -23
  72. package/docs/hooks.md +0 -23
  73. package/docs/hooks.zh-TW.md +0 -23
  74. package/docs/hooks.zh.md +0 -23
  75. package/docs/overview.ja.md +0 -119
  76. package/docs/overview.md +0 -119
  77. package/docs/overview.zh-TW.md +0 -119
  78. package/docs/overview.zh.md +0 -119
  79. package/docs/ui-components-address.ja.md +0 -121
  80. package/docs/ui-components-address.md +0 -121
  81. package/docs/ui-components-address.zh-TW.md +0 -121
  82. package/docs/ui-components-address.zh.md +0 -121
  83. package/docs/ui-components-avatar.ja.md +0 -65
  84. package/docs/ui-components-avatar.md +0 -65
  85. package/docs/ui-components-avatar.zh-TW.md +0 -65
  86. package/docs/ui-components-avatar.zh.md +0 -65
  87. package/docs/ui-components-button.ja.md +0 -99
  88. package/docs/ui-components-button.md +0 -99
  89. package/docs/ui-components-button.zh-TW.md +0 -99
  90. package/docs/ui-components-button.zh.md +0 -99
  91. package/docs/ui-components-logo.ja.md +0 -52
  92. package/docs/ui-components-logo.md +0 -52
  93. package/docs/ui-components-logo.zh-TW.md +0 -52
  94. package/docs/ui-components-logo.zh.md +0 -52
  95. package/docs/ui-components.ja.md +0 -57
  96. package/docs/ui-components.md +0 -57
  97. package/docs/ui-components.zh-TW.md +0 -57
  98. package/docs/ui-components.zh.md +0 -57
  99. package/glossary.md +0 -1
  100. package/src/Address/index.jsx +0 -2
  101. package/src/Avatar/index.jsx +0 -2
  102. package/src/Button/Button.stories.jsx +0 -7
  103. package/src/Button/index.jsx +0 -21
  104. package/src/Connect/Connect.stories.jsx +0 -34
  105. package/src/Connect/assets/locale.js +0 -149
  106. package/src/Connect/assets/login-bg.png +0 -0
  107. package/src/Connect/assets/login-slogan.js +0 -7
  108. package/src/Connect/components/action-button.jsx +0 -22
  109. package/src/Connect/components/app-tips.jsx +0 -156
  110. package/src/Connect/components/auto-height.jsx +0 -38
  111. package/src/Connect/components/back-button.jsx +0 -24
  112. package/src/Connect/components/connect-status.jsx +0 -259
  113. package/src/Connect/components/did-connect-title.jsx +0 -107
  114. package/src/Connect/components/download-tips.jsx +0 -55
  115. package/src/Connect/components/loading.jsx +0 -25
  116. package/src/Connect/components/login-item/connect-choose-list.jsx +0 -328
  117. package/src/Connect/components/login-item/connect-provider-list.jsx +0 -473
  118. package/src/Connect/components/login-item/login-method-item.jsx +0 -139
  119. package/src/Connect/components/login-item/mobile-login-item.jsx +0 -184
  120. package/src/Connect/components/login-item/passkey-login-item.jsx +0 -56
  121. package/src/Connect/components/login-item/wallet-login-options.jsx +0 -129
  122. package/src/Connect/components/login-item/web-login-item.jsx +0 -159
  123. package/src/Connect/components/mask-overlay.jsx +0 -32
  124. package/src/Connect/components/refresh-overlay.jsx +0 -52
  125. package/src/Connect/components/switch-app.jsx +0 -69
  126. package/src/Connect/connect.jsx +0 -635
  127. package/src/Connect/contexts/state.jsx +0 -235
  128. package/src/Connect/fallback-connect.jsx +0 -47
  129. package/src/Connect/fullpage.jsx +0 -3
  130. package/src/Connect/hooks/auth-url.js +0 -31
  131. package/src/Connect/hooks/method-list.js +0 -121
  132. package/src/Connect/hooks/page-show.js +0 -24
  133. package/src/Connect/hooks/provider-list.js +0 -168
  134. package/src/Connect/hooks/security.js +0 -40
  135. package/src/Connect/hooks/token.js +0 -627
  136. package/src/Connect/hooks/use-apps.js +0 -69
  137. package/src/Connect/hooks/use-quick-connect.js +0 -119
  138. package/src/Connect/index.jsx +0 -21
  139. package/src/Connect/landing-page.jsx +0 -3
  140. package/src/Connect/plugins/email/index.jsx +0 -85
  141. package/src/Connect/plugins/email/list-item.jsx +0 -35
  142. package/src/Connect/plugins/email/placeholder.jsx +0 -372
  143. package/src/Connect/plugins/index.js +0 -2
  144. package/src/Connect/use-connect.jsx +0 -321
  145. package/src/Connect/with-blocklet.jsx +0 -26
  146. package/src/Connect/with-bridge-call.jsx +0 -138
  147. package/src/Federated/context.jsx +0 -93
  148. package/src/Federated/index.jsx +0 -1
  149. package/src/Logo/index.jsx +0 -2
  150. package/src/OAuth/bind-conflict-alert.jsx +0 -37
  151. package/src/OAuth/context.jsx +0 -407
  152. package/src/OAuth/guest.svg +0 -20
  153. package/src/OAuth/index.jsx +0 -1
  154. package/src/OAuth/passport-switcher.jsx +0 -2
  155. package/src/Passkey/actions.jsx +0 -217
  156. package/src/Passkey/constants.js +0 -2
  157. package/src/Passkey/context.jsx +0 -395
  158. package/src/Passkey/dialog.jsx +0 -401
  159. package/src/Passkey/icon.jsx +0 -10
  160. package/src/Passkey/index.jsx +0 -2
  161. package/src/Service/index.jsx +0 -96
  162. package/src/Session/assets/did-spaces-guide-cover.svg +0 -1
  163. package/src/Session/assets/did-spaces-guide-icon.svg +0 -7
  164. package/src/Session/context.jsx +0 -7
  165. package/src/Session/did-spaces-guide.jsx +0 -173
  166. package/src/Session/handler.jsx +0 -98
  167. package/src/Session/hooks/use-federated.js +0 -91
  168. package/src/Session/hooks/use-mobile.jsx +0 -6
  169. package/src/Session/hooks/use-protected-routes.js +0 -16
  170. package/src/Session/hooks/use-session-token.js +0 -400
  171. package/src/Session/hooks/use-verify.jsx +0 -76
  172. package/src/Session/index.jsx +0 -1789
  173. package/src/Session/libs/constants.js +0 -17
  174. package/src/Session/libs/did-spaces.js +0 -38
  175. package/src/Session/libs/federated.js +0 -82
  176. package/src/Session/libs/index.js +0 -5
  177. package/src/Session/libs/locales.js +0 -160
  178. package/src/Session/libs/login-mobile.js +0 -80
  179. package/src/Session/window-focus-aware.jsx +0 -28
  180. package/src/SessionManager/index.jsx +0 -2
  181. package/src/Storage/engine/cookie.js +0 -25
  182. package/src/Storage/engine/local-storage.js +0 -57
  183. package/src/Storage/index.js +0 -25
  184. package/src/User/index.js +0 -4
  185. package/src/User/use-did.js +0 -80
  186. package/src/User/wrap-did.jsx +0 -18
  187. package/src/WebWalletSWKeeper/index.jsx +0 -3
  188. package/src/components/PassportSwitcher.jsx +0 -160
  189. package/src/constant.js +0 -27
  190. package/src/error.js +0 -6
  191. package/src/hooks/use-locale.jsx +0 -6
  192. package/src/index.js +0 -32
  193. package/src/locales/en.jsx +0 -15
  194. package/src/locales/index.jsx +0 -13
  195. package/src/locales/zh.jsx +0 -15
  196. package/src/types.d.ts +0 -355
  197. package/src/utils.js +0 -413
  198. package/vite.config.mjs +0 -29
@@ -1,473 +0,0 @@
1
- import PropTypes from 'prop-types';
2
- import { Box } from '@mui/material';
3
- import {
4
- LOGIN_PROVIDER,
5
- LOGIN_PROVIDER_NAME,
6
- LOGIN_PROVIDER_ICON_SIZE,
7
- LAST_USED_LOGIN_METHOD,
8
- WALLET_LOGIN_METHOD,
9
- } from '@arcblock/ux/lib/Util/constant';
10
- import { checkSameProtocol, getWebWalletUrl } from '@arcblock/ux/lib/Util/wallet';
11
- import noop from 'lodash/noop';
12
- import { useMemoizedFn, useCreation } from 'ahooks';
13
- import Cookie from 'js-cookie';
14
- import { detectWalletExtension, getCookieOptions } from '@arcblock/ux/lib/Util';
15
- import { useEffect, useRef } from 'react';
16
- import { mergeSx } from '@arcblock/ux/lib/Util/style';
17
- import ProviderIcon from '@arcblock/ux/lib/DIDConnect/provider-icon';
18
- import { GA_LAST_LOGIN_METHOD } from '@arcblock/ux/lib/withTracker/constant';
19
- import { translate } from '@arcblock/ux/lib/Locale/util';
20
- import Empty from '@arcblock/ux/lib/Empty';
21
- import { useBrowser } from '@arcblock/react-hooks';
22
-
23
- import MobileLoginItem from './mobile-login-item';
24
- import WebLoginItem from './web-login-item';
25
- import LoginMethodItem from './login-method-item';
26
- import WalletLoginOptions from './wallet-login-options';
27
- import { useOAuth } from '../../../OAuth';
28
- import { useStateContext } from '../../contexts/state';
29
- import { getApiErrorMessage, getAppId, logger } from '../../../utils';
30
- import PasskeyLoginItem from './passkey-login-item';
31
- import { usePasskey } from '../../../Passkey';
32
- import { useEmailPlugin } from '../../plugins';
33
- import translations from '../../assets/locale';
34
-
35
- export default function ConnectProviderList({
36
- onSuccess = noop,
37
- onError = noop,
38
- size = 'small',
39
- tokenState,
40
- webWalletUrl = getWebWalletUrl(),
41
- tokenKey,
42
- passkeyBehavior = 'none',
43
- onReset = noop,
44
- providerList = [],
45
- slotProps = {},
46
- disableSwitchApp = false,
47
- forceUpdate = noop,
48
- magicToken = undefined,
49
- baseUrl = '/',
50
- customItems = [],
51
- qrcode = null,
52
- hideQRCode = false,
53
- }) {
54
- const walletLoginRef = useRef(null);
55
- const webLoginRef = useRef(null);
56
- const passkeyLoginRef = useRef(null);
57
- const isSameProtocol = checkSameProtocol(webWalletUrl);
58
- const extension = detectWalletExtension();
59
-
60
- const browser = useBrowser();
61
-
62
- const { loginOAuth, logoutOAuth, t: oauthT, oauthState } = useOAuth();
63
- const { passkeyState } = usePasskey();
64
- const {
65
- extraParams,
66
- locale,
67
- connectState,
68
- plugins,
69
- setPlugins,
70
- setSelectedPlugin,
71
- getPlugin,
72
- showWalletOptions,
73
- setShowWalletOptions,
74
- lastLoginMethod,
75
- } = useStateContext();
76
-
77
- const t = useMemoizedFn((key, data = {}) => {
78
- return translate(translations, key, locale, 'en', data);
79
- });
80
-
81
- const handleLoginOAuth = useMemoizedFn(async (item) => {
82
- localStorage.setItem(GA_LAST_LOGIN_METHOD, item.provider);
83
- tokenState.reset();
84
- oauthState.reset({
85
- status: 'scanned',
86
- });
87
- passkeyState.reset();
88
- connectState.chooseMethod = item.provider;
89
- connectState.walletMethod = ''; // 清除 wallet 登录方式,防止状态污染
90
-
91
- const sourceAppPid = extraParams?.sourceAppPid;
92
- try {
93
- oauthState.loading = true;
94
- oauthState.status = 'scanned';
95
- const loginResult = await loginOAuth(item, {
96
- action: tokenState.action,
97
- ...extraParams,
98
- });
99
- const cookieOptions = getCookieOptions({ returnDomain: false });
100
- Cookie.remove('connected_did', cookieOptions);
101
- Cookie.remove('connected_pk', cookieOptions);
102
- Cookie.remove('connected_wallet_os', cookieOptions);
103
-
104
- if (loginResult?.sessionToken) {
105
- // 登录成功后记录最后使用的登录方式(用于显示 Last Used 标签)
106
- localStorage.setItem(LAST_USED_LOGIN_METHOD, item.provider);
107
- await onSuccess(
108
- {
109
- ...loginResult,
110
- encrypted: false,
111
- },
112
- (val) => val,
113
- {
114
- sourceAppPid,
115
- connected_app: getAppId(tokenState.appInfo, tokenState.memberAppInfo),
116
- }
117
- );
118
- oauthState.loading = false;
119
- oauthState.status = 'succeed';
120
- }
121
- } catch (e) {
122
- logger.error(`Failed login OAuth: ${item.provider}`, e);
123
- const errorMessage = getApiErrorMessage(e, oauthT('loginOAuthFailed'));
124
- oauthState.loading = false;
125
- oauthState.error = errorMessage;
126
- oauthState.status = 'error';
127
- await logoutOAuth({ provider: item.provider });
128
- onError(new Error(errorMessage));
129
- }
130
- });
131
-
132
- const defaultRetryConnect = useMemoizedFn(async () => {
133
- tokenState.reset();
134
- await onReset();
135
- tokenState.status = 'created';
136
- connectState.chooseMethod = 'wallet';
137
- connectState.walletMethod = ''; // 重置 wallet 登录方式,确保扫码登录能正确记录
138
- });
139
-
140
- const handleMobileLoginClick = useMemoizedFn(async () => {
141
- localStorage.setItem(GA_LAST_LOGIN_METHOD, LOGIN_PROVIDER.WALLET);
142
- tokenState.reset();
143
- await onReset();
144
- tokenState.status = 'created';
145
- connectState.chooseMethod = 'wallet';
146
- const connectFn = walletLoginRef.current?.connect;
147
- connectState.retryConnect = () => {
148
- connectFn(defaultRetryConnect);
149
- };
150
- });
151
-
152
- const handleWebLoginClick = useMemoizedFn(() => {
153
- localStorage.setItem(GA_LAST_LOGIN_METHOD, LOGIN_PROVIDER.WALLET);
154
- // HACK: 在点击插件登录时,直接将状态置为扫码中,避免插件登录时的状态切换
155
- tokenState.status = 'scanned';
156
- connectState.chooseMethod = 'wallet-web';
157
- const connectFn = webLoginRef.current.connect;
158
- connectState.retryConnect = async () => {
159
- await onReset();
160
- tokenState.error = '';
161
- tokenState.status = 'scanned';
162
- connectFn();
163
- };
164
- });
165
-
166
- const handleWalletLoginBack = useMemoizedFn(() => {
167
- setShowWalletOptions(false);
168
- });
169
-
170
- const onlyWalletProvider = useCreation(() => {
171
- return providerList.length === 1 && providerList[0].provider === LOGIN_PROVIDER.WALLET;
172
- }, [providerList]);
173
-
174
- useEffect(() => {
175
- if (hideQRCode && onlyWalletProvider && !browser.mobile.any && !showWalletOptions) {
176
- setShowWalletOptions(true);
177
- }
178
- }, [hideQRCode, onlyWalletProvider, browser.mobile.any, setShowWalletOptions, showWalletOptions]);
179
-
180
- const showEmailLogin = providerList.some((p) => p.provider === LOGIN_PROVIDER.EMAIL);
181
-
182
- const emailPlugin = useEmailPlugin({ baseUrl });
183
-
184
- const setupMagicToken = useMemoizedFn(() => {
185
- if (
186
- magicToken &&
187
- providerList.some((provider) => provider.name === LOGIN_PROVIDER.EMAIL) &&
188
- plugins.some((plugin) => plugin.name === LOGIN_PROVIDER.EMAIL)
189
- ) {
190
- const plugin = getPlugin(LOGIN_PROVIDER.EMAIL);
191
- if (plugin.state.status === 'idle') {
192
- localStorage.setItem(GA_LAST_LOGIN_METHOD, LOGIN_PROVIDER.EMAIL);
193
- plugin.state.reset();
194
- plugin.state.magicToken = magicToken;
195
- connectState.chooseMethod = LOGIN_PROVIDER.EMAIL;
196
- setSelectedPlugin(plugin);
197
- forceUpdate();
198
- }
199
- }
200
- });
201
-
202
- // 考虑到切换账号的情况,此时 showEmailLogin 会根据当前上下文的 blocklet 发生变化,所以需要监听 showEmailLogin 的变化
203
- useEffect(() => {
204
- const finalList = [];
205
- if (showEmailLogin) {
206
- // 尽可能确保在 baseUrl 不变的情况下,不更改 email 插件的数据,以确保页面的展示不会出现闪烁
207
- const prevEmailPlugin = getPlugin(LOGIN_PROVIDER.EMAIL);
208
- if (prevEmailPlugin && prevEmailPlugin.baseUrl === emailPlugin.baseUrl) {
209
- finalList.push(prevEmailPlugin);
210
- } else {
211
- finalList.push(emailPlugin);
212
- }
213
- }
214
- setPlugins(finalList);
215
- connectState.retryConnect = defaultRetryConnect;
216
- // HACK: 必须要设置延迟,不然拿不到最新的 plugins 的值
217
- setTimeout(() => {
218
- setupMagicToken();
219
- }, 100);
220
- // eslint-disable-next-line react-hooks/exhaustive-deps
221
- }, [showEmailLogin]);
222
-
223
- const renderProviderList = providerList
224
- .map((item) => {
225
- if (item.provider === LOGIN_PROVIDER.WALLET) {
226
- if (browser.mobile.any && !showWalletOptions) {
227
- return (
228
- <MobileLoginItem
229
- t={t}
230
- isLatest={lastLoginMethod && lastLoginMethod === WALLET_LOGIN_METHOD.MOBILE}
231
- key={LOGIN_PROVIDER.WALLET}
232
- ref={walletLoginRef}
233
- tokenState={tokenState}
234
- sx={[size === 'small' ? { p: 1 } : { p: 2 }]}
235
- locale={locale}
236
- tokenKey={tokenKey}
237
- disableSwitchApp={disableSwitchApp}
238
- onClick={handleMobileLoginClick}
239
- />
240
- );
241
- }
242
- // 是否显示 web 登录项
243
- // 1. 如果隐藏了二维码,会在新页面显示 wallet 登录项
244
- // 2. 如果显示了二维码,不需要在新页面显示 wallet 登录项,根据是否是同一协议、是否安装了钱包扩展、是否是移动端来判断是否显示
245
- const shouldShowWebLoginItem =
246
- hideQRCode || (!hideQRCode && (isSameProtocol || extension) && (!browser.mobile.any || extension));
247
- return shouldShowWebLoginItem ? (
248
- <WebLoginItem
249
- t={t}
250
- isLatest={lastLoginMethod && lastLoginMethod === WALLET_LOGIN_METHOD.WEB}
251
- key={LOGIN_PROVIDER.WALLET}
252
- ref={webLoginRef}
253
- tokenState={tokenState}
254
- webWalletUrl={webWalletUrl}
255
- sx={[size === 'small' ? { p: 1 } : { p: 2 }]}
256
- disableSwitchApp={disableSwitchApp}
257
- autoConnect={!hideQRCode}
258
- onClick={() => {
259
- if (!hideQRCode) {
260
- handleWebLoginClick();
261
- } else {
262
- setShowWalletOptions(true);
263
- }
264
- }}
265
- />
266
- ) : null;
267
- }
268
-
269
- if (item.provider === LOGIN_PROVIDER.PASSKEY) {
270
- if (passkeyBehavior === 'none') {
271
- return null;
272
- }
273
- return (
274
- <PasskeyLoginItem
275
- key={LOGIN_PROVIDER.PASSKEY}
276
- ref={passkeyLoginRef}
277
- onSuccess={onSuccess}
278
- onError={onError}
279
- tokenState={tokenState}
280
- behavior={passkeyBehavior}
281
- sx={[size === 'small' ? { p: 1 } : { p: 2 }]}
282
- onClick={() => {
283
- localStorage.setItem(GA_LAST_LOGIN_METHOD, LOGIN_PROVIDER.PASSKEY);
284
- const connectFn = passkeyLoginRef.current.connect;
285
- connectState.chooseMethod = 'passkey';
286
- connectState.walletMethod = ''; // 清除 wallet 登录方式,防止状态污染
287
- connectState.retryConnect = () => {
288
- passkeyState.verifying = true;
289
- connectState.chooseMethod = 'passkey';
290
- connectFn();
291
- };
292
- }}
293
- slotProps={{
294
- icon: {
295
- sx: {
296
- fontSize: LOGIN_PROVIDER_ICON_SIZE,
297
- '& svg': {
298
- fontSize: LOGIN_PROVIDER_ICON_SIZE,
299
- width: '1em',
300
- height: '1em',
301
- },
302
- },
303
- },
304
- }}
305
- />
306
- );
307
- }
308
-
309
- if (item.provider === LOGIN_PROVIDER.EMAIL) {
310
- const findEmailPlugin = plugins.find((p) => p.name === LOGIN_PROVIDER.EMAIL);
311
- if (!findEmailPlugin) {
312
- return null;
313
- }
314
- return findEmailPlugin?.renderListItem({
315
- key: findEmailPlugin.name,
316
- sx: [size === 'small' ? { p: 1 } : { p: 2 }],
317
- // forceUpdate,
318
- });
319
- }
320
-
321
- if (item.type === 'oauth') {
322
- return (
323
- <LoginMethodItem
324
- t={t}
325
- isLatest={lastLoginMethod && lastLoginMethod === item.provider}
326
- key={item.provider}
327
- title={LOGIN_PROVIDER_NAME[item.provider]}
328
- icon={
329
- <ProviderIcon
330
- provider={item.provider}
331
- sx={{
332
- transform: 'scale(0.95)',
333
- width: LOGIN_PROVIDER_ICON_SIZE,
334
- height: LOGIN_PROVIDER_ICON_SIZE,
335
- color: 'text.primary',
336
- }}
337
- />
338
- }
339
- onClick={() => {
340
- handleLoginOAuth(item);
341
- connectState.retryConnect = () => {
342
- handleLoginOAuth(item);
343
- };
344
- }}
345
- sx={[size === 'small' ? { p: 1.2 } : { p: 2 }]}
346
- />
347
- );
348
- }
349
-
350
- return null;
351
- })
352
- .filter(Boolean);
353
-
354
- return (
355
- <Box className="did-connect__choose" sx={mergeSx({ flex: 1 }, slotProps?.root?.sx)}>
356
- <Box
357
- sx={{
358
- display: 'flex',
359
- flexDirection: 'column',
360
- gap: 2,
361
- }}>
362
- <Box
363
- sx={[
364
- {
365
- display: 'flex',
366
- flexDirection: 'column',
367
- ...(showWalletOptions && !browser.mobile.any ? { alignItems: 'center', gap: 0 } : { gap: 1.5 }),
368
- },
369
- ]}>
370
- {showWalletOptions && !browser.mobile.any ? (
371
- <WalletLoginOptions
372
- qrcode={qrcode}
373
- tokenState={tokenState}
374
- webWalletUrl={webWalletUrl}
375
- size={size}
376
- disableSwitchApp={disableSwitchApp}
377
- tokenKey={tokenKey}
378
- walletLoginRef={walletLoginRef}
379
- webLoginRef={webLoginRef}
380
- onMobileLoginClick={handleMobileLoginClick}
381
- onWebLoginClick={handleWebLoginClick}
382
- onBack={onlyWalletProvider ? undefined : handleWalletLoginBack}
383
- />
384
- ) : (
385
- <Box
386
- sx={{
387
- display: 'grid',
388
- gridTemplateColumns: 'repeat(12, 1fr)' /* 灵活的12列基础网格 */,
389
- gap: 1.5,
390
- '.arc-login-item:nth-child(-n+3)': {
391
- gridColumn: 'span 12',
392
- },
393
- // 当登录项大于等于 5 时,第三个登录项增加一个 marginBottom,用于分割独占一行的和一行多个的登录项
394
- '.arc-login-item:nth-child(3):nth-last-child(n+3)': {
395
- mb: 1,
396
- },
397
- '.arc-login-item:nth-child(4):last-child': {
398
- gridColumn: 'span 12',
399
- },
400
- '.arc-login-item:nth-child(4):nth-last-child(2), .arc-login-item:nth-child(4):nth-last-child(2), .arc-login-item:nth-child(4):nth-last-child(2) ~ .arc-login-item':
401
- {
402
- gridColumn: 'span 6',
403
- justifyContent: 'center',
404
- '.arc-login-item__body, .other-item-icon': {
405
- display: 'none',
406
- },
407
- },
408
- '.arc-login-item:nth-child(4):nth-last-child(3), .arc-login-item:nth-child(4):nth-last-child(3) ~ .arc-login-item':
409
- {
410
- justifyContent: 'center',
411
- gridColumn: 'span 4',
412
- '.arc-login-item__body, .other-item-icon': {
413
- display: 'none',
414
- },
415
- },
416
- '.arc-login-item:nth-child(4):nth-last-child(4), .arc-login-item:nth-child(4):nth-last-child(4) ~ .arc-login-item':
417
- {
418
- gridColumn: 'span 3',
419
- justifyContent: 'center',
420
- '.arc-login-item__body, .other-item-icon': {
421
- display: 'none',
422
- },
423
- },
424
- '&:has(.arc-login-item:nth-child(8)) .arc-login-item:nth-child(n+4)': {
425
- gridColumn: 'span 3',
426
- justifyContent: 'center',
427
- '.arc-login-item__body, .other-item-icon': {
428
- display: 'none',
429
- },
430
- },
431
- }}>
432
- {renderProviderList.length > 0 ? (
433
- renderProviderList
434
- ) : (
435
- <Empty
436
- className="arc-login-item"
437
- sx={{
438
- '.empty-content': {
439
- textAlign: 'center',
440
- },
441
- }}>
442
- {t('noAuthenticationProvider')}
443
- </Empty>
444
- )}
445
- </Box>
446
- )}
447
-
448
- {customItems.map((item) => (!item ? null : item))}
449
- </Box>
450
- </Box>
451
- </Box>
452
- );
453
- }
454
-
455
- ConnectProviderList.propTypes = {
456
- onSuccess: PropTypes.func,
457
- onError: PropTypes.func,
458
- size: PropTypes.oneOf(['small', 'normal', 'large']),
459
- tokenState: PropTypes.object.isRequired,
460
- webWalletUrl: PropTypes.string,
461
- tokenKey: PropTypes.string.isRequired,
462
- passkeyBehavior: PropTypes.oneOf(['none', 'both', 'only-existing', 'only-new']),
463
- onReset: PropTypes.func,
464
- providerList: PropTypes.array,
465
- slotProps: PropTypes.object,
466
- disableSwitchApp: PropTypes.bool,
467
- forceUpdate: PropTypes.func,
468
- magicToken: PropTypes.string,
469
- baseUrl: PropTypes.string,
470
- customItems: PropTypes.arrayOf(PropTypes.node),
471
- qrcode: PropTypes.node,
472
- hideQRCode: PropTypes.bool,
473
- };
@@ -1,139 +0,0 @@
1
- import { Box, Tooltip, Typography, useTheme } from '@mui/material';
2
- import { Icon } from '@iconify/react';
3
- import { isValidElement } from 'react';
4
- import PropTypes from 'prop-types';
5
- import noop from 'lodash/noop';
6
- import { mergeSx } from '@arcblock/ux/lib/Util/style';
7
- import { LOGIN_PROVIDER_ICON_SIZE } from '@arcblock/ux/lib/Util/constant';
8
- import ArrowRightAltRoundedIcon from '@iconify-icons/material-symbols/arrow-right-alt-rounded';
9
-
10
- export default function LoginMethodItem({
11
- isLatest = false,
12
- title,
13
- description = null,
14
- icon,
15
- iconScale = 0.95,
16
- slotProps = {},
17
- mode = 'normal',
18
- t = noop,
19
- ...rest
20
- }) {
21
- const theme = useTheme();
22
-
23
- return (
24
- <Box
25
- {...rest}
26
- className="arc-login-item"
27
- sx={mergeSx(
28
- {
29
- position: 'relative',
30
- display: 'flex',
31
- alignItems: 'center',
32
- gap: 1,
33
- cursor: 'pointer',
34
- p: 1.2,
35
- borderRadius: 1,
36
- backgroundColor: isLatest ? 'grey.100' : 'grey.50',
37
- border: isLatest ? '1px solid' : 'none',
38
- borderColor: isLatest ? 'grey.100' : 'transparent',
39
- textDecoration: 'none',
40
- transition: 'background-color 0.5s',
41
- '&:hover, &:active, &.did-connect__choose-item__active': {
42
- backgroundColor: 'grey.100',
43
- },
44
- '& .other-item-icon': {
45
- opacity: '0',
46
- transform: 'translateX(-100%)',
47
- transition: 'transform 0.2s ease, opacity 0.1s ease',
48
- },
49
- '&:hover': {
50
- '& .other-item-icon': {
51
- display: 'inline-block',
52
- transform: 'translateX(0)',
53
- opacity: '1',
54
- },
55
- },
56
- },
57
- rest?.sx
58
- )}>
59
- <Tooltip title={title}>
60
- <Box
61
- className="arc-login-item__icon"
62
- sx={mergeSx(
63
- {
64
- display: 'flex',
65
- justifyContent: 'center',
66
- alignItems: 'center',
67
- color: 'text.primary',
68
- },
69
- slotProps?.icon?.sx
70
- )}>
71
- {isValidElement(icon) ? (
72
- icon
73
- ) : (
74
- <Box
75
- component={Icon}
76
- icon={icon}
77
- sx={{
78
- transform: `scale(${iconScale})`,
79
- width: LOGIN_PROVIDER_ICON_SIZE,
80
- height: LOGIN_PROVIDER_ICON_SIZE,
81
- }}
82
- />
83
- )}
84
- </Box>
85
- </Tooltip>
86
- {mode === 'normal' ? (
87
- <>
88
- <Box className="arc-login-item__body" sx={{ display: 'flex', flexDirection: 'column', flex: 1 }}>
89
- <Typography
90
- sx={{
91
- fontSize: 14,
92
- fontWeight: '500',
93
- color: 'text.primary',
94
- whiteSpace: 'nowrap',
95
- }}>
96
- {title}
97
- </Typography>
98
- {description ? (
99
- <Typography
100
- sx={{
101
- color: 'text.secondary',
102
- fontSize: 12,
103
- lineHeight: 1,
104
- }}>
105
- {description}
106
- </Typography>
107
- ) : null}
108
- </Box>
109
- {isLatest ? (
110
- <Typography
111
- component="span"
112
- className="latest-badge"
113
- style={{ color: theme.palette.text.secondary, fontSize: 11 }}>
114
- {t('lastUsed')}
115
- </Typography>
116
- ) : (
117
- <Icon
118
- className="other-item-icon"
119
- icon={ArrowRightAltRoundedIcon}
120
- fontSize="1.3rem"
121
- color={theme.palette.primary.main}
122
- />
123
- )}
124
- </>
125
- ) : null}
126
- </Box>
127
- );
128
- }
129
-
130
- LoginMethodItem.propTypes = {
131
- title: PropTypes.string.isRequired,
132
- description: PropTypes.string,
133
- icon: PropTypes.any.isRequired,
134
- iconScale: PropTypes.number,
135
- slotProps: PropTypes.object,
136
- mode: PropTypes.oneOf(['mini', 'simple', 'normal']),
137
- isLatest: PropTypes.bool,
138
- t: PropTypes.func,
139
- };