@arcblock/ux 2.6.9 → 2.7.1
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/babel.config.es.js +12 -0
- package/es/ActionButton/index.js +99 -0
- package/es/ActivityIndicator/index.js +180 -0
- package/es/Address/compact-text.js +105 -0
- package/es/Address/did-address.js +211 -0
- package/es/Address/index.js +23 -0
- package/es/Address/responsive-did-address.js +88 -0
- package/es/Alert/index.js +134 -0
- package/es/AnimationWaiter/default-animation.json +1 -0
- package/es/AnimationWaiter/index.js +239 -0
- package/es/Async/index.js +38 -0
- package/es/Avatar/did-motif.js +64 -0
- package/es/Avatar/etherscan-blockies.js +83 -0
- package/es/Avatar/index.js +176 -0
- package/es/Badge/index.js +98 -0
- package/es/Blocklet/blocklet.js +298 -0
- package/es/Blocklet/index.js +4 -0
- package/es/Blocklet/utils.js +52 -0
- package/es/BlockletNFT/index.js +412 -0
- package/es/Button/index.js +8 -0
- package/es/Button/wrap.js +140 -0
- package/es/ButtonGroup/index.js +6 -0
- package/es/CardSelector/index.js +131 -0
- package/es/Center/index.js +41 -0
- package/es/ClickToCopy/copy-button.js +72 -0
- package/es/ClickToCopy/hook.js +39 -0
- package/es/ClickToCopy/index.js +93 -0
- package/es/CodeBlock/LightBox.js +85 -0
- package/es/CodeBlock/index.js +226 -0
- package/es/Colors/index.js +2 -0
- package/es/Colors/themes/default.js +78 -0
- package/es/ContactForm/index.js +230 -0
- package/es/CookieConsent/index.js +113 -0
- package/es/CountDown/index.js +178 -0
- package/es/DID/index.js +105 -0
- package/es/Datatable/CustomToolbar.js +396 -0
- package/es/Datatable/DatatableContext.js +34 -0
- package/es/Datatable/TableSearch.js +165 -0
- package/es/Datatable/index.js +627 -0
- package/es/Datatable/utils.js +132 -0
- package/es/Dialog/confirm.js +90 -0
- package/es/Dialog/dialog.js +192 -0
- package/es/Dialog/index.js +3 -0
- package/es/DidLogo/index.js +31 -0
- package/es/DriftBot/index.js +70 -0
- package/es/Earth/countries.json +8057 -0
- package/es/Earth/index.js +521 -0
- package/es/Earth/util.js +51 -0
- package/es/Empty/index.js +64 -0
- package/es/ErrorBoundary/fallback.js +73 -0
- package/es/ErrorBoundary/index.js +1 -0
- package/es/Footer/index.js +172 -0
- package/es/Header/auto-hidden.js +35 -0
- package/es/Header/header.js +211 -0
- package/es/Header/index.js +2 -0
- package/es/Header/responsive-header.js +111 -0
- package/es/Icon/image.js +65 -0
- package/es/Icon/index.js +84 -0
- package/es/Img/index.js +217 -0
- package/es/InfoRow/index.js +87 -0
- package/es/Layout/dashboard/external-link.js +58 -0
- package/es/Layout/dashboard/full-page.js +53 -0
- package/es/Layout/dashboard/index.js +275 -0
- package/es/Layout/dashboard/sidebar.js +209 -0
- package/es/Layout/dashboard-legacy/header.js +174 -0
- package/es/Layout/dashboard-legacy/index.js +149 -0
- package/es/Layout/dashboard-legacy/sidebar.js +129 -0
- package/es/Layout/index.js +335 -0
- package/es/Locale/browser-lang.js +52 -0
- package/es/Locale/context.js +114 -0
- package/es/Locale/languages.js +60 -0
- package/es/Locale/selector.js +180 -0
- package/es/Locale/util.js +13 -0
- package/es/Logo/images/logo-dark-text.svg +3 -0
- package/es/Logo/images/logo-dark-top.svg +6 -0
- package/es/Logo/images/logo-light-text.svg +3 -0
- package/es/Logo/images/logo-light-top.svg +6 -0
- package/es/Logo/index.js +136 -0
- package/es/Metric/index.js +132 -0
- package/es/NFTDisplay/README.md +59 -0
- package/es/NFTDisplay/aspect-ratio-container.js +39 -0
- package/es/NFTDisplay/broken.js +18 -0
- package/es/NFTDisplay/demo/data/asset-state-display-url.json +7 -0
- package/es/NFTDisplay/demo/data/asset-state-gzipped-svg-1-1.json +10 -0
- package/es/NFTDisplay/demo/data/asset-state-gzipped-svg-374-130.json +10 -0
- package/es/NFTDisplay/demo/data/asset-state-gzipped-svg-with-foreign-object.json +20 -0
- package/es/NFTDisplay/demo/data/asset-state-svg.json +29 -0
- package/es/NFTDisplay/demo/data/asset-state-url.json +10 -0
- package/es/NFTDisplay/index.js +323 -0
- package/es/NFTDisplay/loading.js +18 -0
- package/es/NFTDisplay/svg-embedder/img.js +45 -0
- package/es/NFTDisplay/svg-embedder/inline-svg.js +39 -0
- package/es/NavMenu/index.js +2 -0
- package/es/NavMenu/nav-menu.js +286 -0
- package/es/NavMenu/style.js +176 -0
- package/es/PageScroller/index.js +286 -0
- package/es/PageScroller/story/FifthComponent.js +9 -0
- package/es/PageScroller/story/FirstComponent.js +9 -0
- package/es/PageScroller/story/FourthComponent.js +12 -0
- package/es/PageScroller/story/FullPage.js +47 -0
- package/es/PageScroller/story/PageContain.js +59 -0
- package/es/PageScroller/story/SecondComponent.js +9 -0
- package/es/PageScroller/story/ThirdComponent.js +9 -0
- package/es/PageScroller/story/index.css +115 -0
- package/es/PageScroller/usePrevValue.js +9 -0
- package/es/PricingTable/PricingPlan.js +124 -0
- package/es/PricingTable/index.js +53 -0
- package/es/QRCode/index.js +72 -0
- package/es/RelativeTime/index.js +98 -0
- package/es/Result/common.js +140 -0
- package/es/Result/demo/fixtures/result-image-404.svg +1 -0
- package/es/Result/index.js +33 -0
- package/es/Result/result.js +59 -0
- package/es/Result/translations.js +54 -0
- package/es/Screenshot/BaseScreenshot/index.js +91 -0
- package/es/Screenshot/BaseScreenshot/shells/Macbook.js +51 -0
- package/es/Screenshot/BaseScreenshot/shells/Phone.js +36 -0
- package/es/Screenshot/demo/images/bg-00.jpg +0 -0
- package/es/Screenshot/demo/images/bg-01.jpg +0 -0
- package/es/Screenshot/demo/images/bg-02.jpg +0 -0
- package/es/Screenshot/demo/images/bg-03.jpg +0 -0
- package/es/Screenshot/demo/images/bg-04.jpg +0 -0
- package/es/Screenshot/demo/images/bg-05.jpg +0 -0
- package/es/Screenshot/demo/images/bg-06.jpg +0 -0
- package/es/Screenshot/demo/images/bg-07.jpg +0 -0
- package/es/Screenshot/demo/images/bg-08.jpg +0 -0
- package/es/Screenshot/demo/images/bg-09.jpg +0 -0
- package/es/Screenshot/devices.css +1366 -0
- package/es/Screenshot/index.js +299 -0
- package/es/SessionManager/federated-login-detecter.js +166 -0
- package/es/SessionManager/index.js +468 -0
- package/es/SessionManager/user-popper.js +132 -0
- package/es/Sparkline/index.js +193 -0
- package/es/Spinner/index.js +28 -0
- package/es/SplitButton/index.js +144 -0
- package/es/Switch/index.js +96 -0
- package/es/Tabs/index.js +48 -0
- package/es/Tag/index.js +108 -0
- package/es/TextCollapse/index.js +92 -0
- package/es/Theme/index.js +16 -0
- package/es/Theme/theme-provider.js +39 -0
- package/es/Theme/theme.js +133 -0
- package/es/Toast/index.js +95 -0
- package/es/Util/deprecate.js +28 -0
- package/es/Util/index.js +298 -0
- package/es/Util/wallet.js +32 -0
- package/es/Video/index.js +89 -0
- package/es/Wallet/Action.js +119 -0
- package/es/Wallet/Download.js +331 -0
- package/es/Wallet/Open.js +45 -0
- package/es/Wallet/images/abtwallet.png +0 -0
- package/es/Wallet/images/android_download.svg +23 -0
- package/es/Wallet/images/app-store.svg +20 -0
- package/es/Wallet/images/google-play.svg +70 -0
- package/es/WebWalletSWKeeper/index.js +115 -0
- package/es/WechatPrompt/images/android.png +0 -0
- package/es/WechatPrompt/images/ios.png +0 -0
- package/es/WechatPrompt/index.js +88 -0
- package/es/index.js +38 -0
- package/es/withTheme/index.js +69 -0
- package/es/withTracker/README.md +34 -0
- package/es/withTracker/error_boundary.js +34 -0
- package/es/withTracker/index.js +56 -0
- package/package.json +272 -5
@@ -0,0 +1,92 @@
|
|
1
|
+
import PropTypes from 'prop-types';
|
2
|
+
import Typography from '@mui/material/Typography';
|
3
|
+
import { styled } from '../Theme';
|
4
|
+
import { withDeprecated } from '../Util/deprecate';
|
5
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
6
|
+
import { jsxs as _jsxs } from "react/jsx-runtime";
|
7
|
+
function TextCollapse({
|
8
|
+
children,
|
9
|
+
startChars,
|
10
|
+
endChars,
|
11
|
+
scaleFactor,
|
12
|
+
maxWidth,
|
13
|
+
style,
|
14
|
+
fontType,
|
15
|
+
...rest
|
16
|
+
}) {
|
17
|
+
if (typeof children !== 'string') {
|
18
|
+
return null;
|
19
|
+
}
|
20
|
+
const isMonospace = fontType === 'monospace';
|
21
|
+
|
22
|
+
// 由于 css 样式产生的省略号长度是不确定的,所以目前 startChars 的长度只能让开发者自己去加上‘省略号’的宽度去设置这个值,要想完美的实现目标功能,最好是改用 js 动态修改文本内容来实现
|
23
|
+
const startWidth = isMonospace ? `${startChars}ch` : `${scaleFactor * (startChars + 3)}em`;
|
24
|
+
const endWidth = isMonospace ? `${endChars}ch` : `${scaleFactor * endChars}em`;
|
25
|
+
const styles = Object.assign(isMonospace ? {
|
26
|
+
fontFamily: '"Courier New", Courier, monospace'
|
27
|
+
} : {}, {
|
28
|
+
fontSize: 'inherit',
|
29
|
+
color: 'inherit',
|
30
|
+
fontWeight: 'inherit',
|
31
|
+
maxWidth
|
32
|
+
}, style);
|
33
|
+
const [startPart, endPart] = [children.slice(0, children.length - endChars), children.slice(children.length - endChars)];
|
34
|
+
return /*#__PURE__*/_jsxs(Container, {
|
35
|
+
component: "span",
|
36
|
+
style: styles,
|
37
|
+
startwidth: startWidth,
|
38
|
+
endwidth: endWidth,
|
39
|
+
...rest,
|
40
|
+
children: [/*#__PURE__*/_jsx("span", {
|
41
|
+
className: "start-part",
|
42
|
+
children: startPart
|
43
|
+
}), /*#__PURE__*/_jsx("span", {
|
44
|
+
className: "end-part",
|
45
|
+
children: endPart
|
46
|
+
})]
|
47
|
+
});
|
48
|
+
}
|
49
|
+
TextCollapse.propTypes = {
|
50
|
+
children: PropTypes.string.isRequired,
|
51
|
+
maxWidth: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
|
52
|
+
fontType: PropTypes.oneOf(['monospace', 'normal']),
|
53
|
+
style: PropTypes.object,
|
54
|
+
startChars: PropTypes.number,
|
55
|
+
endChars: PropTypes.number,
|
56
|
+
scaleFactor: PropTypes.number
|
57
|
+
};
|
58
|
+
TextCollapse.defaultProps = {
|
59
|
+
style: {},
|
60
|
+
startChars: 5,
|
61
|
+
endChars: 5,
|
62
|
+
scaleFactor: 0.45,
|
63
|
+
fontType: 'normal'
|
64
|
+
};
|
65
|
+
export default withDeprecated(TextCollapse, {
|
66
|
+
name: 'TextCollapse'
|
67
|
+
});
|
68
|
+
const Container = styled(Typography)`
|
69
|
+
display: inline-flex;
|
70
|
+
align-items: center;
|
71
|
+
justify-content: start;
|
72
|
+
cursor: pointer;
|
73
|
+
white-space: nowrap;
|
74
|
+
overflow: hidden;
|
75
|
+
|
76
|
+
.start-part,
|
77
|
+
.end-part {
|
78
|
+
display: inline-block;
|
79
|
+
vertical-align: bottom;
|
80
|
+
white-space: nowrap;
|
81
|
+
overflow: hidden;
|
82
|
+
}
|
83
|
+
.start-part {
|
84
|
+
max-width: calc(100% - ${props => props.endwidth});
|
85
|
+
min-width: ${props => props.startwidth};
|
86
|
+
text-overflow: ellipsis;
|
87
|
+
}
|
88
|
+
.end-part {
|
89
|
+
max-width: calc(100% - ${props => props.startwidth});
|
90
|
+
direction: rtl;
|
91
|
+
}
|
92
|
+
`;
|
@@ -0,0 +1,16 @@
|
|
1
|
+
import { styled as muiStyled, useTheme } from '@mui/material/styles';
|
2
|
+
export * from './theme';
|
3
|
+
export { default as ThemeProvider } from './theme-provider';
|
4
|
+
export { useTheme };
|
5
|
+
const isTransientProp = prop => prop.startsWith('$');
|
6
|
+
export const styled = (component, options = {}) => {
|
7
|
+
return muiStyled(component, {
|
8
|
+
...options,
|
9
|
+
shouldForwardProp: prop => {
|
10
|
+
if (options.shouldForwardProp) {
|
11
|
+
return options.shouldForwardProp(prop) && !isTransientProp(prop);
|
12
|
+
}
|
13
|
+
return !isTransientProp(prop);
|
14
|
+
}
|
15
|
+
});
|
16
|
+
};
|
@@ -0,0 +1,39 @@
|
|
1
|
+
import PropTypes from 'prop-types';
|
2
|
+
import { ThemeProvider as MuiThemeProvider } from '@mui/material/styles';
|
3
|
+
import StyledEngineProvider from '@mui/material/StyledEngineProvider';
|
4
|
+
import CssBaseline from '@mui/material/CssBaseline';
|
5
|
+
import { createTheme } from './theme';
|
6
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
7
|
+
import { jsxs as _jsxs } from "react/jsx-runtime";
|
8
|
+
const defaultTheme = createTheme();
|
9
|
+
|
10
|
+
/**
|
11
|
+
* 默认的 theme provider, 可以为 webapp/blocklet 快捷的配置好 mui theme provider
|
12
|
+
*/
|
13
|
+
export default function ThemeProvider({
|
14
|
+
children,
|
15
|
+
theme,
|
16
|
+
injectFirst
|
17
|
+
}) {
|
18
|
+
return (
|
19
|
+
/*#__PURE__*/
|
20
|
+
// injectFirst 会影响 makeStyles 自定义样式和 mui styles 覆盖问题
|
21
|
+
_jsx(StyledEngineProvider, {
|
22
|
+
injectFirst: injectFirst,
|
23
|
+
children: /*#__PURE__*/_jsxs(MuiThemeProvider, {
|
24
|
+
theme: theme,
|
25
|
+
children: [/*#__PURE__*/_jsx(CssBaseline, {}), children]
|
26
|
+
})
|
27
|
+
})
|
28
|
+
);
|
29
|
+
}
|
30
|
+
ThemeProvider.propTypes = {
|
31
|
+
children: PropTypes.any,
|
32
|
+
theme: PropTypes.any,
|
33
|
+
injectFirst: PropTypes.bool
|
34
|
+
};
|
35
|
+
ThemeProvider.defaultProps = {
|
36
|
+
children: null,
|
37
|
+
theme: defaultTheme,
|
38
|
+
injectFirst: true
|
39
|
+
};
|
@@ -0,0 +1,133 @@
|
|
1
|
+
// https://app.zeplin.io/styleguide/5d1436f1e97c2156f49c0725/colors
|
2
|
+
import { createTheme as _createTheme, responsiveFontSizes } from '@mui/material/styles';
|
3
|
+
import '@fontsource/lato/400.css';
|
4
|
+
import '@fontsource/lato/700.css';
|
5
|
+
import colors from '../Colors';
|
6
|
+
const muiDarkTheme = _createTheme({
|
7
|
+
palette: {
|
8
|
+
mode: 'dark'
|
9
|
+
}
|
10
|
+
});
|
11
|
+
|
12
|
+
// https://material-ui.com/customization/default-theme/
|
13
|
+
// eslint-disable-next-line import/prefer-default-export
|
14
|
+
export const create = ({
|
15
|
+
mode = 'light',
|
16
|
+
pageWidth = 'md',
|
17
|
+
palette,
|
18
|
+
typography,
|
19
|
+
overrides,
|
20
|
+
...rest
|
21
|
+
} = {}) => {
|
22
|
+
// palette 考虑 light & dark mode, dark mode 需要持续完善
|
23
|
+
// - 能配合 ColorModeContext 使用
|
24
|
+
// - 为 dark mode 系统的设计整个 palette, 不要单个 color 设置
|
25
|
+
const _palette = mode === 'light' ? Object.assign({
|
26
|
+
...colors,
|
27
|
+
background: {
|
28
|
+
paper: colors.common.white,
|
29
|
+
default: colors.background.default
|
30
|
+
},
|
31
|
+
mode
|
32
|
+
}, palette || {}) : Object.assign({
|
33
|
+
...muiDarkTheme.palette,
|
34
|
+
background: {
|
35
|
+
paper: colors.grey[900],
|
36
|
+
default: colors.grey[900]
|
37
|
+
},
|
38
|
+
mode
|
39
|
+
}, palette || {});
|
40
|
+
const theme = _createTheme({
|
41
|
+
themeName: 'ArcBlock',
|
42
|
+
palette: _palette,
|
43
|
+
typography: Object.assign({
|
44
|
+
useNextVariants: true,
|
45
|
+
color: {
|
46
|
+
// 此处 #222222 必须硬编码, layout/sidebar.js -> Icon/image 加载图片时 color 会影响加载路径
|
47
|
+
// TODO: 此处硬编码的色值后面需要改为 colors.grey[900],
|
48
|
+
// 或者如果可以的话直接删掉 typography#color, 文本颜色建议使用 theme.palette.text 中的色值?
|
49
|
+
// layout 组件建议重构, sidebar 中建议使用 icon 替换 img (#366)
|
50
|
+
main: mode === 'light' ? '#222222' : colors.common.white,
|
51
|
+
gray: mode === 'light' ? colors.grey[500] : colors.grey[300]
|
52
|
+
},
|
53
|
+
fontFamily: ['Lato', 'Avenir', '-apple-system', 'BlinkMacSystemFont', '"Segoe UI"', 'Roboto', '"Helvetica Neue"', 'Arial', 'sans-serif', '"Apple Color Emoji"', '"Segoe UI Emoji"', '"Segoe UI Symbol"'].join(','),
|
54
|
+
// 按最新设计规范, 只使用 400/700
|
55
|
+
fontWeightLight: 400,
|
56
|
+
fontWeightRegular: 400,
|
57
|
+
fontWeightMedium: 700,
|
58
|
+
fontWeightBold: 700,
|
59
|
+
// button 默认使用粗体
|
60
|
+
button: {
|
61
|
+
fontWeight: 700
|
62
|
+
}
|
63
|
+
}, typography || {}),
|
64
|
+
components: {
|
65
|
+
MuiButton: {
|
66
|
+
styleOverrides: {
|
67
|
+
root: {
|
68
|
+
boxShadow: 'none'
|
69
|
+
}
|
70
|
+
}
|
71
|
+
},
|
72
|
+
MuiButtonGroup: {
|
73
|
+
styleOverrides: {
|
74
|
+
root: {
|
75
|
+
boxShadow: 'none'
|
76
|
+
}
|
77
|
+
}
|
78
|
+
},
|
79
|
+
MuiTableCell: {
|
80
|
+
styleOverrides: {
|
81
|
+
root: {
|
82
|
+
borderBottomWidth: '0',
|
83
|
+
paddingTop: '14px',
|
84
|
+
paddingBottom: '14px',
|
85
|
+
paddingLeft: 0,
|
86
|
+
paddingRight: '30px'
|
87
|
+
},
|
88
|
+
head: {
|
89
|
+
textTransform: 'uppercase',
|
90
|
+
color: mode === 'light' ? colors.grey[900] : colors.grey[300]
|
91
|
+
},
|
92
|
+
body: {
|
93
|
+
color: mode === 'light' ? colors.grey[900] : colors.grey[300]
|
94
|
+
}
|
95
|
+
}
|
96
|
+
},
|
97
|
+
...overrides
|
98
|
+
},
|
99
|
+
pageWidth,
|
100
|
+
// TODO: 过时的 colors, 需要各项目负责人检查项目中是否使用 "theme.colors", 如果有需要清除,
|
101
|
+
// 可以从 Colors 模块/theme.palette/mui colors 中取值
|
102
|
+
colors: {
|
103
|
+
white: '#FFFFFF',
|
104
|
+
dark: '#4A707C',
|
105
|
+
gray: '#222222',
|
106
|
+
minor: '#9B9B9B',
|
107
|
+
darkText: '#DCDCDC',
|
108
|
+
background: '#F7F8F8',
|
109
|
+
yellow: '#FFCF71',
|
110
|
+
green: '#44cdc6',
|
111
|
+
red: '#D0021B',
|
112
|
+
blue: '#4E6AF6',
|
113
|
+
primary: '#222222',
|
114
|
+
black: '#222222',
|
115
|
+
secondary: '#44cdc6',
|
116
|
+
mint: '#44cdc6',
|
117
|
+
textSecondary: '#4A4A4A',
|
118
|
+
active: '#5b9025',
|
119
|
+
danger: '#D0021B',
|
120
|
+
lightGrey: '#BCBCBC'
|
121
|
+
},
|
122
|
+
mode,
|
123
|
+
...rest
|
124
|
+
});
|
125
|
+
const enhanced = responsiveFontSizes(theme, {
|
126
|
+
breakpoints: ['xs', 'sm', 'md', 'lg'],
|
127
|
+
disableAlign: false,
|
128
|
+
factor: 3,
|
129
|
+
variants: ['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'subtitle1', 'subtitle2', 'body1', 'body2', 'caption', 'button', 'overline']
|
130
|
+
});
|
131
|
+
return enhanced;
|
132
|
+
};
|
133
|
+
export const createTheme = create;
|
@@ -0,0 +1,95 @@
|
|
1
|
+
import { createRef } from 'react';
|
2
|
+
import { SnackbarProvider, useSnackbar } from 'notistack';
|
3
|
+
import IconButton from '@mui/material/IconButton';
|
4
|
+
import CloseIcon from '@mui/icons-material/Close';
|
5
|
+
|
6
|
+
/**
|
7
|
+
*
|
8
|
+
* @typedef {(message: import('notistack').SnackbarMessage, options?: import('notistack').OptionsObject, ...args: any[]) => import('notistack').SnackbarKey} EnqueueSnackbarFunc
|
9
|
+
*
|
10
|
+
*/
|
11
|
+
|
12
|
+
/**
|
13
|
+
* @type {import('notistack').ProviderContext['enqueueSnackbar']}
|
14
|
+
*/
|
15
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
16
|
+
import { jsxs as _jsxs } from "react/jsx-runtime";
|
17
|
+
const noop = () => {};
|
18
|
+
let success = noop;
|
19
|
+
let error = noop;
|
20
|
+
let warning = noop;
|
21
|
+
let info = noop;
|
22
|
+
/**
|
23
|
+
* @description
|
24
|
+
* @param {(message: import('notistack').SnackbarMessage, options?: import('notistack').OptionsObject) => import('notistack').SnackbarKey} enqueueSnackbar
|
25
|
+
* @param {import('notistack').ProviderContext['enqueueSnackbar']} enqueueSnackbar
|
26
|
+
* @param {import('notistack').VariantType} variant
|
27
|
+
* @returns {import('notistack').ProviderContext['enqueueSnackbar']}
|
28
|
+
*/
|
29
|
+
const genFn = (enqueueSnackbar, variant) => (message, opts = {}) => {
|
30
|
+
enqueueSnackbar(message, {
|
31
|
+
autoHideDuration: 3000,
|
32
|
+
variant,
|
33
|
+
...opts
|
34
|
+
});
|
35
|
+
};
|
36
|
+
|
37
|
+
// eslint-disable-next-line react/prop-types
|
38
|
+
function ToastProvider({
|
39
|
+
children
|
40
|
+
}) {
|
41
|
+
const notistackRef = /*#__PURE__*/createRef();
|
42
|
+
const onClickDismiss = key => () => {
|
43
|
+
notistackRef.current.closeSnackbar(key);
|
44
|
+
};
|
45
|
+
return /*#__PURE__*/_jsxs(SnackbarProvider, {
|
46
|
+
anchorOrigin: {
|
47
|
+
vertical: 'top',
|
48
|
+
horizontal: 'right'
|
49
|
+
},
|
50
|
+
ref: notistackRef
|
51
|
+
// eslint-disable-next-line react/no-unstable-nested-components
|
52
|
+
,
|
53
|
+
action: key => /*#__PURE__*/_jsx(IconButton, {
|
54
|
+
"aria-label": "close",
|
55
|
+
color: "inherit",
|
56
|
+
onClick: onClickDismiss(key),
|
57
|
+
size: "large",
|
58
|
+
children: /*#__PURE__*/_jsx(CloseIcon, {
|
59
|
+
style: {
|
60
|
+
fontSize: 16
|
61
|
+
}
|
62
|
+
})
|
63
|
+
}, "close"),
|
64
|
+
children: [/*#__PURE__*/_jsx(Toast, {}), children]
|
65
|
+
});
|
66
|
+
}
|
67
|
+
function Toast() {
|
68
|
+
const {
|
69
|
+
enqueueSnackbar
|
70
|
+
} = useSnackbar();
|
71
|
+
success = genFn(enqueueSnackbar, 'success');
|
72
|
+
error = genFn(enqueueSnackbar, 'error');
|
73
|
+
warning = genFn(enqueueSnackbar, 'warning');
|
74
|
+
info = genFn(enqueueSnackbar, 'info');
|
75
|
+
return null;
|
76
|
+
}
|
77
|
+
export { ToastProvider };
|
78
|
+
export default {
|
79
|
+
/**
|
80
|
+
* @type {EnqueueSnackbarFunc}
|
81
|
+
*/
|
82
|
+
success: (message, options = {}, ...args) => success(message, options, ...args),
|
83
|
+
/**
|
84
|
+
* @type {EnqueueSnackbarFunc}
|
85
|
+
*/
|
86
|
+
error: (message, options = {}, ...args) => error(message, options, ...args),
|
87
|
+
/**
|
88
|
+
* @type {EnqueueSnackbarFunc}
|
89
|
+
*/
|
90
|
+
warning: (message, options = {}, ...args) => warning(message, options, ...args),
|
91
|
+
/**
|
92
|
+
* @type {EnqueueSnackbarFunc}
|
93
|
+
*/
|
94
|
+
info: (message, options = {}, ...args) => info(message, options, ...args)
|
95
|
+
};
|
@@ -0,0 +1,28 @@
|
|
1
|
+
import { useEffect } from 'react';
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
3
|
+
const warn = (name, alternative) => {
|
4
|
+
if (process.env.NODE_ENV === 'production') {
|
5
|
+
return;
|
6
|
+
}
|
7
|
+
if (typeof console?.warn === 'function') {
|
8
|
+
if (alternative) {
|
9
|
+
console.warn(`DEPRECATED: ${name} is deprecated, use ${alternative} instead.`);
|
10
|
+
} else {
|
11
|
+
console.warn(`DEPRECATED: ${name} is deprecated.`);
|
12
|
+
}
|
13
|
+
}
|
14
|
+
};
|
15
|
+
const withDeprecated = (Component, {
|
16
|
+
name,
|
17
|
+
alternative
|
18
|
+
}) => {
|
19
|
+
return function Deprecated(props) {
|
20
|
+
useEffect(() => {
|
21
|
+
warn(name, alternative);
|
22
|
+
}, []);
|
23
|
+
return /*#__PURE__*/_jsx(Component, {
|
24
|
+
...props
|
25
|
+
});
|
26
|
+
};
|
27
|
+
};
|
28
|
+
export { warn, withDeprecated };
|
package/es/Util/index.js
ADDED
@@ -0,0 +1,298 @@
|
|
1
|
+
/* eslint-disable no-bitwise */
|
2
|
+
import padStart from 'lodash/padStart';
|
3
|
+
let dateTool = null;
|
4
|
+
export function parseQuery(str) {
|
5
|
+
return str.replace(/^\?/, '').split('&').map(x => x.split('=')).filter(([key]) => !!key).reduce((memo, x) => {
|
6
|
+
const key = x[0];
|
7
|
+
const value = decodeURIComponent(x[1]) || true;
|
8
|
+
memo[key] = value;
|
9
|
+
return memo;
|
10
|
+
}, {});
|
11
|
+
}
|
12
|
+
export function stringifyQuery(params = {}) {
|
13
|
+
return new URLSearchParams(params).toString();
|
14
|
+
}
|
15
|
+
|
16
|
+
/**
|
17
|
+
* @param {number} opts.expireInDays
|
18
|
+
* @param {string} opts.path
|
19
|
+
* @param {domain} opts.domain
|
20
|
+
* @param {boolean} opts.returnDomain if === false, opts.domain will be skipped
|
21
|
+
*/
|
22
|
+
export function getCookieOptions(expireInDays = 1) {
|
23
|
+
let opts = {
|
24
|
+
expireInDays
|
25
|
+
};
|
26
|
+
if (typeof expireInDays === 'object') {
|
27
|
+
opts = expireInDays;
|
28
|
+
}
|
29
|
+
if (opts.path === undefined) {
|
30
|
+
opts.path = '/';
|
31
|
+
}
|
32
|
+
if (!opts.expireInDays) {
|
33
|
+
opts.expireInDays = 1;
|
34
|
+
}
|
35
|
+
const options = {
|
36
|
+
expires: opts.expireInDays,
|
37
|
+
path: opts.path,
|
38
|
+
domain: opts.domain || '',
|
39
|
+
sameSite: opts.sameSite || 'lax'
|
40
|
+
};
|
41
|
+
if (typeof window === 'undefined' || opts.domain || opts.returnDomain === false) {
|
42
|
+
if (opts.returnDomain === false) {
|
43
|
+
delete options.domain;
|
44
|
+
}
|
45
|
+
return options;
|
46
|
+
}
|
47
|
+
return options;
|
48
|
+
}
|
49
|
+
export const getColor = props => {
|
50
|
+
if (props.color) {
|
51
|
+
return props.color;
|
52
|
+
}
|
53
|
+
if (props.dark) {
|
54
|
+
return props.theme.palette.common.white;
|
55
|
+
}
|
56
|
+
return props.theme.palette.text.primary;
|
57
|
+
};
|
58
|
+
export const getBackground = props => {
|
59
|
+
if (props.background) {
|
60
|
+
return props.background;
|
61
|
+
}
|
62
|
+
if (props.dark) {
|
63
|
+
return props.theme.palette.common.black;
|
64
|
+
}
|
65
|
+
return props.theme.palette.common.white;
|
66
|
+
};
|
67
|
+
export function mergeProps(props, component, jsonAttrs = []) {
|
68
|
+
const newProps = Object.assign({}, props);
|
69
|
+
Object.keys(component.defaultProps || {}).forEach(x => {
|
70
|
+
if (typeof newProps[x] === 'string' && newProps[x].indexOf('::prop::') === 0) {
|
71
|
+
newProps[x] = component.defaultProps[x];
|
72
|
+
}
|
73
|
+
});
|
74
|
+
if (Array.isArray(jsonAttrs)) {
|
75
|
+
jsonAttrs.forEach(x => {
|
76
|
+
if (typeof newProps[x] === 'string') {
|
77
|
+
try {
|
78
|
+
newProps[x] = JSON.parse(newProps[x]);
|
79
|
+
} catch (err) {
|
80
|
+
// Do nothing
|
81
|
+
}
|
82
|
+
}
|
83
|
+
});
|
84
|
+
}
|
85
|
+
Object.keys(newProps).forEach(x => {
|
86
|
+
if (typeof newProps[x] === 'string' && newProps[x].indexOf('::prop::') === 0) {
|
87
|
+
newProps[x] = '';
|
88
|
+
}
|
89
|
+
});
|
90
|
+
return newProps;
|
91
|
+
}
|
92
|
+
export function getCopyright(startYear = 2017) {
|
93
|
+
const currentYear = new Date().getFullYear();
|
94
|
+
return `${currentYear}` === `${startYear}` ? `© ArcBlock ${currentYear}` : `© ArcBlock ${startYear} - ${currentYear}`;
|
95
|
+
}
|
96
|
+
export const getTimezone = () => {
|
97
|
+
if (typeof Intl === 'object' && typeof Intl.DateTimeFormat === 'function' && typeof Intl.DateTimeFormat().resolvedOptions === 'function') {
|
98
|
+
return Intl.DateTimeFormat().resolvedOptions().timeZone;
|
99
|
+
}
|
100
|
+
return '';
|
101
|
+
};
|
102
|
+
export const str2color = str => {
|
103
|
+
let hash = 0;
|
104
|
+
for (let i = 0; i < str.length; i++) {
|
105
|
+
hash = str.charCodeAt(i) + ((hash << 5) - hash);
|
106
|
+
}
|
107
|
+
let colour = '#';
|
108
|
+
for (let j = 0; j < 3; j++) {
|
109
|
+
const value = hash >> j * 8 & 0xff;
|
110
|
+
colour += `00${value.toString(16)}`.substr(-2);
|
111
|
+
}
|
112
|
+
return colour;
|
113
|
+
};
|
114
|
+
export const formatUptime = uptime => {
|
115
|
+
const total = Math.round(uptime / 1000);
|
116
|
+
const hours = Math.floor(total / 3600);
|
117
|
+
const minutes = Math.floor((total - hours * 3600) / 60);
|
118
|
+
const seconds = total % 60;
|
119
|
+
return `${padStart(hours, 2, '0')}:${padStart(minutes, 2, '0')}:${padStart(seconds, 2, '0')}`;
|
120
|
+
};
|
121
|
+
|
122
|
+
/**
|
123
|
+
* Set the date tool library which support for format() and locale() functions,
|
124
|
+
* moment and dayjs are recommended.
|
125
|
+
* @param {object} the date tool library
|
126
|
+
*/
|
127
|
+
export function setDateTool(tool) {
|
128
|
+
dateTool = tool;
|
129
|
+
}
|
130
|
+
export function getDateTool() {
|
131
|
+
return dateTool;
|
132
|
+
}
|
133
|
+
const createDateFormater = format => (date, {
|
134
|
+
locale,
|
135
|
+
tz
|
136
|
+
}) => {
|
137
|
+
if (dateTool === null) {
|
138
|
+
throw new Error('call setDateTool to set the date tool library, such as: setDateTool(dayjs)');
|
139
|
+
}
|
140
|
+
if (!date) {
|
141
|
+
return '-';
|
142
|
+
}
|
143
|
+
let instance = dateTool(date);
|
144
|
+
if (tz) {
|
145
|
+
instance = instance.tz(tz);
|
146
|
+
}
|
147
|
+
if (typeof locale !== 'undefined') {
|
148
|
+
instance = instance.locale(locale);
|
149
|
+
}
|
150
|
+
return instance.format(format);
|
151
|
+
};
|
152
|
+
|
153
|
+
/**
|
154
|
+
* Format the time string as `ll` format: MMM D, YYYY
|
155
|
+
* Ensure that the setDateTool() function is called first to set the time tool library.
|
156
|
+
* @param {string} date date string
|
157
|
+
* @param {object} option
|
158
|
+
* @param {string} option.locale, default: en
|
159
|
+
* @param {string} option.tz, default: timzone
|
160
|
+
* @returns formated date string
|
161
|
+
*/
|
162
|
+
export function formatToDate(date, {
|
163
|
+
locale,
|
164
|
+
tz
|
165
|
+
} = {}) {
|
166
|
+
return createDateFormater('ll')(date, {
|
167
|
+
locale,
|
168
|
+
tz
|
169
|
+
});
|
170
|
+
}
|
171
|
+
|
172
|
+
/**
|
173
|
+
* Format the time string as `lll` format: MMM D, YYYY h:mm A
|
174
|
+
* Ensure that the setDateTool() function is called first to set the time tool library.
|
175
|
+
* @param {string} date date string
|
176
|
+
* @param {object} option
|
177
|
+
* @param {string} option.locale, default: en
|
178
|
+
* @param {string} option.tz, default: timzone
|
179
|
+
* @returns formated date string
|
180
|
+
*/
|
181
|
+
export function formatToDatetime(date, {
|
182
|
+
locale,
|
183
|
+
tz
|
184
|
+
} = {}) {
|
185
|
+
return createDateFormater('lll')(date, {
|
186
|
+
locale,
|
187
|
+
tz
|
188
|
+
});
|
189
|
+
}
|
190
|
+
export function detectWalletExtension() {
|
191
|
+
const extension = window?.ABT_DEV || window.ABT;
|
192
|
+
if (extension && typeof extension.open === 'function') {
|
193
|
+
return extension;
|
194
|
+
}
|
195
|
+
return null;
|
196
|
+
}
|
197
|
+
export function openWebWallet({
|
198
|
+
webWalletUrl,
|
199
|
+
action = 'login',
|
200
|
+
locale = 'en',
|
201
|
+
url,
|
202
|
+
windowFeatures
|
203
|
+
}) {
|
204
|
+
// web wallet extension
|
205
|
+
const extension = detectWalletExtension();
|
206
|
+
if (extension) {
|
207
|
+
extension.open({
|
208
|
+
action,
|
209
|
+
locale,
|
210
|
+
url: encodeURIComponent(url)
|
211
|
+
});
|
212
|
+
return;
|
213
|
+
}
|
214
|
+
const defaultWindowFeatures = {
|
215
|
+
toolbar: 'no',
|
216
|
+
location: 'no',
|
217
|
+
status: 'no',
|
218
|
+
menubar: 'no',
|
219
|
+
scrollbars: 'yes',
|
220
|
+
resizable: 'yes',
|
221
|
+
// iphone 8plus size
|
222
|
+
width: 414,
|
223
|
+
height: 736
|
224
|
+
};
|
225
|
+
const windowUrl = `${webWalletUrl}?action=${action}&locale=${locale}&url=${encodeURIComponent(url)}`;
|
226
|
+
const mergedWindowFeatures = Object.assign({}, defaultWindowFeatures, windowFeatures);
|
227
|
+
const getWindowWidth = win => {
|
228
|
+
return win.innerWidth || win.document.documentElement.clientWidth || win.document.body.clientWidth;
|
229
|
+
};
|
230
|
+
// 默认在浏览器右上角弹出窗口
|
231
|
+
if (!('left' in mergedWindowFeatures)) {
|
232
|
+
const winWidth = getWindowWidth(window.top || window);
|
233
|
+
const winLeft = window.screenLeft || window.screenX;
|
234
|
+
mergedWindowFeatures.left = winWidth + winLeft - mergedWindowFeatures.width;
|
235
|
+
}
|
236
|
+
if (!('top' in mergedWindowFeatures)) {
|
237
|
+
const winTop = window.screenTop || window.screenY;
|
238
|
+
mergedWindowFeatures.top = winTop;
|
239
|
+
}
|
240
|
+
const strWindowFeatures = Object.keys(mergedWindowFeatures).map(key => `${key}=${mergedWindowFeatures[key]}`).join(',');
|
241
|
+
window.open(windowUrl, 'targetWindow', strWindowFeatures);
|
242
|
+
}
|
243
|
+
export const getFontSize = size => {
|
244
|
+
// 12px 及以上的 size 有效, 否则返回 inherit
|
245
|
+
if (size && Number(size) >= 12) {
|
246
|
+
return `${Number(size)}px`;
|
247
|
+
}
|
248
|
+
return 'inherit';
|
249
|
+
};
|
250
|
+
|
251
|
+
// 参考: asset-chain @arcblock/did
|
252
|
+
export const isEthereumDid = did => {
|
253
|
+
const address = did.replace('did:abt:', '');
|
254
|
+
// check if it has the basic requirements of an address
|
255
|
+
if (!/^(0x)?[0-9a-f]{40}$/i.test(address)) {
|
256
|
+
return false;
|
257
|
+
}
|
258
|
+
return true;
|
259
|
+
};
|
260
|
+
|
261
|
+
/**
|
262
|
+
*
|
263
|
+
* @param {string} url 需要处理的 url
|
264
|
+
* @param {{imageFilter: 'crop'|'resize'; w?: number; h?: number; r?: 0|90|180|270}} params
|
265
|
+
* @returns
|
266
|
+
*/
|
267
|
+
export const appendParams = (url, params) => {
|
268
|
+
if (!params) {
|
269
|
+
return url;
|
270
|
+
}
|
271
|
+
try {
|
272
|
+
// HACK: 如果 url 中带有域名,则 urlInstance.origin 为 url 中的域名;否则,借用当前页面的 location.origin 作为域名来拼接一个 url
|
273
|
+
const urlInstance = new URL(url, window.location.origin);
|
274
|
+
Object.keys(params).forEach(key => {
|
275
|
+
urlInstance.searchParams.set(key, params[key]);
|
276
|
+
});
|
277
|
+
// HACK: 如果前后域名一致,代表前面已经借用了 location.origin,这个时候只需要返回 urlInstance.pathname + urlInstance.search 即可
|
278
|
+
if (urlInstance.origin === window.location.origin) {
|
279
|
+
return urlInstance.pathname + urlInstance.search;
|
280
|
+
}
|
281
|
+
return urlInstance.href;
|
282
|
+
} catch {
|
283
|
+
return url;
|
284
|
+
}
|
285
|
+
};
|
286
|
+
export const getUserAvatar = (avatar, size = 48) => {
|
287
|
+
if (!avatar) {
|
288
|
+
return avatar;
|
289
|
+
}
|
290
|
+
if (avatar.indexOf('/.well-known/service') >= 0) {
|
291
|
+
return appendParams(avatar, {
|
292
|
+
imageFilter: 'resize',
|
293
|
+
w: size,
|
294
|
+
h: size
|
295
|
+
});
|
296
|
+
}
|
297
|
+
return avatar;
|
298
|
+
};
|