@arcblock/ux 2.7.15 → 2.7.16

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 (51) hide show
  1. package/es/Dialog/confirm.js +10 -8
  2. package/es/Img/index.js +7 -7
  3. package/es/SessionManager/account-item.js +132 -0
  4. package/es/SessionManager/add-account-item.js +118 -0
  5. package/es/SessionManager/federated-login-detecter.js +5 -7
  6. package/es/SessionManager/index.js +117 -244
  7. package/es/SessionManager/manage-accounts.js +143 -0
  8. package/es/SessionManager/manage-blocklet.js +62 -0
  9. package/es/SessionManager/menu-accordion.js +95 -0
  10. package/es/SessionManager/translation.js +52 -0
  11. package/es/SessionManager/use-accounts.js +19 -0
  12. package/es/SessionManager/user-info.js +139 -0
  13. package/es/SessionManager/user-popper.js +10 -36
  14. package/es/SessionManager/utils.js +2 -0
  15. package/es/Util/index.js +7 -0
  16. package/lib/Dialog/confirm.js +9 -7
  17. package/lib/Img/index.js +7 -7
  18. package/lib/SessionManager/account-item.js +140 -0
  19. package/lib/SessionManager/add-account-item.js +126 -0
  20. package/lib/SessionManager/federated-login-detecter.js +5 -7
  21. package/lib/SessionManager/index.js +120 -257
  22. package/lib/SessionManager/manage-accounts.js +155 -0
  23. package/lib/SessionManager/manage-blocklet.js +78 -0
  24. package/lib/SessionManager/menu-accordion.js +103 -0
  25. package/lib/SessionManager/translation.js +59 -0
  26. package/lib/SessionManager/use-accounts.js +25 -0
  27. package/lib/SessionManager/user-info.js +155 -0
  28. package/lib/SessionManager/user-popper.js +8 -3
  29. package/lib/SessionManager/utils.js +16 -0
  30. package/lib/Util/index.js +11 -2
  31. package/package.json +8 -5
  32. package/src/Dialog/confirm.js +9 -6
  33. package/src/Img/index.js +5 -5
  34. package/src/SessionManager/account-item.jsx +111 -0
  35. package/src/SessionManager/add-account-item.jsx +115 -0
  36. package/src/SessionManager/federated-login-detecter.jsx +3 -3
  37. package/src/SessionManager/index.jsx +130 -238
  38. package/src/SessionManager/manage-accounts.jsx +143 -0
  39. package/src/SessionManager/manage-blocklet.jsx +64 -0
  40. package/src/SessionManager/menu-accordion.jsx +87 -0
  41. package/src/SessionManager/translation.js +52 -0
  42. package/src/SessionManager/use-accounts.js +18 -0
  43. package/src/SessionManager/user-info.jsx +116 -0
  44. package/src/SessionManager/user-popper.jsx +6 -36
  45. package/src/SessionManager/utils.js +3 -0
  46. package/src/Util/index.js +8 -0
  47. /package/src/Avatar/{did-motif.js → did-motif.jsx} +0 -0
  48. /package/src/Avatar/{index.js → index.jsx} +0 -0
  49. /package/src/Header/{auto-hidden.js → auto-hidden.jsx} +0 -0
  50. /package/src/Header/{header.js → header.jsx} +0 -0
  51. /package/src/Header/{responsive-header.js → responsive-header.jsx} +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arcblock/ux",
3
- "version": "2.7.15",
3
+ "version": "2.7.16",
4
4
  "description": "Common used react components for arcblock products",
