@arcblock/ux 2.13.20 → 2.13.23

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.
Files changed (42) hide show
  1. package/lib/Config/config-provider.d.ts +6 -23
  2. package/lib/Config/config-provider.js +19 -80
  3. package/lib/Config/theme-mode-toggle.js +2 -2
  4. package/lib/DIDConnect/did-connect-container.d.ts +23 -0
  5. package/lib/DIDConnect/did-connect-container.js +270 -0
  6. package/lib/DIDConnect/did-connect-footer.d.ts +3 -1
  7. package/lib/DIDConnect/did-connect-footer.js +5 -3
  8. package/lib/DIDConnect/index.d.ts +1 -0
  9. package/lib/DIDConnect/index.js +2 -1
  10. package/lib/NavMenu/images/payment-kit.png +0 -0
  11. package/lib/NavMenu/products.js +30 -4
  12. package/lib/NavMenu/style.js +2 -1
  13. package/lib/PhoneInput/index.js +2 -1
  14. package/lib/SessionUser/components/quick-login-item.js +4 -4
  15. package/lib/SessionUser/components/un-login.js +6 -5
  16. package/lib/SharedBridge/index.js +8 -8
  17. package/lib/SharedBridge/need-storage-access-api-dialog.d.ts +1 -2
  18. package/lib/SharedBridge/need-storage-access-api-dialog.js +2 -23
  19. package/lib/Theme/index.d.ts +1 -0
  20. package/lib/Theme/index.js +1 -0
  21. package/lib/Theme/theme-provider.d.ts +27 -12
  22. package/lib/Theme/theme-provider.js +123 -16
  23. package/lib/Theme/theme.d.ts +5 -4
  24. package/lib/Theme/theme.js +6 -5
  25. package/package.json +6 -6
  26. package/src/Config/config-provider.tsx +21 -103
  27. package/src/Config/theme-mode-toggle.tsx +2 -2
  28. package/src/DIDConnect/did-connect-container.tsx +320 -0
  29. package/src/DIDConnect/did-connect-footer.tsx +25 -19
  30. package/src/DIDConnect/index.ts +1 -0
  31. package/src/NavMenu/images/payment-kit.png +0 -0
  32. package/src/NavMenu/products.tsx +21 -4
  33. package/src/NavMenu/style.ts +2 -1
  34. package/src/PhoneInput/index.tsx +2 -1
  35. package/src/SessionUser/components/quick-login-item.tsx +3 -3
  36. package/src/SessionUser/components/un-login.tsx +5 -4
  37. package/src/SessionUser/components/user-info.tsx +1 -1
  38. package/src/SharedBridge/index.tsx +4 -12
  39. package/src/SharedBridge/need-storage-access-api-dialog.tsx +1 -23
  40. package/src/Theme/index.ts +1 -0
  41. package/src/Theme/theme-provider.tsx +144 -16
  42. package/src/Theme/theme.ts +8 -9
@@ -1,12 +1,42 @@
1
+ import { createContext, useCallback, useContext, useEffect, useMemo, useState } from 'react';
1
2
  import PropTypes from 'prop-types';
2
- import { GlobalStyles } from '@mui/material';
3
+ import { GlobalStyles, PaletteMode } from '@mui/material';
3
4
  import { ThemeProvider as MuiThemeProvider, Theme, useTheme } from '@mui/material/styles';
4
5
  import StyledEngineProvider from '@mui/material/StyledEngineProvider';
5
6
  import CssBaseline from '@mui/material/CssBaseline';
6
- import { createTheme } from './theme';
7
+ import set from 'lodash/set';
8
+ import { BLOCKLET_THEME_PREFER_KEY } from '@blocklet/theme';
9
+
10
+ import { createTheme, getDefaultThemePrefer, isTheme, lazyThemeConfig, type UserThemeOptions } from './theme';
7
11
 
8
12
  const defaultTheme = createTheme();
9
13
 
