@arcblock/ux 2.12.0 → 2.12.2

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 (59) hide show
  1. package/lib/Address/responsive-did-address.d.ts +0 -1
  2. package/lib/Address/responsive-did-address.js +42 -14
  3. package/lib/Header/demo/images/boards.svg +3 -0
  4. package/lib/Header/demo/images/chatbot.svg +3 -0
  5. package/lib/Header/demo/images/gallery.svg +3 -0
  6. package/lib/NavMenu/images/OCAP.svg +16 -0
  7. package/lib/NavMenu/images/abt-network.svg +18 -0
  8. package/lib/NavMenu/images/ai-kit.svg +46 -0
  9. package/lib/NavMenu/images/aigne.svg +8 -0
  10. package/lib/NavMenu/images/aistro.svg +14 -0
  11. package/lib/NavMenu/images/blocklet-framework.svg +25 -0
  12. package/lib/NavMenu/images/blocklet-launcher.svg +9 -0
  13. package/lib/NavMenu/images/blocklet-server.svg +19 -0
  14. package/lib/NavMenu/images/blocklet-store.svg +11 -0
  15. package/lib/NavMenu/images/creator-studio.svg +42 -0
  16. package/lib/NavMenu/images/did-connect.svg +26 -0
  17. package/lib/NavMenu/images/did-name-service.svg +3 -0
  18. package/lib/NavMenu/images/did-wallet.svg +33 -0
  19. package/lib/NavMenu/images/did.svg +3 -0
  20. package/lib/NavMenu/images/nft-studio.svg +19 -0
  21. package/lib/NavMenu/images/vc.svg +7 -0
  22. package/lib/NavMenu/images/web3-kit.svg +56 -0
  23. package/lib/NavMenu/index.d.ts +1 -0
  24. package/lib/NavMenu/index.js +2 -1
  25. package/lib/NavMenu/nav-menu-context.d.ts +17 -0
  26. package/lib/NavMenu/nav-menu-context.js +19 -0
  27. package/lib/NavMenu/nav-menu.d.ts +10 -5
  28. package/lib/NavMenu/nav-menu.js +76 -36
  29. package/lib/NavMenu/products.d.ts +5 -0
  30. package/lib/NavMenu/products.js +1639 -0
  31. package/lib/NavMenu/style.d.ts +8 -3
  32. package/lib/NavMenu/style.js +215 -175
  33. package/lib/NavMenu/sub-item-group.d.ts +5 -0
  34. package/lib/NavMenu/sub-item-group.js +44 -0
  35. package/package.json +5 -5
  36. package/src/Address/responsive-did-address.tsx +40 -12
  37. package/src/NavMenu/images/OCAP.svg +16 -0
  38. package/src/NavMenu/images/abt-network.svg +18 -0
  39. package/src/NavMenu/images/ai-kit.svg +46 -0
  40. package/src/NavMenu/images/aigne.svg +8 -0
  41. package/src/NavMenu/images/aistro.svg +14 -0
  42. package/src/NavMenu/images/blocklet-framework.svg +25 -0
  43. package/src/NavMenu/images/blocklet-launcher.svg +9 -0
  44. package/src/NavMenu/images/blocklet-server.svg +19 -0
  45. package/src/NavMenu/images/blocklet-store.svg +11 -0
  46. package/src/NavMenu/images/creator-studio.svg +42 -0
  47. package/src/NavMenu/images/did-connect.svg +26 -0
  48. package/src/NavMenu/images/did-name-service.svg +3 -0
  49. package/src/NavMenu/images/did-wallet.svg +33 -0
  50. package/src/NavMenu/images/did.svg +3 -0
  51. package/src/NavMenu/images/nft-studio.svg +19 -0
  52. package/src/NavMenu/images/vc.svg +7 -0
  53. package/src/NavMenu/images/web3-kit.svg +56 -0
  54. package/src/NavMenu/index.ts +1 -0
  55. package/src/NavMenu/nav-menu-context.tsx +30 -0
  56. package/src/NavMenu/nav-menu.tsx +98 -61
  57. package/src/NavMenu/products.tsx +378 -0
  58. package/src/NavMenu/style.ts +220 -183
  59. package/src/NavMenu/sub-item-group.tsx +36 -0
