@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.
- package/lib/Address/did-address.d.ts +6 -5
- package/lib/Address/index.d.ts +1 -1
- package/lib/Avatar/index.d.ts +10 -8
- package/lib/Avatar/index.js +6 -4
- package/lib/Blocklet/blocklet.d.ts +4 -4
- package/lib/Blocklet/blocklet.js +2 -2
- package/lib/BlockletContext/index.d.ts +3 -3
- package/lib/BlockletNFT/index.d.ts +6 -6
- package/lib/BlockletNFT/index.js +3 -3
- package/lib/BlockletV2/blocklet.d.ts +2 -2
- package/lib/Button/wrap.d.ts +4 -4
- package/lib/Button/wrap.js +2 -2
- package/lib/CardSelector/index.js +0 -1
- package/lib/Center/index.d.ts +1 -1
- package/lib/ClickToCopy/copy-button.d.ts +5 -4
- package/lib/ClickToCopy/copy-button.js +0 -1
- package/lib/ClickToCopy/hook.d.ts +3 -8
- package/lib/ClickToCopy/index.d.ts +6 -4
- package/lib/CodeBlock/index.d.ts +3 -1
- package/lib/CookieConsent/index.d.ts +8 -29
- package/lib/CookieConsent/index.js +3 -17
- package/lib/CountDown/index.d.ts +21 -25
- package/lib/CountDown/index.js +12 -11
- package/lib/DID/index.d.ts +9 -8
- package/lib/Datatable/index.d.ts +5 -5
- package/lib/Datatable/index.js +5 -5
- package/lib/Dialog/confirm.d.ts +6 -6
- package/lib/Dialog/confirm.js +3 -3
- package/lib/Dialog/types.d.ts +1 -1
- package/lib/DidLogo/index.d.ts +5 -25
- package/lib/DidLogo/index.js +4 -15
- package/lib/DriftBot/index.d.ts +13 -19
- package/lib/DriftBot/index.js +5 -6
- package/lib/Earth/index.d.ts +28 -10
- package/lib/Earth/index.js +12 -52
- package/lib/Earth/util.d.ts +10 -5
- package/lib/Earth/util.js +1 -0
- package/lib/ErrorBoundary/fallback.d.ts +12 -19
- package/lib/ErrorBoundary/fallback.js +2 -19
- package/lib/ErrorBoundary/index.d.ts +1 -1
- package/lib/Footer/index.d.ts +17 -24
- package/lib/Footer/index.js +2 -11
- package/lib/Header/header.d.ts +2 -2
- package/lib/Icon/image.d.ts +3 -2
- package/lib/Icon/index.d.ts +6 -4
- package/lib/Img/index.d.ts +1 -1
- package/lib/Img/index.js +1 -1
- package/lib/InfoRow/index.d.ts +9 -32
- package/lib/InfoRow/index.js +10 -23
- package/lib/Layout/dashboard/external-link.d.ts +13 -14
- package/lib/Layout/dashboard/external-link.js +5 -22
- package/lib/Layout/dashboard/full-page.d.ts +19 -11
- package/lib/Layout/dashboard/full-page.js +2 -6
- package/lib/Layout/dashboard/index.d.ts +20 -39
- package/lib/Layout/dashboard/index.js +10 -38
- package/lib/Layout/dashboard/sidebar.d.ts +17 -20
- package/lib/Layout/dashboard/sidebar.js +3 -16
- package/lib/Layout/dashboard-legacy/header.d.ts +10 -36
- package/lib/Layout/dashboard-legacy/header.js +5 -24
- package/lib/Layout/dashboard-legacy/index.d.ts +17 -56
- package/lib/Layout/dashboard-legacy/index.js +12 -41
- package/lib/Layout/dashboard-legacy/sidebar.d.ts +15 -26
- package/lib/Layout/dashboard-legacy/sidebar.js +5 -15
- package/lib/Layout/index.d.ts +17 -56
- package/lib/Layout/index.js +24 -50
- package/lib/LoadingMask/index.d.ts +8 -31
- package/lib/LoadingMask/index.js +3 -19
- package/lib/Locale/browser-lang.d.ts +4 -1
- package/lib/Locale/browser-lang.js +8 -3
- package/lib/Locale/context.d.ts +18 -8
- package/lib/Locale/context.js +1 -1
- package/lib/Locale/languages.d.ts +9 -55
- package/lib/Locale/selector.d.ts +10 -26
- package/lib/Locale/selector.js +8 -25
- package/lib/Locale/util.d.ts +4 -3
- package/lib/Locale/util.js +0 -1
- package/lib/Logo/index.d.ts +9 -40
- package/lib/Logo/index.js +88 -46
- package/lib/Metric/index.d.ts +9 -31
- package/lib/Metric/index.js +5 -20
- package/lib/NFTDisplay/aspect-ratio-container.d.ts +5 -12
- package/lib/NFTDisplay/aspect-ratio-container.js +0 -5
- package/lib/NFTDisplay/broken.d.ts +3 -13
- package/lib/NFTDisplay/broken.js +80 -10
- package/lib/NFTDisplay/displayApi.d.ts +1 -1
- package/lib/NFTDisplay/index.d.ts +28 -6
- package/lib/NFTDisplay/index.js +17 -51
- package/lib/NFTDisplay/svg-embedder/img.d.ts +8 -23
- package/lib/NFTDisplay/svg-embedder/img.js +3 -17
- package/lib/NFTDisplay/svg-embedder/inline-svg.d.ts +7 -13
- package/lib/NFTDisplay/svg-embedder/inline-svg.js +1 -8
- package/lib/NavMenu/nav-menu.d.ts +2 -0
- package/lib/NavMenu/nav-menu.js +0 -1
- package/lib/PageScroller/index.d.ts +14 -13
- package/lib/PageScroller/index.js +12 -37
- package/lib/PageScroller/usePrevValue.d.ts +1 -1
- package/lib/PageScroller/usePrevValue.js +1 -2
- package/lib/Passport/index.d.ts +1 -1
- package/lib/Passport/passport.d.ts +10 -30
- package/lib/Passport/passport.js +5 -19
- package/lib/PoweredByArcBlock/index.d.ts +4 -14
- package/lib/PoweredByArcBlock/index.js +1 -8
- package/lib/PricingTable/PricingPlan.d.ts +11 -9
- package/lib/PricingTable/PricingPlan.js +0 -4
- package/lib/PricingTable/index.d.ts +5 -3
- package/lib/PricingTable/index.js +1 -5
- package/lib/QRCode/index.d.ts +11 -22
- package/lib/QRCode/index.js +2 -17
- package/lib/RelativeTime/index.d.ts +12 -40
- package/lib/RelativeTime/index.js +7 -27
- package/lib/Result/common.d.ts +26 -45
- package/lib/Result/common.js +2 -4
- package/lib/Result/index.d.ts +5 -18
- package/lib/Result/index.js +1 -9
- package/lib/Result/result.d.ts +7 -29
- package/lib/Result/result.js +2 -17
- package/lib/Result/translations.d.ts +2 -54
- package/lib/Screenshot/BaseScreenshot/index.d.ts +7 -24
- package/lib/Screenshot/BaseScreenshot/index.js +2 -15
- package/lib/Screenshot/BaseScreenshot/shells/Macbook.d.ts +25 -19
- package/lib/Screenshot/BaseScreenshot/shells/Phone.d.ts +25 -19
- package/lib/Screenshot/index.d.ts +84 -28
- package/lib/Screenshot/index.js +14 -43
- package/lib/SessionBlocklet/index.d.ts +6 -19
- package/lib/SessionBlocklet/index.js +5 -15
- package/lib/SessionManager/index.d.ts +1 -1
- package/lib/SessionPermission/index.d.ts +9 -17
- package/lib/SessionPermission/index.js +3 -11
- package/lib/SessionUser/components/logged-in.d.ts +9 -31
- package/lib/SessionUser/components/logged-in.js +13 -29
- package/lib/SessionUser/components/session-user-item.d.ts +8 -1
- package/lib/SessionUser/components/session-user-item.js +2 -12
- package/lib/SessionUser/components/session-user-switch.d.ts +9 -21
- package/lib/SessionUser/components/session-user-switch.js +3 -15
- package/lib/SessionUser/components/un-login.d.ts +7 -23
- package/lib/SessionUser/components/un-login.js +4 -16
- package/lib/SessionUser/components/user-info.d.ts +12 -29
- package/lib/SessionUser/components/user-info.js +4 -19
- package/lib/SessionUser/index.d.ts +7 -30
- package/lib/SessionUser/index.js +5 -26
- package/lib/SessionUser/libs/translation.d.ts +2 -31
- package/lib/SessionUser/libs/translation.js +1 -0
- package/lib/SessionUser/libs/utils.d.ts +10 -9
- package/lib/Sparkline/index.d.ts +22 -1
- package/lib/Sparkline/index.js +25 -17
- package/lib/Spinner/index.d.ts +6 -1
- package/lib/Spinner/index.js +4 -11
- package/lib/Success/index.d.ts +5 -21
- package/lib/Success/index.js +10 -19
- package/lib/Tabs/index.d.ts +12 -26
- package/lib/Tabs/index.js +7 -37
- package/lib/TextCollapse/index.d.ts +10 -10
- package/lib/TextCollapse/index.js +4 -21
- package/lib/Theme/index.js +0 -2
- package/lib/Theme/theme-provider.d.ts +1 -1
- package/lib/Theme/theme.d.ts +4 -1
- package/lib/Theme/theme.js +1 -2
- package/lib/Typography/index.d.ts +5 -24
- package/lib/Typography/index.js +5 -17
- package/lib/Util/index.d.ts +17 -8
- package/lib/Util/index.js +22 -3
- package/lib/Video/index.d.ts +12 -16
- package/lib/Video/index.js +0 -14
- package/lib/Wallet/Action.d.ts +13 -18
- package/lib/Wallet/Action.js +0 -7
- package/lib/Wallet/Download.d.ts +24 -30
- package/lib/Wallet/Download.js +201 -18
- package/lib/Wallet/Open.d.ts +5 -15
- package/lib/Wallet/Open.js +5 -11
- package/lib/WalletOSIcon/index.d.ts +6 -25
- package/lib/WalletOSIcon/index.js +3 -16
- package/lib/WebWalletSWKeeper/index.d.ts +8 -20
- package/lib/WebWalletSWKeeper/index.js +14 -19
- package/lib/WechatPrompt/index.js +2 -0
- package/lib/global.d.ts +15 -0
- package/lib/type.d.ts +12 -3
- package/lib/withTheme/index.d.ts +8 -6
- package/lib/withTracker/index.d.ts +1 -1
- package/lib/withTracker/index.js +3 -0
- package/package.json +9 -5
- package/src/Address/did-address.tsx +7 -6
- package/src/Address/index.tsx +1 -1
- package/src/Avatar/index.jsx +6 -4
- package/src/Blocklet/blocklet.jsx +2 -2
- package/src/BlockletContext/index.tsx +3 -3
- package/src/BlockletNFT/index.jsx +3 -3
- package/src/BlockletV2/blocklet.tsx +2 -2
- package/src/Button/wrap.jsx +2 -2
- package/src/CardSelector/index.tsx +0 -1
- package/src/Center/index.tsx +1 -1
- package/src/ClickToCopy/copy-button.tsx +4 -4
- package/src/ClickToCopy/hook.ts +3 -2
- package/src/ClickToCopy/index.tsx +6 -5
- package/src/CodeBlock/index.tsx +3 -1
- package/src/CookieConsent/{index.jsx → index.tsx} +16 -19
- package/src/CountDown/{index.jsx → index.tsx} +30 -16
- package/src/DID/index.tsx +9 -8
- package/src/Datatable/index.jsx +5 -5
- package/src/Dialog/confirm.jsx +3 -3
- package/src/Dialog/types.d.ts +1 -1
- package/src/DidLogo/{index.jsx → index.tsx} +7 -14
- package/src/DriftBot/{index.jsx → index.tsx} +13 -11
- package/src/Earth/{index.jsx → index.tsx} +94 -66
- package/src/Earth/{util.js → util.ts} +20 -17
- package/src/ErrorBoundary/{fallback.jsx → fallback.tsx} +20 -21
- package/src/Footer/{index.jsx → index.tsx} +17 -14
- package/src/Header/header.tsx +2 -3
- package/src/Header/responsive-header.tsx +0 -1
- package/src/Icon/image.tsx +3 -3
- package/src/Icon/index.tsx +7 -4
- package/src/Img/index.jsx +1 -1
- package/src/InfoRow/{index.jsx → index.tsx} +32 -25
- package/src/Layout/dashboard/external-link.tsx +46 -0
- package/src/Layout/dashboard/{full-page.jsx → full-page.tsx} +20 -9
- package/src/Layout/dashboard/{index.jsx → index.tsx} +42 -44
- package/src/Layout/dashboard/{sidebar.jsx → sidebar.tsx} +23 -20
- package/src/Layout/dashboard-legacy/{header.jsx → header.tsx} +16 -26
- package/src/Layout/dashboard-legacy/{index.jsx → index.tsx} +32 -46
- package/src/Layout/dashboard-legacy/{sidebar.jsx → sidebar.tsx} +27 -19
- package/src/Layout/{index.jsx → index.tsx} +41 -47
- package/src/LoadingMask/{index.jsx → index.tsx} +18 -20
- package/src/Locale/{browser-lang.js → browser-lang.ts} +9 -7
- package/src/Locale/context.tsx +18 -11
- package/src/Locale/{languages.js → languages.ts} +1 -1
- package/src/Locale/{selector.jsx → selector.tsx} +32 -29
- package/src/Locale/{util.js → util.ts} +9 -2
- package/src/Logo/index.tsx +58 -0
- package/src/Metric/{index.jsx → index.tsx} +23 -18
- package/src/NFTDisplay/{aspect-ratio-container.jsx → aspect-ratio-container.tsx} +9 -7
- package/src/NFTDisplay/{broken.jsx → broken.tsx} +7 -12
- package/src/NFTDisplay/{displayApi.js → displayApi.ts} +4 -4
- package/src/NFTDisplay/{index.jsx → index.tsx} +59 -64
- package/src/NFTDisplay/svg-embedder/{img.jsx → img.tsx} +10 -18
- package/src/NFTDisplay/svg-embedder/{inline-svg.jsx → inline-svg.tsx} +8 -9
- package/src/NavMenu/nav-menu.tsx +2 -3
- package/src/PageScroller/{index.jsx → index.tsx} +40 -53
- package/src/PageScroller/{usePrevValue.js → usePrevValue.ts} +2 -3
- package/src/Passport/{passport.jsx → passport.tsx} +22 -19
- package/src/PoweredByArcBlock/{index.jsx → index.tsx} +6 -11
- package/src/PricingTable/{PricingPlan.jsx → PricingPlan.tsx} +15 -5
- package/src/PricingTable/{index.jsx → index.tsx} +9 -6
- package/src/QRCode/{index.jsx → index.tsx} +14 -19
- package/src/RelativeTime/{index.jsx → index.tsx} +24 -24
- package/src/Result/{common.jsx → common.tsx} +17 -13
- package/src/Result/index.tsx +30 -0
- package/src/Result/{result.jsx → result.tsx} +8 -17
- package/src/Result/{translations.js → translations.ts} +3 -1
- package/src/Screenshot/BaseScreenshot/{index.jsx → index.tsx} +9 -15
- package/src/Screenshot/BaseScreenshot/shells/{Macbook.jsx → Macbook.tsx} +3 -1
- package/src/Screenshot/BaseScreenshot/shells/{Phone.jsx → Phone.tsx} +3 -1
- package/src/Screenshot/{index.jsx → index.tsx} +60 -54
- package/src/SessionBlocklet/{index.jsx → index.tsx} +9 -14
- package/src/SessionPermission/index.tsx +25 -0
- package/src/SessionUser/components/{logged-in.jsx → logged-in.tsx} +49 -31
- package/src/SessionUser/components/session-user-item.tsx +97 -0
- package/src/SessionUser/components/{session-user-switch.jsx → session-user-switch.tsx} +16 -21
- package/src/SessionUser/components/{un-login.jsx → un-login.tsx} +10 -15
- package/src/SessionUser/components/{user-info.jsx → user-info.tsx} +16 -22
- package/src/SessionUser/index.tsx +26 -0
- package/src/SessionUser/libs/{translation.js → translation.ts} +3 -1
- package/src/SessionUser/libs/utils.ts +39 -0
- package/src/Sparkline/{index.jsx → index.tsx} +38 -22
- package/src/Spinner/index.tsx +20 -0
- package/src/Success/{index.jsx → index.tsx} +13 -16
- package/src/Tabs/{index.jsx → index.tsx} +26 -40
- package/src/TextCollapse/{index.jsx → index.tsx} +26 -21
- package/src/Theme/index.ts +0 -1
- package/src/Theme/theme-provider.tsx +1 -1
- package/src/Theme/theme.ts +6 -3
- package/src/Typography/{index.jsx → index.tsx} +19 -22
- package/src/Util/index.ts +26 -9
- package/src/Video/{index.jsx → index.tsx} +7 -10
- package/src/Wallet/{Action.jsx → Action.tsx} +16 -12
- package/src/Wallet/{Download.jsx → Download.tsx} +25 -21
- package/src/Wallet/{Open.jsx → Open.tsx} +8 -11
- package/src/WalletOSIcon/{index.jsx → index.tsx} +8 -16
- package/src/WebWalletSWKeeper/{index.jsx → index.tsx} +21 -24
- package/src/WechatPrompt/{index.jsx → index.tsx} +1 -0
- package/src/global.d.ts +15 -0
- package/src/type.d.ts +12 -3
- package/src/withTheme/{index.jsx → index.tsx} +12 -2
- package/src/withTracker/{index.jsx → index.tsx} +6 -4
- package/src/Layout/dashboard/external-link.jsx +0 -47
- package/src/Logo/index.jsx +0 -66
- package/src/Result/index.jsx +0 -33
- package/src/SessionPermission/index.jsx +0 -28
- package/src/SessionUser/components/session-user-item.jsx +0 -93
- package/src/SessionUser/index.jsx +0 -38
- package/src/SessionUser/libs/utils.js +0 -37
- package/src/Spinner/index.jsx +0 -21
- /package/src/ErrorBoundary/{index.jsx → index.ts} +0 -0
- /package/src/NFTDisplay/{loading.jsx → loading.tsx} +0 -0
- /package/src/Passport/{index.jsx → index.ts} +0 -0
- /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 {
|
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
|
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)
|
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
|
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
|
-
|
102
|
-
|
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 = (
|
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
|
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
|
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
|
-
|
27
|
-
|
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
|
-
|
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
|
-
|
14
|
-
aspect:
|
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
|
-
|
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
|
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(
|
101
|
+
const parsed = useRef<Record<string, any>>({});
|
77
102
|
|
78
103
|
try {
|
79
104
|
// 如果是 raw data 先解析
|
80
|
-
if (typeof
|
105
|
+
if (typeof data === 'string') {
|
81
106
|
parsed.current = JSON.parse(data);
|
82
|
-
|
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
|
-
|
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
|
-
|
12
|
-
|
13
|
-
|
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
|
-
|
8
|
-
|
9
|
-
|
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%;
|
package/src/NavMenu/nav-menu.tsx
CHANGED
@@ -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
|
|