@arcblock/ux 2.10.64 → 2.10.66

Sign up to get free protection for your applications and to get access to all the features.
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',