@@ -1,8 +1,13 @@
1
- type NavMenuBaseProps = {
1
+ type NavMenuProps = {
2
2
  $bgColor: string;
3
3
  $textColor: string;
4
+ };
5
+ export declare const NavMenuRoot: import("@emotion/styled").StyledComponent<import("@mui/system").MUIStyledCommonProps<import("@mui/material").Theme> & NavMenuProps, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLElement>, HTMLElement>, {}>;
6
+ export declare const NavMenuList: import("@emotion/styled").StyledComponent<import("@mui/system").MUIStyledCommonProps<import("@mui/material").Theme>, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLUListElement>, HTMLUListElement>, {}>;
7
+ type NavMenuItemProps = {
4
8
  $activeTextColor: string;
5
9
  };
6
- export declare const HorizontalStyle: import("@emotion/styled").StyledComponent<import("@mui/system").MUIStyledCommonProps<import("@mui/material").Theme> & NavMenuBaseProps & import("react").ClassAttributes<HTMLElement> & import("react").HTMLAttributes<HTMLElement>, {}, {}>;
7
- export declare const InlineStyle: import("@emotion/styled").StyledComponent<import("@mui/system").MUIStyledCommonProps<import("@mui/material").Theme> & NavMenuBaseProps & import("react").ClassAttributes<HTMLElement> & import("react").HTMLAttributes<HTMLElement>, {}, {}>;
10
+ export declare const NavMenuItem: import("@emotion/styled").StyledComponent<import("@mui/system").MUIStyledCommonProps<import("@mui/material").Theme> & NavMenuItemProps, import("react").DetailedHTMLProps<import("react").LiHTMLAttributes<HTMLLIElement>, HTMLLIElement>, {}>;
11
+ export declare const NavMenuSub: import("@emotion/styled").StyledComponent<import("@mui/system").MUIStyledCommonProps<import("@mui/material").Theme> & NavMenuItemProps & import("react").ClassAttributes<HTMLLIElement> & import("react").LiHTMLAttributes<HTMLLIElement>, {}, {}>;
12
+ export declare const NavMenuSubList: import("@emotion/styled").StyledComponent<import("@mui/system").MUIStyledCommonProps<import("@mui/material").Theme>, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLUListElement>, HTMLUListElement>, {}>;
8
13
  export {};
@@ -1,185 +1,225 @@
1
1
  import { styled } from '../Theme';
2
- const NavMenuBase = styled('nav', {
3
- shouldForwardProp: prop => prop !== '$bgColor' && prop !== '$textColor' && prop !== '$activeTextColor'
4
- })`
5
- background-color: ${props => props.$bgColor};
6
- font-size: 16px;
7
- // width: 100%;
8
- ul {
9
- list-style: none;
10
- margin: 0;
11
- padding: 0;
12
- }
13
- .navmenu-item,
14
- .navmenu-sub {
15
- display: flex;
16
- align-items: center;
17
- }
18
- a {
19
- color: inherit;
20
- text-decoration: none;
21
- }
22
- /* active/hover */
23
- .navmenu-item,
24
- .navmenu-sub {
25
- color: ${props => props.$textColor};
26
- }
27
- .navmenu-item--active,
28
- .navmenu-item:hover,
29
- .navmenu-sub--opened {
30
- color: ${props => props.$activeTextColor};
31
- }
32
-
33
- .navmenu-item {
34
- position: relative;
35
- cursor: pointer;
36
- transition: color 0.2s ease-in-out;
37
- a {
38
- white-space: nowrap;
39
- }
40
- a::before {
41
- position: absolute;
42
- top: 0;
43
- right: 0;
44
- bottom: 0;
45
- left: 0;
46
- background-color: transparent;
47
- content: '';
48
- }
49
- }
50
-
51
- .navmenu-sub {
52
- position: relative;
53
- cursor: pointer;
54
- }
55
- /* icon & expand icon */
56
- .navmenu-item-icon,
57
- .navmenu-sub-icon,
58
- .navmenu-sub-expand-icon {
59
- display: flex;
60
- line-height: 1;
61
- }
62
- .navmenu-item-icon,
63
- .navmenu-sub-icon {
64
- margin-right: 4px;
65
- }
66
- .navmenu-item-icon > *,
67
- .navmenu-sub-icon > * {
68
- width: auto;
69
- height: 22px;
70
- max-height: 22px;
71
- font-size: 1.5em;
72
- }
73
- .navmenu-sub-expand-icon {
74
- margin-left: 8px;
75
- > * {
76
- width: 0.8em;
77
- height: 0.8em;
78
- transition: transform 0.2s ease-in-out;
79
- }
80
- }
81
- `;
82
- export const HorizontalStyle = styled(NavMenuBase)`
83
- padding: 8px 16px;
84
- min-width: 50px;
2
+ // .navmenu-root
3
+ export const NavMenuRoot = styled('nav', {
4
+ shouldForwardProp: prop => prop !== '$bgColor' && prop !== '$textColor'
5
+ })(({
6
+ $bgColor,
7
+ $textColor
8
+ }) => ({
9
+ padding: '8px 16px',
10
+ minWidth: '50px',
85
11
  // FIXME: @zhanghan 这个只是临时的解决方案,会导致 header align right 不能真正的右对齐,需要修改 header 才能真正解决这个问题
86
- flex-grow: 100;
12
+ flexGrow: 100,
13
+ backgroundColor: $bgColor,
14
+ color: $textColor,
15
+ fontSize: '16px'
16
+ }));
87
17
 
88
- .navmenu-root {
89
- display: flex;
90
- align-items: center;
91
- }
92
- /* 顶级菜单间隔 */
93
- .navmenu-root > .navmenu-item,
94
- .navmenu-root > .navmenu-sub {
95
- margin-left: 24px;
96
- white-space: nowrap;
97
- }
98
- .navmenu-root > .navmenu-item:first-of-type,
99
- .navmenu-root > .navmenu-sub:first-of-type {
100
- margin-left: 0;
101
- }
102
-
103
- /* 子级列表 */
104
- .navmenu-sub-container {
105
- display: none;
106
- position: absolute;
107
- top: 100%;
108
- }
109
- .navmenu-sub-list {
110
- padding: 16px;
111
- border-radius: 4px;
112
- background: #fff;
113
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
114
- .navmenu-item + .navmenu-item {
115
- margin-top: 8px;
18
+ // .navmenu-list
19
+ export const NavMenuList = styled('ul')(() => ({
20
+ listStyle: 'none',
21
+ margin: 0,
22
+ padding: 0,
23
+ display: 'flex',
24
+ alignItems: 'center',
25
+ // inline 布局
26
+ '&.navmenu-list--inline ': {
27
+ flexDirection: 'column',
28
+ alignItems: 'stretch'
29
+ }
30
+ }));
31
+ // 菜单项 .navmenu-item
32
+ export const NavMenuItem = styled('li', {
33
+ shouldForwardProp: prop => prop !== '$activeTextColor'
34
+ })(({
35
+ $activeTextColor
36
+ }) => ({
37
+ display: 'flex',
38
+ alignItems: 'center',
39
+ position: 'relative',
40
+ padding: '0 12px',
41
+ whiteSpace: 'nowrap',
42
+ cursor: 'pointer',
43
+ transition: 'color 0.2s ease-in-out',
44
+ // 间距调整
45
+ '&:first-of-type': {
46
+ paddingLeft: 0
47
+ },
48
+ '&:last-of-type': {
49
+ paddingRight: 0
50
+ },
51
+ // 内部链接
52
+ a: {
53
+ whiteSpace: 'nowrap',
54
+ color: 'inherit',
55
+ textDecoration: 'none',
56
+ // 扩大点击区域
57
+ '&::before': {
58
+ position: 'absolute',
59
+ top: 0,
60
+ right: 0,
61
+ bottom: 0,
62
+ left: 0,
63
+ backgroundColor: 'transparent',
64
+ content: '""'
116
65
  }
117
- }
118
- /* 二级 sub menu */
119
- .navmenu-root > .navmenu-sub {
120
- white-space: nowrap;
121
- > .navmenu-sub-container {
122
- left: 50%;
123
- transform: translateX(-50%);
124
- padding-top: 16px;
66
+ },
67
+ // 图标
68
+ '.navmenu-item__icon': {
69
+ display: 'flex',
70
+ alignItems: 'center',
71
+ justifyContent: 'center',
72
+ marginRight: '4px',
73
+ '& > *': {
74
+ width: 'auto',
75
+ height: '22px',
76
+ maxHeight: '22px',
77
+ fontSize: '1.5em'
125
78
  }
126
- &.navmenu-sub--opened > .navmenu-sub-container {
127
- display: block;
79
+ },
80
+ // 右侧内容
81
+ '.navmenu-item__content': {
82
+ height: '32px',
83
+ display: 'flex',
84
+ flexDirection: 'column',
85
+ justifyContent: 'center',
86
+ alignItems: 'flex-start',
87
+ gap: '5px'
88
+ },
89
+ '.navmenu-item__label': {
90
+ display: 'flex',
91
+ alignItems: 'center',
92
+ '&-arrow': {
93
+ marginLeft: '6px',
94
+ fontSize: '14px',
95
+ opacity: 0,
96
+ transition: 'opacity 0.2s ease-in-out'
128
97
  }
129
- }
130
- `;
98
+ },
99
+ '.navmenu-item__desc': {
100
+ fontSize: '14px'
101
+ },
102
+ // 悬停状态下
103
+ '&:hover': {
104
+ color: $activeTextColor
105
+ },
106
+ // 选中状态下
107
+ '&.navmenu-item--active': {
108
+ color: $activeTextColor
109
+ },
110
+ // Panel 形态下
111
+ '&.navmenu-item--panel': {
112
+ padding: '8px 16px',
113
+ borderRadius: '8px',
114
+ '.navmenu-item__icon': {
115
+ width: '32px',
116
+ height: '32px',
117
+ marginRight: '16px',
118
+ border: '1px solid #eff1f5',
119
+ borderRadius: '4px',
120
+ color: '#9497a0'
121
+ },
122
+ '.navmenu-item__label': {
123
+ fontSize: '14px',
124
+ lineHeight: 1,
125
+ color: '#26292e'
126
+ },
127
+ '.navmenu-item__desc': {
128
+ fontSize: '12px',
129
+ lineHeight: 1,
130
+ color: '#9497a0'
131
+ },
132
+ '&:hover': {
133
+ background: '#f9f9fb',
134
+ transition: 'background 0.2s ease-in-out',
135
+ '.navmenu-item__label-arrow': {
136
+ opacity: 1
137
+ },
138
+ '.navmenu-item__desc': {
139
+ color: '#26292e',
140
+ transition: 'color 0.2s ease-in-out'
141
+ }
142
+ },
143
+ '&.navmenu-item--active': {
144
+ background: '#f9f9fb'
145
+ }
146
+ },
147
+ // inline 布局中
148
+ '&.navmenu-item--inline': {
149
+ margin: 0,
150
+ padding: '0 16px',
151
+ minHeight: '48px',
152
+ lineHeight: '48px',
153
+ flexWrap: 'wrap'
154
+ }
155
+ }));
131
156
 
