@arcblock/ux 2.10.65 → 2.10.67
Sign up to get free protection for your applications and to get access to all the features.
- package/lib/ActionButton/index.d.ts +1 -1
- package/lib/Alert/index.d.ts +1 -1
- package/lib/AnimationWaiter/index.d.ts +27 -15
- package/lib/AnimationWaiter/index.js +15 -14
- package/lib/Async/index.d.ts +50 -17
- package/lib/Badge/index.d.ts +1 -1
- package/lib/Badge/index.js +7 -1
- package/lib/BlockletContext/index.d.ts +12 -28
- package/lib/BlockletContext/index.js +3 -21
- package/lib/Button/wrap.d.ts +5 -3
- package/lib/Button/wrap.js +2 -1
- package/lib/ButtonGroup/index.d.ts +12 -2
- package/lib/ButtonGroup/index.js +13 -3
- package/lib/CardSelector/index.d.ts +11 -33
- package/lib/CardSelector/index.js +16 -32
- package/lib/Center/index.d.ts +6 -21
- package/lib/Center/index.js +2 -17
- package/lib/ClickToCopy/copy-button.d.ts +9 -26
- package/lib/ClickToCopy/copy-button.js +5 -17
- package/lib/ClickToCopy/hook.d.ts +11 -5
- package/lib/ClickToCopy/hook.js +3 -3
- package/lib/ClickToCopy/index.d.ts +18 -29
- package/lib/ClickToCopy/index.js +0 -13
- package/lib/CodeBlock/LightBox.d.ts +1 -1
- package/lib/CodeBlock/index.d.ts +7 -26
- package/lib/CodeBlock/index.js +4 -17
- package/lib/Colors/index.d.ts +2 -2
- package/lib/Colors/themes/default.d.ts +54 -61
- package/lib/Colors/themes/temp.d.ts +35 -35
- package/lib/ContactForm/index.d.ts +26 -30
- package/lib/ContactForm/index.js +7 -17
- package/lib/Dialog/confirm.d.ts +3 -3
- package/lib/Dialog/confirm.js +2 -2
- package/lib/Earth/index.d.ts +10 -1
- package/lib/Header/auto-hidden.d.ts +6 -11
- package/lib/Header/auto-hidden.js +0 -5
- package/lib/Header/header.d.ts +20 -51
- package/lib/Header/header.js +10 -42
- package/lib/Header/index.d.ts +2 -2
- package/lib/Header/responsive-header.d.ts +10 -22
- package/lib/Header/responsive-header.js +1 -13
- package/lib/Icon/image.d.ts +8 -36
- package/lib/Icon/image.js +6 -24
- package/lib/Icon/index.d.ts +9 -1
- package/lib/Icon/index.js +6 -25
- package/lib/NavMenu/index.d.ts +1 -1
- package/lib/NavMenu/nav-menu.d.ts +37 -51
- package/lib/NavMenu/nav-menu.js +47 -102
- package/lib/NavMenu/style.d.ts +8 -2
- package/lib/NavMenu/style.js +3 -1
- package/lib/PageScroller/index.d.ts +13 -1
- package/lib/Passport/passport.js +1 -1
- package/lib/PricingTable/index.d.ts +3 -1
- package/lib/RelativeTime/index.d.ts +1 -1
- package/lib/Screenshot/BaseScreenshot/index.js +1 -1
- package/lib/SplitButton/index.d.ts +0 -19
- package/lib/SplitButton/index.js +7 -27
- package/lib/TextCollapse/index.d.ts +10 -1
- package/lib/Theme/index.d.ts +5 -13
- package/lib/Theme/index.js +4 -11
- package/lib/Theme/theme-provider.d.ts +16 -18
- package/lib/Theme/theme.d.ts +37 -11
- package/lib/Theme/theme.js +13 -22
- package/lib/Util/constant.d.ts +31 -31
- package/lib/Util/deprecate.d.ts +7 -5
- package/lib/Util/federated.d.ts +21 -21
- package/lib/Util/federated.js +1 -1
- package/lib/Util/index.d.ts +59 -60
- package/lib/Util/index.js +16 -43
- package/lib/Util/passport.d.ts +6 -6
- package/lib/Util/wallet.d.ts +15 -3
- package/lib/WebWalletSWKeeper/index.js +1 -1
- package/lib/global.d.ts +13 -0
- package/lib/index.d.ts +4 -2
- package/lib/index.js +2 -2
- package/lib/type.d.ts +31 -1
- package/package.json +5 -5
- package/src/AnimationWaiter/index.jsx +15 -14
- package/src/Async/{index.jsx → index.tsx} +13 -4
- package/src/Badge/index.jsx +8 -1
- package/src/BlockletContext/{index.jsx → index.tsx} +17 -22
- package/src/Button/wrap.jsx +2 -1
- package/src/ButtonGroup/index.js +13 -3
- package/src/CardSelector/{index.jsx → index.tsx} +32 -33
- package/src/Center/index.tsx +33 -0
- package/src/ClickToCopy/{copy-button.jsx → copy-button.tsx} +15 -16
- package/src/ClickToCopy/{hook.js → hook.ts} +5 -5
- package/src/ClickToCopy/{index.jsx → index.tsx} +12 -17
- package/src/CodeBlock/{index.jsx → index.tsx} +15 -17
- package/src/ContactForm/{index.jsx → index.tsx} +47 -29
- package/src/Dialog/confirm.jsx +2 -2
- package/src/Header/{auto-hidden.jsx → auto-hidden.tsx} +6 -7
- package/src/Header/{header.jsx → header.tsx} +32 -46
- package/src/Header/{responsive-header.jsx → responsive-header.tsx} +9 -15
- package/src/Icon/{image.jsx → image.tsx} +19 -22
- package/src/Icon/{index.jsx → index.tsx} +22 -24
- package/src/NavMenu/{nav-menu.jsx → nav-menu.tsx} +161 -144
- package/src/NavMenu/{style.js → style.ts} +9 -1
- package/src/Passport/passport.jsx +1 -1
- package/src/Screenshot/BaseScreenshot/index.jsx +1 -1
- package/src/SplitButton/index.tsx +10 -23
- package/src/Theme/{index.js → index.ts} +6 -12
- package/src/Theme/{theme-provider.jsx → theme-provider.tsx} +10 -2
- package/src/Theme/{theme.js → theme.ts} +54 -23
- package/src/Util/{deprecate.jsx → deprecate.tsx} +8 -4
- package/src/Util/{federated.js → federated.ts} +3 -3
- package/src/Util/{index.js → index.ts} +85 -59
- package/src/Util/{passport.js → passport.ts} +2 -2
- package/src/Util/{wallet.js → wallet.ts} +1 -1
- package/src/WebWalletSWKeeper/index.jsx +1 -1
- package/src/global.d.ts +13 -0
- package/src/{index.js → index.ts} +2 -2
- package/src/type.d.ts +31 -1
- package/src/Center/index.jsx +0 -41
- /package/src/CodeBlock/{LightBox.jsx → LightBox.tsx} +0 -0
- /package/src/Colors/{index.js → index.ts} +0 -0
- /package/src/Colors/themes/{default.js → default.ts} +0 -0
- /package/src/Colors/themes/{temp.js → temp.ts} +0 -0
- /package/src/Header/{index.js → index.ts} +0 -0
- /package/src/NavMenu/{index.js → index.ts} +0 -0
- /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) =>
|
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({
|
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(
|
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
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
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
|
-
|
262
|
-
|
263
|
-
|
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
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
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
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
active: false,
|
288
|
-
onClick: null,
|
289
|
-
};
|
288
|
+
const handleClick = () => {
|
289
|
+
onClick?.();
|
290
|
+
activate?.(id);
|
291
|
+
};
|
290
292
|
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
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
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
})
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
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
|
-
<
|
349
|
-
|
350
|
-
|
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
|
-
|
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,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 {
|
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
|
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({
|
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 {
|
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
|
-
|
17
|
-
|
18
|
-
|
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
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
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
|
-
|
147
|
-
|
176
|
+
/**
|
177
|
+
* @deprecated 应使用 theme.palette 中的颜色
|
178
|
+
*/
|
148
179
|
colors: {
|
149
180
|
white: '#FFFFFF',
|
150
181
|
dark: '#4A707C',
|