@arcblock/ux 2.10.67 → 2.10.69

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 (294) hide show
  1. package/lib/Address/did-address.d.ts +6 -5
  2. package/lib/Address/index.d.ts +1 -1
  3. package/lib/Avatar/index.d.ts +10 -8
  4. package/lib/Avatar/index.js +6 -4
  5. package/lib/Blocklet/blocklet.d.ts +4 -4
  6. package/lib/Blocklet/blocklet.js +2 -2
  7. package/lib/BlockletContext/index.d.ts +3 -3
  8. package/lib/BlockletNFT/index.d.ts +6 -6
  9. package/lib/BlockletNFT/index.js +3 -3
  10. package/lib/BlockletV2/blocklet.d.ts +2 -2
  11. package/lib/Button/wrap.d.ts +4 -4
  12. package/lib/Button/wrap.js +2 -2
  13. package/lib/CardSelector/index.js +0 -1
  14. package/lib/Center/index.d.ts +1 -1
  15. package/lib/ClickToCopy/copy-button.d.ts +5 -4
  16. package/lib/ClickToCopy/copy-button.js +0 -1
  17. package/lib/ClickToCopy/hook.d.ts +3 -8
  18. package/lib/ClickToCopy/index.d.ts +6 -4
  19. package/lib/CodeBlock/index.d.ts +3 -1
  20. package/lib/CookieConsent/index.d.ts +8 -29
  21. package/lib/CookieConsent/index.js +3 -17
  22. package/lib/CountDown/index.d.ts +21 -25
  23. package/lib/CountDown/index.js +12 -11
  24. package/lib/DID/index.d.ts +9 -8
  25. package/lib/Datatable/index.d.ts +5 -5
  26. package/lib/Datatable/index.js +5 -5
  27. package/lib/Dialog/confirm.d.ts +6 -6
  28. package/lib/Dialog/confirm.js +3 -3
  29. package/lib/Dialog/types.d.ts +1 -1
  30. package/lib/DidLogo/index.d.ts +5 -25
  31. package/lib/DidLogo/index.js +4 -15
  32. package/lib/DriftBot/index.d.ts +13 -19
  33. package/lib/DriftBot/index.js +5 -6
  34. package/lib/Earth/index.d.ts +28 -10
  35. package/lib/Earth/index.js +12 -52
  36. package/lib/Earth/util.d.ts +10 -5
  37. package/lib/Earth/util.js +1 -0
  38. package/lib/ErrorBoundary/fallback.d.ts +12 -19
  39. package/lib/ErrorBoundary/fallback.js +2 -19
  40. package/lib/ErrorBoundary/index.d.ts +1 -1
  41. package/lib/Footer/index.d.ts +17 -24
  42. package/lib/Footer/index.js +2 -11
  43. package/lib/Header/header.d.ts +2 -2
  44. package/lib/Icon/image.d.ts +3 -2
  45. package/lib/Icon/index.d.ts +6 -4
  46. package/lib/Img/index.d.ts +1 -1
  47. package/lib/Img/index.js +1 -1
  48. package/lib/InfoRow/index.d.ts +9 -32
  49. package/lib/InfoRow/index.js +10 -23
  50. package/lib/Layout/dashboard/external-link.d.ts +13 -14
  51. package/lib/Layout/dashboard/external-link.js +5 -22
  52. package/lib/Layout/dashboard/full-page.d.ts +19 -11
  53. package/lib/Layout/dashboard/full-page.js +2 -6
  54. package/lib/Layout/dashboard/index.d.ts +20 -39
  55. package/lib/Layout/dashboard/index.js +10 -38
  56. package/lib/Layout/dashboard/sidebar.d.ts +17 -20
  57. package/lib/Layout/dashboard/sidebar.js +3 -16
  58. package/lib/Layout/dashboard-legacy/header.d.ts +10 -36
  59. package/lib/Layout/dashboard-legacy/header.js +5 -24
  60. package/lib/Layout/dashboard-legacy/index.d.ts +17 -56
  61. package/lib/Layout/dashboard-legacy/index.js +12 -41
  62. package/lib/Layout/dashboard-legacy/sidebar.d.ts +15 -26
  63. package/lib/Layout/dashboard-legacy/sidebar.js +5 -15
  64. package/lib/Layout/index.d.ts +17 -56
  65. package/lib/Layout/index.js +24 -50
  66. package/lib/LoadingMask/index.d.ts +8 -31
  67. package/lib/LoadingMask/index.js +3 -19
  68. package/lib/Locale/browser-lang.d.ts +4 -1
  69. package/lib/Locale/browser-lang.js +8 -3
  70. package/lib/Locale/context.d.ts +18 -8
  71. package/lib/Locale/context.js +1 -1
  72. package/lib/Locale/languages.d.ts +9 -55
  73. package/lib/Locale/selector.d.ts +10 -26
  74. package/lib/Locale/selector.js +8 -25
  75. package/lib/Locale/util.d.ts +4 -3
  76. package/lib/Locale/util.js +0 -1
  77. package/lib/Logo/index.d.ts +9 -40
  78. package/lib/Logo/index.js +88 -46
  79. package/lib/Metric/index.d.ts +9 -31
  80. package/lib/Metric/index.js +5 -20
  81. package/lib/NFTDisplay/aspect-ratio-container.d.ts +5 -12
  82. package/lib/NFTDisplay/aspect-ratio-container.js +0 -5
  83. package/lib/NFTDisplay/broken.d.ts +3 -13
  84. package/lib/NFTDisplay/broken.js +80 -10
  85. package/lib/NFTDisplay/displayApi.d.ts +1 -1
  86. package/lib/NFTDisplay/index.d.ts +28 -6
  87. package/lib/NFTDisplay/index.js +17 -51
  88. package/lib/NFTDisplay/svg-embedder/img.d.ts +8 -23
  89. package/lib/NFTDisplay/svg-embedder/img.js +3 -17
  90. package/lib/NFTDisplay/svg-embedder/inline-svg.d.ts +7 -13
  91. package/lib/NFTDisplay/svg-embedder/inline-svg.js +1 -8
  92. package/lib/NavMenu/nav-menu.d.ts +2 -0
  93. package/lib/NavMenu/nav-menu.js +0 -1
  94. package/lib/PageScroller/index.d.ts +14 -13
  95. package/lib/PageScroller/index.js +12 -37
  96. package/lib/PageScroller/usePrevValue.d.ts +1 -1
  97. package/lib/PageScroller/usePrevValue.js +1 -2
  98. package/lib/Passport/index.d.ts +1 -1
  99. package/lib/Passport/passport.d.ts +10 -30
  100. package/lib/Passport/passport.js +5 -19
  101. package/lib/PoweredByArcBlock/index.d.ts +4 -14
  102. package/lib/PoweredByArcBlock/index.js +1 -8
  103. package/lib/PricingTable/PricingPlan.d.ts +11 -9
  104. package/lib/PricingTable/PricingPlan.js +0 -4
  105. package/lib/PricingTable/index.d.ts +5 -3
  106. package/lib/PricingTable/index.js +1 -5
  107. package/lib/QRCode/index.d.ts +11 -22
  108. package/lib/QRCode/index.js +2 -17
  109. package/lib/RelativeTime/index.d.ts +12 -40
  110. package/lib/RelativeTime/index.js +7 -27
  111. package/lib/Result/common.d.ts +26 -45
  112. package/lib/Result/common.js +2 -4
  113. package/lib/Result/index.d.ts +5 -18
  114. package/lib/Result/index.js +1 -9
  115. package/lib/Result/result.d.ts +7 -29
  116. package/lib/Result/result.js +2 -17
  117. package/lib/Result/translations.d.ts +2 -54
  118. package/lib/Screenshot/BaseScreenshot/index.d.ts +7 -24
  119. package/lib/Screenshot/BaseScreenshot/index.js +2 -15
  120. package/lib/Screenshot/BaseScreenshot/shells/Macbook.d.ts +25 -19
  121. package/lib/Screenshot/BaseScreenshot/shells/Phone.d.ts +25 -19
  122. package/lib/Screenshot/index.d.ts +84 -28
  123. package/lib/Screenshot/index.js +14 -43
  124. package/lib/SessionBlocklet/index.d.ts +6 -19
  125. package/lib/SessionBlocklet/index.js +5 -15
  126. package/lib/SessionManager/index.d.ts +1 -1
  127. package/lib/SessionPermission/index.d.ts +9 -17
  128. package/lib/SessionPermission/index.js +3 -11
  129. package/lib/SessionUser/components/logged-in.d.ts +9 -31
  130. package/lib/SessionUser/components/logged-in.js +13 -29
  131. package/lib/SessionUser/components/session-user-item.d.ts +8 -1
  132. package/lib/SessionUser/components/session-user-item.js +2 -12
  133. package/lib/SessionUser/components/session-user-switch.d.ts +9 -21
  134. package/lib/SessionUser/components/session-user-switch.js +3 -15
  135. package/lib/SessionUser/components/un-login.d.ts +7 -23
  136. package/lib/SessionUser/components/un-login.js +4 -16
  137. package/lib/SessionUser/components/user-info.d.ts +12 -29
  138. package/lib/SessionUser/components/user-info.js +4 -19
  139. package/lib/SessionUser/index.d.ts +7 -30
  140. package/lib/SessionUser/index.js +5 -26
  141. package/lib/SessionUser/libs/translation.d.ts +2 -31
  142. package/lib/SessionUser/libs/translation.js +1 -0
  143. package/lib/SessionUser/libs/utils.d.ts +10 -9
  144. package/lib/Sparkline/index.d.ts +22 -1
  145. package/lib/Sparkline/index.js +25 -17
  146. package/lib/Spinner/index.d.ts +6 -1
  147. package/lib/Spinner/index.js +4 -11
  148. package/lib/Success/index.d.ts +5 -21
  149. package/lib/Success/index.js +10 -19
  150. package/lib/Tabs/index.d.ts +12 -26
  151. package/lib/Tabs/index.js +7 -37
  152. package/lib/TextCollapse/index.d.ts +10 -10
  153. package/lib/TextCollapse/index.js +4 -21
  154. package/lib/Theme/index.js +0 -2
  155. package/lib/Theme/theme-provider.d.ts +1 -1
  156. package/lib/Theme/theme.d.ts +4 -1
  157. package/lib/Theme/theme.js +1 -2
  158. package/lib/Typography/index.d.ts +5 -24
  159. package/lib/Typography/index.js +5 -17
  160. package/lib/Util/index.d.ts +17 -8
  161. package/lib/Util/index.js +22 -3
  162. package/lib/Video/index.d.ts +12 -16
  163. package/lib/Video/index.js +0 -14
  164. package/lib/Wallet/Action.d.ts +13 -18
  165. package/lib/Wallet/Action.js +0 -7
  166. package/lib/Wallet/Download.d.ts +24 -30
  167. package/lib/Wallet/Download.js +201 -18
  168. package/lib/Wallet/Open.d.ts +5 -15
  169. package/lib/Wallet/Open.js +5 -11
  170. package/lib/WalletOSIcon/index.d.ts +6 -25
  171. package/lib/WalletOSIcon/index.js +3 -16
  172. package/lib/WebWalletSWKeeper/index.d.ts +8 -20
  173. package/lib/WebWalletSWKeeper/index.js +14 -19
  174. package/lib/WechatPrompt/index.js +2 -0
  175. package/lib/global.d.ts +15 -0
  176. package/lib/type.d.ts +12 -3
  177. package/lib/withTheme/index.d.ts +8 -6
  178. package/lib/withTracker/index.d.ts +1 -1
  179. package/lib/withTracker/index.js +3 -0
  180. package/package.json +9 -5
  181. package/src/Address/did-address.tsx +7 -6
  182. package/src/Address/index.tsx +1 -1
  183. package/src/Avatar/index.jsx +6 -4
  184. package/src/Blocklet/blocklet.jsx +2 -2
  185. package/src/BlockletContext/index.tsx +3 -3
  186. package/src/BlockletNFT/index.jsx +3 -3
  187. package/src/BlockletV2/blocklet.tsx +2 -2
  188. package/src/Button/wrap.jsx +2 -2
  189. package/src/CardSelector/index.tsx +0 -1
  190. package/src/Center/index.tsx +1 -1
  191. package/src/ClickToCopy/copy-button.tsx +4 -4
  192. package/src/ClickToCopy/hook.ts +3 -2
  193. package/src/ClickToCopy/index.tsx +6 -5
  194. package/src/CodeBlock/index.tsx +3 -1
  195. package/src/CookieConsent/{index.jsx → index.tsx} +16 -19
  196. package/src/CountDown/{index.jsx → index.tsx} +30 -16
  197. package/src/DID/index.tsx +9 -8
  198. package/src/Datatable/index.jsx +5 -5
  199. package/src/Dialog/confirm.jsx +3 -3
  200. package/src/Dialog/types.d.ts +1 -1
  201. package/src/DidLogo/{index.jsx → index.tsx} +7 -14
  202. package/src/DriftBot/{index.jsx → index.tsx} +13 -11
  203. package/src/Earth/{index.jsx → index.tsx} +94 -66
  204. package/src/Earth/{util.js → util.ts} +20 -17
  205. package/src/ErrorBoundary/{fallback.jsx → fallback.tsx} +20 -21
  206. package/src/Footer/{index.jsx → index.tsx} +17 -14
  207. package/src/Header/header.tsx +2 -3
  208. package/src/Header/responsive-header.tsx +0 -1
  209. package/src/Icon/image.tsx +3 -3
  210. package/src/Icon/index.tsx +7 -4
  211. package/src/Img/index.jsx +1 -1
  212. package/src/InfoRow/{index.jsx → index.tsx} +32 -25
  213. package/src/Layout/dashboard/external-link.tsx +46 -0
  214. package/src/Layout/dashboard/{full-page.jsx → full-page.tsx} +20 -9
  215. package/src/Layout/dashboard/{index.jsx → index.tsx} +42 -44
  216. package/src/Layout/dashboard/{sidebar.jsx → sidebar.tsx} +23 -20
  217. package/src/Layout/dashboard-legacy/{header.jsx → header.tsx} +16 -26
  218. package/src/Layout/dashboard-legacy/{index.jsx → index.tsx} +32 -46
  219. package/src/Layout/dashboard-legacy/{sidebar.jsx → sidebar.tsx} +27 -19
  220. package/src/Layout/{index.jsx → index.tsx} +41 -47
  221. package/src/LoadingMask/{index.jsx → index.tsx} +18 -20
  222. package/src/Locale/{browser-lang.js → browser-lang.ts} +9 -7
  223. package/src/Locale/context.tsx +18 -11
  224. package/src/Locale/{languages.js → languages.ts} +1 -1
  225. package/src/Locale/{selector.jsx → selector.tsx} +32 -29
  226. package/src/Locale/{util.js → util.ts} +9 -2
  227. package/src/Logo/index.tsx +58 -0
  228. package/src/Metric/{index.jsx → index.tsx} +23 -18
  229. package/src/NFTDisplay/{aspect-ratio-container.jsx → aspect-ratio-container.tsx} +9 -7
  230. package/src/NFTDisplay/{broken.jsx → broken.tsx} +7 -12
  231. package/src/NFTDisplay/{displayApi.js → displayApi.ts} +4 -4
  232. package/src/NFTDisplay/{index.jsx → index.tsx} +59 -64
  233. package/src/NFTDisplay/svg-embedder/{img.jsx → img.tsx} +10 -18
  234. package/src/NFTDisplay/svg-embedder/{inline-svg.jsx → inline-svg.tsx} +8 -9
  235. package/src/NavMenu/nav-menu.tsx +2 -3
  236. package/src/PageScroller/{index.jsx → index.tsx} +40 -53
  237. package/src/PageScroller/{usePrevValue.js → usePrevValue.ts} +2 -3
  238. package/src/Passport/{passport.jsx → passport.tsx} +22 -19
  239. package/src/PoweredByArcBlock/{index.jsx → index.tsx} +6 -11
  240. package/src/PricingTable/{PricingPlan.jsx → PricingPlan.tsx} +15 -5
  241. package/src/PricingTable/{index.jsx → index.tsx} +9 -6
  242. package/src/QRCode/{index.jsx → index.tsx} +14 -19
  243. package/src/RelativeTime/{index.jsx → index.tsx} +24 -24
  244. package/src/Result/{common.jsx → common.tsx} +17 -13
  245. package/src/Result/index.tsx +30 -0
  246. package/src/Result/{result.jsx → result.tsx} +8 -17
  247. package/src/Result/{translations.js → translations.ts} +3 -1
  248. package/src/Screenshot/BaseScreenshot/{index.jsx → index.tsx} +9 -15
  249. package/src/Screenshot/BaseScreenshot/shells/{Macbook.jsx → Macbook.tsx} +3 -1
  250. package/src/Screenshot/BaseScreenshot/shells/{Phone.jsx → Phone.tsx} +3 -1
  251. package/src/Screenshot/{index.jsx → index.tsx} +60 -54
  252. package/src/SessionBlocklet/{index.jsx → index.tsx} +9 -14
  253. package/src/SessionPermission/index.tsx +25 -0
  254. package/src/SessionUser/components/{logged-in.jsx → logged-in.tsx} +49 -31
  255. package/src/SessionUser/components/session-user-item.tsx +97 -0
  256. package/src/SessionUser/components/{session-user-switch.jsx → session-user-switch.tsx} +16 -21
  257. package/src/SessionUser/components/{un-login.jsx → un-login.tsx} +10 -15
  258. package/src/SessionUser/components/{user-info.jsx → user-info.tsx} +16 -22
  259. package/src/SessionUser/index.tsx +26 -0
  260. package/src/SessionUser/libs/{translation.js → translation.ts} +3 -1
  261. package/src/SessionUser/libs/utils.ts +39 -0
  262. package/src/Sparkline/{index.jsx → index.tsx} +38 -22
  263. package/src/Spinner/index.tsx +20 -0
  264. package/src/Success/{index.jsx → index.tsx} +13 -16
  265. package/src/Tabs/{index.jsx → index.tsx} +26 -40
  266. package/src/TextCollapse/{index.jsx → index.tsx} +26 -21
  267. package/src/Theme/index.ts +0 -1
  268. package/src/Theme/theme-provider.tsx +1 -1
  269. package/src/Theme/theme.ts +6 -3
  270. package/src/Typography/{index.jsx → index.tsx} +19 -22
  271. package/src/Util/index.ts +26 -9
  272. package/src/Video/{index.jsx → index.tsx} +7 -10
  273. package/src/Wallet/{Action.jsx → Action.tsx} +16 -12
  274. package/src/Wallet/{Download.jsx → Download.tsx} +25 -21
  275. package/src/Wallet/{Open.jsx → Open.tsx} +8 -11
  276. package/src/WalletOSIcon/{index.jsx → index.tsx} +8 -16
  277. package/src/WebWalletSWKeeper/{index.jsx → index.tsx} +21 -24
  278. package/src/WechatPrompt/{index.jsx → index.tsx} +1 -0
  279. package/src/global.d.ts +15 -0
  280. package/src/type.d.ts +12 -3
  281. package/src/withTheme/{index.jsx → index.tsx} +12 -2
  282. package/src/withTracker/{index.jsx → index.tsx} +6 -4
  283. package/src/Layout/dashboard/external-link.jsx +0 -47
  284. package/src/Logo/index.jsx +0 -66
  285. package/src/Result/index.jsx +0 -33
  286. package/src/SessionPermission/index.jsx +0 -28
  287. package/src/SessionUser/components/session-user-item.jsx +0 -93
  288. package/src/SessionUser/index.jsx +0 -38
  289. package/src/SessionUser/libs/utils.js +0 -37
  290. package/src/Spinner/index.jsx +0 -21
  291. /package/src/ErrorBoundary/{index.jsx → index.ts} +0 -0
  292. /package/src/NFTDisplay/{loading.jsx → loading.tsx} +0 -0
  293. /package/src/Passport/{index.jsx → index.ts} +0 -0
  294. /package/src/SessionManager/{index.jsx → index.tsx} +0 -0
