@arcblock/ux 2.10.65 → 2.10.67

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 (121) hide show
  1. package/lib/ActionButton/index.d.ts +1 -1
  2. package/lib/Alert/index.d.ts +1 -1
  3. package/lib/AnimationWaiter/index.d.ts +27 -15
  4. package/lib/AnimationWaiter/index.js +15 -14
  5. package/lib/Async/index.d.ts +50 -17
  6. package/lib/Badge/index.d.ts +1 -1
  7. package/lib/Badge/index.js +7 -1
  8. package/lib/BlockletContext/index.d.ts +12 -28
  9. package/lib/BlockletContext/index.js +3 -21
  10. package/lib/Button/wrap.d.ts +5 -3
  11. package/lib/Button/wrap.js +2 -1
  12. package/lib/ButtonGroup/index.d.ts +12 -2
  13. package/lib/ButtonGroup/index.js +13 -3
  14. package/lib/CardSelector/index.d.ts +11 -33
  15. package/lib/CardSelector/index.js +16 -32
  16. package/lib/Center/index.d.ts +6 -21
  17. package/lib/Center/index.js +2 -17
  18. package/lib/ClickToCopy/copy-button.d.ts +9 -26
  19. package/lib/ClickToCopy/copy-button.js +5 -17
  20. package/lib/ClickToCopy/hook.d.ts +11 -5
  21. package/lib/ClickToCopy/hook.js +3 -3
  22. package/lib/ClickToCopy/index.d.ts +18 -29
  23. package/lib/ClickToCopy/index.js +0 -13
  24. package/lib/CodeBlock/LightBox.d.ts +1 -1
  25. package/lib/CodeBlock/index.d.ts +7 -26
  26. package/lib/CodeBlock/index.js +4 -17
  27. package/lib/Colors/index.d.ts +2 -2
  28. package/lib/Colors/themes/default.d.ts +54 -61
  29. package/lib/Colors/themes/temp.d.ts +35 -35
  30. package/lib/ContactForm/index.d.ts +26 -30
  31. package/lib/ContactForm/index.js +7 -17
  32. package/lib/Dialog/confirm.d.ts +3 -3
  33. package/lib/Dialog/confirm.js +2 -2
  34. package/lib/Earth/index.d.ts +10 -1
  35. package/lib/Header/auto-hidden.d.ts +6 -11
  36. package/lib/Header/auto-hidden.js +0 -5
  37. package/lib/Header/header.d.ts +20 -51
  38. package/lib/Header/header.js +10 -42
  39. package/lib/Header/index.d.ts +2 -2
  40. package/lib/Header/responsive-header.d.ts +10 -22
  41. package/lib/Header/responsive-header.js +1 -13
  42. package/lib/Icon/image.d.ts +8 -36
  43. package/lib/Icon/image.js +6 -24
  44. package/lib/Icon/index.d.ts +9 -1
  45. package/lib/Icon/index.js +6 -25
  46. package/lib/NavMenu/index.d.ts +1 -1
  47. package/lib/NavMenu/nav-menu.d.ts +37 -51
  48. package/lib/NavMenu/nav-menu.js +47 -102
  49. package/lib/NavMenu/style.d.ts +8 -2
  50. package/lib/NavMenu/style.js +3 -1
  51. package/lib/PageScroller/index.d.ts +13 -1
  52. package/lib/Passport/passport.js +1 -1
  53. package/lib/PricingTable/index.d.ts +3 -1
  54. package/lib/RelativeTime/index.d.ts +1 -1
  55. package/lib/Screenshot/BaseScreenshot/index.js +1 -1
  56. package/lib/SplitButton/index.d.ts +0 -19
  57. package/lib/SplitButton/index.js +7 -27
  58. package/lib/TextCollapse/index.d.ts +10 -1
  59. package/lib/Theme/index.d.ts +5 -13
  60. package/lib/Theme/index.js +4 -11
  61. package/lib/Theme/theme-provider.d.ts +16 -18
  62. package/lib/Theme/theme.d.ts +37 -11
  63. package/lib/Theme/theme.js +13 -22
  64. package/lib/Util/constant.d.ts +31 -31
  65. package/lib/Util/deprecate.d.ts +7 -5
  66. package/lib/Util/federated.d.ts +21 -21
  67. package/lib/Util/federated.js +1 -1
  68. package/lib/Util/index.d.ts +59 -60
  69. package/lib/Util/index.js +16 -43
  70. package/lib/Util/passport.d.ts +6 -6
  71. package/lib/Util/wallet.d.ts +15 -3
  72. package/lib/WebWalletSWKeeper/index.js +1 -1
  73. package/lib/global.d.ts +13 -0
  74. package/lib/index.d.ts +4 -2
  75. package/lib/index.js +2 -2
  76. package/lib/type.d.ts +31 -1
  77. package/package.json +5 -5
  78. package/src/AnimationWaiter/index.jsx +15 -14
  79. package/src/Async/{index.jsx → index.tsx} +13 -4
  80. package/src/Badge/index.jsx +8 -1
  81. package/src/BlockletContext/{index.jsx → index.tsx} +17 -22
  82. package/src/Button/wrap.jsx +2 -1
  83. package/src/ButtonGroup/index.js +13 -3
  84. package/src/CardSelector/{index.jsx → index.tsx} +32 -33
  85. package/src/Center/index.tsx +33 -0
  86. package/src/ClickToCopy/{copy-button.jsx → copy-button.tsx} +15 -16
  87. package/src/ClickToCopy/{hook.js → hook.ts} +5 -5
  88. package/src/ClickToCopy/{index.jsx → index.tsx} +12 -17
  89. package/src/CodeBlock/{index.jsx → index.tsx} +15 -17
  90. package/src/ContactForm/{index.jsx → index.tsx} +47 -29
  91. package/src/Dialog/confirm.jsx +2 -2
  92. package/src/Header/{auto-hidden.jsx → auto-hidden.tsx} +6 -7
  93. package/src/Header/{header.jsx → header.tsx} +32 -46
  94. package/src/Header/{responsive-header.jsx → responsive-header.tsx} +9 -15
  95. package/src/Icon/{image.jsx → image.tsx} +19 -22
  96. package/src/Icon/{index.jsx → index.tsx} +22 -24
  97. package/src/NavMenu/{nav-menu.jsx → nav-menu.tsx} +161 -144
  98. package/src/NavMenu/{style.js → style.ts} +9 -1
  99. package/src/Passport/passport.jsx +1 -1
  100. package/src/Screenshot/BaseScreenshot/index.jsx +1 -1
  101. package/src/SplitButton/index.tsx +10 -23
  102. package/src/Theme/{index.js → index.ts} +6 -12
  103. package/src/Theme/{theme-provider.jsx → theme-provider.tsx} +10 -2
  104. package/src/Theme/{theme.js → theme.ts} +54 -23
  105. package/src/Util/{deprecate.jsx → deprecate.tsx} +8 -4
  106. package/src/Util/{federated.js → federated.ts} +3 -3
  107. package/src/Util/{index.js → index.ts} +85 -59
  108. package/src/Util/{passport.js → passport.ts} +2 -2
  109. package/src/Util/{wallet.js → wallet.ts} +1 -1
  110. package/src/WebWalletSWKeeper/index.jsx +1 -1
  111. package/src/global.d.ts +13 -0
  112. package/src/{index.js → index.ts} +2 -2
  113. package/src/type.d.ts +31 -1
  114. package/src/Center/index.jsx +0 -41
  115. /package/src/CodeBlock/{LightBox.jsx → LightBox.tsx} +0 -0
  116. /package/src/Colors/{index.js → index.ts} +0 -0
  117. /package/src/Colors/themes/{default.js → default.ts} +0 -0
  118. /package/src/Colors/themes/{temp.js → temp.ts} +0 -0
  119. /package/src/Header/{index.js → index.ts} +0 -0
  120. /package/src/NavMenu/{index.js → index.ts} +0 -0
  121. /package/src/Util/{constant.js → constant.ts} +0 -0
