@arcblock/ux 2.12.64 → 2.12.71

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 (74) hide show
  1. package/lib/Config/config-provider.js +9 -0
  2. package/lib/Config/index.d.ts +1 -0
  3. package/lib/Config/index.js +1 -0
  4. package/lib/Datatable/index.d.ts +2 -2
  5. package/lib/Datatable/index.js +2 -2
  6. package/lib/Header/header.js +6 -2
  7. package/lib/Img/index.js +4 -4
  8. package/lib/Locale/selector.js +8 -18
  9. package/lib/NavMenu/style.js +10 -8
  10. package/lib/NavMenu/sub-item-group.js +6 -2
  11. package/lib/SessionBlocklet/index.js +7 -15
  12. package/lib/SessionUser/components/logged-in.js +4 -8
  13. package/lib/Theme/theme.d.ts +2 -0
  14. package/lib/Theme/theme.js +2 -1
  15. package/lib/UserCard/Cards/avatar-only.d.ts +8 -0
  16. package/lib/UserCard/Cards/avatar-only.js +34 -0
  17. package/lib/UserCard/Cards/basic-info.d.ts +9 -0
  18. package/lib/UserCard/Cards/basic-info.js +51 -0
  19. package/lib/UserCard/Cards/index.d.ts +8 -0
  20. package/lib/UserCard/Cards/index.js +24 -0
  21. package/lib/UserCard/Cards/name-only.d.ts +3 -0
  22. package/lib/UserCard/Cards/name-only.js +18 -0
  23. package/lib/UserCard/Container/card.d.ts +13 -0
  24. package/lib/UserCard/Container/card.js +46 -0
  25. package/lib/UserCard/Container/dialog.d.ts +9 -0
  26. package/lib/UserCard/Container/dialog.js +25 -0
  27. package/lib/UserCard/Content/basic.d.ts +7 -0
  28. package/lib/UserCard/Content/basic.js +139 -0
  29. package/lib/UserCard/Content/clock.d.ts +4 -0
  30. package/lib/UserCard/Content/clock.js +68 -0
  31. package/lib/UserCard/Content/left-layout.d.ts +16 -0
  32. package/lib/UserCard/Content/left-layout.js +33 -0
  33. package/lib/UserCard/Content/minimal.d.ts +15 -0
  34. package/lib/UserCard/Content/minimal.js +61 -0
  35. package/lib/UserCard/Content/tooltip-avatar.d.ts +15 -0
  36. package/lib/UserCard/Content/tooltip-avatar.js +61 -0
  37. package/lib/UserCard/components.d.ts +4 -0
  38. package/lib/UserCard/components.js +45 -0
  39. package/lib/UserCard/index.d.ts +5 -0
  40. package/lib/UserCard/index.js +74 -0
  41. package/lib/UserCard/types.d.ts +107 -0
  42. package/lib/UserCard/types.js +42 -0
  43. package/lib/UserCard/utils.d.ts +2 -0
  44. package/lib/UserCard/utils.js +19 -0
  45. package/lib/hooks/use-clock.d.ts +10 -0
  46. package/lib/hooks/use-clock.js +71 -0
  47. package/package.json +5 -5
  48. package/src/Config/config-provider.tsx +7 -0
  49. package/src/Config/index.ts +1 -0
  50. package/src/Datatable/index.jsx +2 -2
  51. package/src/Header/header.tsx +2 -2
  52. package/src/Img/index.jsx +35 -32
  53. package/src/Locale/selector.tsx +7 -14
  54. package/src/NavMenu/style.ts +8 -8
  55. package/src/NavMenu/sub-item-group.tsx +2 -2
  56. package/src/SessionBlocklet/index.tsx +7 -20
  57. package/src/SessionUser/components/logged-in.tsx +4 -6
  58. package/src/Theme/theme.ts +1 -0
  59. package/src/UserCard/Cards/avatar-only.tsx +38 -0
  60. package/src/UserCard/Cards/basic-info.tsx +50 -0
  61. package/src/UserCard/Cards/index.tsx +24 -0
  62. package/src/UserCard/Cards/name-only.tsx +17 -0
  63. package/src/UserCard/Container/card.tsx +52 -0
  64. package/src/UserCard/Container/dialog.tsx +30 -0
  65. package/src/UserCard/Content/basic.tsx +134 -0
  66. package/src/UserCard/Content/clock.tsx +63 -0
  67. package/src/UserCard/Content/left-layout.tsx +40 -0
  68. package/src/UserCard/Content/minimal.tsx +60 -0
  69. package/src/UserCard/Content/tooltip-avatar.tsx +55 -0
  70. package/src/UserCard/components.tsx +49 -0
  71. package/src/UserCard/index.tsx +63 -0
  72. package/src/UserCard/types.ts +129 -0
  73. package/src/UserCard/utils.ts +22 -0
  74. package/src/hooks/use-clock.tsx +61 -0
