@arcblock/ux 2.13.42 → 2.13.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.
@@ -1,10 +1,11 @@
1
1
  import { useState, useEffect, useRef } from 'react';
2
+ import { Skeleton } from '@mui/material';
3
+
2
4
  import PropTypes from 'prop-types';
3
5
  import Lottie from 'react-lottie-player';
4
6
  import noop from 'lodash/noop';
5
7
 
6
- import lottieJson from './default-animation.json';
7
- import { styled } from '../Theme';
8
+ import { styled, useTheme } from '../Theme';
8
9
 
9
10
  /**
10
11
  * 用于长时间等待的用的动画组件
@@ -35,9 +36,12 @@ export default function AnimationWaiter({
35
36
  increaseSpeed,
36
37
  ...rest
37
38
  }) {
39
+ const theme = useTheme();
38
40
  const [tipsId, setTipsId] = useState(0);
39
41
  const [currentSpeed, setCurrentSpeed] = useState(speed);
40
42
  const [messageId, setMessageId] = useState(0);
43
+ const [defaultAnimation, setDefaultAnimation] = useState(null);
44
+ const [isLoading, setIsLoading] = useState(!animationData);
41
45
  // 动画的开始时间
42
46
  const startTime = useRef(new Date().getTime());
43
47
 
@@ -46,6 +50,29 @@ export default function AnimationWaiter({
46
50
  message = [message];
47
51
  }
48
52
 
53
+ // 懒加载默认动画
54
+ useEffect(() => {
55
+ if (!animationData) {
56
+ setIsLoading(true);
57
+ const loadAnimation = async () => {
58
+ try {
59
+ const module = await (theme.palette.mode === 'dark'
60
+ ? import('./dark-animation.json')
61
+ : import('./default-animation.json'));
62
+
63
+ setDefaultAnimation(module.default || module);
64
+
65
+ setIsLoading(false);
66
+ } catch (error) {
67
+ console.error('Failed to load animation:', error);
68
+ setIsLoading(false);
69
+ }
70
+ };
71
+
72
+ loadAnimation();
73
+ }
74
+ }, [animationData, theme.palette.mode]);
75
+
49
76
  useEffect(() => {
50
77
  if (!message) {
51
78
  return;
@@ -122,16 +149,22 @@ export default function AnimationWaiter({
122
149
 
123
150
  return (
124
151
  <Container {...rest}>
125
- <Lottie
126
- loop
127
- animationData={animationData || lottieJson}
128
- play
129
- speed={currentSpeed}
130
- style={{
131
- width: size,
132
- height: size,
133
- }}
134
- />
152
+ {isLoading ? (
153
+ <div style={{ width: size, height: size, display: 'flex', justifyContent: 'center', alignItems: 'center' }}>
154
+ <Skeleton variant="rounded" width={size * 0.4} height={size * 0.4} />
155
+ </div>
156
+ ) : (
157
+ <Lottie
158
+ loop
159
+ animationData={animationData || defaultAnimation}
160
+ play
161
+ speed={currentSpeed}
162
+ style={{
163
+ width: size,
164
+ height: size,
165
+ }}
166
+ />
167
+ )}
135
168
  {message && (
136
169
  <div className="waiter-message">
137
170
  {message.map((text, index) => {
@@ -183,7 +216,7 @@ AnimationWaiter.propTypes = {
183
216
 
184
217
  AnimationWaiter.defaultProps = {
185
218
  animationData: null,
186
- size: '',
219
+ size: 256,
187
220
  message: '',
188
221
  messageDuration: 5000,
189
222
  messageLoop: true,
@@ -75,7 +75,7 @@ const Container = styled('div', {
75
75
  shouldForwardProp: (prop) => prop !== 'dark',
76
76
  })<ContainerProps>`
77
77
  position: relative;
78
- margin-top: 64px;
78
+ margin-top: ${({ theme }) => theme.spacing(2)};
79
79
  padding: 24px 0 32px;
80
80
  border-top: 1px solid ${(props) => props.theme.palette.divider};
81
81
  box-sizing: border-box;
package/src/Img/index.jsx CHANGED
@@ -127,6 +127,7 @@ function Img({
127
127
  data-id="2"
128
128
  ref={ref}
129
129
  style={outerStyle}
130
+ className="arcblock_ux_img-wrapper"
130
131
  {...rest}
131
132
  sx={mergeSx(
132
133
  {
@@ -47,6 +47,7 @@ const SessionUserItem = forwardRef<HTMLDivElement, SessionUserItemProps>(
47
47
  <Avatar did={sessionItem.userDid} size={36} />
48
48
  </Box>
49
49
  <WalletOSIcon
50
+ color={palette.text.secondary}
50
51
  loading={sessionItem.__isDefault}
51
52
  provider={sessionItem?.extra?.provider}
52
53
  walletOS={sessionItem?.extra?.walletOS}
@@ -1,4 +1,7 @@
1
- import { Typography, Box, Grid } from '@mui/material';
1
+ import Typography from '@mui/material/Typography';
2
+ import Box from '@mui/material/Box';
3
+ import Grid from '@mui/material/Grid';
4
+ import useTheme from '@mui/material/styles/useTheme';
2
5
  import { useCreation, useMemoizedFn } from 'ahooks';
3
6
  import styled from '@emotion/styled';
4
7
  import isArray from 'lodash/isArray';
@@ -10,7 +13,7 @@ import LocationIcon from '@arcblock/icons/lib/Location';
10
13
  import EmailIcon from '@arcblock/icons/lib/Email';
11
14
  import TimezoneIcon from '@arcblock/icons/lib/Timezone';
12
15
  import { joinURL, withoutProtocol } from 'ufo';
13
- import { Fragment, useState, useMemo, useCallback } from 'react';
16
+ import { useState, useMemo, useCallback, cloneElement } from 'react';
14
17
 
15
18
  import { User } from '../types';
16
19
  import Clock from './clock';
@@ -31,6 +34,16 @@ function formatLinkDisplay(link: string): string {
31
34
  return withoutProtocol(link);
32
35
  }
33
36
 
37
+ /**
38
+ * dark mode 下,转换 icon 颜色
39
+ */
40
+ function convertIconColor(isDark: boolean) {
41
+ return isDark
42
+ ? {
43
+ filter: 'brightness(0) saturate(100%) invert(1)',
44
+ }
45
+ : {};
46
+ }
34
47
  const iconSize = {
35
48
  width: 16,
36
49
  height: 16,
@@ -49,9 +62,11 @@ interface RenderItem {
49
62
  }
50
63
 
51
64
  function TimeZoneField({ value }: { value: string }) {
65
+ const theme = useTheme();
66
+ const isDark = theme.palette.mode === 'dark';
52
67
  return (
53
68
  <Box display="flex" alignItems="center" gap={1} className="user-card__timezone-field">
54
- <TimezoneIcon {...iconSize} />
69
+ <TimezoneIcon {...iconSize} style={convertIconColor(isDark)} />
55
70
  <Clock value={value} variant="body2" color="grey.800" />
56
71
  </Box>
57
72
  );
@@ -59,6 +74,8 @@ function TimeZoneField({ value }: { value: string }) {
59
74
 
60
75
  function LinkField({ value }: { value: string }) {
61
76
  const [useFallback, setUseFallback] = useState(false);
77
+ const theme = useTheme();
78
+ const isDark = theme.palette.mode === 'dark';
62
79
  const faviconUrl = useCreation(() => {
63
80
  try {
64
81
  const url = new URL(value);
@@ -82,7 +99,7 @@ function LinkField({ value }: { value: string }) {
82
99
  onError={handleImageError}
83
100
  />
84
101
  ) : (
85
- <LinkIcon {...iconSize} />
102
+ <LinkIcon {...iconSize} style={convertIconColor(isDark)} />
86
103
  )}
87
104
  <LineText variant="body2" color="grey.800">
88
105
  <Typography
@@ -102,9 +119,16 @@ function LinkField({ value }: { value: string }) {
102
119
 
103
120
  function BasicField({ field, value, children }: { field: string; value: string; children?: React.ReactNode }) {
104
121
  const Icon = IconMap[field as keyof typeof IconMap];
122
+ const theme = useTheme();
123
+ const isDark = theme.palette.mode === 'dark';
124
+ const iconColor = convertIconColor(isDark);
105
125
  return (
106
126
  <Box key={field} display="flex" alignItems="center" gap={1} className={`user-card__${field}-field`}>
107
- {Icon ? <Icon {...iconSize} /> : <IconifyIcon icon={infoCircleIcon} {...iconSize} />}
127
+ {Icon ? (
128
+ <Icon {...iconSize} style={iconColor} />
129
+ ) : (
130
+ <IconifyIcon icon={infoCircleIcon} {...iconSize} {...iconColor} />
131
+ )}
108
132
  <LineText variant="body2" color="grey.800">
109
133
  {children ?? value}
110
134
  </LineText>
@@ -29,10 +29,12 @@ function TooltipAvatar({
29
29
  avatarProps,
30
30
  onAvatarClick,
31
31
  }: TooltipAvatarProps) {
32
- const avatarElement = (
33
- <Box display="inline-block">
34
- {renderAvatar(user, avatarSize, avatarProps, onAvatarClick, shouldShowHoverCard || !!tooltipTitle)}
35
- </Box>
32
+ const avatarElement = renderAvatar(
33
+ user,
34
+ avatarSize,
35
+ avatarProps,
36
+ onAvatarClick,
37
+ shouldShowHoverCard || !!tooltipTitle
36
38
  );
37
39
  // 使用普通文本Tooltip
38
40
  if (tooltipTitle) {
@@ -43,18 +43,20 @@ export const renderAvatar = (
43
43
 
44
44
  // 显示用户头像
45
45
  return (
46
- <Avatar
47
- size={avatarSize}
48
- did={user.did}
49
- variant="circle"
50
- style={{
51
- cursor: shouldShowHoverCard || onAvatarClick ? 'pointer' : 'default',
52
- }}
53
- onClick={onClick}
54
- src={user.avatar}
55
- alt={user.fullName || ''}
56
- {...(avatarProps || {})}
57
- />
46
+ <Box className="user-card__avatar" display="flex">
47
+ <Avatar
48
+ size={avatarSize}
49
+ did={user.did}
50
+ variant="circle"
51
+ style={{
52
+ cursor: shouldShowHoverCard || onAvatarClick ? 'pointer' : 'default',
53
+ }}
54
+ onClick={onClick}
55
+ src={user.avatar}
56
+ alt={user.fullName || ''}
57
+ {...(avatarProps || {})}
58
+ />
59
+ </Box>
58
60
  );
59
61
  };
60
62
 
@@ -71,10 +71,12 @@ function UserCard(props: UserCardProps) {
71
71
  shouldShowHoverCard={false}
72
72
  user={user!}
73
73
  avatarProps={props.popupAvatarProps}
74
- shortenLabelProps={props.popupShortenLabelProps}
74
+ shortenLabelProps={props.popupShortenLabelProps || props.shortenLabelProps}
75
75
  renderFields={props.popupRenderFields}
76
76
  renderName={props.popupRenderName}
77
77
  infoType={props.popupInfoType || props.infoType}
78
+ didProps={props.popupDidProps || props.didProps}
79
+ showDid={props.popupShowDid || props.showDid}
78
80
  />
79
81
  </DialogContainer>
80
82
  );
@@ -116,6 +116,8 @@ export interface UserCardProps {
116
116
  showHoverCard?: boolean;
117
117
  showDid?: boolean;
118
118
  didProps?: Partial<DIDProps>;
119
+ popupDidProps?: Partial<DIDProps>;
120
+ popupShowDid?: boolean;
119
121
 
120
122
  avatarProps?: Partial<AvatarProps>;
121
123
  popupAvatarProps?: Partial<AvatarProps>;