132
- /* inline mode */
133
- export const InlineStyle = styled(NavMenuBase)`
134
- font-size: 16px;
135
- .navmenu-root {
136
- display: flex;
137
- flex-direction: column;
138
- align-items: stretch;
139
- }
140
- .navmenu-item,
141
- .navmenu-sub {
142
- padding: 0 16px;
143
- }
144
- & .navmenu-sub {
145
- flex-wrap: wrap;
146
- }
147
- /* 顶级 */
148
- .navmenu-root > .navmenu-item,
149
- .navmenu-root > .navmenu-sub {
150
- line-height: 48px;
151
- border-bottom: 1px solid #eee;
152
- }
153
- /* icon */
154
- .navmenu-item-icon,
155
- .navmenu-sub-icon {
156
- width: 30px;
157
- margin: 0;
158
- }
159
- .navmenu-sub-expand-icon {
160
- margin-left: auto;
161
- }
162
- /* 子级列表 */
163
- .navmenu-sub-container {
164
- display: none;
165
- flex: 1 0 100%;
166
- margin: 0 -16px;
167
- padding-bottom: 8px;
168
- .navmenu-item,
169
- .navmenu-sub {
170
- line-height: 32px;
157
+ // 包含子菜单的导航项 .navmenu-item .navmenu-sub
158
+ export const NavMenuSub = styled(NavMenuItem)(() => ({
159
+ '.navmenu-item': {
160
+ marginLeft: 0
161
+ },
162
+ '& .navmenu-sub__container': {
163
+ visibility: 'hidden',
164
+ opacity: 0,
165
+ position: 'absolute',
166
+ top: '100%',
167
+ left: '50%',
168
+ zIndex: 1,
169
+ transform: 'translateX(-50%)',
170
+ paddingTop: '16px',
171
+ transition: 'opacity 0.2s ease-in-out, visibility 0.2s ease-in-out'
172
+ },
173
+ '&.navmenu-sub--opened > .navmenu-sub__container': {
174
+ visibility: 'visible',
175
+ opacity: 1
176
+ },
177
+ // 扩展图标
178
+ '.navmenu-sub__expand-icon': {
179
+ display: 'flex',
180
+ alignItems: 'center',
181
+ justifyContent: 'center',
182
+ marginLeft: '8px',
183
+ '& > *': {
184
+ width: '0.8em',
185
+ height: '0.8em',
186
+ transition: 'transform 0.2s ease-in-out'
187
+ },
188
+ '.navmenu-item--inline &': {
189
+ marginLeft: 'auto'
171
190
  }
172
- }
173
- .navmenu-sub-list {
174
- padding-left: 16px;
175
- .navmenu-item,
176
- .navmenu-sub {
177
- padding-left: 30px;
178
- font-size: 13px;
191
+ },
192
+ // inline 布局
193
+ '&.navmenu-item--inline': {
194
+ '.navmenu-sub__container': {
195
+ position: 'static',
196
+ transform: 'none',
197
+ flex: '1 0 100%',
198
+ margin: '0 -16px',
199
+ padding: 0,
200
+ height: 0,
201
+ overflow: 'hidden',
202
+ transition: 'height 0.2s ease-in-out'
203
+ },
204
+ '&.navmenu-sub--opened > .navmenu-sub__container': {
205
+ height: 'auto'
206
+ },
207
+ '.navmenu-sub__list': {
208
+ padding: 0,
209
+ paddingLeft: '16px',
210
+ boxShadow: 'none'
179
211
  }
180
212
  }
181
- /* 二级 menu */
182
- .navmenu-sub--opened > .navmenu-sub-container {
183
- display: block;
184
- }
185
- `;
213
+ }));
214
+
215
+ // 下拉子菜单 .navmenu-sub-list
216
+ export const NavMenuSubList = styled('ul')(() => ({
217
+ margin: 0,
218
+ padding: '16px',
219
+ borderRadius: '4px',
220
+ background: '#fff',
221
+ boxShadow: '0 2px 8px rgba(0, 0, 0, 0.15)',
222
+ '& .navmenu-item + .navmenu-item': {
223
+ marginTop: '8px'
224
+ }
225
+ }));
@@ -0,0 +1,5 @@
1
+ import { BoxProps } from '@mui/material';
2
+ export interface NavMenuSubItemGroupProps extends BoxProps {
3
+ label: React.ReactNode;
4
+ }
5
+ export default function NavMenuSubItemGroup({ label, children, className, sx, ...rest }: NavMenuSubItemGroupProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,44 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Box } from '@mui/material';
3
+ import { styled } from '../Theme';
4
+ const Group = styled(Box)`
5
+ padding: 16px 24px;
6
+ border-radius: 8px;
7
+ background-color: white;
8
+ cursor: auto;
9
+
10
+ .group-label {
11
+ margin-bottom: 8px;
12
+ color: #71717b;
13
+ font-size: 12px;
14
+ }
15
+
16
+ .nav {
17
+ list-style: none;
18
+ margin: 0;
19
+ padding: 0;
20
+ }
21
+ `;
22
+ export default function NavMenuSubItemGroup({
23
+ label,
24
+ children,
25
+ className,
26
+ sx,
27
+ ...rest
28
+ }) {
29
+ return /*#__PURE__*/_jsxs(Group, {
30
+ className: `nav-menu-sub-item-group ${className}`,
31
+ sx: {
32
+ ...sx
33
+ },
34
+ ...rest,
35
+ children: [/*#__PURE__*/_jsx(Box, {
36
+ className: "group-label",
37
+ children: label
38
+ }), /*#__PURE__*/_jsx(Box, {
39
+ component: "ul",
40
+ className: "nav",
41
+ children: children
42
+ })]
43
+ });
44
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arcblock/ux",
3
- "version": "2.12.0",
3
+ "version": "2.12.2",
4
4
  "description": "Common used react components for arcblock products",
5
5
  "keywords": [
6
6
  "react",
@@ -68,12 +68,12 @@
68
68
  "react": ">=18.2.0",
69
69
  "react-router-dom": ">=6.22.3"
70
70
  },
71
- "gitHead": "ce9042b3a31a06b60ab4d3b923e8b5903bbbf106",
71
+ "gitHead": "4dc132cab82765eef5194cf00075a13bd5d8e458",
72
72
  "dependencies": {
73
73
  "@arcblock/did-motif": "^1.1.13",
74
- "@arcblock/icons": "^2.12.0",
75
- "@arcblock/nft-display": "^2.12.0",
76
- "@arcblock/react-hooks": "^2.12.0",
74
+ "@arcblock/icons": "^2.12.2",
75
+ "@arcblock/nft-display": "^2.12.2",
76
+ "@arcblock/react-hooks": "^2.12.2",
77
77
  "@babel/plugin-syntax-dynamic-import": "^7.8.3",
78
78
  "@fontsource/inter": "^5.0.16",
79
79
  "@fontsource/ubuntu-mono": "^5.0.18",
@@ -1,4 +1,4 @@
1
- import { useLatest, useSize } from 'ahooks';
1
+ import { useDebounceFn, useLatest } from 'ahooks';
2
2
  import React, { forwardRef, useEffect, useImperativeHandle, useRef, useState } from 'react';
3
3
  import { Box } from '@mui/material';
4
4
  import { styled } from '../Theme';
@@ -12,18 +12,20 @@ import DidAddress, { HTMLDidAddressElement, IDidAddressProps } from './did-addre
12
12
  * - DidAddress 本身以 inline 形式渲染 (方便探测 did-address 的 full-width)
13
13
  * - 组件 mounted 时记录 did address 的 full-width (非 compact 模式的宽度)
14
14
  * - 监听容器宽度变化, 当容器宽度变化时, 对比容器宽度和 did address full-width, => 切换 compact 模式
15
- * - TODO: 初始化时, 在确定是否应该以 compact 模式渲染前, 隐藏显示, 避免闪烁问题
16
15
  */
17
16
  const ResponsiveDidAddress = forwardRef<HTMLDidAddressElement, IResponsiveDidAddressProps>(
18
- ({ style, className, component = 'span', ...rest }, ref) => {
17
+ ({ style, className, component = 'span', size, ...rest }, ref) => {
19
18
  const [compact, setCompact] = useState(false);
20
19
  const isCompact = useLatest(compact);
21
20
  // did address 完整显示时的宽度
22
21
  const [addressFullWidth, setAddressFullWidth] = useState<number | null | undefined>(null);
22
+ const [containerWidth, setContainerWidth] = useState<number | null | undefined>(null);
23
+ const [loading, setLoading] = useState(true);
24
+ const { run: delaySetLoadingFalse } = useDebounceFn(() => setLoading(false), {
25
+ wait: 50,
26
+ });
23
27
  const containerRef = useRef<HTMLDivElement>(null);
24
28
  const innerRef = useRef<HTMLDidAddressElement>(null);
25
- const size = useSize(containerRef);
26
- const containerWidth = size?.width || 0;
27
29
 
28
30
  useImperativeHandle(
29
31
  ref,
@@ -41,22 +43,32 @@ const ResponsiveDidAddress = forwardRef<HTMLDidAddressElement, IResponsiveDidAdd
41
43
  // 存储完整显示时 address 组件的宽度
42
44
  useEffect(() => {
43
45
  const innerWidth = innerRef.current?.offsetWidth || 0;
44
- let resizeObserver: ResizeObserver | null = null;
46
+ let innerObserver: ResizeObserver | null = null;
47
+ let containerObserver: ResizeObserver | null = null;
45
48
 
49
+ // 初始化宽度
46
50
  setAddressFullWidth(innerWidth);
51
+ setContainerWidth(containerRef.current?.offsetWidth);
47
52
 
48
53
  // 由于自定义字体的缘故,innerRef 的初始宽度可能发生二次改变,使用 observer 监听捕获
49
- resizeObserver = new ResizeObserver(() => {
54
+ innerObserver = new ResizeObserver(() => {
50
55
  if (!isCompact.current && innerRef.current?.offsetWidth !== innerWidth) {
51
56
  setAddressFullWidth(innerRef.current?.offsetWidth);
57
+ delaySetLoadingFalse();
52
58
  }
53
59
  });
60
+ containerObserver = new ResizeObserver(() => {
61
+ setContainerWidth(containerRef.current?.offsetWidth);
62
+ });
54
63
 
55
- if (innerRef.current) {
56
- resizeObserver.observe(innerRef.current.getEl());
57
- }
64
+ innerObserver.observe(innerRef.current!.getEl());
65
+ containerObserver.observe(containerRef.current!);
66
+ delaySetLoadingFalse();
58
67
 
59
- return () => resizeObserver.disconnect();
68
+ return () => {
69
+ innerObserver?.disconnect();
70
+ containerObserver?.disconnect();
71
+ };
60
72
  // eslint-disable-next-line react-hooks/exhaustive-deps
61
73
  }, []);
62
74
 
@@ -65,9 +77,23 @@ const ResponsiveDidAddress = forwardRef<HTMLDidAddressElement, IResponsiveDidAdd
65
77
  setCompact(containerWidth < addressFullWidth);
66
78
  }
67
79
  }, [containerWidth, addressFullWidth]);
80
+
68
81
  return (
69
82
  <Root as={component} ref={containerRef} style={style} className={className}>
70
- <StyledDidAddress {...rest} component={component} inline compact={compact} ref={innerRef} />
83
+ <StyledDidAddress
84
+ style={{
85
+ position: loading ? 'absolute' : 'static',
86
+ left: loading ? '-99999px' : 'auto',
87
+ }}
88
+ {...rest}
89
+ size={size}
90
+ component={component}
91
+ inline
92
+ compact={compact}
93
+ ref={innerRef}
94
+ />
95
+ {/* placeholder */}
96
+ {loading && <div style={{ width: '100%', height: `${(size || 16) * 1.5}px` }} />}
71
97
  </Root>
72
98
  );
73
99
  }
@@ -83,6 +109,8 @@ export interface IResponsiveDidAddressProps extends IDidAddressProps {
83
109
 
84
110
  const Root = styled(Box)`
85
111
  display: block;
112
+ width: 100%; /* flex & column & align-items: flex-start 时, 块级元素不会自动铺满容器 */
113
+ font-size: 0;
86
114
  overflow: hidden;
87
115
  ${({ inline }: any) =>
88
116
  inline &&
@@ -0,0 +1,16 @@
1
+ <svg width="420" height="420" viewBox="0 0 420 420" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M210.205 17.1428V113.571V210M210.205 210L376.872 306.19M210.205 210L44.9668 305.238" stroke="url(#paint0_linear_3296_9216)" stroke-opacity="0.6" stroke-width="18"></path>
3
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M247.638 178.49L210.205 200.103L172.921 178.576L200.337 130.776L201.634 128.516L210.205 113.571L218.776 128.437L220.113 130.753L247.638 178.49ZM262.484 169.919L225.056 105.008L210.166 79.1841L195.334 105.042L158.074 170.005L62.7143 114.949L210.205 29.7949L357.695 114.949L262.484 169.919ZM256.201 193.342L218.776 214.949V301.244L284.965 263.044L293.538 258.095L284.986 243.263L256.201 193.342ZM218.776 321.036L302.108 272.943L316.949 264.377L308.389 249.532L271.047 184.77L366.267 129.795V300.103L218.776 385.256V321.036ZM201.634 301.151V214.949L164.392 193.448L136.062 242.84L127.586 257.619L136.083 262.614L201.634 301.151ZM149.546 184.876L112.715 249.09L104.277 263.802L118.898 272.397L201.517 320.969L201.634 321.037V385.256L54.1429 300.103V129.795L149.546 184.876ZM210.205 10L45.5714 105.051L37 110V119.897V310L201.634 405.051L210.205 410L218.776 405.051L383.41 310V119.897V110L374.838 105.051L210.205 10Z" fill="url(#paint1_linear_3296_9216)"></path>
4
+ <defs>
5
+ <linearGradient id="paint0_linear_3296_9216" x1="632.433" y1="166.456" x2="334.741" y2="-292.388" gradientUnits="userSpaceOnUse">
6
+ <stop stop-color="#4EF1BA"></stop>
7
+ <stop offset="0.501904" stop-color="#16CED1"></stop>
8
+ <stop offset="1" stop-color="#3773F2"></stop>
9
+ </linearGradient>
10
+ <linearGradient id="paint1_linear_3296_9216" x1="210.205" y1="-190" x2="-189.795" y2="210" gradientUnits="userSpaceOnUse">
11
+ <stop stop-color="#4EF1BA"></stop>
12
+ <stop offset="0.501904" stop-color="#16CED1"></stop>
13
+ <stop offset="1" stop-color="#3773F2"></stop>
14
+ </linearGradient>
15
+ </defs>
16
+ </svg>
@@ -0,0 +1,18 @@
1
+ <svg width="200" height="200" viewBox="0 0 200 200" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <mask id="mask0_3296_9227" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="8" y="8" width="184" height="184">
3
+ <path d="M192 100C192 49.1898 150.81 8 100 8C49.1898 8 8 49.1898 8 100C8 150.81 49.1898 192 100 192C150.81 192 192 150.81 192 100Z" fill="white"></path>
4
+ </mask>
5
+ <g mask="url(#mask0_3296_9227)">
6
+ <path d="M192 100C192 49.1898 150.81 8 100 8C49.1898 8 8 49.1898 8 100C8 150.81 49.1898 192 100 192C150.81 192 192 150.81 192 100Z" fill="white"></path>
7
+ <path d="M192 8H8V192H192V8Z" fill="url(#paint0_linear_3296_9227)"></path>
8
+ <path opacity="0.6" fill-rule="evenodd" clip-rule="evenodd" d="M98.0594 97.0743V99.3038L96.1184 100.419L40.2002 132.536L42.141 135.88L100 102.648L157.859 135.88L159.8 132.536L103.882 100.419L101.941 99.3038V97.0743V32.84H98.0594V97.0743Z" fill="white"></path>
9
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M100.404 28.6202L162.56 64.5058V136.277L100.404 172.163L38.2485 136.277V64.5058L100.404 28.6202ZM44.0759 65.6272L82.729 87.9437L100.405 57.3287L118.08 87.9435L156.733 65.6272L100.404 33.1061L44.0759 65.6272ZM158.675 68.9914L120.022 91.3078L137.698 121.923L102.347 142.333V166.556L158.675 134.034V68.9914ZM98.4619 166.556V142.333L63.1111 121.923L80.7866 91.3079L42.1332 68.9914V134.034L98.4619 166.556ZM84.1505 93.2501L68.4172 120.501L98.4619 137.847V103.755V101.512L96.5196 100.391L84.1505 93.2501ZM102.347 137.847L132.39 120.501L116.657 93.2503L104.289 100.391L102.347 101.512V103.755V137.847ZM114.715 89.8861L100.404 65.0982L86.0929 89.8858L100.404 98.1485L114.715 89.8861Z" fill="white"></path>
10
+ </g>
11
+ <defs>
12
+ <linearGradient id="paint0_linear_3296_9227" x1="100" y1="-84" x2="-84" y2="100" gradientUnits="userSpaceOnUse">
13
+ <stop stop-color="#4EF1BA"></stop>
14
+ <stop offset="0.501904" stop-color="#16CED1"></stop>
15
+ <stop offset="1" stop-color="#3773F2"></stop>
16
+ </linearGradient>
17
+ </defs>
18
+ </svg>