@arcblock/ux 2.13.47 → 2.13.49
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/NavMenu/products.js +5 -5
- package/lib/RelativeTime/index.d.ts +3 -1
- package/lib/RelativeTime/index.js +18 -13
- package/lib/Theme/theme-provider.js +10 -2
- package/lib/Theme/theme.d.ts +1 -0
- package/lib/Theme/theme.js +16 -6
- package/package.json +8 -7
- package/src/NavMenu/products.tsx +5 -8
- package/src/RelativeTime/index.tsx +26 -28
- package/src/Theme/theme-provider.tsx +11 -1
- package/src/Theme/theme.ts +18 -7
package/lib/NavMenu/products.js
CHANGED
@@ -1374,7 +1374,7 @@ const translations = {
|
|
1374
1374
|
blockletLauncher: {
|
1375
1375
|
description: 'One-click app launcher'
|
1376
1376
|
},
|
1377
|
-
|
1377
|
+
aiKit: {
|
1378
1378
|
description: 'Boost apps with AI'
|
1379
1379
|
},
|
1380
1380
|
paymentKit: {
|
@@ -1444,7 +1444,7 @@ const translations = {
|
|
1444
1444
|
blockletLauncher: {
|
1445
1445
|
description: '一键启动应用程序'
|
1446
1446
|
},
|
1447
|
-
|
1447
|
+
aiKit: {
|
1448
1448
|
description: 'AI 赋能应用'
|
1449
1449
|
},
|
1450
1450
|
paymentKit: {
|
@@ -1599,12 +1599,12 @@ export default function Products({
|
|
1599
1599
|
icon: /*#__PURE__*/_jsx(BlockletLauncherSvg, {})
|
1600
1600
|
}, {
|
1601
1601
|
label: /*#__PURE__*/_jsx(Link, {
|
1602
|
-
to: `https://www.
|
1602
|
+
to: `https://www.aikit.rocks/${locale}`,
|
1603
1603
|
target: "_blank",
|
1604
1604
|
rel: "noreferrer noopener",
|
1605
|
-
children: "
|
1605
|
+
children: "AI Kit"
|
1606
1606
|
}),
|
1607
|
-
description: t('products.
|
1607
|
+
description: t('products.aiKit.description'),
|
1608
1608
|
icon: /*#__PURE__*/_jsx(AIKitSvg, {})
|
1609
1609
|
}, {
|
1610
1610
|
label: /*#__PURE__*/_jsx(Link, {
|
@@ -1,3 +1,4 @@
|
|
1
|
+
import { TooltipProps } from '@mui/material';
|
1
2
|
import 'dayjs/locale/zh-cn';
|
2
3
|
import type { Locale } from '../type';
|
3
4
|
export interface RelativeTimeProps {
|
@@ -12,5 +13,6 @@ export interface RelativeTimeProps {
|
|
12
13
|
enableTooltip?: boolean;
|
13
14
|
useShortTimezone?: boolean;
|
14
15
|
disableTimezone?: boolean;
|
16
|
+
placement?: TooltipProps['placement'];
|
15
17
|
}
|
16
|
-
export default function RelativeTime({ value, locale, withoutSuffix, from, to, type, tz, relativeRange, enableTooltip, useShortTimezone, disableTimezone, ...rest }: RelativeTimeProps): import("react/jsx-runtime").JSX.Element;
|
18
|
+
export default function RelativeTime({ value, locale, withoutSuffix, from, to, type, tz, relativeRange, enableTooltip, useShortTimezone, disableTimezone, placement, ...rest }: RelativeTimeProps): import("react/jsx-runtime").JSX.Element;
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
2
2
|
import { Box, Tooltip } from '@mui/material';
|
3
|
-
import {
|
3
|
+
import { useEffect, useMemo } from 'react';
|
4
4
|
import relativeTime from 'dayjs/plugin/relativeTime';
|
5
5
|
import dayjs from 'dayjs';
|
6
6
|
import 'dayjs/locale/zh-cn';
|
@@ -8,6 +8,7 @@ import localizedFormat from 'dayjs/plugin/localizedFormat';
|
|
8
8
|
import utc from 'dayjs/plugin/utc';
|
9
9
|
import timezone from 'dayjs/plugin/timezone';
|
10
10
|
import updateLocale from 'dayjs/plugin/updateLocale';
|
11
|
+
import { create } from 'zustand';
|
11
12
|
import { formatToDatetime, setDateTool } from '../Util';
|
12
13
|
dayjs.extend(localizedFormat);
|
13
14
|
dayjs.extend(utc);
|
@@ -48,6 +49,12 @@ const translations = {
|
|
48
49
|
shortLocal: '当前时区'
|
49
50
|
}
|
50
51
|
};
|
52
|
+
const useUtcStore = create(set => ({
|
53
|
+
isUtc: false,
|
54
|
+
setIsUtc: isUtc => set({
|
55
|
+
isUtc
|
56
|
+
})
|
57
|
+
}));
|
51
58
|
function useRelativeTime({
|
52
59
|
value,
|
53
60
|
locale = 'en',
|
@@ -63,7 +70,12 @@ function useRelativeTime({
|
|
63
70
|
const sign = timeZoneOffset > 0 ? '-' : '+';
|
64
71
|
const hoursOffset = Math.abs(timeZoneOffset) / 60;
|
65
72
|
const isLocalUtc = timeZoneOffset === 0;
|
66
|
-
const
|
73
|
+
const isUtc = useUtcStore(state => state.isUtc);
|
74
|
+
const setIsUtc = useUtcStore(state => state.setIsUtc);
|
75
|
+
useEffect(() => {
|
76
|
+
setIsUtc(isLocalUtc);
|
77
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
78
|
+
}, [isLocalUtc]);
|
67
79
|
if (!value) {
|
68
80
|
return {
|
69
81
|
innerContent: '-',
|
@@ -137,8 +149,6 @@ function useRelativeTime({
|
|
137
149
|
function UTCChip({
|
138
150
|
locale,
|
139
151
|
isUtc,
|
140
|
-
sign,
|
141
|
-
hoursOffset,
|
142
152
|
setIsUtc,
|
143
153
|
useShortTimezone = true
|
144
154
|
}) {
|
@@ -162,7 +172,7 @@ function UTCChip({
|
|
162
172
|
padding: '4px 8px',
|
163
173
|
lineHeight: 1
|
164
174
|
},
|
165
|
-
onClick: () => setIsUtc(
|
175
|
+
onClick: () => setIsUtc(!isUtc),
|
166
176
|
children: text
|
167
177
|
});
|
168
178
|
}
|
@@ -178,6 +188,7 @@ export default function RelativeTime({
|
|
178
188
|
enableTooltip = true,
|
179
189
|
useShortTimezone = false,
|
180
190
|
disableTimezone = false,
|
191
|
+
placement = 'top-end',
|
181
192
|
...rest
|
182
193
|
}) {
|
183
194
|
const {
|
@@ -185,8 +196,6 @@ export default function RelativeTime({
|
|
185
196
|
popContent,
|
186
197
|
isUtc,
|
187
198
|
setIsUtc,
|
188
|
-
sign,
|
189
|
-
hoursOffset,
|
190
199
|
relativeString
|
191
200
|
} = useRelativeTime({
|
192
201
|
value,
|
@@ -201,7 +210,7 @@ export default function RelativeTime({
|
|
201
210
|
if (type === 'all') {
|
202
211
|
return /*#__PURE__*/_jsx(Tooltip, {
|
203
212
|
title: undefined,
|
204
|
-
placement:
|
213
|
+
placement: placement,
|
205
214
|
enterTouchDelay: 0,
|
206
215
|
children: /*#__PURE__*/_jsxs(Box, {
|
207
216
|
display: "inline-flex",
|
@@ -235,8 +244,6 @@ export default function RelativeTime({
|
|
235
244
|
}), /*#__PURE__*/_jsx(UTCChip, {
|
236
245
|
locale: locale,
|
237
246
|
isUtc: isUtc,
|
238
|
-
sign: sign,
|
239
|
-
hoursOffset: hoursOffset,
|
240
247
|
setIsUtc: setIsUtc,
|
241
248
|
useShortTimezone: useShortTimezone
|
242
249
|
})]
|
@@ -246,7 +253,7 @@ export default function RelativeTime({
|
|
246
253
|
}
|
247
254
|
return /*#__PURE__*/_jsx(Tooltip, {
|
248
255
|
title: enableTooltip ? popContent : undefined,
|
249
|
-
placement:
|
256
|
+
placement: placement,
|
250
257
|
enterTouchDelay: 0,
|
251
258
|
children: /*#__PURE__*/_jsxs(Box, {
|
252
259
|
display: "inline-flex",
|
@@ -259,8 +266,6 @@ export default function RelativeTime({
|
|
259
266
|
}), type === 'utc' && !disableTimezone && /*#__PURE__*/_jsx(UTCChip, {
|
260
267
|
locale: locale,
|
261
268
|
isUtc: isUtc,
|
262
|
-
sign: sign,
|
263
|
-
hoursOffset: hoursOffset,
|
264
269
|
setIsUtc: setIsUtc,
|
265
270
|
useShortTimezone: useShortTimezone
|
266
271
|
})]
|
@@ -8,7 +8,7 @@ import CssBaseline from '@mui/material/CssBaseline';
|
|
8
8
|
import set from 'lodash/set';
|
9
9
|
import { BLOCKLET_THEME_PREFER_KEY } from '@blocklet/theme';
|
10
10
|
import useLocationState from '../hooks/use-location-state';
|
11
|
-
import { createTheme, getDefaultThemePrefer, isTheme, isUxTheme, lazyCreateDefaultTheme } from './theme';
|
11
|
+
import { createTheme, getDefaultThemePrefer, isTheme, isUxTheme, isValidThemeMode, lazyCreateDefaultTheme } from './theme';
|
12
12
|
const defaultTheme = createTheme();
|
13
13
|
|
14
14
|
/** 颜色模式上下文类型 */
|
@@ -180,10 +180,18 @@ function ColorSchemeProvider({
|
|
180
180
|
prefer
|
181
181
|
}), [mode, prefer, toggleMode, changeMode]);
|
182
182
|
|
183
|
-
//
|
183
|
+
// 相应 prefer 或 urlTheme 的改变
|
184
184
|
useEffect(() => {
|
185
185
|
setMode(resolveMode(prefer));
|
186
186
|
}, [prefer, setMode, location.search]);
|
187
|
+
|
188
|
+
// 会话缓存 urlTheme 便于 App Launching 阶段临时统一 theme mode
|
189
|
+
useEffect(() => {
|
190
|
+
const urlTheme = new URLSearchParams(location.search).get('theme');
|
191
|
+
if (isValidThemeMode(urlTheme)) {
|
192
|
+
sessionStorage.setItem(BLOCKLET_THEME_PREFER_KEY, urlTheme);
|
193
|
+
}
|
194
|
+
}, [location.search]);
|
187
195
|
return /*#__PURE__*/_jsx(ColorSchemeContext.Provider, {
|
188
196
|
value: colorSchemeValue,
|
189
197
|
children: /*#__PURE__*/_jsx(BaseThemeProvider, {
|
package/lib/Theme/theme.d.ts
CHANGED
@@ -15,6 +15,7 @@ export declare function collectFontFamilies(obj?: {
|
|
15
15
|
fontFamily?: string;
|
16
16
|
}, fontSet?: Set<string>): Set<string>;
|
17
17
|
export declare function loadFonts(fonts: string[]): Promise<boolean>;
|
18
|
+
export declare function isValidThemeMode(mode: any): mode is PaletteMode;
|
18
19
|
export declare function getDefaultThemePrefer(meta?: {
|
19
20
|
theme: {
|
20
21
|
prefer: 'light' | 'dark' | 'system';
|
package/lib/Theme/theme.js
CHANGED
@@ -72,28 +72,38 @@ export function loadFonts(fonts) {
|
|
72
72
|
}
|
73
73
|
|
74
74
|
// 获取默认主题偏好
|
75
|
+
export function isValidThemeMode(mode) {
|
76
|
+
return mode === 'light' || mode === 'dark';
|
77
|
+
}
|
75
78
|
export function getDefaultThemePrefer(meta) {
|
76
79
|
// 跟随 url theme 参数
|
77
80
|
const urlParams = new URLSearchParams(window.location.search);
|
78
81
|
const urlPrefer = urlParams.get('theme');
|
79
|
-
if (urlPrefer
|
82
|
+
if (isValidThemeMode(urlPrefer)) {
|
80
83
|
return urlPrefer;
|
81
84
|
}
|
85
|
+
|
86
|
+
// 跟随 session theme
|
87
|
+
const sessionPrefer = sessionStorage.getItem(BLOCKLET_THEME_PREFER_KEY);
|
88
|
+
if (isValidThemeMode(sessionPrefer)) {
|
89
|
+
return sessionPrefer;
|
90
|
+
}
|
91
|
+
|
92
|
+
// 跟随 blocklet theme mode
|
82
93
|
const prefer = Object.assign({}, window.blocklet, meta).theme?.prefer;
|
94
|
+
if (prefer === 'light' || prefer === 'dark') {
|
95
|
+
return prefer;
|
96
|
+
}
|
83
97
|
if (prefer === 'system') {
|
84
98
|
// 跟随本地缓存
|
85
99
|
const localPrefer = localStorage.getItem(BLOCKLET_THEME_PREFER_KEY);
|
86
|
-
if (
|
100
|
+
if (isValidThemeMode(localPrefer)) {
|
87
101
|
return localPrefer;
|
88
102
|
}
|
89
103
|
|
90
104
|
// 跟随系统
|
91
105
|
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
|
92
106
|
}
|
93
|
-
// 跟随 blocklet theme mode
|
94
|
-
if (prefer === 'light' || prefer === 'dark') {
|
95
|
-
return prefer;
|
96
|
-
}
|
97
107
|
|
98
108
|
// fallback
|
99
109
|
return 'light';
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@arcblock/ux",
|
3
|
-
"version": "2.13.
|
3
|
+
"version": "2.13.49",
|
4
4
|
"description": "Common used react components for arcblock products",
|
5
5
|
"keywords": [
|
6
6
|
"react",
|
@@ -71,14 +71,14 @@
|
|
71
71
|
"react": ">=18.2.0",
|
72
72
|
"react-router-dom": ">=6.22.3"
|
73
73
|
},
|
74
|
-
"gitHead": "
|
74
|
+
"gitHead": "a924ed1c40a2ca8fea2f50bea4de423d04aadd88",
|
75
75
|
"dependencies": {
|
76
76
|
"@arcblock/did-motif": "^1.1.13",
|
77
|
-
"@arcblock/icons": "^2.13.
|
78
|
-
"@arcblock/nft-display": "^2.13.
|
79
|
-
"@arcblock/react-hooks": "^2.13.
|
77
|
+
"@arcblock/icons": "^2.13.49",
|
78
|
+
"@arcblock/nft-display": "^2.13.49",
|
79
|
+
"@arcblock/react-hooks": "^2.13.49",
|
80
80
|
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
|
81
|
-
"@blocklet/theme": "^2.13.
|
81
|
+
"@blocklet/theme": "^2.13.49",
|
82
82
|
"@fontsource/roboto": "~5.1.1",
|
83
83
|
"@fontsource/ubuntu-mono": "^5.0.18",
|
84
84
|
"@iconify-icons/logos": "^1.2.36",
|
@@ -129,6 +129,7 @@
|
|
129
129
|
"type-fest": "^4.28.0",
|
130
130
|
"validator": "^13.9.0",
|
131
131
|
"versor": "^0.0.4",
|
132
|
-
"webfontloader": "^1.6.28"
|
132
|
+
"webfontloader": "^1.6.28",
|
133
|
+
"zustand": "^5.0.5"
|
133
134
|
}
|
134
135
|
}
|
package/src/NavMenu/products.tsx
CHANGED
@@ -56,7 +56,7 @@ const translations = {
|
|
56
56
|
blockletLauncher: {
|
57
57
|
description: 'One-click app launcher',
|
58
58
|
},
|
59
|
-
|
59
|
+
aiKit: {
|
60
60
|
description: 'Boost apps with AI',
|
61
61
|
},
|
62
62
|
paymentKit: {
|
@@ -126,7 +126,7 @@ const translations = {
|
|
126
126
|
blockletLauncher: {
|
127
127
|
description: '一键启动应用程序',
|
128
128
|
},
|
129
|
-
|
129
|
+
aiKit: {
|
130
130
|
description: 'AI 赋能应用',
|
131
131
|
},
|
132
132
|
paymentKit: {
|
@@ -283,14 +283,11 @@ export default function Products({ className, isOpen, ...rest }: ProductsProps)
|
|
283
283
|
},
|
284
284
|
{
|
285
285
|
label: (
|
286
|
-
<Link
|
287
|
-
|
288
|
-
target="_blank"
|
289
|
-
rel="noreferrer noopener">
|
290
|
-
Al Kit
|
286
|
+
<Link to={`https://www.aikit.rocks/${locale}`} target="_blank" rel="noreferrer noopener">
|
287
|
+
AI Kit
|
291
288
|
</Link>
|
292
289
|
),
|
293
|
-
description: t('products.
|
290
|
+
description: t('products.aiKit.description'),
|
294
291
|
icon: <AIKitSvg />,
|
295
292
|
},
|
296
293
|
{
|
@@ -1,5 +1,5 @@
|
|
1
|
-
import { Box, Tooltip } from '@mui/material';
|
2
|
-
import {
|
1
|
+
import { Box, Tooltip, TooltipProps } from '@mui/material';
|
2
|
+
import { useEffect, useMemo } from 'react';
|
3
3
|
import relativeTime from 'dayjs/plugin/relativeTime';
|
4
4
|
import dayjs from 'dayjs';
|
5
5
|
import 'dayjs/locale/zh-cn';
|
@@ -7,6 +7,7 @@ import localizedFormat from 'dayjs/plugin/localizedFormat';
|
|
7
7
|
import utc from 'dayjs/plugin/utc';
|
8
8
|
import timezone from 'dayjs/plugin/timezone';
|
9
9
|
import updateLocale from 'dayjs/plugin/updateLocale';
|
10
|
+
import { create } from 'zustand';
|
10
11
|
import { formatToDatetime, setDateTool } from '../Util';
|
11
12
|
import type { Locale } from '../type';
|
12
13
|
|
@@ -51,6 +52,12 @@ const translations: Record<Locale, { utc: string; local: string; shortUTC: strin
|
|
51
52
|
},
|
52
53
|
};
|
53
54
|
|
55
|
+
type UtcState = { isUtc: boolean; setIsUtc: (isUtc: boolean) => void };
|
56
|
+
const useUtcStore = create<UtcState>((set) => ({
|
57
|
+
isUtc: false,
|
58
|
+
setIsUtc: (isUtc: boolean) => set({ isUtc }),
|
59
|
+
}));
|
60
|
+
|
54
61
|
export interface RelativeTimeProps {
|
55
62
|
value: string | number;
|
56
63
|
locale?: Locale;
|
@@ -63,6 +70,7 @@ export interface RelativeTimeProps {
|
|
63
70
|
enableTooltip?: boolean;
|
64
71
|
useShortTimezone?: boolean;
|
65
72
|
disableTimezone?: boolean;
|
73
|
+
placement?: TooltipProps['placement'];
|
66
74
|
}
|
67
75
|
|
68
76
|
function useRelativeTime({
|
@@ -89,7 +97,14 @@ function useRelativeTime({
|
|
89
97
|
const sign = timeZoneOffset > 0 ? '-' : '+';
|
90
98
|
const hoursOffset = Math.abs(timeZoneOffset) / 60;
|
91
99
|
const isLocalUtc = timeZoneOffset === 0;
|
92
|
-
|
100
|
+
|
101
|
+
const isUtc = useUtcStore((state) => state.isUtc);
|
102
|
+
const setIsUtc = useUtcStore((state) => state.setIsUtc);
|
103
|
+
|
104
|
+
useEffect(() => {
|
105
|
+
setIsUtc(isLocalUtc);
|
106
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
107
|
+
}, [isLocalUtc]);
|
93
108
|
|
94
109
|
if (!value) {
|
95
110
|
return { innerContent: '-', popContent: '-', isUtc, setIsUtc, sign, hoursOffset };
|
@@ -149,16 +164,12 @@ function useRelativeTime({
|
|
149
164
|
function UTCChip({
|
150
165
|
locale,
|
151
166
|
isUtc,
|
152
|
-
sign,
|
153
|
-
hoursOffset,
|
154
167
|
setIsUtc,
|
155
168
|
useShortTimezone = true,
|
156
169
|
}: {
|
157
170
|
locale: Locale;
|
158
171
|
isUtc?: boolean;
|
159
|
-
|
160
|
-
hoursOffset: number;
|
161
|
-
setIsUtc: (data: any) => void;
|
172
|
+
setIsUtc: (data: boolean) => void;
|
162
173
|
useShortTimezone?: boolean;
|
163
174
|
}) {
|
164
175
|
const text = useMemo(() => {
|
@@ -185,7 +196,7 @@ function UTCChip({
|
|
185
196
|
padding: '4px 8px',
|
186
197
|
lineHeight: 1,
|
187
198
|
}}
|
188
|
-
onClick={() => setIsUtc(
|
199
|
+
onClick={() => setIsUtc(!isUtc)}>
|
189
200
|
{text}
|
190
201
|
</Box>
|
191
202
|
);
|
@@ -203,9 +214,10 @@ export default function RelativeTime({
|
|
203
214
|
enableTooltip = true,
|
204
215
|
useShortTimezone = false,
|
205
216
|
disableTimezone = false,
|
217
|
+
placement = 'top-end',
|
206
218
|
...rest
|
207
219
|
}: RelativeTimeProps) {
|
208
|
-
const { innerContent, popContent, isUtc, setIsUtc,
|
220
|
+
const { innerContent, popContent, isUtc, setIsUtc, relativeString } = useRelativeTime({
|
209
221
|
value,
|
210
222
|
locale,
|
211
223
|
withoutSuffix,
|
@@ -218,7 +230,7 @@ export default function RelativeTime({
|
|
218
230
|
|
219
231
|
if (type === 'all') {
|
220
232
|
return (
|
221
|
-
<Tooltip title={undefined} placement=
|
233
|
+
<Tooltip title={undefined} placement={placement} enterTouchDelay={0}>
|
222
234
|
<Box display="inline-flex" alignItems="center" gap={0.5} {...rest}>
|
223
235
|
<Box component="span" {...rest} sx={{}}>
|
224
236
|
{innerContent}
|
@@ -238,14 +250,7 @@ export default function RelativeTime({
|
|
238
250
|
·
|
239
251
|
</Box>
|
240
252
|
|
241
|
-
<UTCChip
|
242
|
-
locale={locale}
|
243
|
-
isUtc={isUtc}
|
244
|
-
sign={sign}
|
245
|
-
hoursOffset={hoursOffset}
|
246
|
-
setIsUtc={setIsUtc}
|
247
|
-
useShortTimezone={useShortTimezone}
|
248
|
-
/>
|
253
|
+
<UTCChip locale={locale} isUtc={isUtc} setIsUtc={setIsUtc} useShortTimezone={useShortTimezone} />
|
249
254
|
</>
|
250
255
|
)}
|
251
256
|
</Box>
|
@@ -254,21 +259,14 @@ export default function RelativeTime({
|
|
254
259
|
}
|
255
260
|
|
256
261
|
return (
|
257
|
-
<Tooltip title={enableTooltip ? popContent : undefined} placement=
|
262
|
+
<Tooltip title={enableTooltip ? popContent : undefined} placement={placement} enterTouchDelay={0}>
|
258
263
|
<Box display="inline-flex" alignItems="center" gap={1}>
|
259
264
|
<Box component="span" {...rest}>
|
260
265
|
{innerContent}
|
261
266
|
</Box>
|
262
267
|
|
263
268
|
{type === 'utc' && !disableTimezone && (
|
264
|
-
<UTCChip
|
265
|
-
locale={locale}
|
266
|
-
isUtc={isUtc}
|
267
|
-
sign={sign}
|
268
|
-
hoursOffset={hoursOffset}
|
269
|
-
setIsUtc={setIsUtc}
|
270
|
-
useShortTimezone={useShortTimezone}
|
271
|
-
/>
|
269
|
+
<UTCChip locale={locale} isUtc={isUtc} setIsUtc={setIsUtc} useShortTimezone={useShortTimezone} />
|
272
270
|
)}
|
273
271
|
</Box>
|
274
272
|
</Tooltip>
|
@@ -14,6 +14,7 @@ import {
|
|
14
14
|
getDefaultThemePrefer,
|
15
15
|
isTheme,
|
16
16
|
isUxTheme,
|
17
|
+
isValidThemeMode,
|
17
18
|
lazyCreateDefaultTheme,
|
18
19
|
type UxThemeOptions,
|
19
20
|
} from './theme';
|
@@ -225,11 +226,20 @@ function ColorSchemeProvider({
|
|
225
226
|
[mode, prefer, toggleMode, changeMode]
|
226
227
|
);
|
227
228
|
|
228
|
-
//
|
229
|
+
// 相应 prefer 或 urlTheme 的改变
|
229
230
|
useEffect(() => {
|
230
231
|
setMode(resolveMode(prefer));
|
231
232
|
}, [prefer, setMode, location.search]);
|
232
233
|
|
234
|
+
// 会话缓存 urlTheme 便于 App Launching 阶段临时统一 theme mode
|
235
|
+
useEffect(() => {
|
236
|
+
const urlTheme = new URLSearchParams(location.search).get('theme');
|
237
|
+
|
238
|
+
if (isValidThemeMode(urlTheme)) {
|
239
|
+
sessionStorage.setItem(BLOCKLET_THEME_PREFER_KEY, urlTheme);
|
240
|
+
}
|
241
|
+
}, [location.search]);
|
242
|
+
|
233
243
|
return (
|
234
244
|
<ColorSchemeContext.Provider value={colorSchemeValue}>
|
235
245
|
<BaseThemeProvider theme={theme} {...rest}>
|
package/src/Theme/theme.ts
CHANGED
@@ -81,29 +81,40 @@ export function loadFonts(fonts: string[]) {
|
|
81
81
|
}
|
82
82
|
|
83
83
|
// 获取默认主题偏好
|
84
|
+
export function isValidThemeMode(mode: any): mode is PaletteMode {
|
85
|
+
return mode === 'light' || mode === 'dark';
|
86
|
+
}
|
87
|
+
|
84
88
|
export function getDefaultThemePrefer(meta?: { theme: { prefer: 'light' | 'dark' | 'system' } }): PaletteMode {
|
85
89
|
// 跟随 url theme 参数
|
86
90
|
const urlParams = new URLSearchParams(window.location.search);
|
87
91
|
const urlPrefer = urlParams.get('theme');
|
88
|
-
if (urlPrefer
|
92
|
+
if (isValidThemeMode(urlPrefer)) {
|
89
93
|
return urlPrefer;
|
90
94
|
}
|
91
95
|
|
96
|
+
// 跟随 session theme
|
97
|
+
const sessionPrefer = sessionStorage.getItem(BLOCKLET_THEME_PREFER_KEY);
|
98
|
+
if (isValidThemeMode(sessionPrefer)) {
|
99
|
+
return sessionPrefer;
|
100
|
+
}
|
101
|
+
|
102
|
+
// 跟随 blocklet theme mode
|
92
103
|
const prefer = Object.assign({}, window.blocklet, meta).theme?.prefer;
|
104
|
+
if (prefer === 'light' || prefer === 'dark') {
|
105
|
+
return prefer;
|
106
|
+
}
|
107
|
+
|
93
108
|
if (prefer === 'system') {
|
94
109
|
// 跟随本地缓存
|
95
|
-
const localPrefer = localStorage.getItem(BLOCKLET_THEME_PREFER_KEY)
|
96
|
-
if (
|
110
|
+
const localPrefer = localStorage.getItem(BLOCKLET_THEME_PREFER_KEY);
|
111
|
+
if (isValidThemeMode(localPrefer)) {
|
97
112
|
return localPrefer;
|
98
113
|
}
|
99
114
|
|
100
115
|
// 跟随系统
|
101
116
|
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
|
102
117
|
}
|
103
|
-
// 跟随 blocklet theme mode
|
104
|
-
if (prefer === 'light' || prefer === 'dark') {
|
105
|
-
return prefer;
|
106
|
-
}
|
107
118
|
|
108
119
|
// fallback
|
109
120
|
return 'light';
|