@arcblock/ux 3.0.15 → 3.0.16

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.
@@ -1,49 +1,51 @@
1
- import { jsx as i, jsxs as R } from "react/jsx-runtime";
2
- import { createContext as _, use as B, useState as L, useRef as j, useMemo as h, useCallback as C, useEffect as k } from "react";
3
- import { useTheme as y, StyledEngineProvider as D, ThemeProvider as K, CssBaseline as U, GlobalStyles as V } from "@mui/material";
4
- import v from "lodash/set";
5
- import { BLOCKLET_THEME_PREFER_KEY as b, isValidThemeMode as W, getDefaultThemePrefer as w } from "@blocklet/theme";
1
+ import { jsx as m, jsxs as j } from "react/jsx-runtime";
2
+ import { createContext as F, use as G, useState as E, useRef as H, useMemo as f, useCallback as x, useEffect as h } from "react";
3
+ import { useTheme as M, StyledEngineProvider as I, ThemeProvider as N, CssBaseline as O, GlobalStyles as U } from "@mui/material";
4
+ import { deepmerge as A } from "@mui/utils";
5
+ import y from "lodash/set";
6
+ import { useDebounceFn as K } from "ahooks";
7
+ import { getBlockletThemeOptions as V, BLOCKLET_THEME_PREFER_KEY as b, isValidThemeMode as W, getDefaultThemePrefer as $ } from "@blocklet/theme";
6
8
  import { useLocationState as q } from "../hooks/use-location-state.js";
