@blocklet/ui-react 3.4.14 → 3.5.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 (256) hide show
  1. package/lib/common/org-switch/use-org.d.ts +4 -4
  2. package/lib/common/ws.d.ts +22 -1
  3. package/package.json +10 -7
  4. package/.aigne/doc-smith/.local/afs-storage.sqlite3 +0 -0
  5. package/.aigne/doc-smith/config.yaml +0 -78
  6. package/.aigne/doc-smith/history.yaml +0 -14
  7. package/.aigne/doc-smith/media-description.yaml +0 -11
  8. package/.aigne/doc-smith/output/structure-plan.json +0 -255
  9. package/.aigne/doc-smith/translation-cache.yaml +0 -11
  10. package/.aigne/doc-smith/upload-cache.yaml +0 -528
  11. package/build.config.ts +0 -24
  12. package/docs/_sidebar.md +0 -19
  13. package/docs/assets/diagram/component-installer-diagram-0.ja.jpg +0 -0
  14. package/docs/assets/diagram/component-installer-diagram-0.jpg +0 -0
  15. package/docs/assets/diagram/component-installer-diagram-0.zh-TW.jpg +0 -0
  16. package/docs/assets/diagram/component-installer-diagram-0.zh.jpg +0 -0
  17. package/docs/assets/diagram/component-management-diagram-0.ja.jpg +0 -0
  18. package/docs/assets/diagram/component-management-diagram-0.jpg +0 -0
  19. package/docs/assets/diagram/component-management-diagram-0.zh-TW.jpg +0 -0
  20. package/docs/assets/diagram/component-management-diagram-0.zh.jpg +0 -0
  21. package/docs/assets/diagram/core-concepts-diagram-0.ja.jpg +0 -0
  22. package/docs/assets/diagram/core-concepts-diagram-0.jpg +0 -0
  23. package/docs/assets/diagram/core-concepts-diagram-0.zh-TW.jpg +0 -0
  24. package/docs/assets/diagram/core-concepts-diagram-0.zh.jpg +0 -0
  25. package/docs/assets/diagram/dashboard-diagram-0.ja.jpg +0 -0
  26. package/docs/assets/diagram/dashboard-diagram-0.jpg +0 -0
  27. package/docs/assets/diagram/dashboard-diagram-0.zh-TW.jpg +0 -0
  28. package/docs/assets/diagram/dashboard-diagram-0.zh.jpg +0 -0
  29. package/docs/assets/diagram/header-diagram-0.ja.jpg +0 -0
  30. package/docs/assets/diagram/header-diagram-0.jpg +0 -0
  31. package/docs/assets/diagram/header-diagram-0.zh-TW.jpg +0 -0
  32. package/docs/assets/diagram/header-diagram-0.zh.jpg +0 -0
  33. package/docs/assets/diagram/layout-diagram-0.ja.jpg +0 -0
  34. package/docs/assets/diagram/layout-diagram-0.jpg +0 -0
  35. package/docs/assets/diagram/layout-diagram-0.zh-TW.jpg +0 -0
  36. package/docs/assets/diagram/layout-diagram-0.zh.jpg +0 -0
  37. package/docs/assets/diagram/notifications-diagram-0.ja.jpg +0 -0
  38. package/docs/assets/diagram/notifications-diagram-0.jpg +0 -0
  39. package/docs/assets/diagram/notifications-diagram-0.zh-TW.jpg +0 -0
  40. package/docs/assets/diagram/notifications-diagram-0.zh.jpg +0 -0
  41. package/docs/assets/diagram/overview-diagram-0.ja.jpg +0 -0
  42. package/docs/assets/diagram/overview-diagram-0.jpg +0 -0
  43. package/docs/assets/diagram/overview-diagram-0.zh-TW.jpg +0 -0
  44. package/docs/assets/diagram/overview-diagram-0.zh.jpg +0 -0
  45. package/docs/assets/diagram/user-center-diagram-0.ja.jpg +0 -0
  46. package/docs/assets/diagram/user-center-diagram-0.jpg +0 -0
  47. package/docs/assets/diagram/user-center-diagram-0.zh-TW.jpg +0 -0
  48. package/docs/assets/diagram/user-center-diagram-0.zh.jpg +0 -0
  49. package/docs/assets/diagram/user-management-diagram-0.ja.jpg +0 -0
  50. package/docs/assets/diagram/user-management-diagram-0.jpg +0 -0
  51. package/docs/assets/diagram/user-management-diagram-0.zh-TW.jpg +0 -0
  52. package/docs/assets/diagram/user-management-diagram-0.zh.jpg +0 -0
  53. package/docs/assets/diagram/user-sessions-diagram-0.ja.jpg +0 -0
  54. package/docs/assets/diagram/user-sessions-diagram-0.jpg +0 -0
  55. package/docs/assets/diagram/user-sessions-diagram-0.zh-TW.jpg +0 -0
  56. package/docs/assets/diagram/user-sessions-diagram-0.zh.jpg +0 -0
  57. package/docs/components-component-management-blocklet-studio.ja.md +0 -194
  58. package/docs/components-component-management-blocklet-studio.md +0 -194
  59. package/docs/components-component-management-blocklet-studio.zh-TW.md +0 -194
  60. package/docs/components-component-management-blocklet-studio.zh.md +0 -194
  61. package/docs/components-component-management-component-installer.ja.md +0 -182
  62. package/docs/components-component-management-component-installer.md +0 -182
  63. package/docs/components-component-management-component-installer.zh-TW.md +0 -182
  64. package/docs/components-component-management-component-installer.zh.md +0 -182
  65. package/docs/components-component-management.ja.md +0 -30
  66. package/docs/components-component-management.md +0 -30
  67. package/docs/components-component-management.zh-TW.md +0 -30
  68. package/docs/components-component-management.zh.md +0 -30
  69. package/docs/components-layout-dashboard.ja.md +0 -185
  70. package/docs/components-layout-dashboard.md +0 -187
  71. package/docs/components-layout-dashboard.zh-TW.md +0 -185
  72. package/docs/components-layout-dashboard.zh.md +0 -185
  73. package/docs/components-layout-footer.ja.md +0 -165
  74. package/docs/components-layout-footer.md +0 -165
  75. package/docs/components-layout-footer.zh-TW.md +0 -165
  76. package/docs/components-layout-footer.zh.md +0 -165
  77. package/docs/components-layout-header.ja.md +0 -183
  78. package/docs/components-layout-header.md +0 -183
  79. package/docs/components-layout-header.zh-TW.md +0 -183
  80. package/docs/components-layout-header.zh.md +0 -183
  81. package/docs/components-layout.ja.md +0 -31
  82. package/docs/components-layout.md +0 -31
  83. package/docs/components-layout.zh-TW.md +0 -31
  84. package/docs/components-layout.zh.md +0 -31
  85. package/docs/components-notifications.ja.md +0 -125
  86. package/docs/components-notifications.md +0 -125
  87. package/docs/components-notifications.zh-TW.md +0 -125
  88. package/docs/components-notifications.zh.md +0 -125
  89. package/docs/components-user-management-user-center.ja.md +0 -148
  90. package/docs/components-user-management-user-center.md +0 -147
  91. package/docs/components-user-management-user-center.zh-TW.md +0 -148
  92. package/docs/components-user-management-user-center.zh.md +0 -148
  93. package/docs/components-user-management-user-sessions.ja.md +0 -121
  94. package/docs/components-user-management-user-sessions.md +0 -123
  95. package/docs/components-user-management-user-sessions.zh-TW.md +0 -121
  96. package/docs/components-user-management-user-sessions.zh.md +0 -121
  97. package/docs/components-user-management.ja.md +0 -49
  98. package/docs/components-user-management.md +0 -51
  99. package/docs/components-user-management.zh-TW.md +0 -49
  100. package/docs/components-user-management.zh.md +0 -49
  101. package/docs/components-utilities-icon.ja.md +0 -106
  102. package/docs/components-utilities-icon.md +0 -106
  103. package/docs/components-utilities-icon.zh-TW.md +0 -106
  104. package/docs/components-utilities-icon.zh.md +0 -106
  105. package/docs/components-utilities.ja.md +0 -136
  106. package/docs/components-utilities.md +0 -136
  107. package/docs/components-utilities.zh-TW.md +0 -136
  108. package/docs/components-utilities.zh.md +0 -136
  109. package/docs/components.ja.md +0 -27
  110. package/docs/components.md +0 -27
  111. package/docs/components.zh-TW.md +0 -27
  112. package/docs/components.zh.md +0 -27
  113. package/docs/core-concepts.ja.md +0 -134
  114. package/docs/core-concepts.md +0 -135
  115. package/docs/core-concepts.zh-TW.md +0 -134
  116. package/docs/core-concepts.zh.md +0 -134
  117. package/docs/getting-started.ja.md +0 -132
  118. package/docs/getting-started.md +0 -132
  119. package/docs/getting-started.zh-TW.md +0 -132
  120. package/docs/getting-started.zh.md +0 -132
  121. package/docs/hooks-api.ja.md +0 -214
  122. package/docs/hooks-api.md +0 -214
  123. package/docs/hooks-api.zh-TW.md +0 -214
  124. package/docs/hooks-api.zh.md +0 -214
  125. package/docs/how-to-guides.ja.md +0 -413
  126. package/docs/how-to-guides.md +0 -413
  127. package/docs/how-to-guides.zh-TW.md +0 -413
  128. package/docs/how-to-guides.zh.md +0 -413
  129. package/docs/overview.ja.md +0 -51
  130. package/docs/overview.md +0 -51
  131. package/docs/overview.zh-TW.md +0 -51
  132. package/docs/overview.zh.md +0 -51
  133. package/glossary.md +0 -12
  134. package/src/@types/index.ts +0 -230
  135. package/src/@types/shims.d.ts +0 -18
  136. package/src/BlockletStudio/README.md +0 -116
  137. package/src/BlockletStudio/index.tsx +0 -145
  138. package/src/ComponentInstaller/ComponentInstaller.stories.jsx +0 -16
  139. package/src/ComponentInstaller/index.jsx +0 -207
  140. package/src/ComponentInstaller/installer-item.jsx +0 -129
  141. package/src/ComponentInstaller/locales.js +0 -22
  142. package/src/ComponentInstaller/use-component-installed.js +0 -88
  143. package/src/ComponentManager/components/add-component.tsx +0 -136
  144. package/src/ComponentManager/components/check-component.tsx +0 -3
  145. package/src/ComponentManager/components/publish-component.tsx +0 -90
  146. package/src/ComponentManager/components/resource-dialog.tsx +0 -91
  147. package/src/ComponentManager/index.tsx +0 -3
  148. package/src/ComponentManager/libs/locales.ts +0 -15
  149. package/src/Dashboard/Dashboard.stories.jsx +0 -20
  150. package/src/Dashboard/app-shell/app-badge.stories.tsx +0 -64
  151. package/src/Dashboard/app-shell/app-badge.tsx +0 -94
  152. package/src/Dashboard/app-shell/app-header.tsx +0 -104
  153. package/src/Dashboard/app-shell/app-info-context.tsx +0 -182
  154. package/src/Dashboard/app-shell/badges/app-badge-default.tsx +0 -130
  155. package/src/Dashboard/app-shell/badges/app-badge-did.tsx +0 -28
  156. package/src/Dashboard/app-shell/badges/app-badge-state.tsx +0 -40
  157. package/src/Dashboard/app-shell/badges/app-badge-switch.tsx +0 -72
  158. package/src/Dashboard/app-shell/badges/app-badge-version.tsx +0 -60
  159. package/src/Dashboard/app-shell/index.ts +0 -5
  160. package/src/Dashboard/index.jsx +0 -184
  161. package/src/Footer/Footer.stories.jsx +0 -33
  162. package/src/Footer/brand.jsx +0 -81
  163. package/src/Footer/copyright.jsx +0 -22
  164. package/src/Footer/index.jsx +0 -111
  165. package/src/Footer/internal-footer.jsx +0 -139
  166. package/src/Footer/layout/plain.jsx +0 -55
  167. package/src/Footer/layout/row.jsx +0 -43
  168. package/src/Footer/layout/standard.jsx +0 -114
  169. package/src/Footer/links.jsx +0 -321
  170. package/src/Footer/social-media.jsx +0 -55
  171. package/src/Header/Header.stories.jsx +0 -30
  172. package/src/Header/index.tsx +0 -259
  173. package/src/Icon/Icon.stories.jsx +0 -12
  174. package/src/Icon/index.tsx +0 -87
  175. package/src/Notifications/Snackbar.tsx +0 -261
  176. package/src/Notifications/hooks/use-title.tsx +0 -254
  177. package/src/Notifications/hooks/use-width.tsx +0 -16
  178. package/src/Notifications/utils.ts +0 -246
  179. package/src/UserCenter/assets/banner.png +0 -0
  180. package/src/UserCenter/components/config-inviter.tsx +0 -48
  181. package/src/UserCenter/components/config-profile.tsx +0 -99
  182. package/src/UserCenter/components/danger-zone.tsx +0 -82
  183. package/src/UserCenter/components/editable-field.tsx +0 -273
  184. package/src/UserCenter/components/fallback.tsx +0 -57
  185. package/src/UserCenter/components/nft-preview.tsx +0 -84
  186. package/src/UserCenter/components/nft.tsx +0 -279
  187. package/src/UserCenter/components/notification.tsx +0 -319
  188. package/src/UserCenter/components/passport.tsx +0 -107
  189. package/src/UserCenter/components/privacy.tsx +0 -120
  190. package/src/UserCenter/components/settings.tsx +0 -170
  191. package/src/UserCenter/components/status-dialog/date-picker.tsx +0 -77
  192. package/src/UserCenter/components/status-dialog/index.tsx +0 -293
  193. package/src/UserCenter/components/status-selector/duration-menu.tsx +0 -90
  194. package/src/UserCenter/components/status-selector/index.tsx +0 -58
  195. package/src/UserCenter/components/status-selector/menu-item.tsx +0 -56
  196. package/src/UserCenter/components/storage/action.tsx +0 -49
  197. package/src/UserCenter/components/storage/connected.tsx +0 -61
  198. package/src/UserCenter/components/storage/delete.tsx +0 -72
  199. package/src/UserCenter/components/storage/disconnect.tsx +0 -40
  200. package/src/UserCenter/components/storage/icons/empty-spaces-nft.svg +0 -1
  201. package/src/UserCenter/components/storage/icons/long-arrow.svg +0 -5
  202. package/src/UserCenter/components/storage/icons/space-connected.svg +0 -3
  203. package/src/UserCenter/components/storage/icons/space-disconnect.svg +0 -3
  204. package/src/UserCenter/components/storage/index.tsx +0 -41
  205. package/src/UserCenter/components/storage/preview-nft.tsx +0 -72
  206. package/src/UserCenter/components/third-party-login/index.tsx +0 -199
  207. package/src/UserCenter/components/third-party-login/third-party-item.tsx +0 -296
  208. package/src/UserCenter/components/user-center.tsx +0 -787
  209. package/src/UserCenter/components/user-info/address.tsx +0 -143
  210. package/src/UserCenter/components/user-info/index.tsx +0 -4
  211. package/src/UserCenter/components/user-info/link-preview-input.tsx +0 -274
  212. package/src/UserCenter/components/user-info/metadata.tsx +0 -658
  213. package/src/UserCenter/components/user-info/social-actions/chat.tsx +0 -43
  214. package/src/UserCenter/components/user-info/social-actions/follow.tsx +0 -23
  215. package/src/UserCenter/components/user-info/social-actions/index.tsx +0 -17
  216. package/src/UserCenter/components/user-info/switch-role.tsx +0 -42
  217. package/src/UserCenter/components/user-info/timezone-select.tsx +0 -119
  218. package/src/UserCenter/components/user-info/user-basic-info.tsx +0 -292
  219. package/src/UserCenter/components/user-info/user-info-item.tsx +0 -54
  220. package/src/UserCenter/components/user-info/user-info.tsx +0 -91
  221. package/src/UserCenter/components/user-info/user-status.tsx +0 -234
  222. package/src/UserCenter/components/user-info/utils.ts +0 -320
  223. package/src/UserCenter/components/webhook-item.tsx +0 -248
  224. package/src/UserCenter/index.tsx +0 -1
  225. package/src/UserCenter/libs/locales.ts +0 -378
  226. package/src/UserCenter/libs/utils.ts +0 -30
  227. package/src/UserSessions/components/user-session-info.tsx +0 -78
  228. package/src/UserSessions/components/user-sessions.tsx +0 -545
  229. package/src/UserSessions/index.tsx +0 -1
  230. package/src/UserSessions/libs/locales.ts +0 -60
  231. package/src/UserSessions/libs/utils.ts +0 -82
  232. package/src/blocklets.js +0 -195
  233. package/src/common/domain-warning.jsx +0 -178
  234. package/src/common/header-addons.jsx +0 -119
  235. package/src/common/link-blocker.jsx +0 -20
  236. package/src/common/notification-addon.jsx +0 -135
  237. package/src/common/org-switch/avatar-uploader.jsx +0 -271
  238. package/src/common/org-switch/create.jsx +0 -267
  239. package/src/common/org-switch/index.jsx +0 -407
  240. package/src/common/org-switch/locales.js +0 -52
  241. package/src/common/org-switch/use-org.jsx +0 -79
  242. package/src/common/overridable-theme-provider.jsx +0 -17
  243. package/src/common/wallet-hidden-topbar.js +0 -14
  244. package/src/common/wizard-modal.jsx +0 -200
  245. package/src/common/ws.js +0 -68
  246. package/src/contexts/config-user-space.tsx +0 -88
  247. package/src/contexts/user-followers.tsx +0 -54
  248. package/src/hooks/use-follow.tsx +0 -75
  249. package/src/hooks/use-mobile.tsx +0 -6
  250. package/src/index.ts +0 -16
  251. package/src/libs/constant.ts +0 -1
  252. package/src/libs/spaces.tsx +0 -18
  253. package/src/libs/with-hide-when-embed.tsx +0 -24
  254. package/src/types.js +0 -45
  255. package/src/utils.js +0 -161
  256. package/vite.config.mjs +0 -34