@@ -0,0 +1,129 @@
1
+ import React from 'react';
2
+ import { DIDProps } from '../DID';
3
+
4
+ type UserPublicInfo = {
5
+ avatar: string;
6
+ did: string;
7
+ fullName: string;
8
+ sourceAppPid: string | null;
9
+ };
10
+ export type UserMetadataLink = {
11
+ url: string;
12
+ favicon?: string;
13
+ };
14
+
15
+ export enum DurationEnum {
16
+ NoClear = 'no_clear',
17
+ ThirtyMinutes = '30_minutes',
18
+ OneHour = '1_hour',
19
+ FourHours = '4_hours',
20
+ Today = 'today',
21
+ ThisWeek = 'this_week',
22
+ Custom = 'custom',
23
+ }
24
+
25
+ export enum StatusEnum {
26
+ Meeting = 'meeting',
27
+ Community = 'community',
28
+ Holiday = 'holiday',
29
+ OffSick = 'off_sick',
30
+ WorkingRemotely = 'working_remotely',
31
+ }
32
+ export type UserPhoneProps = {
33
+ country: string;
34
+ phoneNumber?: string;
35
+ };
36
+
37
+ export type UserMetadata = {
38
+ bio?: string;
39
+ location?: string;
40
+ timezone?: string;
41
+ joinedAt?: string;
42
+ status?: {
43
+ value: string;
44
+ duration?: DurationEnum;
45
+ dateRange?: Date[];
46
+ };
47
+ links?: UserMetadataLink[];
48
+ cover?: string;
49
+ // 这两个字段是 User, 方便数据更新,在保存时同步
50
+ email?: string;
51
+ phone?: UserPhoneProps;
52
+ };
53
+
54
+ export type UserAddress = {
55
+ country?: string;
56
+ province?: string;
57
+ city?: string;
58
+ line1?: string;
59
+ line2?: string;
60
+ postalCode?: string;
61
+ };
62
+
63
+ export type User = UserPublicInfo & {
64
+ role: string;
65
+ email?: string;
66
+ phone?: string;
67
+ sourceProvider?: string;
68
+ sourceAppPid?: string;
69
+ lastLoginAt?: string;
70
+ lastLoginIp?: string;
71
+ createdAt?: string;
72
+ passports?: any[];
73
+ didSpace?: Record<string, any>;
74
+ connectedAccounts?: any[];
75
+ locale?: string;
76
+ url: string;
77
+ inviter?: string;
78
+ emailVerified?: boolean;
79
+ phoneVerified?: boolean;
80
+ // 1.16.40 新增
81
+ metadata?: UserMetadata;
82
+ // 1.16.41 新增
83
+ address?: UserAddress;
84
+ };
85
+
86
+ // 头像大小
87
+ export const AvatarSize = {
88
+ small: 32,
89
+ medium: 40,
90
+ large: 48,
91
+ xlarge: 64,
92
+ };
93
+
94
+ // 卡片类型
95
+ export enum CardType {
96
+ AvatarOnly = 'AvatarOnly', // 仅头像
97
+ Detailed = 'Detailed', // 详细卡片
98
+ }
99
+
100
+ // 信息类型
101
+ export enum InfoType {
102
+ NameOnly = 'NameOnly', // 仅显示名称
103
+ Minimal = 'Minimal', // 极简模式,显示头像、名称和DID
104
+ Basic = 'Basic', // 基本信息模式
105
+ }
106
+
107
+ // 定义UserCard属性接口
108
+ export interface UserCardProps {
109
+ user: User;
110
+ cardType?: CardType;
111
+ infoType?: InfoType;
112
+ avatarSize?: number;
113
+ showHoverCard?: boolean;
114
+ showDid?: boolean;
115
+ didProps?: DIDProps;
116
+
117
+ // 关注功能相关属性
118
+ isFollowed?: boolean;
119
+ onFollow?: (user: User) => void;
120
+ onUnfollow?: (user: User) => void;
121
+ followLoading?: boolean;
122
+
123
+ // 右上角内容相关属性
124
+ renderTopRightContent?: () => React.ReactNode;
125
+ topRightMaxWidth?: number;
126
+
127
+ // 自定义内容渲染函数
128
+ renderCustomContent?: () => React.ReactNode;
129
+ }
@@ -0,0 +1,22 @@
1
+ import { User } from './types';
2
+
3
+ // 创建仅显示名称首字母的头像
4
+ // eslint-disable-next-line import/prefer-default-export
5
+ export function createNameOnlyAvatar(user: User) {
6
+ if (!user) return null;
7
+
8
+ // 使用全名或邮箱前缀作为显示内容
9
+ let content = '';
10
+ if (user.fullName) {
11
+ // 提取名称首字母
12
+ content = user.fullName.charAt(0).toUpperCase();
13
+ } else if (user.email) {
14
+ // 使用邮箱前缀首字母
15
+ content = user.email.split('@')[0].charAt(0).toUpperCase();
16
+ } else {
17
+ // 如果都没有,使用DID的第一个字符
18
+ content = user.did ? user.did.charAt(0).toUpperCase() : '?';
19
+ }
20
+
21
+ return content;
22
+ }
@@ -0,0 +1,61 @@
1
+ import { useState, useEffect, useCallback } from 'react';
2
+ import dayjs from 'dayjs';
3
+ import utc from 'dayjs/plugin/utc';
4
+ import timezonePlugin from 'dayjs/plugin/timezone';
5
+ import localizedFormat from 'dayjs/plugin/localizedFormat';
6
+ import { formatToDatetime } from '@arcblock/ux/lib/Util';
7
+ import 'dayjs/locale/zh-cn';
8
+ import 'dayjs/locale/en';
9
+
10
+ dayjs.extend(utc);
11
+ dayjs.extend(timezonePlugin);
12
+ dayjs.extend(localizedFormat);
13
+
14
+ const currentTimezone = dayjs.tz.guess();
15
+
16
+ // 获取时间段
17
+ const getTimePhase = (hour: number) => {
18
+ if (hour >= 0 && hour < 6) return { phase: 'dawn', icon: '🌒' }; // 凌晨 00:00-05:59
19
+ if (hour >= 6 && hour < 12) return { phase: 'morning', icon: '🌞' }; // 上午 06:00-11:59
20
+ if (hour >= 12 && hour < 18) return { phase: 'afternoon', icon: '🌞' }; // 下午 12:00-17:59
21
+ return { phase: 'night', icon: '🌒' }; // 晚上 18:00-23:59
22
+ };
23
+
24
+ export default function useClock(timezone = currentTimezone, locale = 'zh') {
25
+ const getLatestTimeInfo = useCallback(() => {
26
+ const currentLocale = locale === 'zh' ? 'zh-cn' : 'en';
27
+ const localeOption = locale === 'zh' ? 'zh-cn' : 'en-us';
28
+ dayjs.locale(currentLocale);
29
+
30
+ const now = dayjs().tz(timezone);
31
+ const hour = now.hour();
32
+ const { phase, icon } = getTimePhase(hour);
33
+
34
+ return {
35
+ formattedTime: now.format('LT'),
36
+ fullDateTime: formatToDatetime(now.toDate(), { tz: timezone, locale: localeOption }),
37
+ phase,
38
+ icon,
39
+ rawTime: now,
40
+ };
41
+ }, [timezone, locale]);
42
+
43
+ const [timeInfo, setTimeInfo] = useState(getLatestTimeInfo());
44
+
45
+ useEffect(() => {
46
+ // 立即更新一次,确保初始状态是最新的
47
+ setTimeInfo(getLatestTimeInfo());
48
+
49
+ // 设置定时器
50
+ const timerId = setInterval(() => {
51
+ setTimeInfo(getLatestTimeInfo());
52
+ }, 6000);
53
+
54
+ // 清理函数
55
+ return () => {
56
+ clearInterval(timerId);
57
+ };
58
+ }, [timezone, locale, getLatestTimeInfo]);
59
+
60
+ return timeInfo;
61
+ }