@arcblock/ux 3.0.15 → 3.0.17
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/Tabs/index.d.ts +2 -1
- package/lib/Tabs/index.js +80 -42
- package/lib/Theme/theme-provider.js +97 -81
- package/lib/Theme/theme.js +0 -1
- package/package.json +7 -7
- package/src/Tabs/index.tsx +46 -7
- package/src/Theme/theme-provider.tsx +50 -7
- package/src/Theme/theme.ts +0 -5
package/lib/Tabs/index.d.ts
CHANGED
@@ -9,6 +9,7 @@ interface TabsProps extends Omit<MuiTabsProps, 'variant' | 'onChange'> {
|
|
9
9
|
onChange: (value: string) => void;
|
10
10
|
variant?: 'card' | 'line' | MuiTabsProps['variant'];
|
11
11
|
iconPosition?: TabProps['iconPosition'];
|
12
|
+
enableTabClick?: boolean;
|
12
13
|
}
|
13
|
-
export default function Tabs({ tabs, current, onChange, variant, iconPosition, ...rest }: TabsProps): import("react/jsx-runtime").JSX.Element;
|
14
|
+
export default function Tabs({ tabs, current, onChange, variant, iconPosition, enableTabClick, ...rest }: TabsProps): import("react/jsx-runtime").JSX.Element;
|
14
15
|
export {};
|
package/lib/Tabs/index.js
CHANGED
@@ -1,25 +1,32 @@
|
|
1
|
-
import { jsx as
|
2
|
-
import { Tabs as
|
3
|
-
import { styled as
|
4
|
-
const
|
5
|
-
tabs: `${
|
6
|
-
tab: `${
|
7
|
-
},
|
8
|
-
[`& .${
|
9
|
-
[`& .${
|
1
|
+
import { jsx as r } from "react/jsx-runtime";
|
2
|
+
import { Tabs as c, Tab as d } from "@mui/material";
|
3
|
+
import { styled as m } from "../Theme/index.js";
|
4
|
+
const b = "index", u = {
|
5
|
+
tabs: `${b}-tabs`,
|
6
|
+
tab: `${b}-tab`
|
7
|
+
}, v = m(c)(({ theme: t }) => ({
|
8
|
+
[`& .${u.tabs}`]: {},
|
9
|
+
[`& .${u.tab}`]: {
|
10
10
|
fontSize: "0.875rem",
|
11
|
-
[
|
11
|
+
[t.breakpoints.up("md")]: {
|
12
12
|
fontSize: "1rem"
|
13
13
|
}
|
14
14
|
}
|
15
15
|
}));
|
16
|
-
function
|
17
|
-
|
18
|
-
|
16
|
+
function f({
|
17
|
+
tabs: t,
|
18
|
+
current: n,
|
19
|
+
onChange: e,
|
20
|
+
iconPosition: s = void 0,
|
21
|
+
enableTabClick: l = !1,
|
22
|
+
...o
|
23
|
+
}) {
|
24
|
+
return /* @__PURE__ */ r(
|
25
|
+
c,
|
19
26
|
{
|
20
27
|
scrollButtons: "auto",
|
21
|
-
value:
|
22
|
-
onChange: (a, i) =>
|
28
|
+
value: n,
|
29
|
+
onChange: (a, i) => !l && e(i),
|
23
30
|
...o,
|
24
31
|
variant: "scrollable",
|
25
32
|
sx: {
|
@@ -63,27 +70,35 @@ function v({ tabs: e, current: t, onChange: r, iconPosition: n = void 0, ...o })
|
|
63
70
|
},
|
64
71
|
...o.sx
|
65
72
|
},
|
66
|
-
children:
|
67
|
-
|
73
|
+
children: t.map((a) => /* @__PURE__ */ r(
|
74
|
+
d,
|
68
75
|
{
|
69
|
-
className:
|
76
|
+
className: u.tab,
|
70
77
|
value: a.value,
|
71
78
|
label: a.label,
|
72
79
|
icon: a.icon,
|
73
|
-
iconPosition:
|
80
|
+
iconPosition: s,
|
81
|
+
onClick: () => l && e(a.value)
|
74
82
|
},
|
75
83
|
a.value
|
76
84
|
))
|
77
85
|
}
|
78
86
|
);
|
79
87
|
}
|
80
|
-
function
|
81
|
-
|
82
|
-
|
88
|
+
function y({
|
89
|
+
tabs: t,
|
90
|
+
current: n,
|
91
|
+
onChange: e,
|
92
|
+
iconPosition: s = void 0,
|
93
|
+
enableTabClick: l = !1,
|
94
|
+
...o
|
95
|
+
}) {
|
96
|
+
return /* @__PURE__ */ r(
|
97
|
+
c,
|
83
98
|
{
|
84
99
|
scrollButtons: "auto",
|
85
|
-
value:
|
86
|
-
onChange: (a, i) =>
|
100
|
+
value: n,
|
101
|
+
onChange: (a, i) => !l && e(i),
|
87
102
|
...o,
|
88
103
|
variant: "scrollable",
|
89
104
|
sx: {
|
@@ -132,14 +147,15 @@ function f({ tabs: e, current: t, onChange: r, iconPosition: n = void 0, ...o })
|
|
132
147
|
},
|
133
148
|
...o.sx
|
134
149
|
},
|
135
|
-
children:
|
136
|
-
|
150
|
+
children: t.map((a) => /* @__PURE__ */ r(
|
151
|
+
d,
|
137
152
|
{
|
138
|
-
className:
|
153
|
+
className: u.tab,
|
139
154
|
value: a.value,
|
140
155
|
label: a.label,
|
141
156
|
icon: a.icon,
|
142
|
-
iconPosition:
|
157
|
+
iconPosition: s,
|
158
|
+
onClick: () => l && e(a.value)
|
143
159
|
},
|
144
160
|
a.value
|
145
161
|
))
|
@@ -147,31 +163,53 @@ function f({ tabs: e, current: t, onChange: r, iconPosition: n = void 0, ...o })
|
|
147
163
|
);
|
148
164
|
}
|
149
165
|
function T({
|
150
|
-
tabs:
|
151
|
-
current:
|
152
|
-
onChange:
|
153
|
-
variant:
|
154
|
-
iconPosition:
|
166
|
+
tabs: t,
|
167
|
+
current: n,
|
168
|
+
onChange: e,
|
169
|
+
variant: s = void 0,
|
170
|
+
iconPosition: l = void 0,
|
171
|
+
enableTabClick: o = !1,
|
155
172
|
...a
|
156
173
|
}) {
|
157
|
-
return
|
158
|
-
|
174
|
+
return s === "card" ? /* @__PURE__ */ r(
|
175
|
+
f,
|
176
|
+
{
|
177
|
+
...a,
|
178
|
+
tabs: t,
|
179
|
+
current: n,
|
180
|
+
enableTabClick: o,
|
181
|
+
onChange: e,
|
182
|
+
iconPosition: l
|
183
|
+
}
|
184
|
+
) : s === "line" ? /* @__PURE__ */ r(
|
185
|
+
y,
|
186
|
+
{
|
187
|
+
...a,
|
188
|
+
tabs: t,
|
189
|
+
current: n,
|
190
|
+
enableTabClick: o,
|
191
|
+
onChange: e,
|
192
|
+
iconPosition: l
|
193
|
+
}
|
194
|
+
) : /* @__PURE__ */ r(
|
195
|
+
v,
|
159
196
|
{
|
160
197
|
scrollButtons: "auto",
|
161
198
|
variant: "scrollable",
|
162
|
-
value:
|
163
|
-
onChange: (i,
|
199
|
+
value: n,
|
200
|
+
onChange: (i, p) => !o && e(p),
|
164
201
|
indicatorColor: "primary",
|
165
202
|
...a,
|
166
|
-
className: [
|
167
|
-
children:
|
168
|
-
|
203
|
+
className: [u.tabs, a.className || ""].join(" "),
|
204
|
+
children: t.map((i) => /* @__PURE__ */ r(
|
205
|
+
d,
|
169
206
|
{
|
170
|
-
className:
|
207
|
+
className: u.tab,
|
171
208
|
value: i.value,
|
172
209
|
label: i.label,
|
173
210
|
icon: i.icon,
|
174
|
-
iconPosition:
|
211
|
+
iconPosition: l,
|
212
|
+
onClick: () => o && e(i.value)
|
175
213
|
},
|
176
214
|
i.value
|
177
215
|
))
|
@@ -1,49 +1,51 @@
|
|
1
|
-
import { jsx as
|
2
|
-
import { createContext as
|
3
|
-
import { useTheme as
|
4
|
-
import
|
5
|
-
import
|
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
|
8
|
-
const
|
9
|
-
function
|
10
|
-
return
|
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
|
13
|
-
function
|
14
|
-
const
|
15
|
-
if (
|
16
|
-
const
|
17
|
-
return /* @__PURE__ */
|
18
|
-
|
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
|
-
[
|
25
|
+
[s]: {
|
24
26
|
width: "12px",
|
25
27
|
height: "12px"
|
26
28
|
},
|
27
|
-
[
|
28
|
-
background:
|
29
|
+
[i]: {
|
30
|
+
background: r
|
29
31
|
},
|
30
|
-
[
|
31
|
-
background:
|
32
|
+
[c]: {
|
33
|
+
background: a,
|
32
34
|
borderRadius: "6px",
|
33
35
|
border: "2px solid",
|
34
|
-
borderColor:
|
36
|
+
borderColor: r,
|
35
37
|
backgroundClip: "padding-box",
|
36
38
|
"&:hover": {
|
37
|
-
background:
|
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
|
-
[
|
46
|
+
[g]: {
|
45
47
|
scrollbarWidth: "auto",
|
46
|
-
scrollbarColor: `${
|
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
|
57
|
+
function _({
|
56
58
|
children: l = null,
|
57
|
-
theme:
|
58
|
-
injectFirst:
|
59
|
-
darkSchemeClass:
|
59
|
+
theme: t = Q,
|
60
|
+
injectFirst: r = !0,
|
61
|
+
darkSchemeClass: a = ""
|
60
62
|
}) {
|
61
|
-
const o =
|
63
|
+
const o = f(() => typeof t == "function" || J(t) ? t : T(t), [t]);
|
62
64
|
return (
|
63
65
|
// injectFirst 会影响 makeStyles 自定义样式和 mui styles 覆盖问题
|
64
|
-
/* @__PURE__ */
|
65
|
-
/* @__PURE__ */
|
66
|
-
/* @__PURE__ */
|
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
|
73
|
+
function ee({
|
72
74
|
children: l = null,
|
73
|
-
theme:
|
74
|
-
prefer:
|
75
|
-
disableBlockletTheme:
|
75
|
+
theme: t = void 0,
|
76
|
+
prefer: r = void 0,
|
77
|
+
disableBlockletTheme: a = !1,
|
76
78
|
...o
|
77
79
|
}) {
|
78
|
-
const [
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
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
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
(
|
93
|
-
|
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
|
-
[
|
96
|
-
),
|
106
|
+
[s, i]
|
107
|
+
), L = f(
|
97
108
|
() => ({
|
98
|
-
mode:
|
99
|
-
toggleMode:
|
100
|
-
changeMode:
|
101
|
-
prefer:
|
109
|
+
mode: s,
|
110
|
+
toggleMode: S,
|
111
|
+
changeMode: v,
|
112
|
+
prefer: r
|
102
113
|
}),
|
103
|
-
[
|
114
|
+
[s, r, S, v]
|
104
115
|
);
|
105
|
-
return
|
106
|
-
|
107
|
-
}, [
|
108
|
-
const
|
109
|
-
W(
|
110
|
-
}, [
|
111
|
-
|
112
|
-
const
|
113
|
-
if (
|
114
|
-
|
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
|
117
|
-
|
127
|
+
const n = document.createElement("meta");
|
128
|
+
n.name = "theme-color", n.content = e, document.head.appendChild(n), d.current = n;
|
118
129
|
}
|
119
|
-
}, [
|
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
|
137
|
+
function me({
|
122
138
|
children: l = null,
|
123
|
-
prefer:
|
124
|
-
enableColorScheme:
|
125
|
-
...
|
139
|
+
prefer: t = void 0,
|
140
|
+
enableColorScheme: r = !1,
|
141
|
+
...a
|
126
142
|
}) {
|
127
|
-
const { toggleMode: o } =
|
128
|
-
return
|
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
|
-
|
132
|
-
|
133
|
-
|
147
|
+
P as ColorSchemeContext,
|
148
|
+
me as default,
|
149
|
+
X as useColorScheme
|
134
150
|
};
|
package/lib/Theme/theme.js
CHANGED
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@arcblock/ux",
|
3
|
-
"version": "3.0.
|
3
|
+
"version": "3.0.17",
|
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": "
|
63
|
+
"gitHead": "4c0ab1335d46f38cc05e804c6ae099dfd6fa9ad8",
|
64
64
|
"dependencies": {
|
65
|
-
"@arcblock/bridge": "3.0.
|
65
|
+
"@arcblock/bridge": "3.0.17",
|
66
66
|
"@arcblock/did": "^1.20.15",
|
67
67
|
"@arcblock/did-motif": "^1.1.14",
|
68
|
-
"@arcblock/icons": "3.0.
|
69
|
-
"@arcblock/nft-display": "3.0.
|
70
|
-
"@arcblock/react-hooks": "3.0.
|
68
|
+
"@arcblock/icons": "3.0.17",
|
69
|
+
"@arcblock/nft-display": "3.0.17",
|
70
|
+
"@arcblock/react-hooks": "3.0.17",
|
71
71
|
"@blocklet/js-sdk": "^1.16.45",
|
72
|
-
"@blocklet/theme": "3.0.
|
72
|
+
"@blocklet/theme": "3.0.17",
|
73
73
|
"@fontsource/roboto": "~5.1.1",
|
74
74
|
"@fontsource/ubuntu-mono": "^5.2.6",
|
75
75
|
"@iconify-icons/logos": "^1.2.36",
|
package/src/Tabs/index.tsx
CHANGED
@@ -25,14 +25,22 @@ interface CardTabsProps extends Omit<MuiTabsProps, 'onChange'> {
|
|
25
25
|
current: any;
|
26
26
|
onChange: (value: string) => void;
|
27
27
|
iconPosition?: TabProps['iconPosition'];
|
28
|
+
enableTabClick?: boolean;
|
28
29
|
}
|
29
30
|
|
30
|
-
function CardTabs({
|
31
|
+
function CardTabs({
|
32
|
+
tabs,
|
33
|
+
current,
|
34
|
+
onChange,
|
35
|
+
iconPosition = undefined,
|
36
|
+
enableTabClick = false,
|
37
|
+
...rest
|
38
|
+
}: CardTabsProps) {
|
31
39
|
return (
|
32
40
|
<MuiTabs
|
33
41
|
scrollButtons="auto"
|
34
42
|
value={current}
|
35
|
-
onChange={(_, newValue) => onChange(newValue)}
|
43
|
+
onChange={(_, newValue) => !enableTabClick && onChange(newValue)}
|
36
44
|
{...rest}
|
37
45
|
variant="scrollable"
|
38
46
|
sx={{
|
@@ -84,6 +92,7 @@ function CardTabs({ tabs, current, onChange, iconPosition = undefined, ...rest }
|
|
84
92
|
label={x.label}
|
85
93
|
icon={x.icon}
|
86
94
|
iconPosition={iconPosition}
|
95
|
+
onClick={() => enableTabClick && onChange(x.value)}
|
87
96
|
/>
|
88
97
|
))}
|
89
98
|
</MuiTabs>
|
@@ -95,14 +104,22 @@ interface LineTabsProps extends Omit<MuiTabsProps, 'onChange'> {
|
|
95
104
|
current: any;
|
96
105
|
onChange: (value: string) => void;
|
97
106
|
iconPosition?: TabProps['iconPosition'];
|
107
|
+
enableTabClick?: boolean;
|
98
108
|
}
|
99
109
|
|
100
|
-
function LineTabs({
|
110
|
+
function LineTabs({
|
111
|
+
tabs,
|
112
|
+
current,
|
113
|
+
onChange,
|
114
|
+
iconPosition = undefined,
|
115
|
+
enableTabClick = false,
|
116
|
+
...rest
|
117
|
+
}: LineTabsProps) {
|
101
118
|
return (
|
102
119
|
<MuiTabs
|
103
120
|
scrollButtons="auto"
|
104
121
|
value={current}
|
105
|
-
onChange={(_, newValue) => onChange(newValue)}
|
122
|
+
onChange={(_, newValue) => !enableTabClick && onChange(newValue)}
|
106
123
|
{...rest}
|
107
124
|
variant="scrollable"
|
108
125
|
sx={{
|
@@ -162,6 +179,7 @@ function LineTabs({ tabs, current, onChange, iconPosition = undefined, ...rest }
|
|
162
179
|
label={x.label}
|
163
180
|
icon={x.icon}
|
164
181
|
iconPosition={iconPosition}
|
182
|
+
onClick={() => enableTabClick && onChange(x.value)}
|
165
183
|
/>
|
166
184
|
))}
|
167
185
|
</MuiTabs>
|
@@ -174,6 +192,7 @@ interface TabsProps extends Omit<MuiTabsProps, 'variant' | 'onChange'> {
|
|
174
192
|
onChange: (value: string) => void;
|
175
193
|
variant?: 'card' | 'line' | MuiTabsProps['variant'];
|
176
194
|
iconPosition?: TabProps['iconPosition'];
|
195
|
+
enableTabClick?: boolean; // 是否启用点击切换 tab,默认不启用,启用后,当前 tab 处于活跃状态下点击 tab 也会触发 onChange 事件,
|
177
196
|
}
|
178
197
|
|
179
198
|
export default function Tabs({
|
@@ -182,14 +201,33 @@ export default function Tabs({
|
|
182
201
|
onChange,
|
183
202
|
variant = undefined,
|
184
203
|
iconPosition = undefined,
|
204
|
+
enableTabClick = false,
|
185
205
|
...rest
|
186
206
|
}: TabsProps) {
|
187
207
|
if (variant === 'card') {
|
188
|
-
return
|
208
|
+
return (
|
209
|
+
<CardTabs
|
210
|
+
{...rest}
|
211
|
+
tabs={tabs}
|
212
|
+
current={current}
|
213
|
+
enableTabClick={enableTabClick}
|
214
|
+
onChange={onChange}
|
215
|
+
iconPosition={iconPosition}
|
216
|
+
/>
|
217
|
+
);
|
189
218
|
}
|
190
219
|
|
191
220
|
if (variant === 'line') {
|
192
|
-
return
|
221
|
+
return (
|
222
|
+
<LineTabs
|
223
|
+
{...rest}
|
224
|
+
tabs={tabs}
|
225
|
+
current={current}
|
226
|
+
enableTabClick={enableTabClick}
|
227
|
+
onChange={onChange}
|
228
|
+
iconPosition={iconPosition}
|
229
|
+
/>
|
230
|
+
);
|
193
231
|
}
|
194
232
|
|
195
233
|
return (
|
@@ -197,7 +235,7 @@ export default function Tabs({
|
|
197
235
|
scrollButtons="auto"
|
198
236
|
variant="scrollable"
|
199
237
|
value={current}
|
200
|
-
onChange={(_, newValue) => onChange(newValue)}
|
238
|
+
onChange={(_, newValue) => !enableTabClick && onChange(newValue)}
|
201
239
|
indicatorColor="primary"
|
202
240
|
{...rest}
|
203
241
|
className={[classes.tabs, rest.className || ''].join(' ')}>
|
@@ -209,6 +247,7 @@ export default function Tabs({
|
|
209
247
|
label={x.label}
|
210
248
|
icon={x.icon}
|
211
249
|
iconPosition={iconPosition}
|
250
|
+
onClick={() => enableTabClick && onChange(x.value)}
|
212
251
|
/>
|
213
252
|
))}
|
214
253
|
</StyledMuiTabs>
|
@@ -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 {
|
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
|
-
|
190
|
-
|
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}>
|
package/src/Theme/theme.ts
CHANGED
@@ -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
|
// 异步加载字体
|