@@ -1,91 +0,0 @@
1
- import { useMemoizedFn, useMount, useUnmount } from 'ahooks';
2
- import { useRef, forwardRef, useImperativeHandle, Ref } from 'react';
3
-
4
- function ResourceDialog(
5
- {
6
- src,
7
- open = false,
8
- componentDid,
9
- loading = true,
10
- storeUrl = '',
11
- onClose = () => {},
12
- onComplete = () => {},
13
- onLoad = () => {},
14
- }: {
15
- src: string;
16
- componentDid: string;
17
- open?: boolean;
18
- loading?: boolean;
19
- storeUrl?: string;
20
- onLoad?: () => void;
21
- onClose?: () => void;
22
- onComplete?: () => void;
23
- },
24
- ref: Ref<{
25
- selectBlocklet: (blockletMeta: any) => void;
26
- }>
27
- ) {
28
- const iframeRef = useRef<HTMLIFrameElement>(null);
29
-
30
- const listener = useMemoizedFn((event: MessageEvent) => {
31
- if (open) {
32
- if (event?.data?.event === 'resourceDialog.close') {
33
- onClose();
34
- }
35
- if (event?.data?.event === 'resourceDialog.complete') {
36
- onComplete();
37
- }
38
- if (event?.data?.event === 'resourceDialog.loaded') {
39
- onLoad();
40
- }
41
- }
42
- });
43
-
44
- useMount(() => {
45
- window.addEventListener('message', listener);
46
- });
47
-
48
- useUnmount(() => {
49
- window.removeEventListener('message', listener);
50
- });
51
-
52
- useImperativeHandle(ref, () => ({
53
- selectBlocklet: (blockletMeta: any) => {
54
- if (iframeRef.current?.contentWindow) {
55
- iframeRef.current.contentWindow.postMessage(
56
- {
57
- event: 'resourceDialog.select',
58
- data: blockletMeta,
59
- componentDid,
60
- storeUrl,
61
- },
62
- '*'
63
- );
64
- }
65
- },
66
- }));
67
-
68
- if (!open) {
69
- return null;
70
- }
71
-
72
- return (
73
- <iframe
74
- ref={iframeRef}
75
- src={src}
76
- title="Resource Dialog"
77
- style={{
78
- position: 'fixed',
79
- top: 0,
80
- left: loading ? '-100vw' : 0,
81
- width: '100vw',
82
- height: '100vh',
83
- zIndex: 9999,
84
- backgroundColor: 'transparent',
85
- border: 'none',
86
- }}
87
- />
88
- );
89
- }
90
-
91
- export default forwardRef(ResourceDialog);
@@ -1,3 +0,0 @@
1
- export { default as PublishComponent } from './components/publish-component';
2
- export { default as AddComponent } from './components/add-component';
3
- export { default as CheckComponent } from './components/check-component';
@@ -1,15 +0,0 @@
1
- export const translations = {
2
- zh: {
3
- importResource: '导入',
4
- exportResource: '导出',
5
- noPermission: '你没有权限执行该操作,请切换管理员通行证或联系管理员进行安装',
6
- needLogin: '登录后才可操作',
7
- },
8
- en: {
9
- importResource: 'Import',
10
- exportResource: 'Export',
11
- noPermission:
12
- 'You do not have permission to perform this operation. Please switch your passport as admin or contact the administrator to install the blocklet',
13
- needLogin: 'Please login first',
14
- },
15
- };
@@ -1,20 +0,0 @@
1
- import Basic from './demo/basic';
2
-
3
- export default {
4
- title: 'Blocklet-UI-React/Dashboard',
5
-
6
- parameters: {
7
- layout: 'fullscreen',
8
- design: {
9
- type: 'figma',
10
- url: 'https://www.figma.com/file/E8TSBWCOyXzETmVOjzbqvw/ArcBlock-UI-Kit?node-id=1504%3A5211',
11
- },
12
- },
13
- };
14
-
15
- Basic.argTypes = {
16
- userRole: { control: 'select', options: [null, 'owner', 'developer'] },
17
- };
18
- Basic.storyName = 'Dashboard';
19
-
20
- export { Basic };
@@ -1,64 +0,0 @@
1
- import { Box, Stack, Typography } from '@mui/material';
2
- import { useState } from 'react';
3
- import { ThemeProvider } from '@arcblock/ux/lib/Theme';
4
- import { ThemeModeToggle } from '@arcblock/ux/lib/Config';
5
- import AppBadge from './app-badge';
6
-
7
- export default {
8
- title: 'Blocklet-UI-React/Dashboard',
9
- component: AppBadge,
10
- };
11
-
12
- export function Badges() {
13
- const [checked, setChecked] = useState(true);
14
-
15
- return (
16
- <ThemeProvider prefer="system">
17
- <ThemeModeToggle />
18
- <Box sx={{ p: 3, backgroundColor: 'background.default' }}>
19
- <Stack spacing={2}>
20
- <Typography variant="h6">Loading</Typography>
21
- <Stack direction="row" spacing={2}>
22
- <AppBadge label="Loading" value="Value" loading />
23
- </Stack>
24
- <Typography variant="h6">Default</Typography>
25
- <Stack direction="row" spacing={2}>
26
- <AppBadge label="Label" value="Value" />
27
- <AppBadge icon="lucide:info" label="Label" value="Value" />
28
- </Stack>
29
- <Typography variant="h6">Number</Typography>
30
- <Stack direction="row" spacing={2}>
31
- <AppBadge variant="number" value={1234} />
32
- <AppBadge variant="number" value={1234567} round={1} />
33
- <AppBadge variant="number" label="Label" value={1234567890} round={2} />
34
- </Stack>
35
- <Typography variant="h6">Time</Typography>
36
- <Stack direction="row" spacing={2}>
37
- <AppBadge variant="time" value={new Date()} />
38
- <AppBadge variant="time" label="Label" value={Date.now() - 3600000} />
39
- </Stack>
40
- <Typography variant="h6">State</Typography>
41
- <Stack direction="row" spacing={2}>
42
- <AppBadge variant="state" value="Running" color="success" />
43
- <AppBadge variant="state" value="Stopped" color="error" />
44
- <AppBadge variant="state" value="Warning" color="warning" />
45
- </Stack>
46
- <Typography variant="h6">Version</Typography>
47
- <Stack direction="row" spacing={2}>
48
- <AppBadge variant="version" value="1.0.0" color="info" />
49
- <AppBadge variant="version" icon="lucide:package" value="2.3.4" color="primary" />
50
- </Stack>
51
- <Typography variant="h6">DID</Typography>
52
- <Stack direction="row" spacing={2}>
53
- <AppBadge variant="did" value="z1kFxaZ5hJXHhqJzXqJzXqJzXqJzXqJzXqJz" />
54
- <AppBadge variant="did" value="0x1234567890123456789012345678901234567890" />
55
- </Stack>
56
- <Typography variant="h6">Switch</Typography>
57
- <Stack direction="row" spacing={2}>
58
- <AppBadge variant="switch" label="Toggle" value={checked} onChange={setChecked} />
59
- </Stack>
60
- </Stack>
61
- </Box>
62
- </ThemeProvider>
63
- );
64
- }
@@ -1,94 +0,0 @@
1
- import React from 'react';
2
- import dayjs from 'dayjs';
3
- import relativeTime from 'dayjs/plugin/relativeTime';
4
- import localizedFormat from 'dayjs/plugin/localizedFormat';
5
- import 'dayjs/locale/zh';
6
- import 'dayjs/locale/zh-tw';
7
- import 'dayjs/locale/ja';
8
- import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
9
- import { AppBadgeDefault, AppBadgeDefaultProps } from './badges/app-badge-default';
10
- import { AppBadgeSwitch, AppBadgeSwitchProps } from './badges/app-badge-switch';
11
- import { AppBadgeVersion, AppBadgeVersionProps } from './badges/app-badge-version';
12
- import { AppBadgeState, AppBadgeStateProps } from './badges/app-badge-state';
13
- import { AppBadgeDID, AppBadgeDIDProps } from './badges/app-badge-did';
14
-
15
- dayjs.extend(relativeTime);
16
- dayjs.extend(localizedFormat);
17
-
18
- export const formatNumber = (num: unknown, round: number = 0): string => {
19
- if (typeof num !== 'number') return '';
20
-
21
- const absNum = Math.abs(num);
22
- let rounded;
23
- let unit = '';
24
-
25
- if (absNum >= 1e12) {
26
- unit = 'T';
27
- rounded = `${(num / 1e12).toFixed(round)}`; // 万亿
28
- } else if (absNum >= 1e9) {
29
- unit = 'B';
30
- rounded = `${(num / 1e9).toFixed(round)}`; // 十亿
31
- } else if (absNum >= 1e6) {
32
- unit = 'M';
33
- rounded = `${(num / 1e6).toFixed(round)}`; // 百万
34
- } else if (absNum >= 1e3) {
35
- unit = 'K';
36
- rounded = `${(num / 1e3).toFixed(round)}`; // 千
37
- } else {
38
- rounded = num.toString();
39
- }
40
-
41
- // 去掉尾部的零
42
- if (round > 0) {
43
- rounded = rounded.replace(/(\.\d*?)0+$/, '$1').replace(/\.$/, '');
44
- }
45
-
46
- return `${rounded}${unit}`;
47
- };
48
-
49
- export const formatTime = (value?: string | number | Date, locale: string = 'en'): string => {
50
- if (!value) return '';
51
-
52
- return dayjs(value).locale(locale).fromNow();
53
- };
54
-
55
- const BadgeVariants: Record<string, React.ComponentType<any>> = {
56
- switch: AppBadgeSwitch,
57
- version: AppBadgeVersion,
58
- state: AppBadgeState,
59
- did: AppBadgeDID,
60
- };
61
-
62
- export type AppBadgeProps =
63
- | (AppBadgeDefaultProps & { variant?: 'default' })
64
- | (AppBadgeDefaultProps & { variant: 'number' })
65
- | (Omit<AppBadgeDefaultProps, 'value'> & { variant: 'time'; value?: string | number | Date })
66
- | (AppBadgeSwitchProps & { variant: 'switch' })
67
- | (AppBadgeVersionProps & { variant: 'version' })
68
- | (AppBadgeStateProps & { variant: 'state' })
69
- | (AppBadgeDIDProps & { variant: 'did' });
70
-
71
- export default function AppBadge(props: AppBadgeProps) {
72
- const { locale = 'en' } = useLocaleContext() || {};
73
-
74
- if (props.variant === 'number') {
75
- const { value, round = 0, ...rest } = props;
76
- const val = formatNumber(Number(value), round);
77
-
78
- return <AppBadgeDefault value={val} {...rest} />;
79
- }
80
- if (props.variant === 'time') {
81
- const { value, ...rest } = props;
82
- const val = formatTime(value, locale);
83
-
84
- return <AppBadgeDefault value={val} {...rest} />;
85
- }
86
- if (props.variant) {
87
- const Badge = BadgeVariants[props.variant];
88
- if (Badge) {
89
- return <Badge {...props} />;
90
- }
91
- }
92
-
93
- return <AppBadgeDefault {...(props as AppBadgeDefaultProps)} />;
94
- }
@@ -1,104 +0,0 @@
1
- import { isValidElement, useEffect } from 'react';
2
- import { Box, Stack, Typography, useMediaQuery, SxProps, Theme } from '@mui/material';
3
- import Tabs from '@arcblock/ux/lib/Tabs';
4
- import AppBadge from './app-badge';
5
- import { useAppInfo } from './app-info-context';
6
-
7
- function useMobile(): boolean {
8
- const isMobile = useMediaQuery((theme: Theme) => theme.breakpoints.down('md'));
9
-
10
- return isMobile;
11
- }
12
-
13
- interface DividerProps {
14
- sx?: SxProps<Theme>;
15
- }
16
-
17
- function Divider({ sx = {} }: DividerProps) {
18
- const isMobile = useMobile();
19
-
20
- return (
21
- <Box sx={{ mx: isMobile ? -2 : -3, borderBottom: '1px solid', borderColor: 'divider', mt: 1.5, mb: 1, ...sx }} />
22
- );
23
- }
24
-
25
- interface AppHeaderProps {
26
- onTabChange?: (tab: string) => void;
27
- }
28
-
29
- function AppHeader({ onTabChange = undefined }: AppHeaderProps) {
30
- const isMobile = useMobile();
31
- const {
32
- inService,
33
- navItem,
34
- icon = undefined,
35
- name = '',
36
- description = undefined,
37
- actions = undefined,
38
- badges = [],
39
- tabs = [],
40
- currentTab = '',
41
- updateAppInfo,
42
- } = useAppInfo();
43
-
44
- // 非 Service 应用,自动更新 name / description
45
- useEffect(() => {
46
- if (!inService) {
47
- updateAppInfo({
48
- name: navItem?.title || '',
49
- description: navItem?.description || '',
50
- });
51
- }
52
- }, [navItem?.title, navItem?.description, inService, updateAppInfo]);
53
-
54
- if (!name) {
55
- return null;
56
- }
57
-
58
- return (
59
- <Box className="app-header" sx={{ mt: 3, mb: 3 }}>
60
- {/* Basic Info */}
61
- <Box
62
- sx={{
63
- display: 'flex',
64
- alignItems: 'center',
65
- gap: 1,
66
- }}>
67
- {icon && <Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'center' }}>{icon}</Box>}
68
- <Stack sx={{ flexGrow: 1 }}>
69
- <Typography variant="h1" sx={{ mb: 0.5 }}>
70
- {name}
71
- </Typography>
72
- {description && (
73
- <Typography
74
- variant="body2"
75
- color="text.secondary"
76
- sx={{ lineHeight: 1.6, '& a': { color: 'primary.main' }, maxWidth: 980 }}>
77
- {description}
78
- </Typography>
79
- )}
80
- </Stack>
81
- {!isMobile && actions && <Box sx={{ ml: 1 }}>{actions}</Box>}
82
- </Box>
83
- {/* Badges */}
84
- {badges.length > 0 && (
85
- <Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 1, alignItems: 'center', mt: 2 }}>
86
- {badges.map((config, index) =>
87
- isValidElement(config) ? config : <AppBadge key={config.label || index} {...config} />
88
- )}
89
- </Box>
90
- )}
91
- {isMobile && actions && <Box sx={{ mt: isMobile ? 2 : 0 }}>{actions}</Box>}
92
- {/* Tabs */}
93
- {tabs.length <= 1 && <Divider />}
94
- {tabs.length > 1 && (
95
- <>
96
- <Tabs tabs={tabs} current={currentTab} onChange={onTabChange} scrollButtons="auto" sx={{ mt: 2.5 }} />
97
- <Divider sx={{ mt: 0 }} />
98
- </>
99
- )}
100
- </Box>
101
- );
102
- }
103
-
104
- export default AppHeader;
@@ -1,182 +0,0 @@
1
- import React, { createContext, useState, useContext, useMemo } from 'react';
2
- import { useCreation, useMemoizedFn } from 'ahooks';
3
- import { withoutTrailingSlash } from 'ufo';
4
- import isPlainObject from 'lodash/isPlainObject';
5
- import { WELLKNOWN_BLOCKLET_ADMIN_PATH } from '@abtnode/constant';
6
- import { Locale } from '@arcblock/ux/lib/type';
7
- import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
8
- import { AppBadgeProps } from './app-badge';
9
-
10
- export type NavItem = {
11
- id: string;
12
- parent: string; // pid
13
- title: string;
14
- link: string;
15
- description?: string;
16
- };
17
-
18
- export interface TabConfig {
19
- value: string;
20
- label?: string;
21
- render?: React.ComponentType | React.ReactNode;
22
- }
23
-
24
- export interface AppInfo {
25
- icon?: React.ReactNode;
26
- name?: React.ReactNode;
27
- description?: React.ReactNode;
28
- badges?: Array<AppBadgeProps | React.ReactElement>;
29
- actions?: React.ReactNode;
30
- tabs?: TabConfig[];
31
- currentTab?: string;
32
- }
33
-
34
- export interface AppInfoContextValue extends AppInfo {
35
- inService: boolean;
36
- currentTab: string;
37
- TabComponent: React.ComponentType | React.ReactNode;
38
- navItem?: NavItem;
39
- updateAppInfo: (patch: Partial<AppInfo>) => void;
40
- }
41
-
42
- const AppInfoContext = createContext<AppInfoContextValue>({
43
- inService: false,
44
- currentTab: '',
45
- TabComponent: null,
46
- navItem: undefined,
47
- updateAppInfo: () => {},
48
- });
49
-
50
- export const getI18nVal = (
51
- obj: Record<string, string | Record<Locale, string>>,
52
- key: string,
53
- locale: Locale = 'en'
54
- ) => {
55
- const val = obj?.[key];
56
-
57
- // @ts-ignore
58
- return isPlainObject(val) ? val[locale] || val.en : val;
59
- };
60
-
61
- // 基于前缀匹配算法查找 NavItem
62
- export const findNavItem = (items: NavItem[], targetLink: string = '', locale: Locale = 'en') => {
63
- const targetParts = targetLink === '/' ? ['/'] : targetLink.split('/').filter(Boolean);
64
-
65
- let result: NavItem | null = null;
66
- let maxLen = 0;
67
-
68
- items.forEach((item) => {
69
- const currentLink = getI18nVal(item, 'link', locale) || '';
70
- const currentParts = currentLink === '/' ? ['/'] : currentLink.split('/').filter(Boolean);
71
-
72
- if (currentParts.length > targetParts.length) {
73
- return;
74
- }
75
-
76
- let isMatch = true;
77
- for (let i = 0; i < currentParts.length; i++) {
78
- if (currentParts[i] !== targetParts[i]) {
79
- isMatch = false;
80
- break;
81
- }
82
- }
83
-
84
- if (isMatch && currentParts.length > maxLen) {
85
- result = item;
86
- maxLen = currentParts.length;
87
- }
88
- });
89
-
90
- return result;
91
- };
92
-
93
- interface AppInfoProviderProps {
94
- path?: string;
95
- currentTab?: string;
96
- meta?: object;
97
- children?: React.ReactNode;
98
- }
99
- export function AppInfoProvider({
100
- path = window?.location?.pathname || '',
101
- currentTab = '',
102
- meta = undefined,
103
- children = null,
104
- }: AppInfoProviderProps) {
105
- const { locale = 'en' } = useLocaleContext() || {};
106
- const targetLink = withoutTrailingSlash(path);
107
- const inService = targetLink.startsWith(WELLKNOWN_BLOCKLET_ADMIN_PATH);
108
- // 便于测试
109
- const blockletMeta = useCreation(() => Object.assign({}, window.blocklet, meta), [meta]);
110
-
111
- // 匹配 Dashboard NavItem
112
- const navItem = useCreation(() => {
113
- // @ts-ignore
114
- const navigations = blockletMeta.navigation?.filter((v) =>
115
- Array.isArray(v.section) ? v.section.includes('dashboard') : v.section === 'dashboard'
116
- );
117
- const items: NavItem[] = navigations?.flatMap((v: { items?: NavItem[] }) => v.items || []);
118
- // 前缀匹配 navItem
119
- const item = findNavItem(items, targetLink, locale);
120
-
121
- if (!item) {
122
- return undefined;
123
- }
124
-
125
- const parentItem = navigations.find((v: NavItem) => v.id === item.parent);
126
- let title = getI18nVal(item, 'title', locale) || '';
127
-
128
- if (!inService) {
129
- // 应用带上父级标题
130
- title = `${getI18nVal(parentItem, 'title', locale) || ''} - ${title}`;
131
- }
132
-
133
- return {
134
- id: item.id,
135
- parent: item.parent,
136
- title,
137
- link: getI18nVal(item, 'link', locale) || '',
138
- description: getI18nVal(item, 'description', locale) || '',
139
- } as NavItem;
140
- }, [path, inService, locale, blockletMeta]);
141
-
142
- const [appInfo, setAppInfo] = useState<AppInfo>({});
143
-
144
- const updateAppInfo = useMemoizedFn((patch: Partial<AppInfo>) => {
145
- setAppInfo((prev) => ({ ...prev, ...patch }));
146
- });
147
-
148
- const value = useMemo(
149
- () => {
150
- const { tabs = [] } = appInfo;
151
- const currentTabConfig = tabs.find((v) => v.value === currentTab);
152
-
153
- let ctab = currentTab;
154
- let TabComponent = null;
155
- // fallback 到第一个 tab
156
- if (!currentTabConfig && tabs.length > 0) {
157
- ctab = tabs[0].value;
158
- TabComponent = tabs[0].render || null;
159
- } else {
160
- TabComponent = currentTabConfig?.render || null;
161
- }
162
-
163
- return {
164
- ...appInfo,
165
- inService,
166
- navItem,
167
- currentTab: ctab,
168
- TabComponent,
169
- updateAppInfo,
170
- };
171
- },
172
- // eslint-disable-next-line react-hooks/exhaustive-deps
173
- [appInfo, navItem, inService, currentTab, updateAppInfo]
174
- );
175
-
176
- return <AppInfoContext.Provider value={value}>{children}</AppInfoContext.Provider>;
177
- }
178
-
179
- export function useAppInfo(): AppInfoContextValue {
180
- const context = useContext(AppInfoContext);
181
- return context;
182
- }