14
+ /** 颜色模式上下文类型 */
15
+ export interface ColorSchemeContextType {
16
+ mode: PaletteMode;
17
+ toggleMode: () => void;
18
+ prefer?: Prefer;
19
+ }
20
+
21
+ export const ColorSchemeContext = createContext<ColorSchemeContextType>({} as ColorSchemeContextType);
22
+ export function useColorScheme() {
23
+ return useContext(ColorSchemeContext);
24
+ }
25
+
26
+ /** 根据偏好获取颜色模式 */
27
+ const resolveMode = (prefer?: Prefer): PaletteMode => {
28
+ if (prefer) {
29
+ if (prefer === 'system') {
30
+ // 取系统默认
31
+ return getDefaultThemePrefer({ theme: { prefer: 'system' } });
32
+ }
33
+ return prefer;
34
+ }
35
+
36
+ return getDefaultThemePrefer();
37
+ };
38
+
39
+ /** 深色模式全局样式 */
10
40
  function DarkSchemeStyles({ className }: { className?: string }) {
11
41
  const theme = useTheme();
12
42
 
@@ -72,22 +102,35 @@ function DarkSchemeStyles({ className }: { className?: string }) {
72
102
  return null;
73
103
  }
74
104
 
75
- export interface ThemeProviderProps {
105
+ export type UxTheme = Partial<Theme> | ((outerTheme: Partial<Theme>) => Theme);
106
+ export type Prefer = 'light' | 'dark' | 'system';
107
+
108
+ interface BaseThemeProviderProps {
76
109
  children?: React.ReactNode;
77
- theme: Theme;
110
+ theme?: UxTheme;
78
111
  injectFirst?: boolean;
79
112
  /** 指定一个类名,DarkSchemeStyles 只会作用于带有该类的元素及其后代 */
80
113
  darkSchemeClass?: string;
81
114
  }
82
115
 
83
- /**
84
- * 默认的 theme provider, 可以为 webapp/blocklet 快捷的配置好 mui theme provider
85
- */
86
- export default function ThemeProvider({ children, theme, injectFirst, darkSchemeClass }: ThemeProviderProps) {
116
+ /** 基础的 theme provider, 可以为 webapp/blocklet 快捷的配置好 mui theme provider */
117
+ function BaseThemeProvider({
118
+ children,
119
+ theme = defaultTheme,
120
+ injectFirst = true,
121
+ darkSchemeClass = '',
122
+ }: BaseThemeProviderProps) {
123
+ const _theme = useMemo(() => {
124
+ if (isTheme(theme)) return theme;
125
+
126
+ // 是 ThemeOptions 则创建一个 theme
127
+ return createTheme(theme);
128
+ }, [theme]);
129
+
87
130
  return (
88
131
  // injectFirst 会影响 makeStyles 自定义样式和 mui styles 覆盖问题
89
132
  <StyledEngineProvider injectFirst={injectFirst}>
90
- <MuiThemeProvider theme={theme}>
133
+ <MuiThemeProvider theme={_theme}>
91
134
  <CssBaseline />
92
135
  <DarkSchemeStyles className={darkSchemeClass} />
93
136
  {children}
@@ -96,16 +139,101 @@ export default function ThemeProvider({ children, theme, injectFirst, darkScheme
96
139
  );
97
140
  }
98
141
 
142
+ interface ColorSchemeProviderProps extends BaseThemeProviderProps {
143
+ prefer?: Prefer;
144
+ disableBlockletTheme?: boolean;
145
+ }
146
+
147
+ /** 带颜色模式切换功能的 theme provider */
148
+ function ColorSchemeProvider({
149
+ children,
150
+ theme: themeInput,
151
+ prefer,
152
+ disableBlockletTheme = false,
153
+ ...rest
154
+ }: ThemeProviderProps) {
155
+ const [mode, setMode] = useState<PaletteMode>(() => resolveMode(prefer));
156
+
157
+ const _themeInput = useMemo(() => {
158
+ let result: UserThemeOptions = {};
159
+ const getThemeConfig = lazyThemeConfig(mode);
160
+
161
+ if (themeInput) {
162
+ if (typeof themeInput === 'function') {
163
+ result = { ...themeInput(getThemeConfig()) };
164
+ } else {
165
+ result = { ...themeInput };
166
+ }
167
+ }
168
+
169
+ set(result, 'palette.mode', mode);
170
+ set(result, 'mode', mode);
171
+
172
+ return result;
173
+ }, [mode, themeInput]);
174
+
175
+ const theme = useMemo(() => {
176
+ return createTheme({ ..._themeInput, disableBlockletTheme });
177
+ }, [_themeInput, disableBlockletTheme]);
178
+
179
+ // 切换明/暗模式
180
+ const toggleMode = useCallback(() => {
181
+ const newMode = mode === 'light' ? 'dark' : 'light';
182
+ setMode(newMode);
183
+ localStorage.setItem(BLOCKLET_THEME_PREFER_KEY, newMode);
184
+ }, [mode, setMode]);
185
+
186
+ const colorSchemeValue = useMemo(
187
+ () => ({
188
+ mode,
189
+ toggleMode,
190
+ prefer,
191
+ }),
192
+ [mode, prefer, toggleMode]
193
+ );
194
+
195
+ useEffect(() => {
196
+ if (prefer) {
197
+ setMode(resolveMode(prefer));
198
+ }
199
+ }, [prefer, setMode]);
200
+
201
+ return (
202
+ <ColorSchemeContext.Provider value={colorSchemeValue}>
203
+ <BaseThemeProvider theme={theme} {...rest}>
204
+ {children}
205
+ </BaseThemeProvider>
206
+ </ColorSchemeContext.Provider>
207
+ );
208
+ }
209
+
210
+ export interface ThemeProviderProps extends ColorSchemeProviderProps {
211
+ /** 下列情况会启用 ColorScheme 功能(让 theme 支持明暗模式切换)
212
+ * 1. 显示打开 enableColorScheme
213
+ * 2. 显示设置 prefer
214
+ * 3. 顶层 ThemeProvider
215
+ */
216
+ enableColorScheme?: boolean;
217
+ }
218
+
219
+ export default function ThemeProvider({ children, prefer, enableColorScheme = false, ...props }: ThemeProviderProps) {
220
+ const { toggleMode } = useColorScheme();
221
+
222
+ if (enableColorScheme || prefer || !toggleMode) {
223
+ return (
224
+ <ColorSchemeProvider prefer={prefer} {...props}>
225
+ {children}
226
+ </ColorSchemeProvider>
227
+ );
228
+ }
229
+
230
+ return <BaseThemeProvider {...props}>{children}</BaseThemeProvider>;
231
+ }
232
+
99
233
  ThemeProvider.propTypes = {
100
234
  children: PropTypes.any,
101
235
  theme: PropTypes.any,
102
236
  injectFirst: PropTypes.bool,
103
237
  darkSchemeClass: PropTypes.string,
104
- };
105
-
106
- ThemeProvider.defaultProps = {
107
- children: null,
108
- theme: defaultTheme,
109
- injectFirst: true,
110
- darkSchemeClass: '',
238
+ enableColorScheme: PropTypes.bool,
111
239
  };
@@ -3,7 +3,6 @@
3
3
  import type { PaletteMode, Theme } from '@mui/material';
4
4
  import { createTheme as _createTheme, responsiveFontSizes, type ThemeOptions } from '@mui/material/styles';
5
5
  import { deepmerge } from '@mui/utils';
6
- import pick from 'lodash/pick';
7
6
  import webfontloader from 'webfontloader';
8
7
  import { BLOCKLET_THEME_LIGHT, BLOCKLET_THEME_DARK, DEFAULT_FONTS, BLOCKLET_THEME_PREFER_KEY } from '@blocklet/theme';
9
8
  import { cleanedObj, deepmergeAll } from '../Util';
@@ -16,6 +15,11 @@ import '@fontsource/roboto/latin-ext-400.css';
16
15
  import '@fontsource/roboto/latin-ext-500.css';
17
16
  import '@fontsource/roboto/latin-ext-700.css';
18
17
 
18
+ /** 是否是 MUI Theme 对象 */
19
+ export function isTheme(obj: any): obj is Theme {
20
+ return obj && typeof obj === 'object' && obj.palette && typeof obj.palette.getContrastText === 'function';
21
+ }
22
+
19
23
  // 收集字体配置
20
24
  export function collectFontFamilies(obj?: { fontFamily?: string }, fontSet: Set<string> = new Set()): Set<string> {
21
25
  if (!obj || typeof obj !== 'object') return fontSet;
@@ -108,18 +112,13 @@ export interface UserThemeOptions extends ThemeOptions {
108
112
  }
109
113
 
110
114
  // 用于获取 Blocklet Theme 配置,便于用户创建自定义主题
111
- export type ThemeConfig = Pick<Theme, 'palette'>;
112
115
  export function lazyThemeConfig(mode: PaletteMode) {
113
- const fields = ['palette'];
114
- let config: ThemeConfig | null = null;
116
+ let config: Partial<Theme> | null = null;
115
117
 
116
118
  return () => {
117
119
  if (config) return config;
118
120
 
119
- config = deepmerge(
120
- pick(createDefaultThemeOptions(mode), fields),
121
- pick(window.blocklet?.theme?.[mode] ?? {}, fields)
122
- ) as ThemeConfig;
121
+ config = deepmerge(createDefaultThemeOptions(mode), window.blocklet?.theme?.[mode] ?? {}) as Partial<Theme>;
123
122
 
124
123
  return config;
125
124
  };
@@ -167,7 +166,7 @@ const defaultUserThemeOptions: UserThemeOptions = {
167
166
  };
168
167
 
169
168
  // https://material-ui.com/customization/default-theme/
170
- export const create = (...args: Array<UserThemeOptions | ((config: ThemeConfig) => UserThemeOptions)>) => {
169
+ export const create = (...args: Array<UserThemeOptions | ((config: Partial<Theme>) => UserThemeOptions)>) => {
171
170
  const defaultPrefer = getDefaultThemePrefer();
172
171
  const getThemeConfig = lazyThemeConfig(defaultPrefer);
173
172
  const userThemeOptions = args.reduce<UserThemeOptions>(