@arcblock/ux 2.12.1 → 2.12.3

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.
@@ -8,7 +8,6 @@ import { HTMLDidAddressElement, IDidAddressProps } from './did-address';
8
8
  * - DidAddress 本身以 inline 形式渲染 (方便探测 did-address 的 full-width)
9
9
  * - 组件 mounted 时记录 did address 的 full-width (非 compact 模式的宽度)
10
10
  * - 监听容器宽度变化, 当容器宽度变化时, 对比容器宽度和 did address full-width, => 切换 compact 模式
11
- * - TODO: 初始化时, 在确定是否应该以 compact 模式渲染前, 隐藏显示, 避免闪烁问题
12
11
  */
13
12
  declare const ResponsiveDidAddress: React.ForwardRefExoticComponent<Omit<IResponsiveDidAddressProps, "ref"> & React.RefAttributes<HTMLDidAddressElement>>;
14
13
  export default ResponsiveDidAddress;
@@ -1,9 +1,10 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- import { useLatest, useSize } from 'ahooks';
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useDebounceFn, useLatest } from 'ahooks';
3
3
  import React, { forwardRef, useEffect, useImperativeHandle, useRef, useState } from 'react';
4
4
  import { Box } from '@mui/material';
5
5
  import { styled } from '../Theme';
6
6
  import DidAddress from './did-address';
7
+ import { getFontSize } from '../Util';
7
8
 
8
9
  /**
9
10
  * 根据父容器宽度自动切换 compact 模式
@@ -13,22 +14,27 @@ import DidAddress from './did-address';
13
14
  * - DidAddress 本身以 inline 形式渲染 (方便探测 did-address 的 full-width)
14
15
  * - 组件 mounted 时记录 did address 的 full-width (非 compact 模式的宽度)
15
16
  * - 监听容器宽度变化, 当容器宽度变化时, 对比容器宽度和 did address full-width, => 切换 compact 模式
16
- * - TODO: 初始化时, 在确定是否应该以 compact 模式渲染前, 隐藏显示, 避免闪烁问题
17
17
  */