5
5
  "keywords": [
6
6
  "react",
@@ -318,16 +318,19 @@
318
318
  "peerDependencies": {
319
319
  "react": ">=18.1.0"
320
320
  },
321
- "gitHead": "a40ed26cfd0cbf892b00f98c773eff8ad7a50570",
321
+ "gitHead": "8adb844a1067ecca748cd70c5978c9f7497e3658",
322
322
  "dependencies": {
323
323
  "@arcblock/did-motif": "^1.1.13",
324
- "@arcblock/icons": "^2.7.15",
325
- "@arcblock/react-hooks": "^2.7.15",
324
+ "@arcblock/icons": "^2.7.16",
325
+ "@arcblock/react-hooks": "^2.7.16",
326
326
  "@babel/plugin-syntax-dynamic-import": "^7.8.3",
327
327
  "@emotion/react": "^11.10.4",
328
328
  "@emotion/styled": "^11.10.4",
329
329
  "@fontsource/lato": "^4.5.10",
330
330
  "@fontsource/ubuntu-mono": "^4.5.11",
331
+ "@iconify-icons/ion": "^1.2.10",
332
+ "@iconify-icons/mdi": "^1.2.47",
333
+ "@iconify/react": "^4.1.1",
331
334
  "@mui/icons-material": "^5.10.6",
332
335
  "@mui/material": "^5.10.8",
333
336
  "@solana/qr-code-styling": "^1.6.0-beta.0",
@@ -341,10 +344,10 @@
341
344
  "dayjs": "^1.11.5",
342
345
  "devices.css": "^0.1.15",
343
346
  "highlight.js": "^11.6.0",
347
+ "iconify-icon": "^1.0.8",
344
348
  "is-svg": "^4.3.2",
345
349
  "js-cookie": "^2.2.1",
346
350
  "lodash": "^4.17.21",
347
- "mdi-material-ui": "^7.5.0",
348
351
  "mui-datatables": "^4.2.2",
349
352
  "notistack": "^2.0.5",
350
353
  "pako": "^2.1.0",
@@ -1,9 +1,8 @@
1
1
  import PropTypes from 'prop-types';
2
- import { useContext, forwardRef, useRef, useImperativeHandle } from 'react';
2
+ import { forwardRef, useRef, useImperativeHandle } from 'react';
3
3
  import { useMemoizedFn, useReactive } from 'ahooks';
4
4
  import noop from 'lodash/noop';
5
5
 
6
- import { LocaleContext } from '../Locale/context';
7
6
  import Button from '../Button';
8
7
  import Dialog from './dialog';
9
8
 
@@ -98,8 +97,6 @@ Confirm.defaultProps = {
98
97
  };
99
98
 
100
99
  const ConfirmHolder = forwardRef((props, ref) => {
101
- const { t } = useContext(LocaleContext);
102
-
103
100
  const state = useReactive({
104
101
  show: false,
105
102
  title: '',
@@ -107,6 +104,8 @@ const ConfirmHolder = forwardRef((props, ref) => {
107
104
  onConfirm: noop,
108
105
  onCancel: noop,
109
106
  loading: false,
107
+ confirmButtonText: 'Confirm',
108
+ cancelButtonText: 'Cancel',
110
109
  });
111
110
  const open = useMemoizedFn((params = {}) => {
112
111
  state.show = true;
@@ -114,6 +113,8 @@ const ConfirmHolder = forwardRef((props, ref) => {
114
113
  state.content = params.content;
115
114
  state.onConfirm = params.onConfirm || noop;
116
115
  state.onCancel = params.onCancel || noop;
116
+ if (params.confirmButtonText) state.confirmButtonText = params.confirmButtonText;
117
+ if (params.cancelButtonText) state.cancelButtonText = params.cancelButtonText;
117
118
  state.loading = false;
118
119
  });
119
120
  const reset = useMemoizedFn(() => {
@@ -121,6 +122,8 @@ const ConfirmHolder = forwardRef((props, ref) => {
121
122
  state.content = '';
122
123
  state.onConfirm = noop;
123
124
  state.onCancel = noop;
125
+ state.confirmButtonText = 'Confirm';
126
+ state.cancelButtonText = 'Cancel';
124
127
  });
125
128
  const close = useMemoizedFn(() => {
126
129
  state.show = false;
@@ -158,7 +161,7 @@ const ConfirmHolder = forwardRef((props, ref) => {
158
161
  onConfirm={onConfirm}
159
162
  onCancel={onCancel}
160
163
  confirmButton={{
161
- text: t('common.confirm'),
164
+ text: state.confirmButtonText,
162
165
  props: {
163
166
  variant: 'contained',
164
167
  color: 'primary',
@@ -166,7 +169,7 @@ const ConfirmHolder = forwardRef((props, ref) => {
166
169
  },
167
170
  }}
168
171
  cancelButton={{
169
- text: t('common.cancel'),
172
+ text: state.cancelButtonText,
170
173
  props: {
171
174
  variant: 'outlined',
172
175
  color: 'primary',
package/src/Img/index.js CHANGED
@@ -1,9 +1,9 @@
1
1
  import { useEffect, useMemo, useState } from 'react';
2
2
  import PropTypes from 'prop-types';
3
- import SvgIcon from '@mui/material/SvgIcon';
4
3
  import { useInView } from 'react-intersection-observer';
5
- import Alert from 'mdi-material-ui/Alert';
6
- import ImageIcon from 'mdi-material-ui/Image';
4
+ import AlertIcon from '@iconify-icons/mdi/alert';
5
+ import ImageIcon from '@iconify-icons/mdi/image';
6
+ import { Icon } from '@iconify/react';
7
7
  import { styled } from '../Theme';
8
8
 
9
9
  /**
@@ -160,12 +160,12 @@ function Img({
160
160
  <div className={`image ${className} ${classes.root}`} style={mergedStyle}>
161
161
  {!fallback && imgState === 'error' && (
162
162
  <div className="image--state" title="loading image">
163
- <SvgIcon component={Alert} className="image--icon" />
163
+ <Icon icon={AlertIcon} className="image--icon" />
164
164
  </div>
165
165
  )}
166
166
  {!placeholder && imgState === 'loading' && (
167
167
  <div className="image--state" title="Image load error">
168
- <SvgIcon component={ImageIcon} className="image--icon" />
168
+ <Icon icon={ImageIcon} className="image--icon" />
169
169
  </div>
170
170
  )}
171
171
  {imgState === 'loaded' && <img className="image--img" src={src} alt={alt} />}
@@ -0,0 +1,111 @@
1
+ import { Box, IconButton, Link, MenuItem, Typography } from '@mui/material';
2
+ import PropTypes from 'prop-types';
3
+ import { Icon } from '@iconify/react';
4
+ import CheckIcon from '@iconify-icons/mdi/check';
5
+ import TrashCanOutlineIcon from '@iconify-icons/mdi/trash-can-outline';
6
+ import { useMemoizedFn } from 'ahooks';
7
+
8
+ import Avatar from '../Avatar';
9
+ import DID from '../DID';
10
+ import { translate } from '../Locale/util';
11
+ import { translations } from './translation';
12
+
13
+ export default function AccountItem({ account, active, onDelete, onChoose, locale }) {
14
+ const t = useMemoizedFn((key, data = {}) => {
15
+ return translate(translations, key, locale, 'en', data);
16
+ });
17
+
18
+ const _onChoose = useMemoizedFn(() => onChoose(account, { active }));
19
+
20
+ const _onDelete = useMemoizedFn((e) => {
21
+ e.preventDefault();
22
+ e.stopPropagation();
23
+ onDelete(account, { active });
24
+ });
25
+
26
+ if (!account?.did || !account?.appName) {
27
+ return null;
28
+ }
29
+
30
+ return (
31
+ <MenuItem
32
+ onClick={_onChoose}
33
+ sx={{
34
+ display: 'flex',
35
+ alignItems: 'center',
36
+ overflow: 'hidden',
37
+ gap: '8px',
38
+ position: 'relative',
39
+ '.account-item-actions': {
40
+ position: 'absolute',
41
+ right: 0,
42
+ top: 0,
43
+ bottom: 0,
44
+ marginRight: '12px',
45
+ display: 'flex',
46
+ alignItems: 'center',
47
+ },
48
+ '.account-item-action': {
49
+ alignItems: 'center',
50
+ display: 'none',
51
+ },
52
+ '&:hover .account-item-action': {
53
+ display: 'flex',
54
+ },
55
+ }}
56
+ className="session-manager-menu-item">
57
+ <Avatar did={account.did} />
58
+ <Box
59
+ sx={{
60
+ flex: 1,
61
+ overflow: 'hidden',
62
+ fontSize: 0,
63
+ '.did-address-avatar': {
64
+ display: 'none !important',
65
+ },
66
+ }}>
67
+ <DID did={account.did} copyable={false} size={14} responsive={false} compact sx={{ lineHeight: 1 }} />
68
+ <Typography variant="caption">
69
+ {t('from')}{' '}
70
+ {account.provider === 'federated' ? (
71
+ <Link href={account.appUrl} target="_blank" underline="none">
72
+ {account.appName}
73
+ </Link>
74
+ ) : (
75
+ account.appName
76
+ )}
77
+ </Typography>
78
+ </Box>
79
+ <Box className="account-item-actions">
80
+ {active ? (
81
+ <Box className="account-item-action" style={{ display: 'flex' }} key="CheckIcon">
82
+ <IconButton color="success">
83
+ <Icon icon={CheckIcon} color="success" />
84
+ </IconButton>
85
+ </Box>
86
+ ) : (
87
+ <Box className="account-item-action" key="TrashCanOutlineIcon">
88
+ <IconButton color="error" onClick={_onDelete}>
89
+ <Icon icon={TrashCanOutlineIcon} color="error" />
90
+ </IconButton>
91
+ </Box>
92
+ )}
93
+ </Box>
94
+ </MenuItem>
95
+ );
96
+ }
97
+
98
+ AccountItem.propTypes = {
99
+ account: PropTypes.object,
100
+ active: PropTypes.bool,
101
+ locale: PropTypes.string,
102
+ onChoose: PropTypes.func,
103
+ onDelete: PropTypes.func,
104
+ };
105
+ AccountItem.defaultProps = {
106
+ account: null,
107
+ active: false,
108
+ locale: 'en',
109
+ onChoose: () => {},
110
+ onDelete: () => {},
111
+ };
@@ -0,0 +1,115 @@
1
+ import { Icon } from '@iconify/react';
2
+ import PropTypes from 'prop-types';
3
+ import { Menu, MenuItem, Typography } from '@mui/material';
4
+ import AddIcon from '@iconify-icons/ion/ios-add-circle-outline';
5
+ import isEmpty from 'lodash/isEmpty';
6
+ import { useCreation, useMemoizedFn, useReactive } from 'ahooks';
7
+ import { useRef } from 'react';
8
+ import { translate } from '../Locale/util';
9
+ import { translations } from './translation';
10
+
11
+ export default function AddAccountItem({ onAdd, locale }) {
12
+ const addRef = useRef(null);
13
+ const state = useReactive({
14
+ open: false,
15
+ });
16
+
17
+ const t = useMemoizedFn((key, data = {}) => {
18
+ return translate(translations, key, locale, 'en', data);
19
+ });
20
+ const apps = useCreation(() => {
21
+ const appList = [];
22
+ if (typeof window === 'undefined') {
23
+ return appList;
24
+ }
25
+ const blocklet = window?.blocklet;
26
+ if (!blocklet) {
27
+ return appList;
28
+ }
29
+ const currentApp = {
30
+ appId: blocklet.appId,
31
+ appName: blocklet.appName,
32
+ appDescription: blocklet.appDescription,
33
+ appLogo: blocklet.appLogo,
34
+ appPid: blocklet.appPid,
35
+ appUrl: blocklet.appUrl,
36
+ version: blocklet.version,
37
+ provider: 'wallet',
38
+ };
39
+ appList.push(currentApp);
40
+ const isFederatedMember = !isEmpty(blocklet.settings?.federated?.master);
41
+ if (isFederatedMember) {
42
+ const federatedMaster = blocklet.settings.federated.master;
43
+ const masterApp = {
44
+ appId: federatedMaster.appId,
45
+ appName: federatedMaster.appName,
46
+ appDescription: federatedMaster.appDescription,
47
+ appLogo: federatedMaster.appLogo,
48
+ appPid: federatedMaster.appPid,
49
+ appUrl: federatedMaster.appUrl,
50
+ version: federatedMaster.version,
51
+ provider: 'federated',
52
+ };
53
+ return [masterApp, currentApp];
54
+ }
55
+ return appList;
56
+ }, [window.blocklet]);
57
+
58
+ const _onAdd = useMemoizedFn(() => {
59
+ if (apps.length <= 1) {
60
+ onAdd(apps[0]);
61
+ } else {
62
+ state.open = true;
63
+ }
64
+ });
65
+ const onClose = useMemoizedFn(() => {
66
+ state.open = false;
67
+ });
68
+
69
+ return (
70
+ <>
71
+ <MenuItem
72
+ ref={addRef}
73
+ onClick={_onAdd}
74
+ className="session-manager-menu-item"
75
+ sx={{ display: 'flex', gap: '8px' }}
76
+ data-cy="sessionManager-switch-trigger">
77
+ <Icon icon={AddIcon} width={24} height={24} />
78
+ <Typography>{t('addAnotherAccount')}</Typography>
79
+ </MenuItem>
80
+ {addRef.current ? (
81
+ <Menu
82
+ anchorEl={addRef.current}
83
+ open={state.open}
84
+ onClose={onClose}
85
+ elevation={0}
86
+ PaperProps={{
87
+ variant: 'outlined',
88
+ }}
89
+ anchorOrigin={{
90
+ vertical: 'top',
91
+ horizontal: 'left',
92
+ }}
93
+ transformOrigin={{
94
+ vertical: 'top',
95
+ horizontal: 'left',
96
+ }}>
97
+ {apps.map((app) => (
98
+ <MenuItem key={app.appId} onClick={() => onAdd(app)}>
99
+ Connect with {app.appName} account
100
+ </MenuItem>
101
+ ))}
102
+ </Menu>
103
+ ) : null}
104
+ </>
105
+ );
106
+ }
107
+
108
+ AddAccountItem.propTypes = {
109
+ onAdd: PropTypes.func,
110
+ locale: PropTypes.string,
111
+ };
112
+ AddAccountItem.defaultProps = {
113
+ onAdd: () => {},
114
+ locale: 'en',
115
+ };
@@ -3,8 +3,8 @@ import { useCallback, useState } from 'react';
3
3
  import Box from '@mui/material/Box';
4
4
  import Chip from '@mui/material/Chip';
5
5
  import Divider from '@mui/material/Divider';
6
- import SvgIcon from '@mui/material/SvgIcon';
7
- import ShieldCheck from 'mdi-material-ui/ShieldCheck';
6
+ import ShieldCheckIcon from '@iconify-icons/mdi/shield-check';
7
+ import { Icon } from '@iconify/react';
8
8
 
9
9
  import UserPopper from './user-popper';
10
10
  import DidAvatar from '../Avatar';
@@ -119,7 +119,7 @@ export default function FederatedLoginDetecter({ session, anchorEl, dark, locale
119
119
  size="small"
120
120
  variant="outlined"
121
121
  sx={{ height: 'auto', marginRight: 0, fontSize: 12 }}
122
- icon={<SvgIcon component={ShieldCheck} style={{ fontSize: '14px' }} />}
122
+ icon={<Icon icon={ShieldCheckIcon} fontSize={14} />}
123
123
  />
124
124
  )}
125
125
  </Box>