@arcblock/ux 2.10.43 → 2.10.44
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/Address/compact-text.d.ts +3 -1
- package/lib/Address/compact-text.js +2 -1
- package/lib/Address/did-address.d.ts +22 -3
- package/lib/Address/did-address.js +37 -59
- package/lib/Address/index.d.ts +4 -13
- package/lib/Address/index.js +10 -13
- package/lib/Address/responsive-did-address.d.ts +8 -22
- package/lib/Address/responsive-did-address.js +15 -19
- package/lib/BlockletV2/blocklet.js +1 -0
- package/lib/BlockletV2/components/icon-text.d.ts +3 -1
- package/lib/BlockletV2/components/icon-text.js +4 -3
- package/lib/DID/index.d.ts +25 -22
- package/lib/DID/index.js +56 -60
- package/lib/type.d.ts +1 -0
- package/package.json +5 -5
- package/src/Address/compact-text.jsx +2 -1
- package/src/Address/did-address.tsx +215 -0
- package/src/Address/index.tsx +18 -0
- package/src/Address/responsive-did-address.tsx +90 -0
- package/src/BlockletV2/blocklet.tsx +3 -1
- package/src/BlockletV2/components/icon-text.tsx +8 -2
- package/src/DID/{index.jsx → index.tsx} +90 -58
- package/src/type.d.ts +1 -0
- package/src/Address/did-address.jsx +0 -220
- package/src/Address/index.jsx +0 -18
- package/src/Address/responsive-did-address.jsx +0 -79
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@arcblock/ux",
|
|
3
|
-
"version": "2.10.
|
|
3
|
+
"version": "2.10.44",
|
|
4
4
|
"description": "Common used react components for arcblock products",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react",
|
|
@@ -64,12 +64,12 @@
|
|
|
64
64
|
"react": ">=18.2.0",
|
|
65
65
|
"react-router-dom": ">=6.22.3"
|
|
66
66
|
},
|
|
67
|
-
"gitHead": "
|
|
67
|
+
"gitHead": "35fb53cce48d64d7affbc3023f7d027f0ec93171",
|
|
68
68
|
"dependencies": {
|
|
69
69
|
"@arcblock/did-motif": "^1.1.13",
|
|
70
|
-
"@arcblock/icons": "^2.10.
|
|
71
|
-
"@arcblock/nft-display": "^2.10.
|
|
72
|
-
"@arcblock/react-hooks": "^2.10.
|
|
70
|
+
"@arcblock/icons": "^2.10.44",
|
|
71
|
+
"@arcblock/nft-display": "^2.10.44",
|
|
72
|
+
"@arcblock/react-hooks": "^2.10.44",
|
|
73
73
|
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
|
|
74
74
|
"@fontsource/inter": "^5.0.16",
|
|
75
75
|
"@fontsource/ubuntu-mono": "^5.0.18",
|
|
@@ -65,7 +65,7 @@ export default function CompactText({ startChars, endChars, children, showCopyBu
|
|
|
65
65
|
CompactText.propTypes = {
|
|
66
66
|
startChars: PropTypes.number,
|
|
67
67
|
endChars: PropTypes.number,
|
|
68
|
-
children: PropTypes.node
|
|
68
|
+
children: PropTypes.node,
|
|
69
69
|
// 在 tooltip 中完整地址后显示复制按钮
|
|
70
70
|
showCopyButtonInTooltip: PropTypes.bool,
|
|
71
71
|
};
|
|
@@ -73,5 +73,6 @@ CompactText.propTypes = {
|
|
|
73
73
|
CompactText.defaultProps = {
|
|
74
74
|
startChars: 6,
|
|
75
75
|
endChars: 6,
|
|
76
|
+
children: null,
|
|
76
77
|
showCopyButtonInTooltip: false,
|
|
77
78
|
};
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
import '@fontsource/ubuntu-mono/400.css';
|
|
2
|
+
import { Check as CheckIcon, ContentCopy as CopyIcon } from '@mui/icons-material';
|
|
3
|
+
import { Box, BoxProps, Tooltip } from '@mui/material';
|
|
4
|
+
import { green } from '@mui/material/colors';
|
|
5
|
+
import copy from 'copy-to-clipboard';
|
|
6
|
+
import noop from 'lodash/noop';
|
|
7
|
+
import React, { forwardRef, ReactNode, useImperativeHandle, useRef, useState } from 'react';
|
|
8
|
+
import { styled } from '../Theme';
|
|
9
|
+
import { getFontSize } from '../Util';
|
|
10
|
+
import CompactText from './compact-text';
|
|
11
|
+
|
|
12
|
+
const translations = {
|
|
13
|
+
en: {
|
|
14
|
+
copy: 'Click To Copy',
|
|
15
|
+
copied: 'Copied!',
|
|
16
|
+
},
|
|
17
|
+
zh: {
|
|
18
|
+
copy: '点击复制',
|
|
19
|
+
copied: '已复制!',
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export interface HTMLDidAddressElement extends HTMLDivElement {
|
|
24
|
+
copy: () => void;
|
|
25
|
+
}
|
|
26
|
+
export interface IDidAddressProps extends BoxProps {
|
|
27
|
+
component?: React.ElementType;
|
|
28
|
+
size?: number;
|
|
29
|
+
copyable?: boolean;
|
|
30
|
+
// compact mode 下, hover 时会在 tooltip 中显示完整地址, showCopyButtonInTooltip = true 时会在完整地址后显示一个复制按钮
|
|
31
|
+
showCopyButtonInTooltip?: boolean;
|
|
32
|
+
content?: string;
|
|
33
|
+
inline?: boolean;
|
|
34
|
+
prepend?: ReactNode;
|
|
35
|
+
append?: ReactNode;
|
|
36
|
+
// 紧凑模式
|
|
37
|
+
compact?: boolean;
|
|
38
|
+
startChars?: number;
|
|
39
|
+
endChars?: number;
|
|
40
|
+
locale?: 'en' | 'zh';
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* DidAddress 组件 (新版设计)
|
|
45
|
+
*
|
|
46
|
+
* - 样式调整
|
|
47
|
+
* - click-to-copy 调整
|
|
48
|
+
* - 长文本截断处理 (Ellipsis)
|
|
49
|
+
* - 支持 inline 或 block 的显示方式
|
|
50
|
+
* - 支持紧凑模式, 该模式下:
|
|
51
|
+
* - 占用宽度较小, 因此不考虑水平空间不够用的情况, 且忽略末尾省略号
|
|
52
|
+
* - 对于多层元素结构的 children, 保持元素结构, 将最内层 text 替换为 CompactText 组件
|
|
53
|
+
* - 为保证 copy 功能正常工作, 原 children 始终渲染, 但在紧凑式下会隐藏
|
|
54
|
+
* - 可配合 useMediaQuery 使用
|
|
55
|
+
*/
|
|
56
|
+
const DidAddress = forwardRef<HTMLDidAddressElement, IDidAddressProps>((props, ref) => {
|
|
57
|
+
const {
|
|
58
|
+
component = 'span',
|
|
59
|
+
size = 0,
|
|
60
|
+
copyable = true,
|
|
61
|
+
showCopyButtonInTooltip = false,
|
|
62
|
+
children = null,
|
|
63
|
+
content = '',
|
|
64
|
+
prepend = null,
|
|
65
|
+
append = null,
|
|
66
|
+
compact = false,
|
|
67
|
+
startChars = 6,
|
|
68
|
+
endChars = 6,
|
|
69
|
+
locale: originalLocale = 'en',
|
|
70
|
+
...rest
|
|
71
|
+
} = props;
|
|
72
|
+
let locale = originalLocale;
|
|
73
|
+
if (!translations[locale]) {
|
|
74
|
+
locale = 'en';
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const [copied, setCopied] = useState(false);
|
|
78
|
+
const textRef = useRef<HTMLDivElement>(null);
|
|
79
|
+
const rootRef = useRef<any>(null);
|
|
80
|
+
|
|
81
|
+
const handleCopy = () => {
|
|
82
|
+
copy(content || textRef.current?.textContent || '');
|
|
83
|
+
setCopied(true);
|
|
84
|
+
// 恢复 copied 状态
|
|
85
|
+
setTimeout(() => {
|
|
86
|
+
setCopied(false);
|
|
87
|
+
}, 1500);
|
|
88
|
+
};
|
|
89
|
+
const onCopy = (e: any) => {
|
|
90
|
+
e.stopPropagation();
|
|
91
|
+
e.preventDefault();
|
|
92
|
+
handleCopy();
|
|
93
|
+
};
|
|
94
|
+
useImperativeHandle(
|
|
95
|
+
ref,
|
|
96
|
+
() =>
|
|
97
|
+
new Proxy(
|
|
98
|
+
{
|
|
99
|
+
copy: handleCopy,
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
get(target: any, key: string) {
|
|
103
|
+
return target[key] || rootRef.current?.[key];
|
|
104
|
+
},
|
|
105
|
+
}
|
|
106
|
+
)
|
|
107
|
+
);
|
|
108
|
+
|
|
109
|
+
let copyElement = null;
|
|
110
|
+
if (copyable) {
|
|
111
|
+
copyElement = (
|
|
112
|
+
<span className="did-address-copy-wrapper" title={copied ? '' : translations[locale].copy}>
|
|
113
|
+
{copied ? (
|
|
114
|
+
<Tooltip title={translations[locale].copied} placement="bottom" arrow open={copied}>
|
|
115
|
+
<CheckIcon className="did-address-copy" style={{ color: green[500] }} />
|
|
116
|
+
</Tooltip>
|
|
117
|
+
) : (
|
|
118
|
+
/* title prop 直接加在 icon 上不生效 */
|
|
119
|
+
<CopyIcon className="did-address-copy" onClick={onCopy} />
|
|
120
|
+
)}
|
|
121
|
+
</span>
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
return (
|
|
126
|
+
<Root as={component} size={size} {...rest} ref={rootRef}>
|
|
127
|
+
{prepend}
|
|
128
|
+
<Box sx={{ display: 'none' }} ref={textRef}>
|
|
129
|
+
{children}
|
|
130
|
+
</Box>
|
|
131
|
+
{/* 注意: 该元素必须渲染(可以隐藏), 以便 compact 模式下复制的文本是完整的 */}
|
|
132
|
+
<Tooltip title={copyable ? '' : translations[locale].copied} placement="bottom" arrow open={copied}>
|
|
133
|
+
{compact ? (
|
|
134
|
+
<Box
|
|
135
|
+
component="span"
|
|
136
|
+
className="did-address-text"
|
|
137
|
+
sx={{
|
|
138
|
+
cursor: copyable ? 'unset' : 'pointer',
|
|
139
|
+
}}
|
|
140
|
+
onDoubleClick={copyable ? noop : onCopy}>
|
|
141
|
+
<CompactText startChars={startChars} endChars={endChars} showCopyButtonInTooltip={showCopyButtonInTooltip}>
|
|
142
|
+
{children}
|
|
143
|
+
</CompactText>
|
|
144
|
+
</Box>
|
|
145
|
+
) : (
|
|
146
|
+
<Box
|
|
147
|
+
component="span"
|
|
148
|
+
className="did-address-text did-address-truncate"
|
|
149
|
+
sx={{
|
|
150
|
+
display: compact ? 'none' : 'inline',
|
|
151
|
+
cursor: copyable ? 'unset' : 'pointer',
|
|
152
|
+
}}
|
|
153
|
+
onDoubleClick={copyable ? noop : onCopy}>
|
|
154
|
+
{children}
|
|
155
|
+
</Box>
|
|
156
|
+
)}
|
|
157
|
+
</Tooltip>
|
|
158
|
+
{copyElement}
|
|
159
|
+
{append}
|
|
160
|
+
</Root>
|
|
161
|
+
);
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
export default DidAddress;
|
|
165
|
+
|
|
166
|
+
const Root = styled<any>(Box, { shouldForwardProp: (prop) => prop !== 'inline' })`
|
|
167
|
+
font-family: 'Ubuntu Mono', monospace;
|
|
168
|
+
&& {
|
|
169
|
+
display: ${({ inline }: any) => (inline ? 'inline-flex' : 'flex')};
|
|
170
|
+
align-items: center;
|
|
171
|
+
max-width: 100%;
|
|
172
|
+
overflow: hidden;
|
|
173
|
+
color: #ccc;
|
|
174
|
+
font-size: ${(props: any) => getFontSize(props.size)};
|
|
175
|
+
font-weight: 400;
|
|
176
|
+
|
|
177
|
+
svg {
|
|
178
|
+
fill: currentColor;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
.did-address-text {
|
|
183
|
+
color: #666;
|
|
184
|
+
}
|
|
185
|
+
/* truncate string with ellipsis */
|
|
186
|
+
.did-address-truncate {
|
|
187
|
+
white-space: nowrap;
|
|
188
|
+
overflow: hidden;
|
|
189
|
+
text-overflow: ellipsis;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
.did-address-copy-wrapper {
|
|
193
|
+
display: flex;
|
|
194
|
+
justify-content: center;
|
|
195
|
+
align-items: center;
|
|
196
|
+
width: 1em;
|
|
197
|
+
height: 1em;
|
|
198
|
+
margin-left: 8px;
|
|
199
|
+
}
|
|
200
|
+
.did-address-copy {
|
|
201
|
+
flex: 0 0 auto;
|
|
202
|
+
font-size: 1em;
|
|
203
|
+
color: #999;
|
|
204
|
+
cursor: pointer;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/* link */
|
|
208
|
+
a {
|
|
209
|
+
color: #666;
|
|
210
|
+
}
|
|
211
|
+
&:hover a {
|
|
212
|
+
color: #222;
|
|
213
|
+
text-decoration: underline;
|
|
214
|
+
}
|
|
215
|
+
`;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { forwardRef } from 'react';
|
|
2
|
+
import DidAddress, { HTMLDidAddressElement, IDidAddressProps } from './did-address';
|
|
3
|
+
import ResponsiveDidAddress from './responsive-did-address';
|
|
4
|
+
|
|
5
|
+
export interface IDidAddressWrapper extends IDidAddressProps {
|
|
6
|
+
responsive?: boolean;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const DidAddressWrapper = forwardRef<HTMLDidAddressElement, IDidAddressWrapper>(
|
|
10
|
+
({ responsive = true, ...rest }, ref) => {
|
|
11
|
+
if (responsive) {
|
|
12
|
+
return <ResponsiveDidAddress {...rest} ref={ref} />;
|
|
13
|
+
}
|
|
14
|
+
return <DidAddress {...rest} ref={ref} />;
|
|
15
|
+
}
|
|
16
|
+
);
|
|
17
|
+
|
|
18
|
+
export default DidAddressWrapper;
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { useSize } from 'ahooks';
|
|
2
|
+
import React, { forwardRef, useEffect, useImperativeHandle, useRef, useState } from 'react';
|
|
3
|
+
import { styled } from '../Theme';
|
|
4
|
+
|
|
5
|
+
import DidAddress, { HTMLDidAddressElement, IDidAddressProps } from './did-address';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* 根据父容器宽度自动切换 compact 模式
|
|
9
|
+
*
|
|
10
|
+
* 实现逻辑:
|
|
11
|
+
* - DidAddress 外层包裹一个容器, 其宽度自动撑满父容器宽度 (即这个容器需要是块级元素或 100% 宽的 inline-block)
|
|
12
|
+
* - DidAddress 本身以 inline 形式渲染 (方便探测 did-address 的 full-width)
|
|
13
|
+
* - 组件 mounted 时记录 did address 的 full-width (非 compact 模式的宽度)
|
|
14
|
+
* - 监听容器宽度变化, 当容器宽度变化时, 对比容器宽度和 did address full-width, => 切换 compact 模式
|
|
15
|
+
* - TODO: 初始化时, 在确定是否应该以 compact 模式渲染前, 隐藏显示, 避免闪烁问题
|
|
16
|
+
*/
|
|
17
|
+
const ResponsiveDidAddress = forwardRef<HTMLDidAddressElement, IResponsiveDidAddressProps>(
|
|
18
|
+
({ style, className, component = 'span', ...rest }, ref) => {
|
|
19
|
+
const [compact, setCompact] = useState(false);
|
|
20
|
+
// did address 完整显示时的宽度
|
|
21
|
+
const [addressFullWidth, setAddressFullWidth] = useState<number | null | undefined>(null);
|
|
22
|
+
const containerRef = useRef<HTMLDivElement>(null);
|
|
23
|
+
const innerRef = useRef<HTMLDidAddressElement>(null);
|
|
24
|
+
const size = useSize(containerRef);
|
|
25
|
+
const containerWidth = size?.width || 0;
|
|
26
|
+
|
|
27
|
+
useImperativeHandle(
|
|
28
|
+
ref,
|
|
29
|
+
() =>
|
|
30
|
+
new Proxy(
|
|
31
|
+
{},
|
|
32
|
+
{
|
|
33
|
+
get(target: any, key: keyof HTMLDidAddressElement) {
|
|
34
|
+
return innerRef.current?.[key];
|
|
35
|
+
},
|
|
36
|
+
}
|
|
37
|
+
)
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
// 存储完整显示时 address 组件的宽度
|
|
41
|
+
useEffect(() => {
|
|
42
|
+
if (!compact && addressFullWidth === null) {
|
|
43
|
+
setAddressFullWidth(innerRef.current?.offsetWidth);
|
|
44
|
+
}
|
|
45
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
46
|
+
}, []);
|
|
47
|
+
|
|
48
|
+
useEffect(() => {
|
|
49
|
+
if (containerWidth && addressFullWidth) {
|
|
50
|
+
setCompact(containerWidth < addressFullWidth);
|
|
51
|
+
}
|
|
52
|
+
}, [containerWidth, addressFullWidth]);
|
|
53
|
+
return (
|
|
54
|
+
<Root as={component} ref={containerRef} style={style} className={className}>
|
|
55
|
+
<StyledDidAddress {...rest} component={component} inline compact={compact} ref={innerRef} />
|
|
56
|
+
</Root>
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
export default ResponsiveDidAddress;
|
|
62
|
+
|
|
63
|
+
export interface IResponsiveDidAddressProps extends IDidAddressProps {
|
|
64
|
+
style?: React.CSSProperties;
|
|
65
|
+
className?: string;
|
|
66
|
+
component?: React.ElementType;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const Root = styled('div')`
|
|
70
|
+
display: block;
|
|
71
|
+
overflow: hidden;
|
|
72
|
+
${({ inline }: any) =>
|
|
73
|
+
inline &&
|
|
74
|
+
`
|
|
75
|
+
display: inline-block;
|
|
76
|
+
width: 100%;
|
|
77
|
+
`}
|
|
78
|
+
`;
|
|
79
|
+
|
|
80
|
+
const StyledDidAddress = styled(DidAddress)`
|
|
81
|
+
&& {
|
|
82
|
+
max-width: none;
|
|
83
|
+
}
|
|
84
|
+
.did-address-text {
|
|
85
|
+
/* 禁止文本 Ellipsis/截断, 以便测量真实的宽度 */
|
|
86
|
+
white-space: nowrap;
|
|
87
|
+
overflow: visible;
|
|
88
|
+
text-overflow: unset;
|
|
89
|
+
}
|
|
90
|
+
`;
|
|
@@ -124,7 +124,9 @@ export default function BlockletStore(props: IBlockletStore) {
|
|
|
124
124
|
/>
|
|
125
125
|
</Stack>
|
|
126
126
|
<Stack direction="row" alignItems="center" gap={2} color="text.secondary">
|
|
127
|
-
<IconText icon={<Avatar src={avatar} did={did} size={20} variant="circle" />}
|
|
127
|
+
<IconText icon={<Avatar src={avatar} did={did} size={20} variant="circle" />} maxWidth={200}>
|
|
128
|
+
{author}
|
|
129
|
+
</IconText>
|
|
128
130
|
<IconText icon={<Icon icon={Download} />} title={download}>
|
|
129
131
|
{formatDownloadCount(download)}
|
|
130
132
|
</IconText>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Stack, Typography } from '@mui/material';
|
|
1
|
+
import { Stack, StackProps, Typography } from '@mui/material';
|
|
2
2
|
import React from 'react';
|
|
3
3
|
|
|
4
4
|
export default function IconText({
|
|
@@ -6,15 +6,21 @@ export default function IconText({
|
|
|
6
6
|
children,
|
|
7
7
|
maxWidth = 100,
|
|
8
8
|
title,
|
|
9
|
+
sx,
|
|
9
10
|
}: {
|
|
10
11
|
icon?: React.ReactNode;
|
|
11
12
|
children?: React.ReactNode;
|
|
12
13
|
maxWidth?: number;
|
|
13
14
|
title?: string;
|
|
15
|
+
sx?: StackProps['sx'];
|
|
14
16
|
}) {
|
|
15
17
|
return (
|
|
16
18
|
(children === 0 || children) && (
|
|
17
|
-
<Stack
|
|
19
|
+
<Stack
|
|
20
|
+
direction="row"
|
|
21
|
+
alignItems="center"
|
|
22
|
+
gap={1}
|
|
23
|
+
sx={[{ maxWidth, overflow: 'hidden' }, ...(Array.isArray(sx) ? sx : [sx])]}>
|
|
18
24
|
{icon}
|
|
19
25
|
<Typography
|
|
20
26
|
flex={1}
|
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
import { forwardRef, useState } from 'react';
|
|
2
|
-
import PropTypes from 'prop-types';
|
|
3
1
|
import { getDIDMotifInfo } from '@arcblock/did-motif';
|
|
4
|
-
import QRCode from 'qrcode.react';
|
|
5
|
-
import { Icon } from '@iconify/react';
|
|
6
2
|
import IconQrCode from '@iconify-icons/material-symbols/qr-code-rounded';
|
|
3
|
+
import { Icon } from '@iconify/react';
|
|
7
4
|
import { Box, Dialog, DialogContent, DialogTitle, Typography } from '@mui/material';
|
|
8
5
|
import { useCreation, useMemoizedFn } from 'ahooks';
|
|
6
|
+
import QRCode from 'qrcode.react';
|
|
7
|
+
import React, { forwardRef, useImperativeHandle, useRef, useState } from 'react';
|
|
9
8
|
|
|
9
|
+
import Address, { IDidAddressWrapper } from '../Address';
|
|
10
|
+
import Avatar from '../Avatar';
|
|
10
11
|
import { temp as colors } from '../Colors';
|
|
11
12
|
import { DID_PREFIX } from '../Util/constant';
|
|
12
|
-
import Address from '../Address';
|
|
13
|
-
import Avatar from '../Avatar';
|
|
14
13
|
|
|
15
|
-
import {
|
|
14
|
+
import { HTMLDidAddressElement } from '../Address/did-address';
|
|
16
15
|
import { translate } from '../Locale/util';
|
|
16
|
+
import { getDIDColor, getFontSize, isEthereumDid } from '../Util';
|
|
17
17
|
|
|
18
18
|
const translations = {
|
|
19
19
|
en: {
|
|
@@ -28,32 +28,32 @@ const translations = {
|
|
|
28
28
|
},
|
|
29
29
|
};
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
did:
|
|
33
|
-
size
|
|
34
|
-
component
|
|
35
|
-
copyable
|
|
36
|
-
responsive
|
|
37
|
-
showCopyButtonInTooltip
|
|
38
|
-
showAvatar
|
|
39
|
-
showQrcode
|
|
40
|
-
inline
|
|
41
|
-
append
|
|
42
|
-
compact
|
|
43
|
-
startChars
|
|
44
|
-
endChars
|
|
45
|
-
locale
|
|
46
|
-
chainId
|
|
47
|
-
}
|
|
31
|
+
interface IDIDPropTypes extends IDidAddressWrapper {
|
|
32
|
+
did: string;
|
|
33
|
+
size?: number;
|
|
34
|
+
component?: React.ElementType;
|
|
35
|
+
copyable?: boolean;
|
|
36
|
+
responsive?: boolean;
|
|
37
|
+
showCopyButtonInTooltip?: boolean;
|
|
38
|
+
showAvatar?: boolean;
|
|
39
|
+
showQrcode?: boolean;
|
|
40
|
+
inline?: boolean;
|
|
41
|
+
append?: any;
|
|
42
|
+
compact?: boolean;
|
|
43
|
+
startChars?: number;
|
|
44
|
+
endChars?: number;
|
|
45
|
+
locale?: 'en' | 'zh';
|
|
46
|
+
chainId?: string;
|
|
47
|
+
}
|
|
48
48
|
|
|
49
49
|
const DEFAULT_CHAIN_ID = 'xenon-2020-01-15';
|
|
50
50
|
|
|
51
|
-
const CHAIN_ID_MAP = {
|
|
51
|
+
const CHAIN_ID_MAP: Record<string, string> = {
|
|
52
52
|
'main.abtnetwork.io': DEFAULT_CHAIN_ID,
|
|
53
53
|
'beta.abtnetwork.io': 'beta',
|
|
54
54
|
};
|
|
55
55
|
|
|
56
|
-
const getFontColor = (did, didMotifInfo, isEthDid) => {
|
|
56
|
+
const getFontColor = (did: string, didMotifInfo: any, isEthDid: boolean) => {
|
|
57
57
|
if (isEthDid) {
|
|
58
58
|
return getDIDColor(did);
|
|
59
59
|
}
|
|
@@ -61,8 +61,8 @@ const getFontColor = (did, didMotifInfo, isEthDid) => {
|
|
|
61
61
|
return didMotifInfo.color;
|
|
62
62
|
};
|
|
63
63
|
|
|
64
|
-
const isSquareMotif = (roleType) => {
|
|
65
|
-
const roles = {
|
|
64
|
+
const isSquareMotif = (roleType: number) => {
|
|
65
|
+
const roles: Record<number, boolean> = {
|
|
66
66
|
0: true, // ACCOUNT
|
|
67
67
|
6: true, // ASSET
|
|
68
68
|
17: true, // TOKEN
|
|
@@ -70,7 +70,7 @@ const isSquareMotif = (roleType) => {
|
|
|
70
70
|
return !roles[roleType];
|
|
71
71
|
};
|
|
72
72
|
|
|
73
|
-
const getAvatarSize = (didMotifInfo, isEthDid, size) => {
|
|
73
|
+
const getAvatarSize = (didMotifInfo: any, isEthDid: boolean, size: number) => {
|
|
74
74
|
if (isEthDid) {
|
|
75
75
|
return size * 0.75;
|
|
76
76
|
}
|
|
@@ -80,21 +80,55 @@ const getAvatarSize = (didMotifInfo, isEthDid, size) => {
|
|
|
80
80
|
return size;
|
|
81
81
|
};
|
|
82
82
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
83
|
+
export interface HTMLDIDElement extends HTMLDidAddressElement {
|
|
84
|
+
openQRCode: () => void;
|
|
85
|
+
closeQRCode: () => void;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const DID = forwardRef<HTMLDIDElement, IDIDPropTypes>((props, ref) => {
|
|
89
|
+
const {
|
|
90
|
+
did,
|
|
91
|
+
showAvatar = true,
|
|
92
|
+
showQrcode = false,
|
|
93
|
+
locale = 'en',
|
|
94
|
+
size = 0,
|
|
95
|
+
component = 'span',
|
|
96
|
+
copyable = true,
|
|
97
|
+
responsive = true,
|
|
98
|
+
showCopyButtonInTooltip = false,
|
|
99
|
+
inline = false,
|
|
100
|
+
append = null,
|
|
101
|
+
compact = false,
|
|
102
|
+
startChars = 6,
|
|
103
|
+
endChars = 6,
|
|
104
|
+
} = props;
|
|
105
|
+
|
|
106
|
+
const rest = {
|
|
107
|
+
size,
|
|
108
|
+
component,
|
|
109
|
+
copyable,
|
|
110
|
+
responsive,
|
|
111
|
+
showCopyButtonInTooltip,
|
|
112
|
+
inline,
|
|
113
|
+
append,
|
|
114
|
+
compact,
|
|
115
|
+
startChars,
|
|
116
|
+
endChars,
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
const addressRef = useRef<any>(null);
|
|
120
|
+
|
|
87
121
|
const t = useMemoizedFn((key, data = {}) => {
|
|
88
122
|
return translate(translations, key, locale, 'en', data);
|
|
89
123
|
});
|
|
90
124
|
|
|
125
|
+
let chainId = props.chainId || '';
|
|
91
126
|
try {
|
|
92
127
|
if (!chainId) {
|
|
93
|
-
const chainHostUrl = window
|
|
128
|
+
const chainHostUrl = (window as any).blocklet?.CHAIN_HOST;
|
|
94
129
|
if (chainHostUrl) {
|
|
95
130
|
const chainHost = new URL(chainHostUrl).hostname;
|
|
96
131
|
if (chainHost) {
|
|
97
|
-
// eslint-disable-next-line no-param-reassign
|
|
98
132
|
chainId = CHAIN_ID_MAP[chainHost];
|
|
99
133
|
}
|
|
100
134
|
}
|
|
@@ -116,6 +150,7 @@ const DID = forwardRef(({ did, showAvatar, showQrcode, chainId, locale, ...rest
|
|
|
116
150
|
showAvatar && (
|
|
117
151
|
<Avatar
|
|
118
152
|
key="avatar"
|
|
153
|
+
src=""
|
|
119
154
|
did={did}
|
|
120
155
|
size={getAvatarSize(didMotifInfo, isEthDid, rest.size || 18)}
|
|
121
156
|
style={{ display: 'inline-flex', alignItems: 'center', marginLeft: 2, marginRight: 4 }}
|
|
@@ -133,8 +168,22 @@ const DID = forwardRef(({ did, showAvatar, showQrcode, chainId, locale, ...rest
|
|
|
133
168
|
setOpen(true);
|
|
134
169
|
});
|
|
135
170
|
|
|
171
|
+
useImperativeHandle(ref, () => {
|
|
172
|
+
return new Proxy(
|
|
173
|
+
{
|
|
174
|
+
openQRCode: () => setOpen(true),
|
|
175
|
+
closeQRCode: () => setOpen(false),
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
get(target: any, key: string) {
|
|
179
|
+
return target[key] || addressRef?.current?.[key];
|
|
180
|
+
},
|
|
181
|
+
}
|
|
182
|
+
);
|
|
183
|
+
});
|
|
184
|
+
|
|
136
185
|
const downloadUrl = useCreation(() => {
|
|
137
|
-
if (['zh', 'en'].includes) {
|
|
186
|
+
if (['zh', 'en'].includes(locale)) {
|
|
138
187
|
return `https://www.didwallet.io/${locale}`;
|
|
139
188
|
}
|
|
140
189
|
return 'https://www.didwallet.io/en';
|
|
@@ -165,15 +214,16 @@ const DID = forwardRef(({ did, showAvatar, showQrcode, chainId, locale, ...rest
|
|
|
165
214
|
return (
|
|
166
215
|
<>
|
|
167
216
|
<Address
|
|
168
|
-
ref={ref}
|
|
169
217
|
locale={locale}
|
|
170
218
|
content={`${DID_PREFIX}${did}`}
|
|
171
219
|
{...rest}
|
|
220
|
+
ref={addressRef}
|
|
172
221
|
prepend={prepend}
|
|
173
222
|
append={
|
|
174
223
|
<>
|
|
175
224
|
{showQrcode ? (
|
|
176
225
|
<Box
|
|
226
|
+
id="did-qrcode-button"
|
|
177
227
|
component={Icon}
|
|
178
228
|
icon={IconQrCode}
|
|
179
229
|
onClick={openQrCode}
|
|
@@ -197,7 +247,8 @@ const DID = forwardRef(({ did, showAvatar, showQrcode, chainId, locale, ...rest
|
|
|
197
247
|
{t('scanQrcode')}
|
|
198
248
|
</Typography>
|
|
199
249
|
</DialogTitle>
|
|
200
|
-
|
|
250
|
+
{/* @ts-ignore */}
|
|
251
|
+
<DialogContent align={'center' as any}>
|
|
201
252
|
<QRCode
|
|
202
253
|
// eslint-disable-next-line max-len
|
|
203
254
|
value={`abt://abtwallet.io/i?did=${DID_PREFIX}${did}&action=didRecognize&chainID=${
|
|
@@ -208,7 +259,7 @@ const DID = forwardRef(({ did, showAvatar, showQrcode, chainId, locale, ...rest
|
|
|
208
259
|
level="M"
|
|
209
260
|
/>
|
|
210
261
|
<Box sx={{ marginTop: 1, textAlign: 'center' }}>
|
|
211
|
-
<Address
|
|
262
|
+
<Address locale={locale} content={`${DID_PREFIX}${did}`} prepend={prepend} {...rest} copyable>
|
|
212
263
|
{did}
|
|
213
264
|
</Address>
|
|
214
265
|
</Box>
|
|
@@ -228,22 +279,3 @@ const DID = forwardRef(({ did, showAvatar, showQrcode, chainId, locale, ...rest
|
|
|
228
279
|
});
|
|
229
280
|
|
|
230
281
|
export default DID;
|
|
231
|
-
|
|
232
|
-
DID.propTypes = DIDPropTypes;
|
|
233
|
-
|
|
234
|
-
DID.defaultProps = {
|
|
235
|
-
size: 0,
|
|
236
|
-
component: 'span',
|
|
237
|
-
copyable: true,
|
|
238
|
-
responsive: true,
|
|
239
|
-
showCopyButtonInTooltip: false,
|
|
240
|
-
showAvatar: true,
|
|
241
|
-
showQrcode: false,
|
|
242
|
-
inline: false,
|
|
243
|
-
append: null,
|
|
244
|
-
compact: false,
|
|
245
|
-
startChars: 6,
|
|
246
|
-
endChars: 6,
|
|
247
|
-
locale: 'en',
|
|
248
|
-
chainId: '',
|
|
249
|
-
};
|
package/src/type.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
declare module '@arcblock/did-motif';
|