7
- import { createTheme as g, lazyCreateDefaultTheme as z, isUxTheme as A, isTheme as F } from "./theme.js";
8
- const G = g(), $ = _({});
9
- function H() {
10
- return B($);
9
+ import { createTheme as T, lazyCreateDefaultTheme as z, isUxTheme as Y, isTheme as J } from "./theme.js";
10
+ const Q = T(), P = F({});
11
+ function X() {
12
+ return G(P);
11
13
  }
12
- const x = (l) => l ? l === "system" ? w({ theme: { prefer: "system" } }) : l : w();
13
- function I({ className: l = void 0 }) {
14
- const e = y();
15
- if (e.palette.mode === "dark") {
16
- const s = "transparent", n = e.palette.grey[300], o = (l || "").trim().split(/\s+/).filter(Boolean).map((c) => c.startsWith(".") ? c : `.${c}`).join(" "), r = o ? `${o}::-webkit-scrollbar, ${o} *::-webkit-scrollbar` : "*::-webkit-scrollbar", a = o ? `${o}::-webkit-scrollbar-track, ${o} *::-webkit-scrollbar-track` : "*::-webkit-scrollbar-track", m = o ? `${o}::-webkit-scrollbar-thumb, ${o} *::-webkit-scrollbar-thumb` : "*::-webkit-scrollbar-thumb", d = o ? `${o}, ${o} *` : "*";
17
- return /* @__PURE__ */ i(
18
- V,
14
+ const B = (l) => l ? l === "system" ? $({ theme: { prefer: "system" } }) : l : $();
15
+ function Z({ className: l = void 0 }) {
16
+ const t = M();
17
+ if (t.palette.mode === "dark") {
18
+ const r = "transparent", a = t.palette.grey[300], o = (l || "").trim().split(/\s+/).filter(Boolean).map((u) => u.startsWith(".") ? u : `.${u}`).join(" "), s = o ? `${o}::-webkit-scrollbar, ${o} *::-webkit-scrollbar` : "*::-webkit-scrollbar", i = o ? `${o}::-webkit-scrollbar-track, ${o} *::-webkit-scrollbar-track` : "*::-webkit-scrollbar-track", c = o ? `${o}::-webkit-scrollbar-thumb, ${o} *::-webkit-scrollbar-thumb` : "*::-webkit-scrollbar-thumb", g = o ? `${o}, ${o} *` : "*";
19
+ return /* @__PURE__ */ m(
20
+ U,
19
21
  {
20
22
  styles: {
21
23
  // Chrome, Safari, Edge
22
24
  "@supports selector(::-webkit-scrollbar)": {
23
- [r]: {
25
+ [s]: {
24
26
  width: "12px",
25
27
  height: "12px"
26
28
  },
27
- [a]: {
28
- background: s
29
+ [i]: {
30
+ background: r
29
31
  },
30
- [m]: {
31
- background: n,
32
+ [c]: {
33
+ background: a,
32
34
  borderRadius: "6px",
33
35
  border: "2px solid",
34
- borderColor: s,
36
+ borderColor: r,
35
37
  backgroundClip: "padding-box",
36
38
  "&:hover": {
37
- background: e.palette.grey[400],
39
+ background: t.palette.grey[400],
38
40
  backgroundClip: "padding-box"
39
41
  }
40
42
  }
41
43
  },
42
44
  // Firefox
43
45
  "@supports not selector(::-webkit-scrollbar)": {
44
- [d]: {
46
+ [g]: {
45
47
  scrollbarWidth: "auto",
46
- scrollbarColor: `${n} ${s}`
48
+ scrollbarColor: `${a} ${r}`
47
49
  }
48
50
  }
49
51
  }
@@ -52,83 +54,97 @@ function I({ className: l = void 0 }) {
52
54
  }
53
55
  return null;
54
56
  }
55
- function E({
57
+ function _({
56
58
  children: l = null,
57
- theme: e = G,
58
- injectFirst: s = !0,
59
- darkSchemeClass: n = ""
59
+ theme: t = Q,
60
+ injectFirst: r = !0,
61
+ darkSchemeClass: a = ""
60
62
  }) {
61
- const o = h(() => typeof e == "function" || F(e) ? e : g(e), [e]);
63
+ const o = f(() => typeof t == "function" || J(t) ? t : T(t), [t]);
62
64
  return (
63
65
  // injectFirst 会影响 makeStyles 自定义样式和 mui styles 覆盖问题
64
- /* @__PURE__ */ i(D, { injectFirst: s, children: /* @__PURE__ */ R(K, { theme: o, children: [
65
- /* @__PURE__ */ i(U, {}),
66
- /* @__PURE__ */ i(I, { className: n }),
66
+ /* @__PURE__ */ m(I, { injectFirst: r, children: /* @__PURE__ */ j(N, { theme: o, children: [
67
+ /* @__PURE__ */ m(O, {}),
68
+ /* @__PURE__ */ m(Z, { className: a }),
67
69
  l
68
70
  ] }) })
69
71
  );
70
72
  }
71
- function N({
73
+ function ee({
72
74
  children: l = null,
73
- theme: e = void 0,
74
- prefer: s = void 0,
75
- disableBlockletTheme: n = !1,
75
+ theme: t = void 0,
76
+ prefer: r = void 0,
77
+ disableBlockletTheme: a = !1,
76
78
  ...o
77
79
  }) {
78
- const [r, a] = L(() => x(s)), m = y(), d = q(), c = j(null), p = h(() => {
79
- let t = {};
80
- const u = z(r);
81
- if (e)
82
- if (typeof e == "function") {
83
- const M = u();
84
- A(m) ? t = { ...e(m, { mode: r }) } : t = { ...e(M, { mode: r }) };
80
+ const [s, i] = E(() => B(r)), [c, g] = E(null), u = M(), k = q(), d = H(null), { run: w } = K(
81
+ (e) => {
82
+ g(e);
83
+ },
84
+ {
85
+ wait: 200
86
+ }
87
+ ), C = f(() => {
88
+ let e = {};
89
+ if (t) {
90
+ const R = z(s);
91
+ if (typeof t == "function") {
92
+ const D = R();
93
+ Y(u) ? e = { ...t(u, { mode: s }) } : e = { ...t(D, { mode: s }) };
85
94
  } else
86
- t = { ...e };
87
- return v(t, "palette.mode", r), v(t, "mode", r), t;
88
- }, [r, e, m]), f = h(() => g({ ...p, disableBlockletTheme: n }), [p, n]), T = C(() => {
89
- const t = r === "light" ? "dark" : "light";
90
- a(t), sessionStorage.removeItem(b), localStorage.setItem(b, t);
91
- }, [r, a]), S = C(
92
- (t) => {
93
- r !== t && (a(t), sessionStorage.removeItem(b), localStorage.setItem(b, t));
95
+ e = { ...t };
96
+ }
97
+ let n = s;
98
+ return c && (n = c.mode || "light", e = A(e, V(n, c))), y(e, "palette.mode", n), y(e, "mode", n), e;
99
+ }, [s, t, u, c]), p = f(() => T({ ...C, disableBlockletTheme: !!c || a }), [C, a, c]), S = x(() => {
100
+ const e = s === "light" ? "dark" : "light";
101
+ i(e), sessionStorage.removeItem(b), localStorage.setItem(b, e);
102
+ }, [s, i]), v = x(
103
+ (e) => {
104
+ s !== e && (i(e), sessionStorage.removeItem(b), localStorage.setItem(b, e));
94
105
  },
95
- [r, a]
96
- ), P = h(
106
+ [s, i]
107
+ ), L = f(
97
108
  () => ({
98
- mode: r,
99
- toggleMode: T,
100
- changeMode: S,
101
- prefer: s
109
+ mode: s,
110
+ toggleMode: S,
111
+ changeMode: v,
112
+ prefer: r
102
113
  }),
103
- [r, s, T, S]
114
+ [s, r, S, v]
104
115
  );
105
- return k(() => {
106
- a(x(s));
107
- }, [s, a, d.search]), k(() => {
108
- const t = new URLSearchParams(d.search).get("theme");
109
- W(t) && sessionStorage.setItem(b, t);
110
- }, [d.search]), k(() => {
111
- c.current || (c.current = document.querySelector('meta[name="theme-color"]'));
112
- const t = f.palette.background.default;
113
- if (c.current)
114
- c.current.setAttribute("content", t);
116
+ return h(() => {
117
+ i(B(r));
118
+ }, [r, i, k.search]), h(() => {
119
+ const e = new URLSearchParams(k.search).get("theme");
120
+ W(e) && sessionStorage.setItem(b, e);
121
+ }, [k.search]), h(() => {
122
+ d.current || (d.current = document.querySelector('meta[name="theme-color"]'));
123
+ const e = p.palette.background.default;
124
+ if (d.current)
125
+ d.current.setAttribute("content", e);
115
126
  else {
116
- const u = document.createElement("meta");
117
- u.name = "theme-color", u.content = t, document.head.appendChild(u), c.current = u;
127
+ const n = document.createElement("meta");
128
+ n.name = "theme-color", n.content = e, document.head.appendChild(n), d.current = n;
118
129
  }
119
- }, [f.palette.background.default]), /* @__PURE__ */ i($, { value: P, children: /* @__PURE__ */ i(E, { theme: f, ...o, children: l }) });
130
+ }, [p.palette.background.default]), h(() => {
131
+ const e = (n) => {
132
+ n.origin === window.origin && n.data.type === "THEME_BUILDER_CONFIG_CHANGED" && w(n.data.payload);
133
+ };
134
+ return window.addEventListener("message", e), () => window.removeEventListener("message", e);
135
+ }, [w]), /* @__PURE__ */ m(P, { value: L, children: /* @__PURE__ */ m(_, { theme: p, ...o, children: l }) });
120
136
  }
121
- function te({
137
+ function me({
122
138
  children: l = null,
123
- prefer: e = void 0,
124
- enableColorScheme: s = !1,
125
- ...n
139
+ prefer: t = void 0,
140
+ enableColorScheme: r = !1,
141
+ ...a
126
142
  }) {
127
- const { toggleMode: o } = H();
128
- return s || e || !o ? /* @__PURE__ */ i(N, { prefer: e, ...n, children: l }) : /* @__PURE__ */ i(E, { ...n, children: l });
143
+ const { toggleMode: o } = X();
144
+ return r || t || !o ? /* @__PURE__ */ m(ee, { prefer: t, ...a, children: l }) : /* @__PURE__ */ m(_, { ...a, children: l });
129
145
  }
130
146
  export {
131
- $ as ColorSchemeContext,
132
- te as default,
133
- H as useColorScheme
147
+ P as ColorSchemeContext,
148
+ me as default,
149
+ X as useColorScheme
134
150
  };
@@ -60,7 +60,6 @@ const m = ({ palette: e, components: t, overrides: o, ...r }) => ({
60
60
  },
61
61
  ...r
62
62
  }), v = {
63
- // @ts-expect-error
64
63
  themeName: "ArcBlock",
65
64
  pageWidth: "md",
66
65
  disableBlockletTheme: !1,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arcblock/ux",
3
- "version": "3.0.15",
3
+ "version": "3.0.16",
4
4
  "description": "Common used react components for arcblock products",
5
5
  "keywords": [
6
6
  "react",
@@ -60,16 +60,16 @@
60
60
  "react": "^19.0.0",
61
61
  "react-router-dom": "^6.22.3"
62
62
  },
63
- "gitHead": "56670fd3ff4223fcdaaf1b38eb2e993217344328",
63
+ "gitHead": "b7aaaae0a729d3f600eef2a7c7d479182e15fd4d",
64
64
  "dependencies": {
65
- "@arcblock/bridge": "3.0.15",
65
+ "@arcblock/bridge": "3.0.16",
66
66
  "@arcblock/did": "^1.20.15",
67
67
  "@arcblock/did-motif": "^1.1.14",
68
- "@arcblock/icons": "3.0.15",
69
- "@arcblock/nft-display": "3.0.15",
70
- "@arcblock/react-hooks": "3.0.15",
68
+ "@arcblock/icons": "3.0.16",
69
+ "@arcblock/nft-display": "3.0.16",
70
+ "@arcblock/react-hooks": "3.0.16",
71
71
  "@blocklet/js-sdk": "^1.16.45",
72
- "@blocklet/theme": "3.0.15",
72
+ "@blocklet/theme": "3.0.16",
73
73
  "@fontsource/roboto": "~5.1.1",
74
74
  "@fontsource/ubuntu-mono": "^5.2.6",
75
75
  "@iconify-icons/logos": "^1.2.36",
@@ -9,8 +9,16 @@ import {
9
9
  useTheme,
10
10
  CssBaseline,
11
11
  } from '@mui/material';
12
+ import { deepmerge } from '@mui/utils';
12
13
  import set from 'lodash/set';
13
- import { BLOCKLET_THEME_PREFER_KEY, getDefaultThemePrefer, isValidThemeMode } from '@blocklet/theme';
14
+ import { useDebounceFn } from 'ahooks';
15
+ import {
16
+ BLOCKLET_THEME_PREFER_KEY,
17
+ getDefaultThemePrefer,
18
+ isValidThemeMode,
19
+ getBlockletThemeOptions,
20
+ type BlockletThemeMeta,
21
+ } from '@blocklet/theme';
14
22
 
15
23
  import { useLocationState } from '../hooks/use-location-state';
16
24
  import { createTheme, isTheme, isUxTheme, lazyCreateDefaultTheme, type UxThemeOptions } from './theme';
@@ -164,15 +172,27 @@ function ColorSchemeProvider({
164
172
  ...rest
165
173
  }: ThemeProviderProps) {
166
174
  const [mode, setMode] = useState<PaletteMode>(() => resolveMode(prefer));
175
+ const [themeBuilderConfig, setThemeBuilderConfig] = useState<BlockletThemeMeta | null>(null);
167
176
  const parentTheme = useTheme();
168
177
  const location = useLocationState();
169
178
  const metaThemeColorRef = useRef<HTMLMetaElement | null>(null);
170
179
 
180
+ // 使用防抖函数包装 setThemeBuilderConfig,避免过于频繁的主题修改
181
+ const { run: debouncedSetThemeBuilderConfig } = useDebounceFn(
182
+ (config: BlockletThemeMeta | null) => {
183
+ setThemeBuilderConfig(config);
184
+ },
185
+ {
186
+ wait: 200,
187
+ }
188
+ );
189
+
171
190
  const _themeInput = useMemo(() => {
172
191
  let result: UxThemeOptions = {};
173
- const createBaseTheme = lazyCreateDefaultTheme(mode);
174
192
 
175
193
  if (themeInput) {
194
+ const createBaseTheme = lazyCreateDefaultTheme(mode);
195
+
176
196
  if (typeof themeInput === 'function') {
177
197
  const baseTheme = createBaseTheme();
178
198
 
@@ -186,15 +206,22 @@ function ColorSchemeProvider({
186
206
  }
187
207
  }
188
208
 
189
- set(result, 'palette.mode', mode);
190
- set(result, 'mode', mode);
209
+ // 接受 ThemeBuilder 配置
210
+ let _mode = mode;
211
+ if (themeBuilderConfig) {
212
+ _mode = themeBuilderConfig.mode || 'light';
213
+ result = deepmerge(result, getBlockletThemeOptions(_mode, themeBuilderConfig));
214
+ }
215
+
216
+ set(result, 'palette.mode', _mode);
217
+ set(result, 'mode', _mode);
191
218
 
192
219
  return result;
193
- }, [mode, themeInput, parentTheme]);
220
+ }, [mode, themeInput, parentTheme, themeBuilderConfig]);
194
221
 
195
222
  const theme = useMemo(() => {
196
- return createTheme({ ..._themeInput, disableBlockletTheme });
197
- }, [_themeInput, disableBlockletTheme]);
223
+ return createTheme({ ..._themeInput, disableBlockletTheme: !!themeBuilderConfig || disableBlockletTheme });
224
+ }, [_themeInput, disableBlockletTheme, themeBuilderConfig]);
198
225
 
199
226
  // 切换明/暗模式
200
227
  const toggleMode = useCallback(() => {
@@ -258,6 +285,22 @@ function ColorSchemeProvider({
258
285
  }
259
286
  }, [theme.palette.background.default]);
260
287
 
288
+ // 监听来自 ThemeBuilder 的消息,支持 Blocklet 实时预览
289
+ useEffect(() => {
290
+ const handleMessage = (event: MessageEvent) => {
291
+ // 必须同源
292
+ if (event.origin !== window.origin) return;
293
+
294
+ if (event.data.type === 'THEME_BUILDER_CONFIG_CHANGED') {
295
+ debouncedSetThemeBuilderConfig(event.data.payload);
296
+ }
297
+ };
298
+
299
+ window.addEventListener('message', handleMessage);
300
+
301
+ return () => window.removeEventListener('message', handleMessage);
302
+ }, [debouncedSetThemeBuilderConfig]);
303
+
261
304
  return (
262
305
  <ColorSchemeContext value={colorSchemeValue}>
263
306
  <BaseThemeProvider theme={theme} {...rest}>
@@ -33,7 +33,6 @@ export function isTheme(obj: any): obj is Theme {
33
33
 
34
34
  /** 是否是 UX Theme 对象 */
35
35
  export function isUxTheme(obj: any): obj is Theme {
36
- // @ts-expect-error
37
36
  return isTheme(obj) && obj.__isUxTheme__ === true;
38
37
  }
39
38
 
@@ -119,7 +118,6 @@ export function lazyCreateDefaultTheme(mode: PaletteMode) {
119
118
  }
120
119
 
121
120
  // 主要处理 overrides
122
- // @ts-expect-error
123
121
  const normalizeUserThemeOptions = ({ palette, components, overrides, ...rest }: UxThemeOptions) => {
124
122
  const result: UxThemeOptions = {
125
123
  palette,
@@ -134,7 +132,6 @@ const normalizeUserThemeOptions = ({ palette, components, overrides, ...rest }:
134
132
  };
135
133
 
136
134
  const defaultUxThemeOptions: UxThemeOptions = {
137
- // @ts-expect-error
138
135
  themeName: 'ArcBlock',
139
136
  pageWidth: 'md',
140
137
  disableBlockletTheme: false,
@@ -170,7 +167,6 @@ export const create = (...args: Array<UxThemeOptions | ((baseTheme: Theme) => Ux
170
167
  deepmerge(acc, normalizeUserThemeOptions(typeof curr === 'function' ? curr(createBaseTheme()) : curr)),
171
168
  normalizeUserThemeOptions(defaultUxThemeOptions)
172
169
  );
173
- // @ts-expect-error
174
170
  const prefer = userThemeOptions.mode || userThemeOptions.palette?.mode || defaultPrefer;
175
171
  const blockletThemeOptions = getBlockletThemeOptions(prefer);
176
172
  const defaultThemeOptions = createDefaultThemeOptions(prefer);
@@ -192,7 +188,6 @@ export const create = (...args: Array<UxThemeOptions | ((baseTheme: Theme) => Ux
192
188
 
193
189
  // 创建主题
194
190
  const theme = _createTheme(mergedThemeOptions);
195
- // @ts-expect-error
196
191
  theme.__isUxTheme__ = true;
197
192
 
198
193
  // 异步加载字体