@arcblock/ux 2.13.12 → 2.13.13

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 (95) hide show
  1. package/lib/ActivityIndicator/index.js +9 -5
  2. package/lib/Address/did-address.js +14 -7
  3. package/lib/BlockletV2/blocklet.js +1 -1
  4. package/lib/CloseButton/index.js +1 -2
  5. package/lib/Colors/index.d.ts +1 -3
  6. package/lib/Colors/index.js +2 -4
  7. package/lib/Colors/themes/default.d.ts +3 -66
  8. package/lib/Colors/themes/default.js +4 -74
  9. package/lib/Colors/themes/did-connect.d.ts +11 -6
  10. package/lib/Colors/themes/did-connect.js +17 -12
  11. package/lib/Colors/themes/temp.d.ts +3 -0
  12. package/lib/Colors/themes/temp.js +3 -0
  13. package/lib/Config/config-provider.d.ts +4 -5
  14. package/lib/Config/config-provider.js +7 -26
  15. package/lib/Config/theme-mode-toggle.js +0 -1
  16. package/lib/DID/index.js +3 -4
  17. package/lib/Datatable/CustomToolbar.js +3 -0
  18. package/lib/Datatable/index.js +105 -71
  19. package/lib/Footer/index.js +2 -5
  20. package/lib/Header/header.js +3 -1
  21. package/lib/Header/responsive-header.js +3 -1
  22. package/lib/Layout/dashboard/index.js +14 -2
  23. package/lib/Layout/dashboard/sidebar.js +1 -2
  24. package/lib/LoadingMask/index.js +4 -3
  25. package/lib/Locale/selector.js +3 -3
  26. package/lib/NavMenu/nav-menu.js +14 -9
  27. package/lib/NavMenu/products.js +3 -1
  28. package/lib/NavMenu/style.js +7 -3
  29. package/lib/NavMenu/sub-item-group.js +1 -1
  30. package/lib/PhoneInput/country-select.js +2 -3
  31. package/lib/SessionBlocklet/index.js +3 -3
  32. package/lib/SessionUser/components/did-space.js +14 -28
  33. package/lib/SessionUser/components/logged-in.js +2 -2
  34. package/lib/SessionUser/components/quick-login-item.js +13 -11
  35. package/lib/SessionUser/components/session-user-item.js +5 -6
  36. package/lib/SessionUser/components/session-user-switch.js +15 -13
  37. package/lib/SessionUser/components/un-login.js +9 -7
  38. package/lib/SessionUser/components/user-info.js +9 -8
  39. package/lib/SessionUser/images/did-spaces.svg +7 -13
  40. package/lib/Success/index.js +8 -4
  41. package/lib/Switch/index.js +3 -3
  42. package/lib/Tabs/index.js +8 -9
  43. package/lib/Theme/theme-provider.d.ts +5 -1
  44. package/lib/Theme/theme-provider.js +60 -5
  45. package/lib/Theme/theme.d.ts +6 -3
  46. package/lib/Theme/theme.js +55 -19
  47. package/lib/UserCard/Container/card.js +1 -1
  48. package/lib/UserCard/Container/dialog.js +1 -1
  49. package/lib/Util/index.d.ts +8 -0
  50. package/lib/Util/index.js +23 -1
  51. package/lib/type.d.ts +5 -1
  52. package/package.json +7 -6
  53. package/src/ActivityIndicator/index.jsx +4 -4
  54. package/src/Address/did-address.tsx +5 -5
  55. package/src/BlockletV2/blocklet.tsx +1 -1
  56. package/src/CloseButton/index.tsx +1 -2
  57. package/src/Colors/index.ts +2 -7
  58. package/src/Colors/themes/default.ts +4 -50
  59. package/src/Colors/themes/did-connect.ts +13 -6
  60. package/src/Colors/themes/temp.ts +3 -0
  61. package/src/Config/config-provider.tsx +17 -30
  62. package/src/Config/theme-mode-toggle.tsx +1 -1
  63. package/src/DID/index.tsx +3 -4
  64. package/src/Datatable/CustomToolbar.jsx +1 -0
  65. package/src/Datatable/index.jsx +107 -70
  66. package/src/Footer/index.tsx +2 -2
  67. package/src/Header/header.tsx +1 -1
  68. package/src/Header/responsive-header.tsx +2 -0
  69. package/src/Layout/dashboard/index.tsx +8 -4
  70. package/src/Layout/dashboard/sidebar.tsx +1 -2
  71. package/src/LoadingMask/index.tsx +3 -4
  72. package/src/Locale/selector.tsx +3 -4
  73. package/src/NavMenu/nav-menu.tsx +15 -10
  74. package/src/NavMenu/products.tsx +1 -1
  75. package/src/NavMenu/style.ts +5 -2
  76. package/src/NavMenu/sub-item-group.tsx +1 -1
  77. package/src/PhoneInput/country-select.tsx +2 -3
  78. package/src/SessionBlocklet/index.tsx +3 -3
  79. package/src/SessionUser/components/did-space.tsx +14 -10
  80. package/src/SessionUser/components/logged-in.tsx +2 -2
  81. package/src/SessionUser/components/quick-login-item.tsx +11 -12
  82. package/src/SessionUser/components/session-user-item.tsx +3 -6
  83. package/src/SessionUser/components/session-user-switch.tsx +13 -12
  84. package/src/SessionUser/components/un-login.tsx +7 -6
  85. package/src/SessionUser/components/user-info.tsx +7 -8
  86. package/src/SessionUser/images/did-spaces.svg +7 -13
  87. package/src/Success/index.tsx +6 -4
  88. package/src/Switch/index.jsx +3 -3
  89. package/src/Tabs/index.tsx +8 -9
  90. package/src/Theme/theme-provider.tsx +73 -2
  91. package/src/Theme/theme.ts +73 -22
  92. package/src/UserCard/Container/card.tsx +1 -1
  93. package/src/UserCard/Container/dialog.tsx +1 -1
  94. package/src/Util/index.ts +25 -0
  95. package/src/type.d.ts +5 -1
