@arcblock/ux 2.10.66 → 2.10.68
Sign up to get free protection for your applications and to get access to all the features.
- 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 +2 -18
- 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 +1 -15
- 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 +3 -14
- 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 +4 -16
- 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 +11 -6
- package/lib/Util/index.js +6 -0
- 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} +17 -19
- 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} +13 -17
- 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} +8 -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} +7 -13
- 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 +14 -8
- 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
|
|