@arcblock/ux 2.11.35 → 2.11.37

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.
@@ -4,6 +4,7 @@ import React, { ReactNode } from 'react';
4
4
  import type { Locale } from '../type';
5
5
  export interface HTMLDidAddressElement extends HTMLDivElement {
6
6
  copy: () => void;
7
+ getEl: () => HTMLDivElement;
7
8
  }
8
9
  export interface IDidAddressProps extends BoxProps {
9
10
  component?: React.ElementType;
@@ -69,7 +69,8 @@ const DidAddress = /*#__PURE__*/forwardRef((props, ref) => {
69
69
  handleCopy();
70
70
  };
71
71
  useImperativeHandle(ref, () => new Proxy({
72
- copy: handleCopy
72
+ copy: handleCopy,
73
+ getEl: () => rootRef.current
73
74
  }, {
74
75
  get(target, key) {
75
76
  return target[key] || rootRef.current?.[key];
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- import { useSize } from 'ahooks';
2
+ import { useLatest, useSize } 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';
@@ -22,6 +22,7 @@ const ResponsiveDidAddress = /*#__PURE__*/forwardRef(({
22
22
  ...rest
23
23
  }, ref) => {
24
24
  const [compact, setCompact] = useState(false);
25
+ const isCompact = useLatest(compact);
25
26
  // did address 完整显示时的宽度
26
27
  const [addressFullWidth, setAddressFullWidth] = useState(null);
27
28
  const containerRef = useRef(null);
@@ -36,9 +37,20 @@ const ResponsiveDidAddress = /*#__PURE__*/forwardRef(({
36
37
 
37
38
  // 存储完整显示时 address 组件的宽度
38
39
  useEffect(() => {
39
- if (!compact && addressFullWidth === null) {
40
- setAddressFullWidth(innerRef.current?.offsetWidth);
40
+ const innerWidth = innerRef.current?.offsetWidth || 0;
41
+ let resizeObserver = null;
42
+ setAddressFullWidth(innerWidth);
43
+
44
+ // 由于自定义字体的缘故,innerRef 的初始宽度可能发生二次改变,使用 observer 监听捕获
45
+ resizeObserver = new ResizeObserver(() => {
46
+ if (!isCompact.current && innerRef.current?.offsetWidth !== innerWidth) {
47
+ setAddressFullWidth(innerRef.current?.offsetWidth);
48
+ }
49
+ });
50
+ if (innerRef.current) {
51
+ resizeObserver.observe(innerRef.current.getEl());
41
52
  }
53
+ return () => resizeObserver.disconnect();
42
54
  // eslint-disable-next-line react-hooks/exhaustive-deps
43
55
  }, []);
44
56
  useEffect(() => {
@@ -30,7 +30,8 @@ function DIDMotif({
30
30
  component: "svg",
31
31
  ref: svgRef,
32
32
  ...rest,
33
- style: styles
33
+ style: styles,
34
+ className: "arc-avatar-did-motif"
34
35
  });
35
36
  }
36
37
  return /*#__PURE__*/_jsx(Box, {
@@ -42,6 +43,7 @@ function DIDMotif({
42
43
  height: size,
43
44
  ...rest.style
44
45
  },
46
+ className: "arc-avatar-did-motif",
45
47
  children: /*#__PURE__*/_jsx(Box, {
46
48
  component: "svg",
47
49
  ref: svgRef,
@@ -0,0 +1,7 @@
1
+ import { ButtonProps } from '@mui/material';
2
+ type Props<D extends React.ElementType, P = {}> = {
3
+ icon?: React.ReactNode;
4
+ children?: React.ReactNode;
5
+ } & ButtonProps<D, P>;
6
+ export declare function AddonButton<D extends React.ElementType, P = {}>({ icon, children, sx, ...rest }: Props<D, P>): import("react/jsx-runtime").JSX.Element;
7
+ export {};
@@ -0,0 +1,33 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { Button } from '@mui/material';
3
+ // eslint-disable-next-line import/prefer-default-export
4
+ export function AddonButton({
5
+ icon,
6
+ children,
7
+ sx,
8
+ ...rest
9
+ }) {
10
+ const mergedSx = [{
11
+ height: 32,
12
+ minWidth: 32,
13
+ borderColor: 'divider',
14
+ borderRadius: '100vh',
15
+ fontSize: 14,
16
+ color: 'text.secondary',
17
+ ...(!children && {
18
+ padding: 0,
19
+ height: 32,
20
+ '.MuiButton-startIcon': {
21
+ margin: 0
22
+ }
23
+ })
24
+ }, ...(Array.isArray(sx) ? sx : [sx])];
25
+ return /*#__PURE__*/_jsx(Button, {
26
+ startIcon: icon,
27
+ color: "inherit",
28
+ variant: "outlined",
29
+ sx: mergedSx,
30
+ ...rest,
31
+ children: children
32
+ });
33
+ }
@@ -89,8 +89,35 @@ function Header({
89
89
  }), children, align === 'left' && /*#__PURE__*/_jsx(Box, {
90
90
  display: "inline-block",
91
91
  flexGrow: 1
92
- }), /*#__PURE__*/_jsx("div", {
92
+ }), /*#__PURE__*/_jsx(Box, {
93
93
  className: "header-addons",
94
+ sx: {
95
+ display: 'flex',
96
+ alignItems: 'center',
97
+ gap: 1.5,
98
+ '> *': {
99
+ m: '0px!important'
100
+ },
101
+ '.MuiIconButton-root': {
102
+ width: 32,
103
+ height: 32,
104
+ p: 0,
105
+ border: 1,
106
+ borderColor: 'divider'
107
+ },
108
+ '.MuiIconButton-root svg, .MuiButton-root svg': {
109
+ fontSize: 18,
110
+ width: '1em!important',
111
+ height: '1em!important'
112
+ },
113
+ '.arc-session-user-logged-in > *, .arc-session-user-logged-in svg': {
114
+ width: '100%!important',
115
+ height: '100%!important'
116
+ },
117
+ '.arc-session-user-unlogin svg': {
118
+ transform: 'scale(1)!important'
119
+ }
120
+ },
94
121
  children: addons
95
122
  })]
96
123
  })
@@ -103,6 +103,7 @@ export default function LoggedIn({
103
103
  onClick: () => onTogglePopper(),
104
104
  size: "medium",
105
105
  "data-cy": "sessionManager-logout-popup",
106
+ className: "arc-session-user-logged-in",
106
107
  "aria-label": "User info button",
107
108
  children: /*#__PURE__*/_jsx(DidAvatar, {
108
109
  variant: "circle",
@@ -1,7 +1,7 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { Box, CircularProgress, IconButton } from '@mui/material';
3
3
  import { Icon } from '@iconify/react';
4
- import PersonOutlineRoundedIcon from 'iconify-icons-material-symbols-400/person-outline-rounded';
4
+ import UserIcon from '@iconify-icons/tabler/user';
5
5
  import { useRef } from 'react';
6
6
  import { useMemoizedFn } from 'ahooks';
7
7
  import noop from 'lodash/noop';
@@ -24,6 +24,7 @@ export default function UnLogin({
24
24
  ref: userAnchorRef,
25
25
  onClick: _onLogin,
26
26
  "data-cy": "sessionManager-login",
27
+ className: "arc-session-user-unlogin",
27
28
  size: "medium",
28
29
  "aria-label": "Login button",
29
30
  children: isFirstLoading ? /*#__PURE__*/_jsx(Box, {
@@ -40,7 +41,7 @@ export default function UnLogin({
40
41
  }
41
42
  })
42
43
  }) : /*#__PURE__*/_jsx(Icon, {
43
- icon: PersonOutlineRoundedIcon,
44
+ icon: UserIcon,
44
45
  fontSize: size,
45
46
  color: dark ? '#fff' : 'inherit',
46
47
  style: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arcblock/ux",
3
- "version": "2.11.35",
3
+ "version": "2.11.37",
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": "61ce1e356b37df6fafb6e9330deb217791005a7a",
71
+ "gitHead": "5b00e4fe7b54625734ce8e61e9ec41f35cb851ac",
72
72
  "dependencies": {
73
73
  "@arcblock/did-motif": "^1.1.13",
74
- "@arcblock/icons": "^2.11.35",
75
- "@arcblock/nft-display": "^2.11.35",
76
- "@arcblock/react-hooks": "^2.11.35",
74
+ "@arcblock/icons": "^2.11.37",
75
+ "@arcblock/nft-display": "^2.11.37",
76
+ "@arcblock/react-hooks": "^2.11.37",
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",
@@ -23,6 +23,7 @@ const translations: Translations = {
23
23
 
24
24
  export interface HTMLDidAddressElement extends HTMLDivElement {
25
25
  copy: () => void;
26
+ getEl: () => HTMLDivElement;
26
27
  }
27
28
  export interface IDidAddressProps extends BoxProps {
28
29
  component?: React.ElementType;
@@ -98,6 +99,7 @@ const DidAddress = forwardRef<HTMLDidAddressElement, IDidAddressProps>((props, r
98
99
  new Proxy(
99
100
  {
100
101
  copy: handleCopy,
102
+ getEl: () => rootRef.current,
101
103
  },
102
104
  {
103
105
  get(target: any, key: string) {
@@ -1,4 +1,4 @@
1
- import { useSize } from 'ahooks';
1
+ import { useLatest, useSize } 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';
@@ -17,6 +17,7 @@ import DidAddress, { HTMLDidAddressElement, IDidAddressProps } from './did-addre
17
17
  const ResponsiveDidAddress = forwardRef<HTMLDidAddressElement, IResponsiveDidAddressProps>(
18
18
  ({ style, className, component = 'span', ...rest }, ref) => {
19
19
  const [compact, setCompact] = useState(false);
20
+ const isCompact = useLatest(compact);
20
21
  // did address 完整显示时的宽度
21
22
  const [addressFullWidth, setAddressFullWidth] = useState<number | null | undefined>(null);
22
23
  const containerRef = useRef<HTMLDivElement>(null);
@@ -39,9 +40,23 @@ const ResponsiveDidAddress = forwardRef<HTMLDidAddressElement, IResponsiveDidAdd
39
40
 
40
41
  // 存储完整显示时 address 组件的宽度
41
42
  useEffect(() => {
42
- if (!compact && addressFullWidth === null) {
43
- setAddressFullWidth(innerRef.current?.offsetWidth);
43
+ const innerWidth = innerRef.current?.offsetWidth || 0;
44
+ let resizeObserver: ResizeObserver | null = null;
45
+
46
+ setAddressFullWidth(innerWidth);
47
+
48
+ // 由于自定义字体的缘故,innerRef 的初始宽度可能发生二次改变,使用 observer 监听捕获
49
+ resizeObserver = new ResizeObserver(() => {
50
+ if (!isCompact.current && innerRef.current?.offsetWidth !== innerWidth) {
51
+ setAddressFullWidth(innerRef.current?.offsetWidth);
52
+ }
53
+ });
54
+
55
+ if (innerRef.current) {
56
+ resizeObserver.observe(innerRef.current.getEl());
44
57
  }
58
+
59
+ return () => resizeObserver.disconnect();
45
60
  // eslint-disable-next-line react-hooks/exhaustive-deps
46
61
  }, []);
47
62
 
@@ -13,10 +13,14 @@ function DIDMotif({ did, size, animation, shape, responsive, ...rest }) {
13
13
  if (responsive) {
14
14
  // fix avatar 显示问题 (safari 下父容器为 flex 时 inline svg 显示不出来, 需要明确指定 width)
15
15
  const styles = { ...rest.style, width: '100%' };
16
- return <Box component="svg" ref={svgRef} {...rest} style={styles} />;
16
+ return <Box component="svg" ref={svgRef} {...rest} style={styles} className="arc-avatar-did-motif" />;
17
17
  }
18
18
  return (
19
- <Box component="span" {...rest} style={{ display: 'inline-block', width: size, height: size, ...rest.style }}>
19
+ <Box
20
+ component="span"
21
+ {...rest}
22
+ style={{ display: 'inline-block', width: size, height: size, ...rest.style }}
23
+ className="arc-avatar-did-motif">
20
24
  <Box component="svg" ref={svgRef} style={{ width: '100%' }} />
21
25
  </Box>
22
26
  );
@@ -0,0 +1,36 @@
1
+ import { Button, ButtonProps } from '@mui/material';
2
+
3
+ type Props<D extends React.ElementType, P = {}> = {
4
+ icon?: React.ReactNode;
5
+ children?: React.ReactNode;
6
+ } & ButtonProps<D, P>;
7
+
8
+ // eslint-disable-next-line import/prefer-default-export
9
+ export function AddonButton<D extends React.ElementType, P = {}>({ icon, children, sx, ...rest }: Props<D, P>) {
10
+ const mergedSx = [
11
+ {
12
+ height: 32,
13
+ minWidth: 32,
14
+ borderColor: 'divider',
15
+ borderRadius: '100vh',
16
+ fontSize: 14,
17
+ color: 'text.secondary',
18
+
19
+ ...(!children && {
20
+ padding: 0,
21
+ height: 32,
22
+
23
+ '.MuiButton-startIcon': {
24
+ margin: 0,
25
+ },
26
+ }),
27
+ },
28
+ ...(Array.isArray(sx) ? sx : [sx]),
29
+ ];
30
+
31
+ return (
32
+ <Button startIcon={icon} color="inherit" variant="outlined" sx={mergedSx} {...rest}>
33
+ {children}
34
+ </Button>
35
+ );
36
+ }
@@ -89,7 +89,37 @@ function Header({
89
89
  {align === 'right' && <Box display="inline-block" flexGrow={1} />}
90
90
  {children}
91
91
  {align === 'left' && <Box display="inline-block" flexGrow={1} />}
92
- <div className="header-addons">{addons}</div>
92
+ <Box
93
+ className="header-addons"
94
+ sx={{
95
+ display: 'flex',
96
+ alignItems: 'center',
97
+ gap: 1.5,
98
+ '> *': {
99
+ m: '0px!important',
100
+ },
101
+ '.MuiIconButton-root': {
102
+ width: 32,
103
+ height: 32,
104
+ p: 0,
105
+ border: 1,
106
+ borderColor: 'divider',
107
+ },
108
+ '.MuiIconButton-root svg, .MuiButton-root svg': {
109
+ fontSize: 18,
110
+ width: '1em!important',
111
+ height: '1em!important',
112
+ },
113
+ '.arc-session-user-logged-in > *, .arc-session-user-logged-in svg': {
114
+ width: '100%!important',
115
+ height: '100%!important',
116
+ },
117
+ '.arc-session-user-unlogin svg': {
118
+ transform: 'scale(1)!important',
119
+ },
120
+ }}>
121
+ {addons}
122
+ </Box>
93
123
  </Container>
94
124
  </Root>
95
125
  );
@@ -134,6 +134,7 @@ export default function LoggedIn({
134
134
  onClick={() => onTogglePopper()}
135
135
  size="medium"
136
136
  data-cy="sessionManager-logout-popup"
137
+ className="arc-session-user-logged-in"
137
138
  aria-label="User info button">
138
139
  <DidAvatar variant="circle" did={session.user.did} src={avatar} size={size} shape="circle" />
139
140
  </IconButton>
@@ -1,6 +1,6 @@
1
1
  import { Box, CircularProgress, IconButton } from '@mui/material';
2
2
  import { Icon } from '@iconify/react';
3
- import PersonOutlineRoundedIcon from 'iconify-icons-material-symbols-400/person-outline-rounded';
3
+ import UserIcon from '@iconify-icons/tabler/user';
4
4
  import { useRef } from 'react';
5
5
  import { useMemoizedFn } from 'ahooks';
6
6
  import noop from 'lodash/noop';
@@ -30,6 +30,7 @@ export default function UnLogin({ session, onLogin = noop, size = 24, dark = fal
30
30
  ref={userAnchorRef}
31
31
  onClick={_onLogin}
32
32
  data-cy="sessionManager-login"
33
+ className="arc-session-user-unlogin"
33
34
  size="medium"
34
35
  aria-label="Login button">
35
36
  {isFirstLoading ? (
@@ -38,7 +39,7 @@ export default function UnLogin({ session, onLogin = noop, size = 24, dark = fal
38
39
  </Box>
39
40
  ) : (
40
41
  <Icon
41
- icon={PersonOutlineRoundedIcon}
42
+ icon={UserIcon}
42
43
  fontSize={size}
43
44
  color={dark ? '#fff' : 'inherit'}
44
45
  style={{ transform: 'scale(1.25)' }}