@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.
- 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',
|