@@ -1,6 +1,5 @@
1
1
  import { Tabs as MuiTabs, Tab as MuiTab, type TabsProps as MuiTabsProps } from '@mui/material';
2
2
 
3
- import { temp as colors } from '../Colors';
4
3
  import { styled } from '../Theme';
5
4
 
6
5
  const PREFIX = 'index';
@@ -47,7 +46,7 @@ function CardTabs({ tabs, current, onChange, ...rest }: CardTabsProps) {
47
46
  },
48
47
  '.MuiTabs-flexContainer': {
49
48
  borderRadius: '100vw',
50
- backgroundColor: colors.backgroundsBgComponent,
49
+ backgroundColor: 'grey.200',
51
50
  padding: 0.5,
52
51
  display: 'inline-flex',
53
52
  columnGap: 0.25,
@@ -60,15 +59,15 @@ function CardTabs({ tabs, current, onChange, ...rest }: CardTabsProps) {
60
59
  minHeight: 'auto',
61
60
  lineHeight: 1,
62
61
  py: 1,
63
- color: colors.foregroundsFgSubtile,
62
+ color: 'text.secondary',
64
63
  fontSize: '13px',
65
64
  fontWeight: 'normal',
66
65
  textTransform: 'capitalize',
67
66
  transition: 'background-color 0.2s ease',
68
67
  '&.Mui-selected, &:hover': {
69
68
  backgroundColor: 'white',
70
- borderColor: colors.lineBorderBase,
71
- color: colors.foregroundsFgBase,
69
+ borderColor: 'grey.100',
70
+ color: 'grey.A700',
72
71
  },
73
72
  },
74
73
  '.MuiTabs-indicator': {
@@ -115,7 +114,7 @@ function LineTabs({ tabs, current, onChange, ...rest }: LineTabsProps) {
115
114
  zIndex: -1,
116
115
  width: '100%',
117
116
  height: '1px',
118
- backgroundColor: colors.strokeBorderStrong,
117
+ backgroundColor: 'grey.300',
119
118
  },
120
119
  }
121
120
  : {},
@@ -131,18 +130,18 @@ function LineTabs({ tabs, current, onChange, ...rest }: LineTabsProps) {
131
130
  lineHeight: 1,
132
131
  py: 1,
133
132
  px: 0,
134
- color: colors.foregroundsFgSubtile,
133
+ color: 'text.secondary',
135
134
  fontSize: '14px',
136
135
  fontWeight: 500,
137
136
  textTransform: 'capitalize',
138
137
  minWidth: 'auto',
139
138
  '&.Mui-selected, &:hover': {
140
- color: colors.foregroundsFgBase,
139
+ color: 'primary.main',
141
140
  },
142
141
  },
143
142
  '.MuiTabs-indicator': {
144
143
  height: '1px',
145
- backgroundColor: colors.foregroundsFgBase,
144
+ backgroundColor: 'primary.main',
146
145
  },
147
146
  ...rest.sx,
148
147
  }}>