@@ -1,3 +1,4 @@
1
+ /* eslint-disable no-unused-vars */
1
2
  import {
2
3
  Children,
3
4
  cloneElement,
@@ -7,42 +8,85 @@ import {
7
8
  useRef,
8
9
  forwardRef,
9
10
  useLayoutEffect,
11
+ isValidElement,
10
12
  } from 'react';
11
- import PropTypes from 'prop-types';
12
13
  import clsx from 'clsx';
13
14
  import { MoreHoriz as MoreHorizIcon, ExpandMore as ExpandMoreIcon, Menu as MenuIcon } from '@mui/icons-material';
14
15
  import { useCreation, useMemoizedFn, useReactive, useSize, useThrottleFn } from 'ahooks';
15
16
  import { HorizontalStyle, InlineStyle } from './style';
16
17
 
17
- const NavMenuContext = createContext();
18
+ const NavMenuContext = createContext<{
19
+ activeId: string | null;
20
+ openedIds: string[];
21
+ hiddenItemCount: number;
22
+ mode: 'horizontal' | 'vertical' | 'inline';
23
+ activate: (id: string) => void;
24
+ open: (id: string) => void;
25
+ close: (id: string) => void;
26
+ } | null>(null);
18
27
 
19
28
  // 过滤 children 中的 Item/Sub, 忽略其它类型的 element
20
- function filterItems(children) {
29
+ function filterItems(children: React.ReactNode) {
21
30
  if (children) {
22
31
  // eslint-disable-next-line no-use-before-define
23
- return Children.toArray(children).filter((child) => child.type === Item || child.type === Sub);
32
+ return Children.toArray(children).filter((child) => {
33
+ if (!isValidElement(child)) {
34
+ return false;
35
+ }
36
+ return child.type === Item || child.type === Sub;
37
+ }) as React.ReactElement[];
24
38
  }
25
39
  return null;
26
40
  }
27
41
 
28
- function useUniqueId(id) {
42
+ function useUniqueId(id?: string) {
29
43
  const _id = useRef(id || `navmenu-item-id-${Math.random().toString(36).slice(2)}`);
30
44
  return _id.current;
31
45
  }
32
46
 
47
+ export type ItemOptions = {
48
+ id?: string;
49
+ icon?: React.ReactNode;
50
+ label?: React.ReactNode;
51
+ active?: boolean;
52
+ children?: ItemOptions[];
53
+ };
54
+
55
+ export interface NavMenuProps extends React.HTMLAttributes<HTMLElement> {
56
+ items?: ItemOptions[];
57
+ mode?: 'horizontal' | 'vertical' | 'inline';
58
+ children?: React.ReactNode;
59
+ activeId?: string | null;
60
+ textColor?: string;
61
+ activeTextColor?: string;
62
+ bgColor?: string;
63
+ // eslint-disable-next-line no-unused-vars
64
+ onSelected?: (id: string) => void;
65
+ }
66
+
33
67
  /**
34
68
  * NavMenu, 导航组件, 可用于 header/footer/sidebar
35
69
  */
36
- function NavMenu({ items, mode, children, activeId, textColor, activeTextColor, bgColor, onSelected, ...rest }) {
70
+ function NavMenu({
71
+ items = [],
72
+ mode = 'horizontal',
73
+ children: _childs = null,
74
+ activeId = null,
75
+ textColor = '#9397a1',
76
+ activeTextColor = '#25292f',
77
+ bgColor = '#fff',
78
+ onSelected,
79
+ ...rest
80
+ }: NavMenuProps) {
37
81
  // eslint-disable-next-line no-param-reassign
38
- children = filterItems(children);
82
+ const children = filterItems(_childs);
39
83
  if (!items?.length && !children?.length) {
40
84
  throw new Error("One of 'items' or 'children' is required by NavMenu component.");
41
85
  }
42
86
 
43
87
  const currentState = useReactive({
44
88
  activeId,
45
- openedIds: [],
89
+ openedIds: [] as string[],
46
90
  hiddenItemCount: 0,
47
91
  });
48
92
 
@@ -50,7 +94,7 @@ function NavMenu({ items, mode, children, activeId, textColor, activeTextColor,
50
94
  currentState.activeId = id;
51
95
  onSelected?.(id);
52
96
  });
53
- const open = useMemoizedFn((id) => {
97
+ const open = useMemoizedFn((id: string) => {
54
98
  currentState.openedIds.push(id);
55
99
  });
56
100
  const close = useMemoizedFn((id) => {
@@ -67,9 +111,9 @@ function NavMenu({ items, mode, children, activeId, textColor, activeTextColor,
67
111
  };
68
112
  }, [currentState.activeId, currentState.hiddenItemCount, currentState.openedIds, mode, activate, open, close]);
69
113
 
70
- const navMenuRef = useRef();
71
- const itemRefs = useRef([]);
72
- const moreIconRef = useRef();
114
+ const navMenuRef = useRef<HTMLUListElement | null>(null);
115
+ const itemRefs = useRef<HTMLElement[]>([]);
116
+ const moreIconRef = useRef<HTMLLIElement | null>(null);
73
117
  const isAllItemsHidden = currentState.hiddenItemCount === itemRefs.current?.length;
74
118
  const style = isAllItemsHidden ? { marginLeft: '0px' } : undefined;
75
119
 
@@ -77,10 +121,10 @@ function NavMenu({ items, mode, children, activeId, textColor, activeTextColor,
77
121
  return isAllItemsHidden ? <MenuIcon /> : <MoreHorizIcon />;
78
122
  }, [isAllItemsHidden]);
79
123
 
80
- const renderChildrenWithRef = (childrenElement) => {
124
+ const renderChildrenWithRef = (childrenElement: React.ReactElement[]) => {
81
125
  return Children.map(childrenElement, (child, index) => {
82
126
  return cloneElement(child, {
83
- ref: (el) => {
127
+ ref: (el: HTMLElement) => {
84
128
  itemRefs.current[index] = el;
85
129
  },
86
130
  });
@@ -153,7 +197,7 @@ function NavMenu({ items, mode, children, activeId, textColor, activeTextColor,
153
197
 
154
198
  const classes = clsx('navmenu', `navmenu--${mode}`, rest.className);
155
199
 
156
- const renderItem = (item, index, isTopLevel = false) => {
200
+ const renderItem = (item: ItemOptions, index: number, isTopLevel = false) => {
157
201
  if (item?.children) {
158
202
  // 对于 Sub 组件,如果它是顶级组件,则包含 ref
159
203
  return (
@@ -165,11 +209,11 @@ function NavMenu({ items, mode, children, activeId, textColor, activeTextColor,
165
209
  ref={
166
210
  isTopLevel
167
211
  ? (el) => {
168
- itemRefs.current[index] = el;
212
+ itemRefs.current[index] = el!;
169
213
  }
170
214
  : undefined
171
215
  }>
172
- {item.children.map((childItem, childIndex) => renderItem(childItem, childIndex, false))}
216
+ {item.children.map((childItem, childIndex: number) => renderItem(childItem, childIndex, false))}
173
217
  </Sub>
174
218
  );
175
219
  }
@@ -185,7 +229,7 @@ function NavMenu({ items, mode, children, activeId, textColor, activeTextColor,
185
229
  ref={
186
230
  isTopLevel
187
231
  ? (el) => {
188
- itemRefs.current[index] = el;
232
+ itemRefs.current[index] = el!;
189
233
  }
190
234
  : undefined
191
235
  }
@@ -208,7 +252,7 @@ function NavMenu({ items, mode, children, activeId, textColor, activeTextColor,
208
252
  $activeTextColor={activeTextColor}
209
253
  $bgColor={bgColor}>
210
254
  <ul className="navmenu-root" ref={navMenuRef}>
211
- {items ? items.map((item, index) => renderItem(item, index, true)) : renderChildrenWithRef(children)}
255
+ {items ? items.map((item, index) => renderItem(item, index, true)) : renderChildrenWithRef(children || [])}
212
256
  {currentState.hiddenItemCount > 0 && (
213
257
  <Sub expandIcon={false} icon={icon} label="" ref={moreIconRef} style={style}>
214
258
  {content}
@@ -220,139 +264,112 @@ function NavMenu({ items, mode, children, activeId, textColor, activeTextColor,
220
264
  );
221
265
  }
222
266
 
223
- NavMenu.propTypes = {
224
- items: PropTypes.array,
225
- // 默认水平方向布局,
226
- // inline 模式: 垂直布局, 且通过 click 事件来收缩/伸展子菜单, 适用于移动端
227
- mode: PropTypes.oneOf(['horizontal', 'vertical', 'inline']),
228
- children: PropTypes.array,
229
- activeId: PropTypes.string,
230
- textColor: PropTypes.string,
231
- activeTextColor: PropTypes.string,
232
- bgColor: PropTypes.string,
233
- onSelected: PropTypes.func,
234
- };
235
- NavMenu.defaultProps = {
236
- items: null,
237
- mode: 'horizontal',
238
- children: null,
239
- activeId: null,
240
- textColor: '#9397a1',
241
- activeTextColor: '#25292f',
242
- bgColor: '#fff',
243
- onSelected: null,
244
- };
245
-
246
- /**
247
- * Item
248
- */
249
- const Item = forwardRef(({ id: _id, icon, label, active, onClick, ...rest }, ref) => {
250
- const id = useUniqueId(_id);
251
- const { activeId, activate } = useContext(NavMenuContext);
252
- const classes = clsx('navmenu-item', { 'navmenu-item--active': activeId === id }, rest.className);
253
-
254
- useEffect(() => {
255
- if (active) {
256
- activate(id);
257
- }
258
- // eslint-disable-next-line react-hooks/exhaustive-deps
259
- }, [active]);
267
+ export interface ItemProps extends React.HTMLAttributes<HTMLLIElement> {
268
+ id?: string;
269
+ icon?: React.ReactNode;
270
+ label?: React.ReactNode;
271
+ active?: boolean;
272
+ onClick?: () => void;
273
+ }
260
274
 
261
- const handleClick = () => {
262
- onClick?.();
263
- activate(id);
264
- };
275
+ const Item = forwardRef<HTMLLIElement, ItemProps>(
276
+ ({ id: _id = '', icon = null, label = '', active = false, onClick = null, ...rest }, ref) => {
277
+ const id = useUniqueId(_id);
278
+ const { activeId, activate } = useContext(NavMenuContext) || {};
279
+ const classes = clsx('navmenu-item', { 'navmenu-item--active': activeId === id }, rest.className);
265
280
 
266
- return (
267
- // eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions
268
- <li {...rest} className={classes} onClick={handleClick} ref={ref}>
269
- {icon && <span className="navmenu-item-icon">{icon}</span>}
270
- <span className="navmenu-item-label">{label}</span>
271
- </li>
272
- );
273
- });
274
-
275
- Item.propTypes = {
276
- id: PropTypes.string,
277
- icon: PropTypes.element,
278
- label: PropTypes.node,
279
- active: PropTypes.bool,
280
- onClick: PropTypes.func,
281
- };
281
+ useEffect(() => {
282
+ if (active) {
283
+ activate?.(id);
284
+ }
285
+ // eslint-disable-next-line react-hooks/exhaustive-deps
286
+ }, [active]);
282
287
 
283
- Item.defaultProps = {
284
- id: null,
285
- icon: null,
286
- label: '',
287
- active: false,
288
- onClick: null,
289
- };
288
+ const handleClick = () => {
289
+ onClick?.();
290
+ activate?.(id);
291
+ };
290
292
 
291
- /**
292
- * Sub
293
- */
294
- const Sub = forwardRef(({ id: _id, icon, label, children, expandIcon, ...rest }, ref) => {
295
- const id = useUniqueId(_id);
296
- const { openedIds, open, close, mode } = useContext(NavMenuContext);
297
- const isOpen = openedIds.includes(id);
298
- const classes = clsx('navmenu-sub', { 'navmenu-sub--opened': isOpen }, rest.className);
299
- const isInlineMode = mode === 'inline';
300
- // inline mode 时使用 click 事件控制收缩/伸展子菜单
301
- const props = isInlineMode
302
- ? {
303
- onClick: () => {
304
- if (openedIds.includes(id)) {
305
- close(id);
306
- } else {
307
- open(id);
308
- }
309
- },
310
- }
311
- : {
312
- onMouseEnter: () => open(id),
313
- onMouseLeave: () => close(id),
314
- };
315
- // inline mode, 避免点击子菜单项时触发父菜单的 open/close
316
- const containerProps = isInlineMode
317
- ? {
318
- onClick: (e) => e.stopPropagation(),
319
- }
320
- : {};
293
+ return (
294
+ // eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions
295
+ <li {...rest} className={classes} onClick={handleClick} ref={ref}>
296
+ {icon && <span className="navmenu-item-icon">{icon}</span>}
297
+ <span className="navmenu-item-label">{label}</span>
298
+ </li>
299
+ );
300
+ }
301
+ );
302
+
303
+ export interface SubProps extends React.HTMLAttributes<HTMLLIElement> {
304
+ id?: string;
305
+ icon?: React.ReactNode;
306
+ label?: React.ReactNode;
307
+ children?: Array<React.ReactElement>;
308
+ // eslint-disable-next-line no-unused-vars
309
+ expandIcon?: React.ReactNode | ((props: { isOpen: boolean }) => React.ReactNode);
310
+ }
321
311
 
322
- return (
323
- <li {...rest} className={classes} {...props} ref={ref}>
324
- {icon && <span className="navmenu-sub-icon">{icon}</span>}
325
- <span className="navmenu-sub-label">{label}</span>
326
- {expandIcon && <span className="navmenu-sub-expand-icon">{expandIcon?.({ isOpen }) || expandIcon}</span>}
327
- <div className="navmenu-sub-container" {...containerProps}>
328
- <ul className="navmenu-sub-list">{filterItems(children)}</ul>
329
- </div>
330
- </li>
331
- );
332
- });
333
-
334
- Sub.propTypes = {
335
- id: PropTypes.string,
336
- icon: PropTypes.element,
337
- label: PropTypes.node.isRequired,
338
- children: PropTypes.array.isRequired,
339
- expandIcon: PropTypes.oneOfType([PropTypes.node, PropTypes.func]),
340
- };
312
+ const Sub = forwardRef<HTMLLIElement, SubProps>(
313
+ (
314
+ {
315
+ id: _id = '',
316
+ icon = null,
317
+ label = null,
318
+ children,
319
+ expandIcon = ({ isOpen }) => (
320
+ <ExpandMoreIcon
321
+ style={{
322
+ transform: `rotate(${isOpen ? 180 : 0}deg)`,
323
+ }}
324
+ />
325
+ ),
326
+ ...rest
327
+ },
328
+ ref
329
+ ) => {
330
+ const id = useUniqueId(_id);
331
+ const { openedIds, open, close, mode } = useContext(NavMenuContext) || {};
332
+ const isOpen = openedIds?.includes(id) ?? false;
333
+ const classes = clsx('navmenu-sub', { 'navmenu-sub--opened': isOpen }, rest.className);
334
+ const isInlineMode = mode === 'inline';
335
+ // inline mode 时使用 click 事件控制收缩/伸展子菜单
336
+ const props = isInlineMode
337
+ ? {
338
+ onClick: () => {
339
+ if (openedIds?.includes(id)) {
340
+ close?.(id);
341
+ } else {
342
+ open?.(id);
343
+ }
344
+ },
345
+ }
346
+ : {
347
+ onMouseEnter: () => open?.(id),
348
+ onMouseLeave: () => close?.(id),
349
+ };
350
+ // inline mode, 避免点击子菜单项时触发父菜单的 open/close
351
+ const containerProps = isInlineMode
352
+ ? {
353
+ onClick: (e: React.MouseEvent) => e.stopPropagation(),
354
+ }
355
+ : {};
341
356
 
342
- Sub.defaultProps = {
343
- id: null,
344
- icon: null,
345
- // eslint-disable-next-line react/prop-types
346
- expandIcon: ({ isOpen }) => {
347
357
  return (
348
- <ExpandMoreIcon
349
- style={{
350
- transform: `rotate(${isOpen ? 180 : 0}deg)`,
351
- }}
352
- />
358
+ <li {...rest} className={classes} {...props} ref={ref}>
359
+ {icon && <span className="navmenu-sub-icon">{icon}</span>}
360
+ <span className="navmenu-sub-label">{label}</span>
361
+ {expandIcon && (
362
+ <span className="navmenu-sub-expand-icon">
363
+ {typeof expandIcon === 'function' ? expandIcon({ isOpen }) : expandIcon}
364
+ </span>
365
+ )}
366
+ <div className="navmenu-sub-container" {...containerProps}>
367
+ <ul className="navmenu-sub-list">{filterItems(children)}</ul>
368
+ </div>
369
+ </li>
353
370
  );
354
- },
355
- };
371
+ }
372
+ );
356
373
 
357
374
  NavMenu.Item = Item;
358
375
  NavMenu.Sub = Sub;
@@ -1,6 +1,14 @@
1
1
  import { styled } from '../Theme';
2
2
 
3
- const NavMenuBase = styled('nav')`
3
+ type NavMenuBaseProps = {
4
+ $bgColor: string;
5
+ $textColor: string;
6
+ $activeTextColor: string;
7
+ };
8
+
9
+ const NavMenuBase = styled('nav', {
10
+ shouldForwardProp: (prop) => prop !== '$bgColor' && prop !== '$textColor' && prop !== '$activeTextColor',
11
+ })<NavMenuBaseProps>`
4
12
  background-color: ${(props) => props.$bgColor};
5
13
  font-size: 16px;
6
14
  // width: 100%;
@@ -1,10 +1,10 @@
1
1
  import PropTypes from 'prop-types';
2
2
  import upperFirst from 'lodash/upperFirst';
3
3
  import { Box } from '@mui/material';
4
- import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
5
4
  import RevokeIcon from '@arcblock/icons/lib/RevokeIcon';
6
5
 
7
6
  import NFTDisplay from '../NFTDisplay';
7
+ import { useLocaleContext } from '../Locale/context';
8
8
 
9
9
  export default function Passport({ passport, user, color, width, icon, children, createPassportSvg, ...rest }) {
10
10
  const { t } = useLocaleContext();
@@ -1,8 +1,8 @@
1
- import { styled } from '@arcblock/ux/lib/Theme';
2
1
  import PropTypes from 'prop-types';
3
2
 
4
3
  import phone from './shells/Phone';
5
4
  import macbook from './shells/Macbook';
5
+ import { styled } from '../../Theme';
6
6
 
7
7
  const map = {
8
8
  phone,
@@ -1,5 +1,4 @@
1
1
  import React, { useState, useRef, isValidElement } from 'react';
2
- import PropTypes from 'prop-types';
3
2
  import ExpandMore from '@mui/icons-material/ExpandMore';
4
3
  import Popper from '@mui/material/Popper';
5
4
  import Paper from '@mui/material/Paper';
@@ -23,7 +22,16 @@ export interface SplitButtonProps extends Omit<ButtonGroupProps, 'children'> {
23
22
  }
24
23
 
25
24
  export default function SplitButton(props: SplitButtonProps) {
26
- const { size, color, menu, children, variant, onClick, menuButtonProps, ...rest } = props;
25
+ const {
26
+ size = 'medium',
27
+ color = 'primary',
28
+ menu = [],
29
+ children = null,
30
+ variant = 'contained',
31
+ onClick = noop,
32
+ menuButtonProps = {},
33
+ ...rest
34
+ } = props;
27
35
 
28
36
  const [open, setOpen] = useState(false);
29
37
  const anchorRef = useRef<HTMLDivElement | null>(null);
@@ -74,27 +82,6 @@ export default function SplitButton(props: SplitButtonProps) {
74
82
  );
75
83
  }
76
84
 
77
- SplitButton.propTypes = {
78
- size: PropTypes.string,
79
- color: PropTypes.string,
80
- menu: PropTypes.oneOfType([PropTypes.node, PropTypes.array]),
81
- // 也可以是用于渲染主按钮的 function
82
- children: PropTypes.node,
83
- variant: PropTypes.oneOf(['outlined', 'contained']),
84
- onClick: PropTypes.func,
85
- menuButtonProps: PropTypes.object,
86
- };
87
-
88
- SplitButton.defaultProps = {
89
- size: 'medium',
90
- color: 'primary',
91
- menu: [],
92
- children: null,
93
- variant: 'contained',
94
- onClick: noop,
95
- menuButtonProps: {},
96
- };
97
-
98
85
  SplitButton.Item = MenuItem;
99
86
 
100
87
  const StyledButtonGroup = styled(ButtonGroup)`
@@ -1,24 +1,18 @@
1
+ /* eslint-disable no-unused-vars */
2
+ import { CreateMUIStyled, Theme } from '@mui/material';
1
3
  import { styled as muiStyled, useTheme } from '@mui/material/styles';
2
4
 
3
5
  export * from './theme';
4
6
  export { default as ThemeProvider } from './theme-provider';
5
7
  export { useTheme };
6
8
 
7
- const isTransientProp = (prop) => prop.startsWith('$');
9
+ const isTransientProp = (prop: string) => prop.startsWith('$');
8
10
 
9
- /**
10
- * @typedef {import('@mui/material/styles').Theme} Theme
11
- * @typedef {import('@mui/material/styles').CreateMUIStyled<Theme>} Styled
12
- */
13
-
14
- /**
15
- * @type {Styled}
16
- */
17
- export const styled = (component, options = {}) => {
11
+ export const styled: CreateMUIStyled<Theme> = (component: any, options?: any) => {
18
12
  return muiStyled(component, {
19
13
  ...options,
20
- shouldForwardProp: (prop) => {
21
- if (options.shouldForwardProp) {
14
+ shouldForwardProp: (prop: string) => {
15
+ if (options?.shouldForwardProp) {
22
16
  return options.shouldForwardProp(prop) && !isTransientProp(prop);
23
17
  }
24
18
  return !isTransientProp(prop);
@@ -1,5 +1,5 @@
1
1
  import PropTypes from 'prop-types';
2
- import { ThemeProvider as MuiThemeProvider } from '@mui/material/styles';
2
+ import { ThemeProvider as MuiThemeProvider, Theme } from '@mui/material/styles';
3
3
  import StyledEngineProvider from '@mui/material/StyledEngineProvider';
4
4
  import CssBaseline from '@mui/material/CssBaseline';
5
5
  import { createTheme } from './theme';
@@ -9,7 +9,15 @@ const defaultTheme = createTheme();
9
9
  /**
10
10
  * 默认的 theme provider, 可以为 webapp/blocklet 快捷的配置好 mui theme provider
11
11
  */
12
- export default function ThemeProvider({ children, theme, injectFirst }) {
12
+ export default function ThemeProvider({
13
+ children,
14
+ theme,
15
+ injectFirst,
16
+ }: {
17
+ children: React.ReactNode;
18
+ theme: Theme;
19
+ injectFirst: boolean;
20
+ }) {
13
21
  return (
14
22
  // injectFirst 会影响 makeStyles 自定义样式和 mui styles 覆盖问题
15
23
  <StyledEngineProvider injectFirst={injectFirst}>
@@ -1,5 +1,15 @@
1
+ /* eslint-disable no-unused-vars */
2
+ /* eslint-disable no-shadow */
1
3
  // https://app.zeplin.io/styleguide/5d1436f1e97c2156f49c0725/colors
2
- import { createTheme as _createTheme, responsiveFontSizes } from '@mui/material/styles';
4
+ import {
5
+ createTheme as _createTheme,
6
+ Components,
7
+ PaletteOptions,
8
+ responsiveFontSizes,
9
+ type Theme,
10
+ type ThemeOptions,
11
+ } from '@mui/material/styles';
12
+ import { Typography, TypographyOptions } from '@mui/material/styles/createTypography';
3
13
  // 为了避免加载全量的字体导致打包后体积太大,目前只选择了 latin 语系的字体
4
14
  import '@fontsource/inter/latin-300.css';
5
15
  import '@fontsource/inter/latin-400.css';
@@ -9,35 +19,54 @@ import '@fontsource/inter/latin-ext-300.css';
9
19
  import '@fontsource/inter/latin-ext-400.css';
10
20
  import '@fontsource/inter/latin-ext-500.css';
11
21
  import '@fontsource/inter/latin-ext-700.css';
12
-
13
22
  import colors from '../Colors';
14
23
 
15
- /**
16
- * @typedef {import('@mui/material/styles').Theme} Theme
17
- * @typedef {import('@mui/material/styles').TypographyVariantsOptions} TypographyVariantsOptions
18
- * @typedef {import('@mui/material/styles').Components} Components
19
- */
24
+ // 扩展 Theme 和 ThemeOptions 接口
25
+ declare module '@mui/material/styles/createTheme' {
26
+ interface Theme {
27
+ mode?: string;
28
+ themeName?: string;
29
+ pageWidth?: string;
30
+ colors?: Record<string, string>;
31
+ typography: Typography & {
32
+ useNextVariants: boolean;
33
+ color: Record<string, string>;
34
+ button: {
35
+ fontWeight?: number;
36
+ };
37
+ };
38
+ }
39
+ interface ThemeOptions {
40
+ mode?: string;
41
+ themeName?: string;
42
+ pageWidth?: string;
43
+ colors?: Record<string, string>;
44
+ }
45
+ }
20
46
 
21
47
  const muiDarkTheme = _createTheme({ palette: { mode: 'dark' } });
22
48
 
23
49
  // https://material-ui.com/customization/default-theme/
24
- /**
25
- * @description
26
- * @export
27
- * @param {{
28
- * mode?: string,
29
- * pageWidth?: string,
30
- * palette?: import('@mui/material/styles').PaletteOptions,
31
- * typography?: TypographyVariantsOptions,
32
- * overrides?: Components<Omit<Theme, 'components'>>,
33
- * }} options
34
- * @return {Theme}
35
- */
36
- export const create = ({ mode = 'light', pageWidth = 'md', palette, typography, overrides = {}, ...rest } = {}) => {
50
+ export const create = ({
51
+ mode = 'light',
52
+ pageWidth = 'md',
53
+ typography,
54
+ /** @deprecated 使用 components 替代 */
55
+ overrides,
56
+ // original theme options
57
+ palette,
58
+ components,
59
+ ...rest
60
+ }: {
61
+ mode?: string;
62
+ pageWidth?: string;
63
+ typography?: TypographyOptions;
64
+ overrides?: Components<Omit<Theme, 'components'>>;
65
+ } & ThemeOptions = {}) => {
37
66
  // palette 考虑 light & dark mode, dark mode 需要持续完善
38
67
  // - 能配合 ColorModeContext 使用
39
68
  // - 为 dark mode 系统的设计整个 palette, 不要单个 color 设置
40
- const _palette =
69
+ const _palette: PaletteOptions =
41
70
  mode === 'light'
42
71
  ? Object.assign(
43
72
  {
@@ -141,10 +170,12 @@ export const create = ({ mode = 'light', pageWidth = 'md', palette, typography,
141
170
  },
142
171
  },
143
172
  ...overrides,
173
+ ...components,
144
174
  },
145
175
  pageWidth,
146
- // TODO: 过时的 colors, 需要各项目负责人检查项目中是否使用 "theme.colors", 如果有需要清除,
147
- // 可以从 Colors 模块/theme.palette/mui colors 中取值
176
+ /**
177
+ * @deprecated 应使用 theme.palette 中的颜色
178
+ */
148
179
  colors: {
149
180
  white: '#FFFFFF',
150
181
  dark: '#4A707C',