@@ -1,6 +1,5 @@
1
1
  /* eslint-disable react/jsx-no-bind */
2
- import { useState, useContext, useRef, useMemo } from 'react';
3
- import PropTypes from 'prop-types';
2
+ import React, { useState, useContext, useRef, useMemo } from 'react';
4
3
  import { Button, Typography, IconButton, Popper, MenuItem, MenuList, Box, ClickAwayListener } from '@mui/material';
5
4
  import { Icon as IconifyIcon } from '@iconify/react';
6
5
  import CheckIcon from '@iconify-icons/material-symbols/check';
@@ -11,16 +10,34 @@ import { getColor, getBackground } from '../Util';
11
10
  import { temp as colors } from '../Colors';
12
11
  import { LocaleContext } from './context';
13
12
  import { styled, useTheme } from '../Theme';
13
+ import type { Locale } from '../type';
14
+
15
+ export interface LocaleSelectorProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onChange'> {
16
+ showText?: true | false;
17
+ popperProps?: React.HTMLAttributes<HTMLDivElement>;
18
+ popperType?: 'hover' | 'click';
19
+ icon?: React.ComponentType<any>;
20
+ size?: number;
21
+ onChange?: (locale: Locale) => void;
22
+ }
14
23
 
15
- export default function LocaleSelector(props) {
16
- const { showText, popperProps, popperType, icon: Icon, size, ...rest } = props;
24
+ export default function LocaleSelector(props: LocaleSelectorProps) {
25
+ const {
26
+ showText = true,
27
+ popperProps = {},
28
+ popperType = 'click',
29
+ icon: Icon,
30
+ size = 24,
31
+ onChange = noop,
32
+ ...rest
33
+ } = props;
17
34
  const { locale, changeLocale, languages } = useContext(LocaleContext);
18
- const anchorEl = useRef(null);
35
+ const anchorEl = useRef<HTMLButtonElement>(null);
19
36
  const [open, setOpen] = useState(false);
20
37
  const theme = useTheme();
21
38
  const dark = theme?.palette?.mode === 'dark';
22
39
 
23
- const onSelect = (newLocale) => {
40
+ const onSelect = (newLocale: Locale) => {
24
41
  changeLocale(newLocale);
25
42
  setOpen(false);
26
43
  if (typeof props.onChange === 'function') {
@@ -28,14 +45,14 @@ export default function LocaleSelector(props) {
28
45
  }
29
46
  };
30
47
 
31
- const onClose = (e) => {
32
- if (anchorEl.current?.contains(e.target)) {
48
+ const onClose = (e: MouseEvent | TouchEvent) => {
49
+ if (anchorEl.current?.contains(e.target as Node)) {
33
50
  return;
34
51
  }
35
52
  setOpen(false);
36
53
  };
37
54
 
38
- const ButtonComponent = showText ? Button : IconButton;
55
+ const ButtonComponent: typeof Button = showText ? Button : IconButton;
39
56
 
40
57
  const handleEventProps =
41
58
  popperType === 'hover'
@@ -62,14 +79,14 @@ export default function LocaleSelector(props) {
62
79
  }, [Icon, size]);
63
80
 
64
81
  return (
65
- <Div component="div" dark={dark} theme={theme} {...rest} {...handleEventProps}>
82
+ <Div dark={dark} theme={theme} {...rest} {...handleEventProps}>
66
83
  <ButtonComponent ref={anchorEl} className="trigger" role="button" aria-label="Locale selector button">
67
84
  <Box display="flex" alignItems="center">
68
85
  {renderIcon}
69
86
 
70
87
  {showText ? (
71
88
  <Typography component="strong" className="trigger-text">
72
- {languages.find((x) => x.code === locale).name}
89
+ {languages.find((x) => x.code === locale)?.name}
73
90
  </Typography>
74
91
  ) : (
75
92
  ''
@@ -82,7 +99,7 @@ export default function LocaleSelector(props) {
82
99
  <ClickAwayListener onClickAway={onClose}>
83
100
  <MenuList>
84
101
  {languages.map(({ code, name }) => (
85
- <MenuItem key={code} className="locale-item" onClick={() => onSelect(code, name)}>
102
+ <MenuItem key={code} className="locale-item" onClick={() => onSelect(code)}>
86
103
  <IconifyIcon
87
104
  icon={CheckIcon}
88
105
  className={code === locale ? 'check-icon check-icon-visible' : 'check-icon'}
@@ -98,27 +115,13 @@ export default function LocaleSelector(props) {
98
115
  );
99
116
  }
100
117
 
101
- LocaleSelector.propTypes = {
102
- size: PropTypes.number,
103
- showText: PropTypes.bool,
104
- popperProps: PropTypes.object,
105
- onChange: PropTypes.func,
106
- popperType: PropTypes.oneOf(['hover', 'click']),
107
- icon: PropTypes.any,
108
- };
109
-
110
- LocaleSelector.defaultProps = {
111
- showText: true,
112
- size: 24,
113
- popperProps: {},
114
- onChange: noop,
115
- popperType: 'click',
116
- icon: null,
118
+ type DivProps = React.HTMLAttributes<HTMLDivElement> & {
119
+ dark: boolean;
117
120
  };
118
121
 
119
122
  const Div = styled('div', {
120
123
  shouldForwardProp: (prop) => prop !== 'dark',
121
- })`
124
+ })<DivProps>`
122
125
  display: inline-block;
123
126
 
124
127
  .trigger {
@@ -1,10 +1,17 @@
1
1
  import get from 'lodash/get';
2
+ import type { Locale, Translations } from '../type';
2
3
 
3
4
  /* eslint-disable no-prototype-builtins */
4
- export const replace = (template, data) =>
5
+ export const replace = (template: string, data: Record<string, any>) =>
5
6
  template.replace(/{(\w*)}/g, (m, key) => (data.hasOwnProperty(key) ? data[key] : ''));
6
7
 
7
- export const translate = (translations, key, locale, fallbackLocale = 'en', data = {}) => {
8
+ export const translate = (
9
+ translations: Translations,
10
+ key: string,
11
+ locale: Locale,
12
+ fallbackLocale = 'en',
13
+ data = {}
14
+ ) => {
8
15
  const translation = translations[locale];
9
16
  const translationValue = get(translation, key);
10
17
  const fallbackValue = get(translations[fallbackLocale], key);
@@ -0,0 +1,58 @@
1
+ import { type SxProps } from '@mui/material';
2
+ import { styled } from '../Theme';
3
+
4
+ import { ReactComponent as LightLogo } from './images/logo-light-top.svg';
5
+ import { ReactComponent as LightText } from './images/logo-light-text.svg';
6
+ import { ReactComponent as DarkLogo } from './images/logo-dark-top.svg';
7
+ import { ReactComponent as DarkText } from './images/logo-dark-text.svg';
8
+
9
+ export interface LogoProps extends React.HTMLAttributes<HTMLSpanElement> {
10
+ mode?: 'light' | 'dark';
11
+ layout?: 'vertical' | 'horizontal';
12
+ showText?: true | false;
13
+ showLogo?: true | false;
14
+ size?: number;
15
+ sx?: SxProps;
16
+ }
17
+
18
+ export default function Logo({
19
+ showText = true,
20
+ showLogo = true,
21
+ mode = 'dark',
22
+ layout = 'vertical',
23
+ size,
24
+ style = {},
25
+ ...rest
26
+ }: LogoProps) {
27
+ const isLight = mode === 'light';
28
+ const logo = isLight ? <LightLogo /> : <DarkLogo />;
29
+ const text = isLight ? <LightText className="logo-text" /> : <DarkText className="logo-text" />;
30
+
31
+ if (size) {
32
+ style.width = `${size}px`;
33
+ style.height = `${size}px`;
34
+ }
35
+
36
+ return (
37
+ <Container layout={layout} style={style} {...rest}>
38
+ {showLogo && logo}
39
+ {showText && text}
40
+ </Container>
41
+ );
42
+ }
43
+
44
+ type ContainerProps = {
45
+ layout: 'vertical' | 'horizontal';
46
+ };
47
+
48
+ const Container = styled('span')<ContainerProps>`
49
+ display: inline-flex;
50
+ flex-direction: ${(props) => (props.layout === 'horizontal' ? 'row' : 'column')};
51
+ justify-content: center;
52
+ align-items: center;
53
+
54
+ .logo-text {
55
+ ${(props) => (props.layout === 'vertical' ? 'margin-top: 8px;' : '')}
56
+ ${(props) => (props.layout === 'vertical' ? '' : 'margin-left: 8px;')};
57
+ }
58
+ `;
@@ -1,10 +1,28 @@
1
1
  /* eslint-disable react/no-danger */
2
- import PropTypes from 'prop-types';
2
+ import { Link } from '@mui/material';
3
3
 
4
4
  import ImageIcon from '../Icon/image';
5
5
  import { styled } from '../Theme';
6
6
 
7
- export default function Metric({ icon, value, name, url, animated, LinkComponent, prefix }) {
7
+ export interface MetricProps {
8
+ icon: string;
9
+ value: string | number;
10
+ name: React.ReactNode;
11
+ url?: string;
12
+ animated?: false | true;
13
+ LinkComponent?: React.ElementType;
14
+ prefix?: string;
15
+ }
16
+
17
+ export default function Metric({
18
+ icon,
19
+ value,
20
+ name,
21
+ url = '',
22
+ animated = false,
23
+ LinkComponent = Link,
24
+ prefix = '/images',
25
+ }: MetricProps) {
8
26
  const metric = (
9
27
  <>
10
28
  <div className="metric__image">
@@ -23,24 +41,11 @@ export default function Metric({ icon, value, name, url, animated, LinkComponent
23
41
  return <Container>{url ? <LinkComponent to={url}>{metric}</LinkComponent> : metric}</Container>;
24
42
  }
25
43
 
26
- Metric.propTypes = {
27
- icon: PropTypes.string.isRequired,
28
- value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
29
- name: PropTypes.node.isRequired,
30
- animated: PropTypes.bool,
31
- url: PropTypes.string,
32
- LinkComponent: PropTypes.any,
33
- prefix: PropTypes.string,
34
- };
35
-
36
- Metric.defaultProps = {
37
- animated: false,
38
- url: '',
39
- LinkComponent: null,
40
- prefix: '/images',
44
+ type ContainerProps = {
45
+ size?: 'small' | 'large';
41
46
  };
42
47
 
43
- const Container = styled('div')`
48
+ const Container = styled('div')<ContainerProps>`
44
49
  border-left: 1px solid ${(props) => props.theme.typography.color.main};
45
50
  padding: 10px 0 10px 16px;
46
51
  @media (max-width: ${(props) => props.theme.breakpoints.values.sm}px) {
@@ -1,8 +1,11 @@
1
- import PropTypes from 'prop-types';
2
-
3
1
  import { styled } from '../Theme';
4
2
 
5
- function AspectRatioContainer({ aspect, children, ...rest }) {
3
+ export interface AspectRatioContainerProps {
4
+ aspect: number;
5
+ children?: React.ReactNode;
6
+ }
7
+
8
+ function AspectRatioContainer({ aspect, children, ...rest }: AspectRatioContainerProps) {
6
9
  return (
7
10
  <Root aspect={aspect} {...rest}>
8
11
  <span className="aspect-ratio-container__inner">{children}</span>
@@ -10,12 +13,11 @@ function AspectRatioContainer({ aspect, children, ...rest }) {
10
13
  );
11
14
  }
12
15
 
13
- AspectRatioContainer.propTypes = {
14
- aspect: PropTypes.number.isRequired,
15
- children: PropTypes.node.isRequired,
16
+ type RootProps = {
17
+ aspect: number;
16
18
  };
17
19
 
18
- const Root = styled('span')`
20
+ const Root = styled('span')<RootProps>`
19
21
  display: block;
20
22
  position: relative;
21
23
  width: 100%;
@@ -1,10 +1,13 @@
1
1
  import Box from '@mui/material/Box';
2
- import PropTypes from 'prop-types';
3
- // eslint-disable-next-line import/no-unresolved
4
- import NFTBroken from './NFTBroken.svg?react';
5
2
  import { styled } from '../Theme';
6
3
 
7
- export default function Broken({ children } = {}) {
4
+ import { ReactComponent as NFTBroken } from './NFTBroken.svg';
5
+
6
+ export interface BrokenProps {
7
+ children?: React.ReactNode;
8
+ }
9
+
10
+ export default function Broken({ children = 'Non-publicly accessible NFT' }: BrokenProps = {}) {
8
11
  return (
9
12
  <Root>
10
13
  <NFTBroken className="nft-display-broken-background" />
@@ -13,14 +16,6 @@ export default function Broken({ children } = {}) {
13
16
  );
14
17
  }
15
18
 
16
- Broken.propTypes = {
17
- children: PropTypes.node,
18
- };
19
-
20
- Broken.defaultProps = {
21
- children: 'Non-publicly accessible NFT',
22
- };
23
-
24
19
  const Root = styled(Box)`
25
20
  width: 100%;
26
21
  height: 100%;
@@ -1,10 +1,10 @@
1
- import axios from 'axios';
1
+ import axios, { AxiosAdapter, type AxiosResponse } from 'axios';
2
2
  import adapter from 'axios/lib/adapters/xhr.js';
3
3
 
4
4
  const cache = new Map();
5
5
  const EXPIRATION_TIME_MS = 10 * 60 * 1000; // 10 minutes
6
6
 
7
- const cacheAdapterEnhancer = (config) => {
7
+ const cacheAdapterEnhancer: AxiosAdapter = (config) => {
8
8
  const { url, method } = config;
9
9
  const cacheKey = JSON.stringify({ url, method });
10
10
 
@@ -22,12 +22,12 @@ const cacheAdapterEnhancer = (config) => {
22
22
  }
23
23
 
24
24
  return adapter(config)
25
- .then((response) => {
25
+ .then((response: AxiosResponse) => {
26
26
  // cache headers
27
27
  cache.set(cacheKey, { headers: response.headers, timestamp: Date.now() });
28
28
  return response;
29
29
  })
30
- .catch((error) => {
30
+ .catch((error: unknown) => {
31
31
  // cache error
32
32
  cache.set(cacheKey, { error, timestamp: Date.now() });
33
33
  throw error;
@@ -1,6 +1,5 @@
1
1
  /* eslint-disable react-hooks/rules-of-hooks */
2
- import { useRef, useEffect, useState } from 'react';
3
- import PropTypes from 'prop-types';
2
+ import React, { useRef, useEffect, useState } from 'react';
4
3
  import clsx from 'clsx';
5
4
  import { Buffer } from 'buffer';
6
5
  import get from 'lodash/get';
@@ -8,6 +7,7 @@ import pako from 'pako';
8
7
  import base64 from 'base64-url';
9
8
  import isSvg from 'is-svg';
10
9
  import noop from 'lodash/noop';
10
+ import { Box, type BoxProps } from '@mui/material';
11
11
 
12
12
  import AspectRatioContainer from './aspect-ratio-container';
13
13
  import ImgSvgEmbedder from './svg-embedder/img';
@@ -22,11 +22,11 @@ import displayApi from './displayApi';
22
22
  * - 旧: assetState.data.value (.credentialSubject.display)
23
23
  * - 新: assetState.display
24
24
  */
25
- export function getNFTData(assetState) {
25
+ export function getNFTData(assetState: Record<string, any>) {
26
26
  return assetState?.display || assetState?.data?.value;
27
27
  }
28
28
 
29
- function fromBase64(v) {
29
+ function fromBase64(v: string) {
30
30
  if (typeof v !== 'string') {
31
31
  throw new Error('fromBase64 requires input to be a string');
32
32
  }
@@ -38,7 +38,7 @@ function fromBase64(v) {
38
38
  // };
39
39
 
40
40
  // 仅针对非 url type 的情况
41
- const getSvgEmbedder = (preferredSvgEmbedder) => {
41
+ const getSvgEmbedder = (preferredSvgEmbedder: 'img' | 'svg') => {
42
42
  const embedders = {
43
43
  img: ImgSvgEmbedder,
44
44
  svg: InlineSvgEmbedder,
@@ -46,6 +46,31 @@ const getSvgEmbedder = (preferredSvgEmbedder) => {
46
46
  return embedders[preferredSvgEmbedder];
47
47
  };
48
48
 
49
+ export interface NFTDisplayProps extends BoxProps {
50
+ /** asset data 可以是 raw data 和 parsed data */
51
+ data: string | Record<string, any>;
52
+ address: string;
53
+ inset?: false | true;
54
+ aspect?: number;
55
+ component?: React.ElementType<any>;
56
+ className?: string;
57
+ renderError?: () => React.ReactNode;
58
+ renderLoading?: () => React.ReactNode;
59
+ /** 对于非 url type 的情况, 支持优先选用的 svg 嵌入方式, 默认是 img */
60
+ preferredSvgEmbedder?: 'img' | 'svg';
61
+ /** 针对非 url type 的情况, 检测 svg 有效性, 默认禁用 */
62
+ checkSvg?: false | true;
63
+ /** loading 最小显示时间 (避免闪烁) */
64
+ minimumLoadingTime?: number;
65
+ /** 完成回调, 无论加载成功|失败 */
66
+ onCompleted?: () => void;
67
+ /**
68
+ * 图片处理,参考:https://team.arcblock.io/comment/docs/c158aee4-accd-42f4-9ced-6a23f28c00e0/en/blocklet-image-service-guide
69
+ * 配置参数会全部转发给 Image Service
70
+ */
71
+ imageFilter?: object | null;
72
+ }
73
+
49
74
  /**
50
75
  * TODO:
51
76
  * 考虑把 asset data 解析部分和 nft display 分离, android 端有相关使用场景 - 只传入 svg 或 url, 也可以传入 asset data,
@@ -56,30 +81,31 @@ function NFTDisplay({
56
81
  address,
57
82
  inset,
58
83
  aspect,
59
- component,
60
- className,
84
+ component = 'span',
85
+ className = '',
61
86
  renderError,
62
87
  renderLoading,
63
- preferredSvgEmbedder,
64
- checkSvg,
65
- minimumLoadingTime,
66
- onCompleted,
67
- imageFilter,
88
+ preferredSvgEmbedder = 'img',
89
+ checkSvg = false,
90
+ minimumLoadingTime = 0,
91
+ onCompleted = noop,
92
+ imageFilter = null,
68
93
  ...rest
69
- }) {
70
- const wrapRoot = (children) => (
71
- <Root as={component} {...rest} className={clsx(className, { 'nft-display--inset': inset })}>
94
+ }: NFTDisplayProps) {
95
+ const wrapRoot = (children: React.ReactNode) => (
96
+ <Root component={component} {...rest} className={clsx(className, { 'nft-display--inset': inset })}>
72
97
  {children}
73
98
  </Root>
74
99
  );
75
100
 
76
- const parsed = useRef(data);
101
+ const parsed = useRef<Record<string, any>>({});
77
102
 
78
103
  try {
79
104
  // 如果是 raw data 先解析
80
- if (typeof parsed.current === 'string') {
105
+ if (typeof data === 'string') {
81
106
  parsed.current = JSON.parse(data);
82
- // console.log('[debug] parse data')
107
+ } else {
108
+ parsed.current = data;
83
109
  }
84
110
 
85
111
  const { vcId } = parsed.current;
@@ -91,7 +117,12 @@ function NFTDisplay({
91
117
  const isUrlType = type === 'url';
92
118
 
93
119
  // 首次加载, 对于 url type 的情况, loading 为 true
94
- const [state, setState] = useState({
120
+ const [state, setState] = useState<{
121
+ loading: boolean;
122
+ error: boolean;
123
+ loadingUrlType: boolean;
124
+ urlType: string | null;
125
+ }>({
95
126
  loading: isUrlType,
96
127
  error: false,
97
128
  loadingUrlType: true,
@@ -101,7 +132,7 @@ function NFTDisplay({
101
132
  // console.log('[debug] render', {type, minimumLoadingTime}, JSON.stringify(state))
102
133
 
103
134
  // assemble the complete url
104
- const getFullContentUrl = ({ useImageFilter = false, t } = {}) => {
135
+ const getFullContentUrl = ({ useImageFilter = false, t }: { useImageFilter?: boolean; t?: string } = {}) => {
105
136
  const urlObj = new URL(content);
106
137
 
107
138
  // check protocol
@@ -139,12 +170,13 @@ function NFTDisplay({
139
170
  url: getFullContentUrl({ useImageFilter: false, t: 'nftdisplay' }),
140
171
  method: 'HEAD',
141
172
  });
173
+ // @ts-expect-error
142
174
  const contentType = response?.headers?.get('Content-Type');
143
175
  setState({ ...state, loadingUrlType: false, urlType: contentType });
144
176
  } catch (error) {
145
177
  console.error('Failed to fetch url content type', error);
146
178
  // display an error message when timeout occurs to avoid repeated waiting.
147
- if (error?.message?.includes('timeout')) {
179
+ if ((error as Error)?.message?.includes('timeout')) {
148
180
  setState({ ...state, loadingUrlType: false, loading: false, error: true });
149
181
  return;
150
182
  }
@@ -154,7 +186,7 @@ function NFTDisplay({
154
186
  };
155
187
 
156
188
  useEffect(() => {
157
- let timer;
189
+ let timer: NodeJS.Timeout;
158
190
  if (minimumLoadingTime > 0) {
159
191
  timer = setTimeout(() => setMinimumLoadingReady(true), minimumLoadingTime);
160
192
  }
@@ -295,7 +327,7 @@ function NFTDisplay({
295
327
  </>
296
328
  );
297
329
  } catch (e) {
298
- console.error(e?.message, {
330
+ console.error((e as Error)?.message, {
299
331
  nftId: address,
300
332
  vcId: parsed?.current?.vcId,
301
333
  });
@@ -303,44 +335,7 @@ function NFTDisplay({
303
335
  }
304
336
  }
305
337
 
306
- NFTDisplay.propTypes = {
307
- // asset data 可以是 raw data 和 parsed data
308
- data: PropTypes.oneOfType([PropTypes.object, PropTypes.string]).isRequired,
309
- address: PropTypes.string.isRequired,
310
- component: PropTypes.string,
311
- inset: PropTypes.bool,
312
- aspect: PropTypes.number,
313
- className: PropTypes.string,
314
- renderError: PropTypes.func,
315
- renderLoading: PropTypes.func,
316
- // 对于非 url type 的情况, 支持优先选用的 svg 嵌入方式, 默认是 img
317
- preferredSvgEmbedder: PropTypes.oneOf(['img', 'svg']),
318
- // 针对非 url type 的情况, 检测 svg 有效性, 默认禁用
319
- checkSvg: PropTypes.bool,
320
- // loading 最小显示时间 (避免闪烁)
321
- minimumLoadingTime: PropTypes.number,
322
- // 完成回调, 无论加载成功|失败
323
- onCompleted: PropTypes.func,
324
- // 图片处理,参考:https://team.arcblock.io/comment/docs/c158aee4-accd-42f4-9ced-6a23f28c00e0/en/blocklet-image-service-guide
325
- // 配置参数会全部转发给 Image Service
326
- imageFilter: PropTypes.object,
327
- };
328
-
329
- NFTDisplay.defaultProps = {
330
- component: 'span',
331
- inset: false,
332
- aspect: 0,
333
- className: '',
334
- renderError: null,
335
- renderLoading: null,
336
- preferredSvgEmbedder: 'img',
337
- checkSvg: false,
338
- minimumLoadingTime: 0,
339
- onCompleted: noop,
340
- imageFilter: null,
341
- };
342
-
343
- const Root = styled('div')`
338
+ const Root = styled(Box)`
344
339
  display: flex;
345
340
  justify-content: center;
346
341
  align-items: center;
@@ -369,11 +364,11 @@ const Root = styled('div')`
369
364
  }
370
365
  `;
371
366
 
372
- function withAspectRatio(Component) {
367
+ function withAspectRatio(Component: React.ComponentType<NFTDisplayProps>) {
373
368
  // eslint-disable-next-line func-names, react/prop-types
374
- return function ({ aspect, inset, ...rest }) {
369
+ return function ({ aspect, inset, ...rest }: NFTDisplayProps) {
375
370
  // inset 比 aspect ratio 优先级高, 如果同时设置了 inset 和 aspect, 则后者不生效
376
- const applyAspectRatio = aspect > 0 && !inset;
371
+ const applyAspectRatio = aspect && aspect > 0 && !inset;
377
372
  if (applyAspectRatio) {
378
373
  return (
379
374
  <AspectRatioContainer aspect={aspect}>
@@ -1,16 +1,20 @@
1
- import PropTypes from 'prop-types';
2
1
  import InlineSvgEmbedder from './inline-svg';
3
2
 
4
- const svgToImgUrl = (svg) => {
3
+ const svgToImgUrl = (svg: string) => {
5
4
  // fix: #225, https://stackoverflow.com/a/52135328)
6
5
  const blob = new Blob([svg], { type: 'image/svg+xml' });
7
6
  return URL.createObjectURL(blob);
8
7
  };
9
8
 
10
- /**
11
- * 基于 <img> 嵌入 svg
12
- */
13
- function ImgEmbedder({ svg, alt, fallback, ...rest }) {
9
+ export interface ImgEmbedderProps extends React.HTMLAttributes<HTMLImageElement> {
10
+ svg: string;
11
+ alt?: string;
12
+ /** 对于包含 foreignObject 的 svg, fallback inline svg + shadow DOM */
13
+ fallback?: true | false;
14
+ }
15
+
16
+ /** 基于 <img> 嵌入 svg */
17
+ function ImgEmbedder({ svg, alt = '', fallback = true, ...rest }: ImgEmbedderProps) {
14
18
  // 包含 foreignObject 的 svg, fallback 到 shadow dom
15
19
  if (fallback && svg.indexOf('</foreignObject>') > -1) {
16
20
  return <InlineSvgEmbedder svg={svg} />;
@@ -20,16 +24,4 @@ function ImgEmbedder({ svg, alt, fallback, ...rest }) {
20
24
  return <img src={url} onLoad={() => URL.revokeObjectURL(url)} alt={alt} {...rest} />;
21
25
  }
22
26
 
23
- ImgEmbedder.propTypes = {
24
- svg: PropTypes.string.isRequired,
25
- alt: PropTypes.string,
26
- // 对于包含 foreignObject 的 svg, fallback 到 inline svg + shadow DOM
27
- fallback: PropTypes.bool,
28
- };
29
-
30
- ImgEmbedder.defaultProps = {
31
- alt: '',
32
- fallback: true,
33
- };
34
-
35
27
  export default ImgEmbedder;
@@ -1,12 +1,15 @@
1
- import PropTypes from 'prop-types';
2
1
  import root from 'react-shadow/emotion';
2
+ import { type SxProps } from '@mui/material';
3
3
 
4
4
  import { styled } from '../../Theme';
5
5
 
6
- /**
7
- * inline svg 的方式嵌入 svg, 使用 shadow DOM 避免样式污染
8
- */
9
- function InlineSvg({ svg, ...rest }) {
6
+ export interface InlineSvgProps extends React.HTMLAttributes<HTMLSpanElement> {
7
+ svg: string;
8
+ sx?: SxProps;
9
+ }
10
+
11
+ /** inline svg 的方式嵌入 svg, 使用 shadow DOM 避免样式污染 */
12
+ function InlineSvg({ svg, ...rest }: InlineSvgProps) {
10
13
  return (
11
14
  <Root {...rest}>
12
15
  <Inner dangerouslySetInnerHTML={{ __html: svg }} />
@@ -14,10 +17,6 @@ function InlineSvg({ svg, ...rest }) {
14
17
  );
15
18
  }
16
19
 
17
- InlineSvg.propTypes = {
18
- svg: PropTypes.string.isRequired,
19
- };
20
-
21
20
  const Root = styled(root.span)`
22
21
  display: block;
23
22
  width: 100%;
@@ -1,4 +1,3 @@
1
- /* eslint-disable no-unused-vars */
2
1
  import {
3
2
  Children,
4
3
  cloneElement,
@@ -10,6 +9,7 @@ import {
10
9
  useLayoutEffect,
11
10
  isValidElement,
12
11
  } from 'react';
12
+ import { type SxProps } from '@mui/material';
13
13
  import clsx from 'clsx';
14
14
  import { MoreHoriz as MoreHorizIcon, ExpandMore as ExpandMoreIcon, Menu as MenuIcon } from '@mui/icons-material';
15
15
  import { useCreation, useMemoizedFn, useReactive, useSize, useThrottleFn } from 'ahooks';
@@ -60,8 +60,8 @@ export interface NavMenuProps extends React.HTMLAttributes<HTMLElement> {
60
60
  textColor?: string;
61
61
  activeTextColor?: string;
62
62
  bgColor?: string;
63
- // eslint-disable-next-line no-unused-vars
64
63
  onSelected?: (id: string) => void;
64
+ sx?: SxProps;
65
65
  }
66
66
 
67
67
  /**
@@ -305,7 +305,6 @@ export interface SubProps extends React.HTMLAttributes<HTMLLIElement> {
305
305
  icon?: React.ReactNode;
306
306
  label?: React.ReactNode;
307
307
  children?: Array<React.ReactElement>;
308
- // eslint-disable-next-line no-unused-vars
309
308
  expandIcon?: React.ReactNode | ((props: { isOpen: boolean }) => React.ReactNode);
310
309
  }
311
310