@@ -1,26 +1,95 @@
1
1
  import PropTypes from 'prop-types';
2
- import { ThemeProvider as MuiThemeProvider, Theme } from '@mui/material/styles';
2
+ import { GlobalStyles } from '@mui/material';
3
+ import { ThemeProvider as MuiThemeProvider, Theme, useTheme } from '@mui/material/styles';
3
4
  import StyledEngineProvider from '@mui/material/StyledEngineProvider';
4
5
  import CssBaseline from '@mui/material/CssBaseline';
5
6
  import { createTheme } from './theme';
6
7
 
7
8
  const defaultTheme = createTheme();
8
9
 
10
+ function DarkSchemeStyles({ className }: { className?: string }) {
11
+ const theme = useTheme();
12
+
13
+ if (theme.palette.mode === 'dark') {
14
+ const trackColor = 'transparent';
15
+ const thumbColor = theme.palette.grey[300];
16
+
17
+ // 处理作用域选择器
18
+ const prefix = (className || '')
19
+ .trim()
20
+ .split(/\s+/)
21
+ .filter(Boolean)
22
+ .map((c) => (c.startsWith('.') ? c : `.${c}`))
23
+ .join(' ');
24
+
25
+ const webkitScrollbar = prefix
26
+ ? `${prefix}::-webkit-scrollbar, ${prefix} *::-webkit-scrollbar`
27
+ : '*::-webkit-scrollbar';
28
+ const webkitTrack = prefix
29
+ ? `${prefix}::-webkit-scrollbar-track, ${prefix} *::-webkit-scrollbar-track`
30
+ : '*::-webkit-scrollbar-track';
31
+ const webkitThumb = prefix
32
+ ? `${prefix}::-webkit-scrollbar-thumb, ${prefix} *::-webkit-scrollbar-thumb`
33
+ : '*::-webkit-scrollbar-thumb';
34
+ const firefoxSelector = prefix ? `${prefix}, ${prefix} *` : '*';
35
+
36
+ return (
37
+ <GlobalStyles
38
+ styles={{
39
+ // Chrome, Safari, Edge
40
+ '@supports selector(::-webkit-scrollbar)': {
41
+ [webkitScrollbar]: {
42
+ width: '12px',
43
+ height: '12px',
44
+ },
45
+ [webkitTrack]: {
46
+ background: trackColor,
47
+ },
48
+ [webkitThumb]: {
49
+ background: thumbColor,
50
+ borderRadius: '6px',
51
+ border: '2px solid',
52
+ borderColor: trackColor,
53
+ backgroundClip: 'padding-box',
54
+ '&:hover': {
55
+ background: theme.palette.grey[400],
56
+ backgroundClip: 'padding-box',
57
+ },
58
+ },
59
+ },
60
+ // Firefox
61
+ '@supports not selector(::-webkit-scrollbar)': {
62
+ [firefoxSelector]: {
63
+ scrollbarWidth: 'auto',
64
+ scrollbarColor: `${thumbColor} ${trackColor}`,
65
+ },
66
+ },
67
+ }}
68
+ />
69
+ );
70
+ }
71
+
72
+ return null;
73
+ }
74
+
9
75
  export interface ThemeProviderProps {
10
76
  children?: React.ReactNode;
11
77
  theme: Theme;
12
78
  injectFirst?: boolean;
79
+ /** 指定一个类名,DarkSchemeStyles 只会作用于带有该类的元素及其后代 */
80
+ darkSchemeClass?: string;
13
81
  }
14
82
 
15
83
  /**
16
84
  * 默认的 theme provider, 可以为 webapp/blocklet 快捷的配置好 mui theme provider
17
85
  */
