@arcblock/ux 2.13.12 → 2.13.14
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/ActivityIndicator/index.js +9 -5
- package/lib/Address/did-address.js +14 -7
- package/lib/Address/responsive-did-address.js +3 -1
- package/lib/BlockletV2/blocklet.js +1 -1
- package/lib/CloseButton/index.js +1 -2
- package/lib/Colors/index.d.ts +1 -3
- package/lib/Colors/index.js +2 -4
- package/lib/Colors/themes/default.d.ts +3 -66
- package/lib/Colors/themes/default.js +4 -74
- package/lib/Colors/themes/did-connect.d.ts +11 -6
- package/lib/Colors/themes/did-connect.js +17 -12
- package/lib/Colors/themes/temp.d.ts +3 -0
- package/lib/Colors/themes/temp.js +3 -0
- package/lib/Config/config-provider.d.ts +4 -5
- package/lib/Config/config-provider.js +7 -26
- package/lib/Config/theme-mode-toggle.js +0 -1
- package/lib/DID/index.js +3 -4
- package/lib/DIDConnect/app-icon.d.ts +8 -0
- package/lib/DIDConnect/app-icon.js +31 -0
- package/lib/DIDConnect/app-info-item.d.ts +7 -0
- package/lib/DIDConnect/app-info-item.js +73 -0
- package/lib/DIDConnect/did-connect-footer.d.ts +4 -0
- package/lib/DIDConnect/did-connect-footer.js +54 -0
- package/lib/DIDConnect/did-connect-logo.d.ts +1 -0
- package/lib/DIDConnect/did-connect-logo.js +11 -0
- package/lib/DIDConnect/index.d.ts +7 -0
- package/lib/DIDConnect/index.js +7 -0
- package/lib/DIDConnect/powered-by.d.ts +3 -0
- package/lib/DIDConnect/powered-by.js +46 -0
- package/lib/DIDConnect/with-container.d.ts +11 -0
- package/lib/DIDConnect/with-container.js +273 -0
- package/lib/DIDConnect/with-ux-theme.d.ts +1 -0
- package/lib/DIDConnect/with-ux-theme.js +23 -0
- package/lib/Datatable/CustomToolbar.js +3 -0
- package/lib/Datatable/index.js +105 -71
- package/lib/Dialog/confirm.d.ts +6 -1
- package/lib/Dialog/confirm.js +7 -3
- package/lib/Dialog/use-confirm.js +6 -0
- package/lib/Footer/index.js +2 -5
- package/lib/Header/header.js +3 -1
- package/lib/Header/responsive-header.js +3 -1
- package/lib/Layout/dashboard/index.js +14 -2
- package/lib/Layout/dashboard/sidebar.js +1 -2
- package/lib/LoadingMask/index.js +4 -3
- package/lib/Locale/selector.js +3 -3
- package/lib/Locale/util.d.ts +3 -3
- package/lib/Locale/util.js +6 -1
- package/lib/LoginButton/index.d.ts +12 -0
- package/lib/LoginButton/index.js +74 -0
- package/lib/NavMenu/nav-menu.js +14 -9
- package/lib/NavMenu/products.js +3 -1
- package/lib/NavMenu/style.js +7 -3
- package/lib/NavMenu/sub-item-group.js +1 -1
- package/lib/PhoneInput/country-select.js +2 -3
- package/lib/SessionBlocklet/index.js +3 -3
- package/lib/SessionUser/components/did-space.js +14 -28
- package/lib/SessionUser/components/logged-in.js +2 -2
- package/lib/SessionUser/components/quick-login-item.js +13 -11
- package/lib/SessionUser/components/session-user-item.js +5 -6
- package/lib/SessionUser/components/session-user-switch.js +15 -13
- package/lib/SessionUser/components/un-login.js +51 -38
- package/lib/SessionUser/components/user-info.js +9 -8
- package/lib/SessionUser/images/did-spaces.svg +7 -13
- package/lib/SharedBridge/index.d.ts +16 -0
- package/lib/SharedBridge/index.js +109 -0
- package/lib/SharedBridge/need-storage-access-api-dialog.d.ts +7 -0
- package/lib/SharedBridge/need-storage-access-api-dialog.js +212 -0
- package/lib/Success/index.js +8 -4
- package/lib/Switch/index.js +3 -3
- package/lib/Tabs/index.js +8 -9
- package/lib/Theme/index.d.ts +2 -2
- package/lib/Theme/index.js +1 -1
- package/lib/Theme/theme-provider.d.ts +5 -1
- package/lib/Theme/theme-provider.js +60 -5
- package/lib/Theme/theme.d.ts +6 -3
- package/lib/Theme/theme.js +55 -19
- package/lib/UserCard/Container/card.js +1 -1
- package/lib/UserCard/Container/dialog.js +1 -1
- package/lib/Util/iframe.d.ts +5 -0
- package/lib/Util/iframe.js +24 -0
- package/lib/Util/index.d.ts +18 -1
- package/lib/Util/index.js +90 -5
- package/lib/type.d.ts +5 -1
- package/package.json +8 -6
- package/src/ActivityIndicator/index.jsx +4 -4
- package/src/Address/did-address.tsx +5 -5
- package/src/Address/responsive-did-address.tsx +11 -1
- package/src/BlockletV2/blocklet.tsx +1 -1
- package/src/CloseButton/index.tsx +1 -2
- package/src/Colors/index.ts +2 -7
- package/src/Colors/themes/default.ts +4 -50
- package/src/Colors/themes/did-connect.ts +13 -6
- package/src/Colors/themes/temp.ts +3 -0
- package/src/Config/config-provider.tsx +17 -30
- package/src/Config/theme-mode-toggle.tsx +1 -1
- package/src/DID/index.tsx +3 -4
- package/src/DIDConnect/app-icon.tsx +36 -0
- package/src/DIDConnect/app-info-item.tsx +82 -0
- package/src/DIDConnect/did-connect-footer.tsx +51 -0
- package/src/DIDConnect/did-connect-logo.tsx +8 -0
- package/src/DIDConnect/index.ts +7 -0
- package/src/DIDConnect/powered-by.tsx +48 -0
- package/src/DIDConnect/with-container.tsx +307 -0
- package/src/DIDConnect/with-ux-theme.tsx +22 -0
- package/src/Datatable/CustomToolbar.jsx +1 -0
- package/src/Datatable/index.jsx +107 -70
- package/src/Dialog/confirm.jsx +31 -23
- package/src/Dialog/use-confirm.jsx +6 -0
- package/src/Footer/index.tsx +2 -2
- package/src/Header/header.tsx +1 -1
- package/src/Header/responsive-header.tsx +2 -0
- package/src/Layout/dashboard/index.tsx +8 -4
- package/src/Layout/dashboard/sidebar.tsx +1 -2
- package/src/LoadingMask/index.tsx +3 -4
- package/src/Locale/selector.tsx +3 -4
- package/src/Locale/util.ts +7 -2
- package/src/LoginButton/index.tsx +73 -0
- package/src/NavMenu/nav-menu.tsx +15 -10
- package/src/NavMenu/products.tsx +1 -1
- package/src/NavMenu/style.ts +5 -2
- package/src/NavMenu/sub-item-group.tsx +1 -1
- package/src/PhoneInput/country-select.tsx +2 -3
- package/src/SessionBlocklet/index.tsx +3 -3
- package/src/SessionUser/components/did-space.tsx +14 -10
- package/src/SessionUser/components/logged-in.tsx +2 -2
- package/src/SessionUser/components/quick-login-item.tsx +11 -12
- package/src/SessionUser/components/session-user-item.tsx +3 -6
- package/src/SessionUser/components/session-user-switch.tsx +13 -12
- package/src/SessionUser/components/un-login.tsx +41 -33
- package/src/SessionUser/components/user-info.tsx +7 -8
- package/src/SessionUser/images/did-spaces.svg +7 -13
- package/src/SharedBridge/index.tsx +123 -0
- package/src/SharedBridge/need-storage-access-api-dialog.tsx +171 -0
- package/src/Success/index.tsx +6 -4
- package/src/Switch/index.jsx +3 -3
- package/src/Tabs/index.tsx +8 -9
- package/src/Theme/index.ts +2 -2
- package/src/Theme/theme-provider.tsx +73 -2
- package/src/Theme/theme.ts +73 -22
- package/src/UserCard/Container/card.tsx +1 -1
- package/src/UserCard/Container/dialog.tsx +1 -1
- package/src/Util/iframe.ts +19 -0
- package/src/Util/index.ts +102 -4
- package/src/type.d.ts +5 -1
@@ -1,17 +1,68 @@
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
2
2
|
import PropTypes from 'prop-types';
|
3
|
-
import {
|
3
|
+
import { GlobalStyles } from '@mui/material';
|
4
|
+
import { ThemeProvider as MuiThemeProvider, useTheme } from '@mui/material/styles';
|
4
5
|
import StyledEngineProvider from '@mui/material/StyledEngineProvider';
|
5
6
|
import CssBaseline from '@mui/material/CssBaseline';
|
6
7
|
import { createTheme } from './theme';
|
7
8
|
const defaultTheme = createTheme();
|
9
|
+
function DarkSchemeStyles({
|
10
|
+
className
|
11
|
+
}) {
|
12
|
+
const theme = useTheme();
|
13
|
+
if (theme.palette.mode === 'dark') {
|
14
|
+
const trackColor = 'transparent';
|
15
|
+
const thumbColor = theme.palette.grey[300];
|
16
|
+
|
17
|
+
// 处理作用域选择器
|
18
|
+
const prefix = (className || '').trim().split(/\s+/).filter(Boolean).map(c => c.startsWith('.') ? c : `.${c}`).join(' ');
|
19
|
+
const webkitScrollbar = prefix ? `${prefix}::-webkit-scrollbar, ${prefix} *::-webkit-scrollbar` : '*::-webkit-scrollbar';
|
20
|
+
const webkitTrack = prefix ? `${prefix}::-webkit-scrollbar-track, ${prefix} *::-webkit-scrollbar-track` : '*::-webkit-scrollbar-track';
|
21
|
+
const webkitThumb = prefix ? `${prefix}::-webkit-scrollbar-thumb, ${prefix} *::-webkit-scrollbar-thumb` : '*::-webkit-scrollbar-thumb';
|
22
|
+
const firefoxSelector = prefix ? `${prefix}, ${prefix} *` : '*';
|
23
|
+
return /*#__PURE__*/_jsx(GlobalStyles, {
|
24
|
+
styles: {
|
25
|
+
// Chrome, Safari, Edge
|
26
|
+
'@supports selector(::-webkit-scrollbar)': {
|
27
|
+
[webkitScrollbar]: {
|
28
|
+
width: '12px',
|
29
|
+
height: '12px'
|
30
|
+
},
|
31
|
+
[webkitTrack]: {
|
32
|
+
background: trackColor
|
33
|
+
},
|
34
|
+
[webkitThumb]: {
|
35
|
+
background: thumbColor,
|
36
|
+
borderRadius: '6px',
|
37
|
+
border: '2px solid',
|
38
|
+
borderColor: trackColor,
|
39
|
+
backgroundClip: 'padding-box',
|
40
|
+
'&:hover': {
|
41
|
+
background: theme.palette.grey[400],
|
42
|
+
backgroundClip: 'padding-box'
|
43
|
+
}
|
44
|
+
}
|
45
|
+
},
|
46
|
+
// Firefox
|
47
|
+
'@supports not selector(::-webkit-scrollbar)': {
|
48
|
+
[firefoxSelector]: {
|
49
|
+
scrollbarWidth: 'auto',
|
50
|
+
scrollbarColor: `${thumbColor} ${trackColor}`
|
51
|
+
}
|
52
|
+
}
|
53
|
+
}
|
54
|
+
});
|
55
|
+
}
|
56
|
+
return null;
|
57
|
+
}
|
8
58
|
/**
|
9
59
|
* 默认的 theme provider, 可以为 webapp/blocklet 快捷的配置好 mui theme provider
|
10
60
|
*/
|
11
61
|
export default function ThemeProvider({
|
12
62
|
children,
|
13
63
|
theme,
|
14
|
-
injectFirst
|
64
|
+
injectFirst,
|
65
|
+
darkSchemeClass
|
15
66
|
}) {
|
16
67
|
return (
|
17
68
|
/*#__PURE__*/
|
@@ -20,7 +71,9 @@ export default function ThemeProvider({
|
|
20
71
|
injectFirst: injectFirst,
|
21
72
|
children: /*#__PURE__*/_jsxs(MuiThemeProvider, {
|
22
73
|
theme: theme,
|
23
|
-
children: [/*#__PURE__*/_jsx(CssBaseline, {}),
|
74
|
+
children: [/*#__PURE__*/_jsx(CssBaseline, {}), /*#__PURE__*/_jsx(DarkSchemeStyles, {
|
75
|
+
className: darkSchemeClass
|
76
|
+
}), children]
|
24
77
|
})
|
25
78
|
})
|
26
79
|
);
|
@@ -28,10 +81,12 @@ export default function ThemeProvider({
|
|
28
81
|
ThemeProvider.propTypes = {
|
29
82
|
children: PropTypes.any,
|
30
83
|
theme: PropTypes.any,
|
31
|
-
injectFirst: PropTypes.bool
|
84
|
+
injectFirst: PropTypes.bool,
|
85
|
+
darkSchemeClass: PropTypes.string
|
32
86
|
};
|
33
87
|
ThemeProvider.defaultProps = {
|
34
88
|
children: null,
|
35
89
|
theme: defaultTheme,
|
36
|
-
injectFirst: true
|
90
|
+
injectFirst: true,
|
91
|
+
darkSchemeClass: ''
|
37
92
|
};
|
package/lib/Theme/theme.d.ts
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
import type { PaletteMode } from '@mui/material';
|
1
|
+
import type { PaletteMode, Theme } from '@mui/material';
|
2
2
|
import { type ThemeOptions } from '@mui/material/styles';
|
3
3
|
import { deepmerge } from '@mui/utils';
|
4
4
|
import '@fontsource/roboto/latin-400.css';
|
@@ -11,10 +11,13 @@ export declare function collectFontFamilies(obj?: {
|
|
11
11
|
fontFamily?: string;
|
12
12
|
}, fontSet?: Set<string>): Set<string>;
|
13
13
|
export declare function loadFonts(fonts: string[]): Promise<boolean>;
|
14
|
+
export declare function getDefaultThemePrefer(): PaletteMode;
|
14
15
|
export declare function createDefaultThemeOptions(mode?: PaletteMode): ThemeOptions;
|
15
16
|
export interface UserThemeOptions extends ThemeOptions {
|
16
17
|
disableBlockletTheme?: boolean;
|
17
18
|
}
|
18
|
-
export
|
19
|
-
export declare
|
19
|
+
export type ThemeConfig = Pick<Theme, 'palette'>;
|
20
|
+
export declare function lazyThemeConfig(mode: PaletteMode): () => ThemeConfig;
|
21
|
+
export declare const create: (...args: Array<UserThemeOptions | ((config: ThemeConfig) => UserThemeOptions)>) => Theme;
|
22
|
+
export declare const createTheme: (...args: Array<UserThemeOptions | ((config: ThemeConfig) => UserThemeOptions)>) => Theme;
|
20
23
|
export { deepmerge };
|
package/lib/Theme/theme.js
CHANGED
@@ -3,9 +3,10 @@
|
|
3
3
|
|
4
4
|
import { createTheme as _createTheme, responsiveFontSizes } from '@mui/material/styles';
|
5
5
|
import { deepmerge } from '@mui/utils';
|
6
|
+
import pick from 'lodash/pick';
|
6
7
|
import webfontloader from 'webfontloader';
|
7
|
-
import { BLOCKLET_THEME_LIGHT, BLOCKLET_THEME_DARK, DEFAULT_FONTS } from '@blocklet/theme';
|
8
|
-
import { cleanedObj } from '../Util';
|
8
|
+
import { BLOCKLET_THEME_LIGHT, BLOCKLET_THEME_DARK, DEFAULT_FONTS, BLOCKLET_THEME_PREFER_KEY } from '@blocklet/theme';
|
9
|
+
import { cleanedObj, deepmergeAll } from '../Util';
|
9
10
|
|
10
11
|
// 默认只加载最基本的 roboto latin 字体
|
11
12
|
import '@fontsource/roboto/latin-400.css';
|
@@ -61,6 +62,27 @@ export function loadFonts(fonts) {
|
|
61
62
|
});
|
62
63
|
}
|
63
64
|
|
65
|
+
// 获取默认主题偏好
|
66
|
+
export function getDefaultThemePrefer() {
|
67
|
+
const prefer = window.blocklet?.theme?.prefer;
|
68
|
+
if (prefer === 'system') {
|
69
|
+
// 本地缓存
|
70
|
+
const localPrefer = localStorage.getItem(BLOCKLET_THEME_PREFER_KEY);
|
71
|
+
if (localPrefer && (localPrefer === 'light' || localPrefer === 'dark')) {
|
72
|
+
return localPrefer;
|
73
|
+
}
|
74
|
+
|
75
|
+
// 跟随系统
|
76
|
+
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
|
77
|
+
}
|
78
|
+
if (prefer === 'light' || prefer === 'dark') {
|
79
|
+
return prefer;
|
80
|
+
}
|
81
|
+
|
82
|
+
// 未设置偏好
|
83
|
+
return 'light';
|
84
|
+
}
|
85
|
+
|
64
86
|
// 创建默认主题配置
|
65
87
|
export function createDefaultThemeOptions(mode = 'light') {
|
66
88
|
if (mode === 'dark') {
|
@@ -68,26 +90,35 @@ export function createDefaultThemeOptions(mode = 'light') {
|
|
68
90
|
}
|
69
91
|
return BLOCKLET_THEME_LIGHT;
|
70
92
|
}
|
71
|
-
|
93
|
+
|
94
|
+
// 用于获取 Blocklet Theme 配置,便于用户创建自定义主题
|
95
|
+
|
96
|
+
export function lazyThemeConfig(mode) {
|
97
|
+
const fields = ['palette'];
|
98
|
+
let config = null;
|
99
|
+
return () => {
|
100
|
+
if (config) return config;
|
101
|
+
config = deepmerge(pick(createDefaultThemeOptions(mode), fields), pick(window.blocklet?.theme?.[mode] ?? {}, fields));
|
102
|
+
return config;
|
103
|
+
};
|
104
|
+
}
|
105
|
+
|
106
|
+
// 主要处理 overrides
|
72
107
|
const normalizeUserThemeOptions = ({
|
73
|
-
mode = 'light',
|
74
108
|
palette,
|
75
109
|
components,
|
76
110
|
overrides,
|
77
111
|
...rest
|
78
112
|
}) => {
|
79
|
-
|
80
|
-
|
81
|
-
palette: {
|
82
|
-
...palette,
|
83
|
-
mode
|
84
|
-
},
|
113
|
+
const result = {
|
114
|
+
palette,
|
85
115
|
components: {
|
86
116
|
...overrides,
|
87
117
|
...components
|
88
118
|
},
|
89
119
|
...rest
|
90
120
|
};
|
121
|
+
return result;
|
91
122
|
};
|
92
123
|
const defaultUserThemeOptions = {
|
93
124
|
themeName: 'ArcBlock',
|
@@ -118,20 +149,25 @@ const defaultUserThemeOptions = {
|
|
118
149
|
|
119
150
|
// https://material-ui.com/customization/default-theme/
|
120
151
|
export const create = (...args) => {
|
121
|
-
const
|
152
|
+
const defaultPrefer = getDefaultThemePrefer();
|
153
|
+
const getThemeConfig = lazyThemeConfig(defaultPrefer);
|
154
|
+
const userThemeOptions = args.reduce((acc, curr) => deepmerge(acc, normalizeUserThemeOptions(typeof curr === 'function' ? curr(getThemeConfig()) : curr)), normalizeUserThemeOptions(defaultUserThemeOptions));
|
155
|
+
const prefer = userThemeOptions.mode || userThemeOptions.palette?.mode || defaultPrefer;
|
156
|
+
const blockletThemeOptions = window.blocklet?.theme?.[prefer] ?? {};
|
157
|
+
const defaultThemeOptions = createDefaultThemeOptions(prefer);
|
122
158
|
const {
|
123
|
-
mode,
|
124
159
|
disableBlockletTheme
|
125
160
|
} = userThemeOptions;
|
126
|
-
const blockletThemeOptions = window.blocklet?.theme?.[mode] ?? {};
|
127
|
-
const defaultThemeOptions = createDefaultThemeOptions(mode);
|
128
161
|
|
129
162
|
// 合并配置
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
163
|
+
const mergedThemeOptions = deepmergeAll([defaultThemeOptions, !disableBlockletTheme && cleanedObj(blockletThemeOptions), cleanedObj(userThemeOptions),
|
164
|
+
// 确保 mode 跟 prefer 一致
|
165
|
+
{
|
166
|
+
mode: prefer,
|
167
|
+
palette: {
|
168
|
+
mode: prefer
|
169
|
+
}
|
170
|
+
}].filter(Boolean));
|
135
171
|
|
136
172
|
// 创建主题
|
137
173
|
const theme = _createTheme(mergedThemeOptions);
|
@@ -0,0 +1,24 @@
|
|
1
|
+
export function getCallbackAction(id, action) {
|
2
|
+
return `callback_${action}_${id}`;
|
3
|
+
}
|
4
|
+
|
5
|
+
// eslint-disable-next-line require-await
|
6
|
+
export async function callIframe(iframe, action) {
|
7
|
+
const callbackAction = getCallbackAction(iframe.dataset.id, action);
|
8
|
+
const promise = new Promise(resolve => {
|
9
|
+
const handleMessage = ({
|
10
|
+
data
|
11
|
+
}) => {
|
12
|
+
if (data.action === callbackAction) {
|
13
|
+
window.removeEventListener('message', handleMessage);
|
14
|
+
resolve(data);
|
15
|
+
}
|
16
|
+
};
|
17
|
+
window.addEventListener('message', handleMessage);
|
18
|
+
});
|
19
|
+
iframe?.contentWindow?.postMessage({
|
20
|
+
action,
|
21
|
+
callback: callbackAction
|
22
|
+
}, '*');
|
23
|
+
return promise;
|
24
|
+
}
|
package/lib/Util/index.d.ts
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
import Cookies from 'js-cookie';
|
2
|
+
import { type DeepmergeOptions } from '@mui/utils/deepmerge';
|
1
3
|
import type { $TSFixMe, Locale } from '../type';
|
2
4
|
declare let dateTool: $TSFixMe | null;
|
3
5
|
/** 是否常见二段式顶级域名 */
|
@@ -13,7 +15,7 @@ export declare function getCookieOptions(expireInDays?: number | {
|
|
13
15
|
returnDomain?: boolean;
|
14
16
|
sameSite?: Cookies.CookieAttributes['sameSite'];
|
15
17
|
secure?: boolean;
|
16
|
-
}):
|
18
|
+
}): Cookies.CookieAttributes;
|
17
19
|
export declare const getColor: (props: $TSFixMe) => any;
|
18
20
|
export declare const getBackground: (props: $TSFixMe) => any;
|
19
21
|
/**
|
@@ -75,6 +77,7 @@ export declare const sleep: (time?: number) => Promise<void>;
|
|
75
77
|
export declare const isUrl: (str: string) => boolean;
|
76
78
|
export declare const getVisitorId: () => string | null;
|
77
79
|
export declare const setVisitorId: (value: string | null) => void;
|
80
|
+
export declare const ensureVisitorId: () => void;
|
78
81
|
export declare const getDIDColor: (did: string) => any;
|
79
82
|
type NestedTranslation = {
|
80
83
|
[key: string]: string | NestedTranslation;
|
@@ -92,4 +95,18 @@ export declare const getTranslation: (translations: TranslationsObject, locale:
|
|
92
95
|
}) => string;
|
93
96
|
export declare const lazyRetry: (fn: () => Promise<any>) => import("react").LazyExoticComponent<import("react").ComponentType<any>>;
|
94
97
|
export declare const cleanedObj: (obj: object) => import("lodash").Dictionary<any>;
|
98
|
+
/**
|
99
|
+
* 将十六进制颜色转换为 RGBA
|
100
|
+
* @param hex 十六进制颜色字符串 (例如: "#FF0000" 或 "FF0000")
|
101
|
+
* @param alpha 透明度值 (0-1 之间,默认为 1)
|
102
|
+
* @returns RGBA 颜色字符串 (例如: "rgba(255, 0, 0, 1)")
|
103
|
+
*/
|
104
|
+
export declare function hexToRgba(hex: string, alpha?: number): string;
|
105
|
+
/**
|
106
|
+
* 依次对数组中的对象进行深度合并
|
107
|
+
* @param objects - 需要合并的对象数组
|
108
|
+
* @param options - deepmerge 的配置选项
|
109
|
+
* @returns 合并后的对象
|
110
|
+
*/
|
111
|
+
export declare function deepmergeAll<T>(objects: T[], options?: DeepmergeOptions): T;
|
95
112
|
export {};
|
package/lib/Util/index.js
CHANGED
@@ -5,7 +5,11 @@ import { getDIDMotifInfo, colors } from '@arcblock/did-motif';
|
|
5
5
|
import isNil from 'lodash/isNil';
|
6
6
|
import omitBy from 'lodash/omitBy';
|
7
7
|
import pRetry from 'p-retry';
|
8
|
+
import Cookies from 'js-cookie';
|
9
|
+
import colorConvert from 'color-convert';
|
10
|
+
import deepmerge from '@mui/utils/deepmerge';
|
8
11
|
import { DID_PREFIX, BLOCKLET_SERVICE_PATH_PREFIX } from './constant';
|
12
|
+
import { getFederatedEnabled } from './federated';
|
9
13
|
let dateTool = null;
|
10
14
|
const IP_V4_REGEX = /^(\d{1,3}\.){3}\d{1,3}(:\d+)?$/;
|
11
15
|
// 常见顶级域名
|
@@ -359,15 +363,63 @@ export const sleep = (time = 0) => {
|
|
359
363
|
export const isUrl = str => {
|
360
364
|
return /^https?:\/\//.test(str);
|
361
365
|
};
|
362
|
-
const visitorIdKey = '
|
366
|
+
const visitorIdKey = 'vid';
|
367
|
+
const visitorIdKeyLegacy = '__visitor_id';
|
363
368
|
export const getVisitorId = () => {
|
364
|
-
|
369
|
+
// FIXME: @zhanghan 短期内做一个兼容,确保在 migrate 前的请求能够携带正确的 vid
|
370
|
+
return Cookies.get(visitorIdKey) || localStorage.getItem(visitorIdKeyLegacy);
|
365
371
|
};
|
366
372
|
export const setVisitorId = value => {
|
367
373
|
if (value === null) {
|
368
|
-
|
374
|
+
Cookies.remove(visitorIdKey, {
|
375
|
+
sameSite: 'None',
|
376
|
+
secure: true
|
377
|
+
});
|
369
378
|
} else {
|
370
|
-
|
379
|
+
Cookies.set(visitorIdKey, value, {
|
380
|
+
sameSite: 'None',
|
381
|
+
secure: true,
|
382
|
+
expires: 365
|
383
|
+
});
|
384
|
+
}
|
385
|
+
};
|
386
|
+
export const ensureVisitorId = () => {
|
387
|
+
let visitorId = localStorage.getItem(visitorIdKeyLegacy);
|
388
|
+
if (visitorId) {
|
389
|
+
localStorage.removeItem(visitorIdKeyLegacy);
|
390
|
+
setVisitorId(visitorId);
|
391
|
+
}
|
392
|
+
if (getVisitorId()) {
|
393
|
+
return;
|
394
|
+
}
|
395
|
+
if (!getFederatedEnabled()) {
|
396
|
+
try {
|
397
|
+
// 在支持 crypto.randomUUID 的环境中使用
|
398
|
+
if (window.crypto && typeof window.crypto.randomUUID === 'function') {
|
399
|
+
visitorId = window.crypto.randomUUID();
|
400
|
+
} else {
|
401
|
+
// 在不支持 crypto.randomUUID 的环境中生成随机 ID
|
402
|
+
const randomValues = new Uint8Array(16);
|
403
|
+
if (window.crypto && typeof window.crypto.getRandomValues === 'function') {
|
404
|
+
window.crypto.getRandomValues(randomValues);
|
405
|
+
} else {
|
406
|
+
// 降级方案:使用 Math.random 生成
|
407
|
+
for (let i = 0; i < 16; i++) {
|
408
|
+
randomValues[i] = Math.floor(Math.random() * 256);
|
409
|
+
}
|
410
|
+
}
|
411
|
+
|
412
|
+
// 转换为 UUID 格式
|
413
|
+
const hexArray = Array.from(randomValues).map(b => b.toString(16).padStart(2, '0'));
|
414
|
+
visitorId = [hexArray.slice(0, 4).join(''), hexArray.slice(4, 6).join(''), hexArray.slice(6, 8).join(''), hexArray.slice(8, 10).join(''), hexArray.slice(10, 16).join('')].join('-');
|
415
|
+
}
|
416
|
+
} catch (error) {
|
417
|
+
// 如果上述方法都失败,使用时间戳和随机数生成
|
418
|
+
visitorId = `${Date.now()}-${Math.random().toString(36).substring(2, 15)}`;
|
419
|
+
}
|
420
|
+
}
|
421
|
+
if (visitorId) {
|
422
|
+
setVisitorId(visitorId);
|
371
423
|
}
|
372
424
|
};
|
373
425
|
export const getDIDColor = did => {
|
@@ -426,4 +478,37 @@ export const lazyRetry = fn => /*#__PURE__*/lazy(() => pRetry(async () => {
|
|
426
478
|
}));
|
427
479
|
export const cleanedObj = obj => {
|
428
480
|
return omitBy(obj, isNil);
|
429
|
-
};
|
481
|
+
};
|
482
|
+
|
483
|
+
/**
|
484
|
+
* 将十六进制颜色转换为 RGBA
|
485
|
+
* @param hex 十六进制颜色字符串 (例如: "#FF0000" 或 "FF0000")
|
486
|
+
* @param alpha 透明度值 (0-1 之间,默认为 1)
|
487
|
+
* @returns RGBA 颜色字符串 (例如: "rgba(255, 0, 0, 1)")
|
488
|
+
*/
|
489
|
+
export function hexToRgba(hex, alpha = 1) {
|
490
|
+
const [r, g, b] = colorConvert.hex.rgb(hex);
|
491
|
+
// 返回 RGBA 格式
|
492
|
+
return `rgba(${r}, ${g}, ${b}, ${alpha})`;
|
493
|
+
}
|
494
|
+
|
495
|
+
/**
|
496
|
+
* 依次对数组中的对象进行深度合并
|
497
|
+
* @param objects - 需要合并的对象数组
|
498
|
+
* @param options - deepmerge 的配置选项
|
499
|
+
* @returns 合并后的对象
|
500
|
+
*/
|
501
|
+
export function deepmergeAll(objects, options) {
|
502
|
+
if (!Array.isArray(objects)) {
|
503
|
+
throw new Error('First argument should be an array');
|
504
|
+
}
|
505
|
+
if (objects.length === 0) {
|
506
|
+
return {};
|
507
|
+
}
|
508
|
+
if (objects.length === 1) {
|
509
|
+
return objects[0];
|
510
|
+
}
|
511
|
+
return objects.reduce((acc, obj) => {
|
512
|
+
return deepmerge(acc, obj, options);
|
513
|
+
});
|
514
|
+
}
|
package/lib/type.d.ts
CHANGED
@@ -25,7 +25,11 @@ export type Blocklet = {
|
|
25
25
|
version: string;
|
26
26
|
mode: string;
|
27
27
|
tenantMode: 'single' | 'multiple';
|
28
|
-
theme:
|
28
|
+
theme: {
|
29
|
+
prefer?: PaletteMode | 'system';
|
30
|
+
light: Theme;
|
31
|
+
dark: Theme;
|
32
|
+
};
|
29
33
|
navigation: $TSFixMe[];
|
30
34
|
preferences: Record<string, any>;
|
31
35
|
languages: {
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@arcblock/ux",
|
3
|
-
"version": "2.13.
|
3
|
+
"version": "2.13.14",
|
4
4
|
"description": "Common used react components for arcblock products",
|
5
5
|
"keywords": [
|
6
6
|
"react",
|
@@ -40,6 +40,7 @@
|
|
40
40
|
"@babel/cli": "^7.19.3",
|
41
41
|
"@babel/core": "^7.19.3",
|
42
42
|
"@babel/plugin-proposal-class-properties": "^7.18.6",
|
43
|
+
"@babel/plugin-transform-typescript": "^7.24.7",
|
43
44
|
"@babel/preset-env": "^7.19.3",
|
44
45
|
"@babel/preset-react": "^7.18.6",
|
45
46
|
"@babel/preset-typescript": "^7.24.7",
|
@@ -70,14 +71,14 @@
|
|
70
71
|
"react": ">=18.2.0",
|
71
72
|
"react-router-dom": ">=6.22.3"
|
72
73
|
},
|
73
|
-
"gitHead": "
|
74
|
+
"gitHead": "b9f48199169b641a2d3277806501471a56dd496d",
|
74
75
|
"dependencies": {
|
75
76
|
"@arcblock/did-motif": "^1.1.13",
|
76
|
-
"@arcblock/icons": "^2.13.
|
77
|
-
"@arcblock/nft-display": "^2.13.
|
78
|
-
"@arcblock/react-hooks": "^2.13.
|
77
|
+
"@arcblock/icons": "^2.13.14",
|
78
|
+
"@arcblock/nft-display": "^2.13.14",
|
79
|
+
"@arcblock/react-hooks": "^2.13.14",
|
79
80
|
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
|
80
|
-
"@blocklet/theme": "^2.13.
|
81
|
+
"@blocklet/theme": "^2.13.14",
|
81
82
|
"@fontsource/roboto": "~5.1.1",
|
82
83
|
"@fontsource/ubuntu-mono": "^5.0.18",
|
83
84
|
"@iconify-icons/logos": "^1.2.36",
|
@@ -93,6 +94,7 @@
|
|
93
94
|
"awesome-phonenumber": "^7.4.0",
|
94
95
|
"axios": "^1.7.5",
|
95
96
|
"base64-url": "^2.3.3",
|
97
|
+
"color-convert": "^3.0.1",
|
96
98
|
"copy-to-clipboard": "^3.3.2",
|
97
99
|
"core-js": "^3.25.5",
|
98
100
|
"d3-geo": "^1.12.1",
|
@@ -3,8 +3,7 @@ import PropTypes from 'prop-types';
|
|
3
3
|
import { green, blue } from '@mui/material/colors';
|
4
4
|
|
5
5
|
import Logo from '../Logo';
|
6
|
-
import
|
7
|
-
import { styled } from '../Theme';
|
6
|
+
import { styled, useTheme } from '../Theme';
|
8
7
|
|
9
8
|
/**
|
10
9
|
* ActivityIndicator is used when we want to tell the user the request they made on the UI will take time.
|
@@ -21,6 +20,7 @@ import { styled } from '../Theme';
|
|
21
20
|
*/
|
22
21
|
export default function ActivityIndicator({ messages, interval, ...rest }) {
|
23
22
|
const [index, setIndex] = useState(0);
|
23
|
+
const { palette } = useTheme();
|
24
24
|
|
25
25
|
useEffect(() => {
|
26
26
|
const timer = setInterval(() => {
|
@@ -42,7 +42,7 @@ export default function ActivityIndicator({ messages, interval, ...rest }) {
|
|
42
42
|
<Logo style={{ transform: 'scale(0.6)' }} showText={false} />
|
43
43
|
<Orbit size={56} orbitColor={green[500]} atomColor={green[500]} duration={1} />
|
44
44
|
<Orbit size={80} orbitColor={blue[800]} atomColor={blue[800]} duration={1.5} />
|
45
|
-
<Orbit size={100} orbitColor={
|
45
|
+
<Orbit size={100} orbitColor={palette.grey[900]} atomColor={palette.grey[900]} />
|
46
46
|
</div>
|
47
47
|
</div>
|
48
48
|
</Div>
|
@@ -75,7 +75,7 @@ const Div = styled('div')`
|
|
75
75
|
}
|
76
76
|
|
77
77
|
.pm-loader-text {
|
78
|
-
color: ${
|
78
|
+
color: ${({ theme }) => theme.palette.grey[900]};
|
79
79
|
font-size: 14px;
|
80
80
|
text-align: center;
|
81
81
|
position: relative;
|
@@ -116,7 +116,7 @@ const DidAddress = forwardRef<HTMLDidAddressElement, IDidAddressProps>((props, r
|
|
116
116
|
<span className="did-address-copy-wrapper" title={copied ? '' : translations[locale].copy}>
|
117
117
|
{copied ? (
|
118
118
|
<Tooltip title={translations[locale].copied} placement="bottom" arrow open={copied}>
|
119
|
-
<CheckIcon className="did-address-copy"
|
119
|
+
<CheckIcon className="did-address-copy" sx={{ color: 'success.main' }} />
|
120
120
|
</Tooltip>
|
121
121
|
) : (
|
122
122
|
/* title prop 直接加在 icon 上不生效 */
|
@@ -184,7 +184,7 @@ const Root = styled<any>(Box, { shouldForwardProp: (prop) => prop !== 'inline' }
|
|
184
184
|
}
|
185
185
|
|
186
186
|
.did-address-text {
|
187
|
-
color:
|
187
|
+
color: ${({ theme }) => theme.palette.text.secondary};
|
188
188
|
}
|
189
189
|
/* truncate string with ellipsis */
|
190
190
|
.did-address-truncate {
|
@@ -204,16 +204,16 @@ const Root = styled<any>(Box, { shouldForwardProp: (prop) => prop !== 'inline' }
|
|
204
204
|
.did-address-copy {
|
205
205
|
flex: 0 0 auto;
|
206
206
|
font-size: 1em;
|
207
|
-
color:
|
207
|
+
color: ${({ theme }) => theme.palette.text.secondary};
|
208
208
|
cursor: pointer;
|
209
209
|
}
|
210
210
|
|
211
211
|
/* link */
|
212
212
|
a {
|
213
|
-
color:
|
213
|
+
color: ${({ theme }) => theme.palette.text.secondary};
|
214
214
|
}
|
215
215
|
&:hover a {
|
216
|
-
color:
|
216
|
+
color: ${({ theme }) => theme.palette.text.primary};
|
217
217
|
text-decoration: underline;
|
218
218
|
}
|
219
219
|
`;
|
@@ -80,7 +80,17 @@ const ResponsiveDidAddress = forwardRef<HTMLDidAddressElement, IResponsiveDidAdd
|
|
80
80
|
}, [containerWidth, addressFullWidth]);
|
81
81
|
|
82
82
|
return (
|
83
|
-
<Root
|
83
|
+
<Root
|
84
|
+
as={component}
|
85
|
+
ref={containerRef}
|
86
|
+
style={style}
|
87
|
+
className={className}
|
88
|
+
size={size}
|
89
|
+
{...(component === 'span'
|
90
|
+
? {}
|
91
|
+
: {
|
92
|
+
inline: rest.inline,
|
93
|
+
})}>
|
84
94
|
<StyledDidAddress
|
85
95
|
style={{
|
86
96
|
position: loading ? 'absolute' : 'static',
|
@@ -105,7 +105,7 @@ export default function BlockletStore(props: IBlockletStore) {
|
|
105
105
|
variant="outlined"
|
106
106
|
onClick={handleMainClick}
|
107
107
|
{...rest}
|
108
|
-
sx={{ p: { xs: 2, md: 3 }, borderRadius:
|
108
|
+
sx={{ p: { xs: 2, md: 3 }, borderRadius: 1, ...rest.sx }}>
|
109
109
|
<Stack flex={1} direction="row" gap={1} alignItems="center" overflow="hidden" sx={{ '& > *': { flexShrink: 0 } }}>
|
110
110
|
<Avatar src={cover} did={did} size={48} variant="rounded" style={{ borderRadius: '8px', overflow: 'hidden' }} />
|
111
111
|
<Typography
|
@@ -4,7 +4,6 @@ import { Icon } from '@iconify/react';
|
|
4
4
|
import CloseRoundedIcon from '@iconify-icons/material-symbols/close-rounded';
|
5
5
|
import noop from 'lodash/noop';
|
6
6
|
|
7
|
-
import { temp as colors } from '../Colors';
|
8
7
|
import { mergeSx } from '../Util/style';
|
9
8
|
|
10
9
|
export default function CloseButton({
|
@@ -23,7 +22,7 @@ export default function CloseButton({
|
|
23
22
|
{
|
24
23
|
fontSize: 0,
|
25
24
|
cursor: 'pointer',
|
26
|
-
color:
|
25
|
+
color: 'text.secondary',
|
27
26
|
transition: 'transform 0.25s ease-in-out 0s',
|
28
27
|
transformOrigin: 'center',
|
29
28
|
'&:hover': {
|
package/src/Colors/index.ts
CHANGED
@@ -1,9 +1,4 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
// @compatibility
|
5
|
-
const colors = BLOCKLET_THEME_LIGHT.palette as Theme['palette'];
|
6
|
-
|
7
|
-
export default colors;
|
1
|
+
// eslint-disable-next-line no-restricted-exports
|
2
|
+
export { default } from './themes/default';
|
8
3
|
export { default as temp } from './themes/temp';
|
9
4
|
export { default as didConnectColors } from './themes/did-connect';
|