18
18
  const ResponsiveDidAddress = /*#__PURE__*/forwardRef(({
19
19
  style,
20
20
  className,
21
21
  component = 'span',
22
+ size = 0,
22
23
  ...rest
23
24
  }, ref) => {
24
25
  const [compact, setCompact] = useState(false);
25
26
  const isCompact = useLatest(compact);
26
27
  // did address 完整显示时的宽度
27
28
  const [addressFullWidth, setAddressFullWidth] = useState(null);
29
+ const [containerWidth, setContainerWidth] = useState(null);
30
+ const [loading, setLoading] = useState(true);
31
+ const {
32
+ run: delaySetLoadingFalse
33
+ } = useDebounceFn(() => setLoading(false), {
34
+ wait: 50
35
+ });
28
36
  const containerRef = useRef(null);
29
37
  const innerRef = useRef(null);
30
- const size = useSize(containerRef);
31
- const containerWidth = size?.width || 0;
32
38
  useImperativeHandle(ref, () => new Proxy({}, {
33
39
  get(target, key) {
34
40
  return innerRef.current?.[key];
@@ -38,19 +44,30 @@ const ResponsiveDidAddress = /*#__PURE__*/forwardRef(({
38
44
  // 存储完整显示时 address 组件的宽度
39
45
  useEffect(() => {
40
46
  const innerWidth = innerRef.current?.offsetWidth || 0;
41
- let resizeObserver = null;
47
+ let innerObserver = null;
48
+ let containerObserver = null;
49
+
50
+ // 初始化宽度
42
51
  setAddressFullWidth(innerWidth);
52
+ setContainerWidth(containerRef.current?.offsetWidth);
43
53
 
44
54
  // 由于自定义字体的缘故,innerRef 的初始宽度可能发生二次改变,使用 observer 监听捕获
45
- resizeObserver = new ResizeObserver(() => {
55
+ innerObserver = new ResizeObserver(() => {
46
56
  if (!isCompact.current && innerRef.current?.offsetWidth !== innerWidth) {
47
57
  setAddressFullWidth(innerRef.current?.offsetWidth);
58
+ delaySetLoadingFalse();
48
59
  }
49
60
  });
50
- if (innerRef.current) {
51
- resizeObserver.observe(innerRef.current.getEl());
52
- }
53
- return () => resizeObserver.disconnect();
61
+ containerObserver = new ResizeObserver(() => {
62
+ setContainerWidth(containerRef.current?.offsetWidth);
63
+ });
64
+ innerObserver.observe(innerRef.current.getEl());
65
+ containerObserver.observe(containerRef.current);
66
+ delaySetLoadingFalse();
67
+ return () => {
68
+ innerObserver?.disconnect();
69
+ containerObserver?.disconnect();
70
+ };
54
71
  // eslint-disable-next-line react-hooks/exhaustive-deps
55
72
  }, []);
56
73
  useEffect(() => {
@@ -58,23 +75,41 @@ const ResponsiveDidAddress = /*#__PURE__*/forwardRef(({
58
75
  setCompact(containerWidth < addressFullWidth);
59
76
  }
60
77
  }, [containerWidth, addressFullWidth]);
61
- return /*#__PURE__*/_jsx(Root, {
78
+ return /*#__PURE__*/_jsxs(Root, {
62
79
  as: component,
63
80
  ref: containerRef,
64
81
  style: style,
65
82
  className: className,
66
- children: /*#__PURE__*/_jsx(StyledDidAddress, {
83
+ size: size,
84
+ inline: rest.inline,
85
+ children: [/*#__PURE__*/_jsx(StyledDidAddress, {
86
+ style: {
87
+ position: loading ? 'absolute' : 'static',
88
+ left: loading ? '-99999px' : 'auto'
89
+ },
67
90
  ...rest,
91
+ size: size,
68
92
  component: component,
69
93
  inline: true,
70
94
  compact: compact,
71
95
  ref: innerRef
72
- })
96
+ }), loading && /*#__PURE__*/_jsx("div", {
97
+ style: {
98
+ width: '100%',
99
+ height: `${(size || 16) * 1.5}px`
100
+ }
101
+ })]
73
102
  });
74
103
  });
75
104
  export default ResponsiveDidAddress;
76
- const Root = styled(Box)`
105
+ const Root = styled(Box, {
106
+ shouldForwardProp: prop => prop !== 'size'
107
+ })`
77
108
  display: block;
109
+ width: 100%; /* flex & column & align-items: flex-start 时, 块级元素不会自动铺满容器 */
110
+ font-size: ${({
111
+ size
112
+ }) => getFontSize(size)};
78
113
  overflow: hidden;
79
114
  ${({
80
115
  inline
@@ -58,7 +58,7 @@ export declare function openWebWallet({ webWalletUrl, action, locale, url, windo
58
58
  }): {
59
59
  type: string;
60
60
  };
61
- export declare const getFontSize: (size: string) => string;
61
+ export declare const getFontSize: (size: string | number) => string;
62
62
  export declare const isEthereumDid: (did: string) => boolean;
63
63
  export declare const appendParams: (url: string, params: {
64
64
  imageFilter: "crop" | "resize";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arcblock/ux",
3
- "version": "2.12.1",
3
+ "version": "2.12.3",
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": "f354d93f7db5e2e0547b75a05b5e47fd9a9587ac",
71
+ "gitHead": "d0ad7fcbd9bbae010ad58235494150e3c0814d43",
72
72
  "dependencies": {
73
73
  "@arcblock/did-motif": "^1.1.13",
74
- "@arcblock/icons": "^2.12.1",
75
- "@arcblock/nft-display": "^2.12.1",
76
- "@arcblock/react-hooks": "^2.12.1",
74
+ "@arcblock/icons": "^2.12.3",
75
+ "@arcblock/nft-display": "^2.12.3",
76
+ "@arcblock/react-hooks": "^2.12.3",
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,8 +1,9 @@
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';
5
5
  import DidAddress, { HTMLDidAddressElement, IDidAddressProps } from './did-address';
6
+ import { getFontSize } from '../Util';
6
7
 
7
8
  /**
8
9
  * 根据父容器宽度自动切换 compact 模式
@@ -12,18 +13,20 @@ import DidAddress, { HTMLDidAddressElement, IDidAddressProps } from './did-addre
12
13
  * - DidAddress 本身以 inline 形式渲染 (方便探测 did-address 的 full-width)
13
14
  * - 组件 mounted 时记录 did address 的 full-width (非 compact 模式的宽度)
14
15
  * - 监听容器宽度变化, 当容器宽度变化时, 对比容器宽度和 did address full-width, => 切换 compact 模式
15
- * - TODO: 初始化时, 在确定是否应该以 compact 模式渲染前, 隐藏显示, 避免闪烁问题
16
16
  */
17
17
  const ResponsiveDidAddress = forwardRef<HTMLDidAddressElement, IResponsiveDidAddressProps>(
18
- ({ style, className, component = 'span', ...rest }, ref) => {
18
+ ({ style, className, component = 'span', size = 0, ...rest }, ref) => {
19
19
  const [compact, setCompact] = useState(false);
20
20
  const isCompact = useLatest(compact);
21
21
  // did address 完整显示时的宽度
22
22
  const [addressFullWidth, setAddressFullWidth] = useState<number | null | undefined>(null);
23
+ const [containerWidth, setContainerWidth] = useState<number | null | undefined>(null);
24
+ const [loading, setLoading] = useState(true);
25
+ const { run: delaySetLoadingFalse } = useDebounceFn(() => setLoading(false), {
26
+ wait: 50,
27
+ });
23
28
  const containerRef = useRef<HTMLDivElement>(null);
24
29
  const innerRef = useRef<HTMLDidAddressElement>(null);
25
- const size = useSize(containerRef);
26
- const containerWidth = size?.width || 0;
27
30
 
28
31
  useImperativeHandle(
29
32
  ref,
@@ -41,22 +44,32 @@ const ResponsiveDidAddress = forwardRef<HTMLDidAddressElement, IResponsiveDidAdd
41
44
  // 存储完整显示时 address 组件的宽度
42
45
  useEffect(() => {
43
46
  const innerWidth = innerRef.current?.offsetWidth || 0;
44
- let resizeObserver: ResizeObserver | null = null;
47
+ let innerObserver: ResizeObserver | null = null;
48
+ let containerObserver: ResizeObserver | null = null;
45
49
 
50
+ // 初始化宽度
46
51
  setAddressFullWidth(innerWidth);
52
+ setContainerWidth(containerRef.current?.offsetWidth);
47
53
 
48
54
  // 由于自定义字体的缘故,innerRef 的初始宽度可能发生二次改变,使用 observer 监听捕获
49
- resizeObserver = new ResizeObserver(() => {
55
+ innerObserver = new ResizeObserver(() => {
50
56
  if (!isCompact.current && innerRef.current?.offsetWidth !== innerWidth) {
51
57
  setAddressFullWidth(innerRef.current?.offsetWidth);
58
+ delaySetLoadingFalse();
52
59
  }
53
60
  });
61
+ containerObserver = new ResizeObserver(() => {
62
+ setContainerWidth(containerRef.current?.offsetWidth);
63
+ });
54
64
 
55
- if (innerRef.current) {
56
- resizeObserver.observe(innerRef.current.getEl());
57
- }
65
+ innerObserver.observe(innerRef.current!.getEl());
66
+ containerObserver.observe(containerRef.current!);
67
+ delaySetLoadingFalse();
58
68
 
59
- return () => resizeObserver.disconnect();
69
+ return () => {
70
+ innerObserver?.disconnect();
71
+ containerObserver?.disconnect();
72
+ };
60
73
  // eslint-disable-next-line react-hooks/exhaustive-deps
61
74
  }, []);
62
75
 
@@ -65,9 +78,23 @@ const ResponsiveDidAddress = forwardRef<HTMLDidAddressElement, IResponsiveDidAdd
65
78
  setCompact(containerWidth < addressFullWidth);
66
79
  }
67
80
  }, [containerWidth, addressFullWidth]);
81
+
68
82
  return (
69
- <Root as={component} ref={containerRef} style={style} className={className}>
70
- <StyledDidAddress {...rest} component={component} inline compact={compact} ref={innerRef} />
83
+ <Root as={component} ref={containerRef} style={style} className={className} size={size} inline={rest.inline}>
84
+ <StyledDidAddress
85
+ style={{
86
+ position: loading ? 'absolute' : 'static',
87
+ left: loading ? '-99999px' : 'auto',
88
+ }}
89
+ {...rest}
90
+ size={size}
91
+ component={component}
92
+ inline
93
+ compact={compact}
94
+ ref={innerRef}
95
+ />
96
+ {/* placeholder */}
97
+ {loading && <div style={{ width: '100%', height: `${(size || 16) * 1.5}px` }} />}
71
98
  </Root>
72
99
  );
73
100
  }
@@ -81,10 +108,17 @@ export interface IResponsiveDidAddressProps extends IDidAddressProps {
81
108
  component?: React.ElementType;
82
109
  }
83
110
 
84
- const Root = styled(Box)`
111
+ type RootProps = {
112
+ size: number;
113
+ inline?: boolean;
114
+ };
115
+
116
+ const Root = styled(Box, { shouldForwardProp: (prop) => prop !== 'size' })<RootProps>`
85
117
  display: block;
118
+ width: 100%; /* flex & column & align-items: flex-start 时, 块级元素不会自动铺满容器 */
119
+ font-size: ${({ size }) => getFontSize(size)};
86
120
  overflow: hidden;
87
- ${({ inline }: any) =>
121
+ ${({ inline }) =>
88
122
  inline &&
89
123
  `
90
124
  display: inline-block;
package/src/Util/index.ts CHANGED
@@ -313,7 +313,7 @@ export function openWebWallet({
313
313
  return { type: 'web' };
314
314
  }
315
315
 
316
- export const getFontSize = (size: string) => {
316
+ export const getFontSize = (size: string | number) => {
317
317
  // 12px 及以上的 size 有效, 否则返回 inherit
318
318
  if (size && Number(size) >= 12) {
319
319
  return `${Number(size)}px`;