18
- export default function ThemeProvider({ children, theme, injectFirst }: ThemeProviderProps) {
86
+ export default function ThemeProvider({ children, theme, injectFirst, darkSchemeClass }: ThemeProviderProps) {
19
87
  return (
20
88
  // injectFirst 会影响 makeStyles 自定义样式和 mui styles 覆盖问题
21
89
  <StyledEngineProvider injectFirst={injectFirst}>
22
90
  <MuiThemeProvider theme={theme}>
23
91
  <CssBaseline />
92
+ <DarkSchemeStyles className={darkSchemeClass} />
24
93
  {children}
25
94
  </MuiThemeProvider>
26
95
  </StyledEngineProvider>
@@ -31,10 +100,12 @@ ThemeProvider.propTypes = {
31
100
  children: PropTypes.any,
32
101
  theme: PropTypes.any,
33
102
  injectFirst: PropTypes.bool,
103
+ darkSchemeClass: PropTypes.string,
34
104
  };
35
105
 
36
106
  ThemeProvider.defaultProps = {
37
107
  children: null,
38
108
  theme: defaultTheme,
39
109
  injectFirst: true,
110
+ darkSchemeClass: '',
40
111
  };
@@ -1,12 +1,13 @@
1
1
  /* eslint-disable no-shadow */
2
2
  // https://app.zeplin.io/styleguide/5d1436f1e97c2156f49c0725/colors
3
- import type { PaletteMode } from '@mui/material';
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';
6
7
  import webfontloader from 'webfontloader';
7
- import { BLOCKLET_THEME_LIGHT, BLOCKLET_THEME_DARK, DEFAULT_FONTS } from '@blocklet/theme';
8
+ import { BLOCKLET_THEME_LIGHT, BLOCKLET_THEME_DARK, DEFAULT_FONTS, BLOCKLET_THEME_PREFER_KEY } from '@blocklet/theme';
8
9
 
9
- import { cleanedObj } from '../Util';
10
+ import { cleanedObj, deepmergeAll } from '../Util';
10
11
 
11
12
  // 默认只加载最基本的 roboto latin 字体
12
13
  import '@fontsource/roboto/latin-400.css';
@@ -71,6 +72,29 @@ export function loadFonts(fonts: string[]) {
71
72
  });
72
73
  }
73
74
 
75
+ // 获取默认主题偏好
76
+ export function getDefaultThemePrefer(): PaletteMode {
77
+ const prefer = window.blocklet?.theme?.prefer;
78
+
79
+ if (prefer === 'system') {
80
+ // 本地缓存
81
+ const localPrefer = localStorage.getItem(BLOCKLET_THEME_PREFER_KEY) as PaletteMode;
82
+ if (localPrefer && (localPrefer === 'light' || localPrefer === 'dark')) {
83
+ return localPrefer;
84
+ }
85
+
86
+ // 跟随系统
87
+ return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
88
+ }
89
+
90
+ if (prefer === 'light' || prefer === 'dark') {
91
+ return prefer;
92
+ }
93
+
94
+ // 未设置偏好
95
+ return 'light';
96
+ }
97
+
74
98
  // 创建默认主题配置
75
99
  export function createDefaultThemeOptions(mode: PaletteMode = 'light') {
76
100
  if (mode === 'dark') {
@@ -84,20 +108,36 @@ export interface UserThemeOptions extends ThemeOptions {
84
108
  disableBlockletTheme?: boolean;
85
109
  }
86
110
 
87
- // 主要处理 mode overrides
88
- const normalizeUserThemeOptions = ({ mode = 'light', palette, components, overrides, ...rest }: UserThemeOptions) => {
89
- return {
90
- mode,
91
- palette: {
92
- ...palette,
93
- mode,
94
- },
111
+ // 用于获取 Blocklet Theme 配置,便于用户创建自定义主题
112
+ export type ThemeConfig = Pick<Theme, 'palette'>;
113
+ export function lazyThemeConfig(mode: PaletteMode) {
114
+ const fields = ['palette'];
115
+ let config: ThemeConfig | null = null;
116
+
117
+ return () => {
118
+ if (config) return config;
119
+
120
+ config = deepmerge(
121
+ pick(createDefaultThemeOptions(mode), fields),
122
+ pick(window.blocklet?.theme?.[mode] ?? {}, fields)
123
+ ) as ThemeConfig;
124
+
125
+ return config;
126
+ };
127
+ }
128
+
129
+ // 主要处理 overrides
130
+ const normalizeUserThemeOptions = ({ palette, components, overrides, ...rest }: UserThemeOptions) => {
131
+ const result: UserThemeOptions = {
132
+ palette,
95
133
  components: {
96
134
  ...overrides,
97
135
  ...components,
98
136
  },
99
137
  ...rest,
100
138
  };
139
+
140
+ return result;
101
141
  };
102
142
 
103
143
  const defaultUserThemeOptions: UserThemeOptions = {
@@ -128,21 +168,32 @@ const defaultUserThemeOptions: UserThemeOptions = {
128
168
  };
129
169
 
130
170
  // https://material-ui.com/customization/default-theme/
131
- export const create = (...args: UserThemeOptions[]) => {
132
- const userThemeOptions = args.reduce(
133
- (acc, curr) => deepmerge(acc, normalizeUserThemeOptions(curr)),
171
+ export const create = (...args: Array<UserThemeOptions | ((config: ThemeConfig) => UserThemeOptions)>) => {
172
+ const defaultPrefer = getDefaultThemePrefer();
173
+ const getThemeConfig = lazyThemeConfig(defaultPrefer);
174
+ const userThemeOptions = args.reduce<UserThemeOptions>(
175
+ (acc, curr) =>
176
+ deepmerge(acc, normalizeUserThemeOptions(typeof curr === 'function' ? curr(getThemeConfig()) : curr)),
134
177
  normalizeUserThemeOptions(defaultUserThemeOptions)
135
178
  );
136
- const { mode, disableBlockletTheme } = userThemeOptions;
137
- const blockletThemeOptions = window.blocklet?.theme?.[mode] ?? {};
138
- const defaultThemeOptions = createDefaultThemeOptions(mode);
179
+ const prefer = userThemeOptions.mode || userThemeOptions.palette?.mode || defaultPrefer;
180
+ const blockletThemeOptions = window.blocklet?.theme?.[prefer] ?? {};
181
+ const defaultThemeOptions = createDefaultThemeOptions(prefer);
182
+ const { disableBlockletTheme } = userThemeOptions;
139
183
 
140
184
  // 合并配置
141
- let mergedThemeOptions = defaultThemeOptions;
142
- if (!disableBlockletTheme) {
143
- mergedThemeOptions = deepmerge(defaultThemeOptions, cleanedObj(blockletThemeOptions));
144
- }
145
- mergedThemeOptions = deepmerge(mergedThemeOptions, cleanedObj(userThemeOptions));
185
+ const mergedThemeOptions = deepmergeAll(
186
+ [
187
+ defaultThemeOptions,
188
+ !disableBlockletTheme && cleanedObj(blockletThemeOptions),
189
+ cleanedObj(userThemeOptions),
190
+ // 确保 mode 跟 prefer 一致
191
+ {
192
+ mode: prefer,
193
+ palette: { mode: prefer },
194
+ },
195
+ ].filter(Boolean) as ThemeOptions[]
196
+ );
146
197
 
147
198
  // 创建主题
148
199
  const theme = _createTheme(mergedThemeOptions);
@@ -24,7 +24,7 @@ function CardContainer({
24
24
  const commonStyles = {
25
25
  minWidth: 320,
26
26
  p: 2,
27
- borderRadius: 2,
27
+ borderRadius: 1,
28
28
  ...(cardType === CardType.Detailed
29
29
  ? {
30
30
  border: '1px solid',
@@ -22,7 +22,7 @@ function DialogContainer({ children, sx }: DialogContainerProps) {
22
22
  backgroundColor: theme.palette.background.paper,
23
23
  border: '1px solid',
24
24
  borderColor: 'divider',
25
- borderRadius: 2,
25
+ borderRadius: 1,
26
26
  maxWidth: 500,
27
27
  minWidth: 320,
28
28
  display: 'flex',
package/src/Util/index.ts CHANGED
@@ -5,6 +5,7 @@ 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 deepmerge, { type DeepmergeOptions } from '@mui/utils/deepmerge';
8
9
  import { DID_PREFIX, BLOCKLET_SERVICE_PATH_PREFIX } from './constant';
9
10
  import type { $TSFixMe, Locale } from '../type';
10
11
 
@@ -538,3 +539,27 @@ export const lazyRetry = (fn: () => Promise<any>) =>
538
539
  export const cleanedObj = (obj: object) => {
539
540
  return omitBy(obj, isNil);
540
541
  };
542
+
543
+ /**
544
+ * 依次对数组中的对象进行深度合并
545
+ * @param objects - 需要合并的对象数组
546
+ * @param options - deepmerge 的配置选项
547
+ * @returns 合并后的对象
548
+ */
549
+ export function deepmergeAll<T>(objects: T[], options?: DeepmergeOptions): T {
550
+ if (!Array.isArray(objects)) {
551
+ throw new Error('First argument should be an array');
552
+ }
553
+
554
+ if (objects.length === 0) {
555
+ return {} as T;
556
+ }
557
+
558
+ if (objects.length === 1) {
559
+ return objects[0];
560
+ }
561
+
562
+ return objects.reduce((acc, obj) => {
563
+ return deepmerge(acc, obj, options);
564
+ });
565
+ }
package/src/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: Record<PaletteMode, 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: {