one-design-next 0.0.42 → 0.0.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/dist/_genui-types.d.ts +3 -1
- package/dist/artifact/index.d.ts +3 -1
- package/dist/artifact/index.js +6 -2
- package/dist/artifact/style/index.css +13 -2
- package/dist/chat-item/index.d.ts +5 -2
- package/dist/chat-item/index.js +158 -78
- package/dist/chat-item/style/index.css +42 -69
- package/dist/fab/index.d.ts +1 -0
- package/dist/fab/index.js +6 -1
- package/dist/fab/style/index.css +14 -1
- package/package.json +1 -1
package/dist/_genui-types.d.ts
CHANGED
|
@@ -215,7 +215,9 @@ export interface Conversation {
|
|
|
215
215
|
title: string;
|
|
216
216
|
preview?: string;
|
|
217
217
|
timestamp?: number;
|
|
218
|
-
|
|
218
|
+
/** 对话类型。`'human'` 为人工客服会话;默认视为 AI。 */
|
|
219
|
+
type?: 'ai' | 'human';
|
|
220
|
+
status?: 'generating' | 'waiting' | 'unread' | 'error';
|
|
219
221
|
}
|
|
220
222
|
export interface MessageSnapshot {
|
|
221
223
|
content: string;
|
package/dist/artifact/index.d.ts
CHANGED
|
@@ -10,13 +10,15 @@ export interface ArtifactProps {
|
|
|
10
10
|
thumbnailUrl?: string;
|
|
11
11
|
/** 右上角品牌 LOGO(16x16),不传时展示兜底占位块。 */
|
|
12
12
|
brandLogoUrl?: string;
|
|
13
|
+
/** 宽度模式:默认响应式;支持固定 354,或最小 354 且宽度自适应填充。 */
|
|
14
|
+
widthMode?: 'responsive' | 'fixed-354' | 'fill-min-354';
|
|
13
15
|
onOpen?: () => void;
|
|
14
16
|
}
|
|
15
17
|
/**
|
|
16
18
|
* 对话流内的单个产物摘要卡片。
|
|
17
19
|
* 本期聚焦单项展示,保留 `type` 字段以支持未来“报告 / 人群”等产物类型扩展。
|
|
18
20
|
*/
|
|
19
|
-
export declare function Artifact({ title, statRange, createdAt, status, thumbnailUrl, brandLogoUrl, onOpen, }: ArtifactProps): import("react").JSX.Element;
|
|
21
|
+
export declare function Artifact({ title, statRange, createdAt, status, thumbnailUrl, brandLogoUrl, widthMode, onOpen, }: ArtifactProps): import("react").JSX.Element;
|
|
20
22
|
export declare namespace Artifact {
|
|
21
23
|
var displayName: string;
|
|
22
24
|
}
|
package/dist/artifact/index.js
CHANGED
|
@@ -53,6 +53,8 @@ export function Artifact(_ref) {
|
|
|
53
53
|
status = _ref$status === void 0 ? 'Done' : _ref$status,
|
|
54
54
|
thumbnailUrl = _ref.thumbnailUrl,
|
|
55
55
|
brandLogoUrl = _ref.brandLogoUrl,
|
|
56
|
+
_ref$widthMode = _ref.widthMode,
|
|
57
|
+
widthMode = _ref$widthMode === void 0 ? 'responsive' : _ref$widthMode,
|
|
56
58
|
onOpen = _ref.onOpen;
|
|
57
59
|
var isGenerating = status === 'Generating';
|
|
58
60
|
var isInteractive = !!onOpen && !isGenerating;
|
|
@@ -191,14 +193,16 @@ export function Artifact(_ref) {
|
|
|
191
193
|
onMouseMove: handleMouseMove,
|
|
192
194
|
onMouseLeave: handleMouseLeave,
|
|
193
195
|
style: spotlightStyle,
|
|
194
|
-
"data-odn-artifact-status": status
|
|
196
|
+
"data-odn-artifact-status": status,
|
|
197
|
+
"data-odn-artifact-width-mode": widthMode
|
|
195
198
|
}, content) : /*#__PURE__*/React.createElement("div", {
|
|
196
199
|
"data-odn-artifact": true,
|
|
197
200
|
onMouseEnter: !isGenerating ? handleMouseEnter : undefined,
|
|
198
201
|
onMouseMove: !isGenerating ? handleMouseMove : undefined,
|
|
199
202
|
onMouseLeave: !isGenerating ? handleMouseLeave : undefined,
|
|
200
203
|
style: spotlightStyle,
|
|
201
|
-
"data-odn-artifact-status": status
|
|
204
|
+
"data-odn-artifact-status": status,
|
|
205
|
+
"data-odn-artifact-width-mode": widthMode
|
|
202
206
|
}, content);
|
|
203
207
|
}
|
|
204
208
|
Artifact.displayName = 'Artifact';
|
|
@@ -16,7 +16,7 @@ html {
|
|
|
16
16
|
width: min(100%, 376px);
|
|
17
17
|
height: var(--odn-artifact-copy-height);
|
|
18
18
|
display: grid;
|
|
19
|
-
grid-template-columns:
|
|
19
|
+
grid-template-columns: minmax(0, 1fr) var(--odn-artifact-visual-width);
|
|
20
20
|
align-items: stretch;
|
|
21
21
|
gap: 0;
|
|
22
22
|
text-align: left;
|
|
@@ -30,6 +30,17 @@ html {
|
|
|
30
30
|
transition: border-color 0.15s ease, background-color 0.15s ease, box-shadow 0.15s ease;
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
+
[data-odn-artifact][data-odn-artifact-width-mode=fixed-354] {
|
|
34
|
+
width: 354px;
|
|
35
|
+
max-width: 354px;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
[data-odn-artifact][data-odn-artifact-width-mode=fill-min-354] {
|
|
39
|
+
width: 100%;
|
|
40
|
+
min-width: 354px;
|
|
41
|
+
max-width: none;
|
|
42
|
+
}
|
|
43
|
+
|
|
33
44
|
button[data-odn-artifact] {
|
|
34
45
|
cursor: pointer;
|
|
35
46
|
font: inherit;
|
|
@@ -44,7 +55,7 @@ button[data-odn-artifact] {
|
|
|
44
55
|
[data-odn-artifact-copy] {
|
|
45
56
|
position: relative;
|
|
46
57
|
z-index: 1;
|
|
47
|
-
width:
|
|
58
|
+
width: 100%;
|
|
48
59
|
height: var(--odn-artifact-copy-height);
|
|
49
60
|
padding: var(--odn-artifact-padding-y) var(--odn-artifact-padding-right) var(--odn-artifact-padding-y) var(--odn-artifact-padding-left);
|
|
50
61
|
box-sizing: border-box;
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
2
|
import './style';
|
|
3
|
-
type StatusIndicator = 'generating' | 'unread' | 'error';
|
|
3
|
+
type StatusIndicator = 'generating' | 'waiting' | 'unread' | 'error';
|
|
4
|
+
type ConversationType = 'ai' | 'human';
|
|
4
5
|
export interface ChatItemProps {
|
|
5
6
|
id: string;
|
|
6
7
|
title: string;
|
|
7
8
|
active?: boolean;
|
|
9
|
+
/** 对话类型。`'human'` 时标题后展示客服 icon;默认 `'ai'`。 */
|
|
10
|
+
type?: ConversationType;
|
|
8
11
|
status?: StatusIndicator;
|
|
9
12
|
onClick?: (id: string) => void;
|
|
10
13
|
onRename?: (id: string, newTitle: string) => void;
|
|
@@ -20,7 +23,7 @@ export interface ChatItemProps {
|
|
|
20
23
|
defaultDeleteOpen?: boolean;
|
|
21
24
|
onDeleteOpenChange?: (open: boolean) => void;
|
|
22
25
|
}
|
|
23
|
-
export declare function ChatItem({ id, title, active, status, onClick, onRename, onDelete, actionMenuZIndex, renaming: renamingProp, defaultRenaming, onRenamingChange, menuOpen: menuOpenProp, defaultMenuOpen, onMenuOpenChange, deleteOpen: deleteOpenProp, defaultDeleteOpen, onDeleteOpenChange, }: ChatItemProps): import("react").JSX.Element;
|
|
26
|
+
export declare function ChatItem({ id, title, active, type, status, onClick, onRename, onDelete, actionMenuZIndex, renaming: renamingProp, defaultRenaming, onRenamingChange, menuOpen: menuOpenProp, defaultMenuOpen, onMenuOpenChange, deleteOpen: deleteOpenProp, defaultDeleteOpen, onDeleteOpenChange, }: ChatItemProps): import("react").JSX.Element;
|
|
24
27
|
export declare namespace ChatItem {
|
|
25
28
|
var displayName: string;
|
|
26
29
|
}
|
package/dist/chat-item/index.js
CHANGED
|
@@ -8,7 +8,7 @@ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o =
|
|
|
8
8
|
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
|
|
9
9
|
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
|
|
10
10
|
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
11
|
-
import { useState, useRef, useEffect,
|
|
11
|
+
import { useState, useRef, useEffect, useLayoutEffect } from 'react';
|
|
12
12
|
import HoverFill from "../hover-fill";
|
|
13
13
|
import Icon from "../icon";
|
|
14
14
|
import Dialog from "../dialog";
|
|
@@ -16,54 +16,99 @@ import Dropdown from "../dropdown";
|
|
|
16
16
|
import "./style";
|
|
17
17
|
var STATUS_ARIA_LABEL = {
|
|
18
18
|
generating: '生成中',
|
|
19
|
+
waiting: '等待处理',
|
|
19
20
|
unread: '未读更新',
|
|
20
21
|
error: '生成出错'
|
|
21
22
|
};
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
}, /*#__PURE__*/React.createElement("span", {
|
|
40
|
-
"data-odn-chat-item-jelly-dot": true
|
|
41
|
-
}), /*#__PURE__*/React.createElement("span", {
|
|
42
|
-
"data-odn-chat-item-jelly-traveler": true
|
|
43
|
-
}), /*#__PURE__*/React.createElement("svg", {
|
|
44
|
-
width: "0",
|
|
45
|
-
height: "0",
|
|
46
|
-
style: {
|
|
47
|
-
position: 'absolute'
|
|
23
|
+
var ELLIPSIS = '…';
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* 有 trailing(客服 icon / status)时,用 DOM 实测把标题裁到可用宽度。
|
|
27
|
+
* 解决 CSS text-overflow 按字符边界截断后,省略号右侧留白把 status 顶开的问题。
|
|
28
|
+
* 量准时:截断标题宽 ≈ label − trailing − gap,整组仍铺满行,trailing 贴右缘。
|
|
29
|
+
*/
|
|
30
|
+
function useFittedTitle(title, enabled, labelRef, titleRef, trailingRef) {
|
|
31
|
+
var _useState = useState(title),
|
|
32
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
33
|
+
fitted = _useState2[0],
|
|
34
|
+
setFitted = _useState2[1];
|
|
35
|
+
useLayoutEffect(function () {
|
|
36
|
+
var _document$fonts;
|
|
37
|
+
if (!enabled) {
|
|
38
|
+
setFitted(title);
|
|
39
|
+
return;
|
|
48
40
|
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
41
|
+
var label = labelRef.current;
|
|
42
|
+
var titleEl = titleRef.current;
|
|
43
|
+
if (!label || !titleEl) return;
|
|
44
|
+
var cancelled = false;
|
|
45
|
+
var probe = document.createElement('span');
|
|
46
|
+
probe.setAttribute('aria-hidden', 'true');
|
|
47
|
+
probe.style.cssText = 'position:absolute;visibility:hidden;pointer-events:none;white-space:nowrap;left:-9999px;top:0;';
|
|
48
|
+
var syncProbeFont = function syncProbeFont() {
|
|
49
|
+
var cs = getComputedStyle(titleEl);
|
|
50
|
+
probe.style.fontFamily = cs.fontFamily;
|
|
51
|
+
probe.style.fontSize = cs.fontSize;
|
|
52
|
+
probe.style.fontWeight = cs.fontWeight;
|
|
53
|
+
probe.style.fontStyle = cs.fontStyle;
|
|
54
|
+
probe.style.letterSpacing = cs.letterSpacing;
|
|
55
|
+
probe.style.fontFeatureSettings = cs.fontFeatureSettings;
|
|
56
|
+
probe.style.fontVariationSettings = cs.fontVariationSettings;
|
|
57
|
+
};
|
|
58
|
+
var measure = function measure(text) {
|
|
59
|
+
probe.textContent = text;
|
|
60
|
+
return probe.getBoundingClientRect().width;
|
|
61
|
+
};
|
|
62
|
+
var fit = function fit() {
|
|
63
|
+
var _trailing$getBounding;
|
|
64
|
+
if (cancelled) return;
|
|
65
|
+
syncProbeFont();
|
|
66
|
+
if (!probe.isConnected) document.body.appendChild(probe);
|
|
67
|
+
var trailing = trailingRef.current;
|
|
68
|
+
var gap = trailing ? Number.parseFloat(getComputedStyle(label).columnGap || getComputedStyle(label).gap) || 0 : 0;
|
|
69
|
+
var trailingWidth = (_trailing$getBounding = trailing === null || trailing === void 0 ? void 0 : trailing.getBoundingClientRect().width) !== null && _trailing$getBounding !== void 0 ? _trailing$getBounding : 0;
|
|
70
|
+
// 用浮点宽度,避免 offsetWidth 取整导致少算 1px、过早截断
|
|
71
|
+
var maxWidth = Math.max(0, label.getBoundingClientRect().width - trailingWidth - gap);
|
|
72
|
+
if (measure(title) <= maxWidth + 0.5) {
|
|
73
|
+
setFitted(title);
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
var lo = 0;
|
|
77
|
+
var hi = title.length;
|
|
78
|
+
var best = ELLIPSIS;
|
|
79
|
+
while (lo <= hi) {
|
|
80
|
+
var mid = lo + hi >> 1;
|
|
81
|
+
var candidate = "".concat(title.slice(0, mid)).concat(ELLIPSIS);
|
|
82
|
+
if (measure(candidate) <= maxWidth + 0.5) {
|
|
83
|
+
best = candidate;
|
|
84
|
+
lo = mid + 1;
|
|
85
|
+
} else {
|
|
86
|
+
hi = mid - 1;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
setFitted(best);
|
|
90
|
+
};
|
|
91
|
+
fit();
|
|
92
|
+
void ((_document$fonts = document.fonts) === null || _document$fonts === void 0 ? void 0 : _document$fonts.ready.then(function () {
|
|
93
|
+
if (!cancelled) fit();
|
|
94
|
+
}));
|
|
95
|
+
var ro = new ResizeObserver(fit);
|
|
96
|
+
ro.observe(label);
|
|
97
|
+
var trailing = trailingRef.current;
|
|
98
|
+
if (trailing) ro.observe(trailing);
|
|
99
|
+
// hover 时 btn padding-right 变化会改变 label 宽度
|
|
100
|
+
var btn = label.closest('[data-odn-chat-item-btn]');
|
|
101
|
+
if (btn) ro.observe(btn);
|
|
102
|
+
return function () {
|
|
103
|
+
cancelled = true;
|
|
104
|
+
ro.disconnect();
|
|
105
|
+
probe.remove();
|
|
106
|
+
};
|
|
107
|
+
}, [title, enabled, labelRef, titleRef, trailingRef]);
|
|
108
|
+
return enabled ? fitted : title;
|
|
64
109
|
}
|
|
65
|
-
function ChatItemStatus(
|
|
66
|
-
var status =
|
|
110
|
+
function ChatItemStatus(_ref) {
|
|
111
|
+
var status = _ref.status;
|
|
67
112
|
var label = STATUS_ARIA_LABEL[status];
|
|
68
113
|
if (status === 'generating') {
|
|
69
114
|
return /*#__PURE__*/React.createElement("span", {
|
|
@@ -71,7 +116,19 @@ function ChatItemStatus(_ref2) {
|
|
|
71
116
|
"data-odn-chat-item-status-generating": true,
|
|
72
117
|
"aria-label": label,
|
|
73
118
|
role: "status"
|
|
74
|
-
}, /*#__PURE__*/React.createElement(
|
|
119
|
+
}, /*#__PURE__*/React.createElement(Icon, {
|
|
120
|
+
name: "loading",
|
|
121
|
+
spin: true,
|
|
122
|
+
size: 12
|
|
123
|
+
}));
|
|
124
|
+
}
|
|
125
|
+
if (status === 'waiting') {
|
|
126
|
+
return /*#__PURE__*/React.createElement("span", {
|
|
127
|
+
"data-odn-chat-item-status": true,
|
|
128
|
+
"data-odn-chat-item-status-waiting": true,
|
|
129
|
+
"aria-label": label,
|
|
130
|
+
role: "status"
|
|
131
|
+
}, "\u5F85\u56DE\u590D");
|
|
75
132
|
}
|
|
76
133
|
if (status === 'error') {
|
|
77
134
|
return /*#__PURE__*/React.createElement("span", {
|
|
@@ -94,10 +151,10 @@ function ChatItemStatus(_ref2) {
|
|
|
94
151
|
}));
|
|
95
152
|
}
|
|
96
153
|
function useControllableState(controlled, defaultValue, onChange) {
|
|
97
|
-
var
|
|
98
|
-
|
|
99
|
-
internal =
|
|
100
|
-
setInternal =
|
|
154
|
+
var _useState3 = useState(defaultValue),
|
|
155
|
+
_useState4 = _slicedToArray(_useState3, 2),
|
|
156
|
+
internal = _useState4[0],
|
|
157
|
+
setInternal = _useState4[1];
|
|
101
158
|
var value = controlled !== null && controlled !== void 0 ? controlled : internal;
|
|
102
159
|
var setValue = function setValue(next) {
|
|
103
160
|
onChange === null || onChange === void 0 || onChange(next);
|
|
@@ -105,35 +162,37 @@ function useControllableState(controlled, defaultValue, onChange) {
|
|
|
105
162
|
};
|
|
106
163
|
return [value, setValue];
|
|
107
164
|
}
|
|
108
|
-
export function ChatItem(
|
|
109
|
-
var id =
|
|
110
|
-
title =
|
|
111
|
-
active =
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
165
|
+
export function ChatItem(_ref2) {
|
|
166
|
+
var id = _ref2.id,
|
|
167
|
+
title = _ref2.title,
|
|
168
|
+
active = _ref2.active,
|
|
169
|
+
_ref2$type = _ref2.type,
|
|
170
|
+
type = _ref2$type === void 0 ? 'ai' : _ref2$type,
|
|
171
|
+
status = _ref2.status,
|
|
172
|
+
_onClick = _ref2.onClick,
|
|
173
|
+
onRename = _ref2.onRename,
|
|
174
|
+
onDelete = _ref2.onDelete,
|
|
175
|
+
actionMenuZIndex = _ref2.actionMenuZIndex,
|
|
176
|
+
renamingProp = _ref2.renaming,
|
|
177
|
+
_ref2$defaultRenaming = _ref2.defaultRenaming,
|
|
178
|
+
defaultRenaming = _ref2$defaultRenaming === void 0 ? false : _ref2$defaultRenaming,
|
|
179
|
+
onRenamingChange = _ref2.onRenamingChange,
|
|
180
|
+
menuOpenProp = _ref2.menuOpen,
|
|
181
|
+
_ref2$defaultMenuOpen = _ref2.defaultMenuOpen,
|
|
182
|
+
defaultMenuOpen = _ref2$defaultMenuOpen === void 0 ? false : _ref2$defaultMenuOpen,
|
|
183
|
+
onMenuOpenChange = _ref2.onMenuOpenChange,
|
|
184
|
+
deleteOpenProp = _ref2.deleteOpen,
|
|
185
|
+
_ref2$defaultDeleteOp = _ref2.defaultDeleteOpen,
|
|
186
|
+
defaultDeleteOpen = _ref2$defaultDeleteOp === void 0 ? false : _ref2$defaultDeleteOp,
|
|
187
|
+
onDeleteOpenChange = _ref2.onDeleteOpenChange;
|
|
129
188
|
var _useControllableState = useControllableState(renamingProp, defaultRenaming, onRenamingChange),
|
|
130
189
|
_useControllableState2 = _slicedToArray(_useControllableState, 2),
|
|
131
190
|
renaming = _useControllableState2[0],
|
|
132
191
|
setRenaming = _useControllableState2[1];
|
|
133
|
-
var
|
|
134
|
-
|
|
135
|
-
draft =
|
|
136
|
-
setDraft =
|
|
192
|
+
var _useState5 = useState(title),
|
|
193
|
+
_useState6 = _slicedToArray(_useState5, 2),
|
|
194
|
+
draft = _useState6[0],
|
|
195
|
+
setDraft = _useState6[1];
|
|
137
196
|
var _useControllableState3 = useControllableState(deleteOpenProp, defaultDeleteOpen, onDeleteOpenChange),
|
|
138
197
|
_useControllableState4 = _slicedToArray(_useControllableState3, 2),
|
|
139
198
|
deleteOpen = _useControllableState4[0],
|
|
@@ -143,6 +202,13 @@ export function ChatItem(_ref3) {
|
|
|
143
202
|
menuOpen = _useControllableState6[0],
|
|
144
203
|
setMenuOpen = _useControllableState6[1];
|
|
145
204
|
var inputRef = useRef(null);
|
|
205
|
+
var labelRef = useRef(null);
|
|
206
|
+
var titleRef = useRef(null);
|
|
207
|
+
var trailingRef = useRef(null);
|
|
208
|
+
var showStatus = Boolean(status && !active);
|
|
209
|
+
var showTypeIcon = type === 'human';
|
|
210
|
+
var fitTitle = showTypeIcon || showStatus;
|
|
211
|
+
var displayTitle = useFittedTitle(title, fitTitle, labelRef, titleRef, trailingRef);
|
|
146
212
|
useEffect(function () {
|
|
147
213
|
if (!renaming) setDraft(title);
|
|
148
214
|
}, [title, renaming]);
|
|
@@ -203,13 +269,27 @@ export function ChatItem(_ref3) {
|
|
|
203
269
|
"data-odn-chat-item-btn": true,
|
|
204
270
|
"data-odn-chat-item-active": active || undefined
|
|
205
271
|
}, /*#__PURE__*/React.createElement("span", {
|
|
206
|
-
"data-odn-chat-item-label": true
|
|
272
|
+
"data-odn-chat-item-label": true,
|
|
273
|
+
ref: labelRef
|
|
207
274
|
}, /*#__PURE__*/React.createElement("span", {
|
|
275
|
+
ref: titleRef,
|
|
208
276
|
"data-odn-chat-item-title": true,
|
|
209
|
-
"data-odn-chat-item-title-bold": active ? '' : undefined
|
|
210
|
-
|
|
277
|
+
"data-odn-chat-item-title-bold": active ? '' : undefined,
|
|
278
|
+
"data-odn-chat-item-title-fitted": fitTitle ? '' : undefined,
|
|
279
|
+
title: title
|
|
280
|
+
}, displayTitle), (showTypeIcon || showStatus) && /*#__PURE__*/React.createElement("span", {
|
|
281
|
+
"data-odn-chat-item-trailing": true,
|
|
282
|
+
ref: trailingRef
|
|
283
|
+
}, showTypeIcon && /*#__PURE__*/React.createElement("span", {
|
|
284
|
+
"data-odn-chat-item-type-icon": true,
|
|
285
|
+
"aria-label": "\u4EBA\u5DE5\u5BA2\u670D\u4F1A\u8BDD",
|
|
286
|
+
role: "img"
|
|
287
|
+
}, /*#__PURE__*/React.createElement(Icon, {
|
|
288
|
+
name: "support-bold",
|
|
289
|
+
size: 12
|
|
290
|
+
})), showStatus && status && /*#__PURE__*/React.createElement(ChatItemStatus, {
|
|
211
291
|
status: status
|
|
212
|
-
}))), /*#__PURE__*/React.createElement(Dropdown, {
|
|
292
|
+
})))), /*#__PURE__*/React.createElement(Dropdown, {
|
|
213
293
|
trigger: "click",
|
|
214
294
|
placement: "bottomRight",
|
|
215
295
|
zIndex: actionMenuZIndex,
|
|
@@ -98,12 +98,15 @@
|
|
|
98
98
|
[data-odn-chat-item-label] {
|
|
99
99
|
display: flex;
|
|
100
100
|
align-items: center;
|
|
101
|
-
gap:
|
|
101
|
+
gap: 4px;
|
|
102
|
+
flex: 1 1 auto;
|
|
102
103
|
min-width: 0;
|
|
104
|
+
max-width: 100%;
|
|
103
105
|
}
|
|
104
106
|
|
|
105
107
|
[data-odn-chat-item-title] {
|
|
106
|
-
|
|
108
|
+
/* 0 1 auto:短标题不撑开(icon 贴字);长标题可收缩省略,trailing 被顶到右缘 */
|
|
109
|
+
flex: 0 1 auto;
|
|
107
110
|
min-width: 0;
|
|
108
111
|
font-size: 14px;
|
|
109
112
|
overflow: hidden;
|
|
@@ -111,10 +114,34 @@
|
|
|
111
114
|
white-space: nowrap;
|
|
112
115
|
}
|
|
113
116
|
|
|
117
|
+
/* JS 已裁到可用宽度:按内容收缩,省略号后无字符边界留白;量准时整组仍铺满行 */
|
|
118
|
+
[data-odn-chat-item-title-fitted] {
|
|
119
|
+
flex: 0 0 auto;
|
|
120
|
+
overflow: visible;
|
|
121
|
+
text-overflow: clip;
|
|
122
|
+
}
|
|
123
|
+
|
|
114
124
|
[data-odn-chat-item-title-bold] {
|
|
115
125
|
font-weight: 500;
|
|
116
126
|
}
|
|
117
127
|
|
|
128
|
+
[data-odn-chat-item-trailing] {
|
|
129
|
+
flex-shrink: 0;
|
|
130
|
+
display: inline-flex;
|
|
131
|
+
align-items: center;
|
|
132
|
+
gap: 6px;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
[data-odn-chat-item-type-icon] {
|
|
136
|
+
flex-shrink: 0;
|
|
137
|
+
display: flex;
|
|
138
|
+
align-items: center;
|
|
139
|
+
justify-content: center;
|
|
140
|
+
width: 12px;
|
|
141
|
+
height: 12px;
|
|
142
|
+
color: var(--odn-color-black-8);
|
|
143
|
+
}
|
|
144
|
+
|
|
118
145
|
[data-odn-chat-item-status] {
|
|
119
146
|
flex-shrink: 0;
|
|
120
147
|
width: 14px;
|
|
@@ -135,6 +162,19 @@
|
|
|
135
162
|
color: var(--odn-color-black-8);
|
|
136
163
|
}
|
|
137
164
|
|
|
165
|
+
[data-odn-chat-item-status-waiting] {
|
|
166
|
+
width: auto;
|
|
167
|
+
height: 16px;
|
|
168
|
+
color: #fff;
|
|
169
|
+
font-size: 11px;
|
|
170
|
+
font-weight: 600;
|
|
171
|
+
line-height: 16px;
|
|
172
|
+
white-space: nowrap;
|
|
173
|
+
background: var(--odn-color-orange-6);
|
|
174
|
+
padding: 0 3px;
|
|
175
|
+
border-radius: 4px;
|
|
176
|
+
}
|
|
177
|
+
|
|
138
178
|
[data-odn-chat-item-status-error] {
|
|
139
179
|
color: var(--odn-color-error);
|
|
140
180
|
}
|
|
@@ -190,73 +230,6 @@
|
|
|
190
230
|
color: var(--odn-color-black-12);
|
|
191
231
|
}
|
|
192
232
|
|
|
193
|
-
/* ChatItem 的 Dropdown 面板:宽度根据内容自适应(hug),不使用默认 128px */
|
|
194
|
-
[data-odn-chat-item-jelly] {
|
|
195
|
-
position: relative;
|
|
196
|
-
display: inline-flex;
|
|
197
|
-
align-items: center;
|
|
198
|
-
justify-content: center;
|
|
199
|
-
flex-shrink: 0;
|
|
200
|
-
width: var(--uib-size);
|
|
201
|
-
height: var(--uib-size);
|
|
202
|
-
}
|
|
203
|
-
[data-odn-chat-item-jelly]::before, [data-odn-chat-item-jelly]::after,
|
|
204
|
-
[data-odn-chat-item-jelly] [data-odn-chat-item-jelly-dot] {
|
|
205
|
-
content: "";
|
|
206
|
-
position: absolute;
|
|
207
|
-
width: 33%;
|
|
208
|
-
height: 33%;
|
|
209
|
-
background-color: var(--uib-color);
|
|
210
|
-
border-radius: 100%;
|
|
211
|
-
will-change: transform;
|
|
212
|
-
}
|
|
213
|
-
[data-odn-chat-item-jelly]::before {
|
|
214
|
-
right: 0;
|
|
215
|
-
bottom: 6%;
|
|
216
|
-
animation: odn-chat-item-jelly-grow var(--uib-speed) ease calc(var(--uib-speed) * -0.666) infinite;
|
|
217
|
-
}
|
|
218
|
-
[data-odn-chat-item-jelly]::after {
|
|
219
|
-
left: 0;
|
|
220
|
-
bottom: 6%;
|
|
221
|
-
animation: odn-chat-item-jelly-grow var(--uib-speed) ease calc(var(--uib-speed) * -0.333) infinite;
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
[data-odn-chat-item-jelly-dot] {
|
|
225
|
-
top: 6%;
|
|
226
|
-
left: 30%;
|
|
227
|
-
animation: odn-chat-item-jelly-grow var(--uib-speed) ease infinite;
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
[data-odn-chat-item-jelly-traveler] {
|
|
231
|
-
position: absolute;
|
|
232
|
-
top: 6%;
|
|
233
|
-
left: 30%;
|
|
234
|
-
width: 33%;
|
|
235
|
-
height: 33%;
|
|
236
|
-
background-color: var(--uib-color);
|
|
237
|
-
border-radius: 100%;
|
|
238
|
-
animation: odn-chat-item-jelly-triangulate var(--uib-speed) ease infinite;
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
@keyframes odn-chat-item-jelly-grow {
|
|
242
|
-
0%, 85%, 100% {
|
|
243
|
-
transform: scale(1.5);
|
|
244
|
-
}
|
|
245
|
-
50%, 60% {
|
|
246
|
-
transform: scale(0);
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
@keyframes odn-chat-item-jelly-triangulate {
|
|
250
|
-
0%, 100% {
|
|
251
|
-
transform: none;
|
|
252
|
-
}
|
|
253
|
-
33.333% {
|
|
254
|
-
transform: translate(120%, 175%);
|
|
255
|
-
}
|
|
256
|
-
66.666% {
|
|
257
|
-
transform: translate(-95%, 175%);
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
233
|
[data-odn-dropdown-content].odn-chat-item-action-menu {
|
|
261
234
|
min-width: 0;
|
|
262
235
|
width: max-content;
|
package/dist/fab/index.d.ts
CHANGED
package/dist/fab/index.js
CHANGED
|
@@ -61,7 +61,8 @@ var Fab = /*#__PURE__*/React.forwardRef(function (_ref3, ref) {
|
|
|
61
61
|
_ref3$speed = _ref3.speed,
|
|
62
62
|
speed = _ref3$speed === void 0 ? 1.49 : _ref3$speed,
|
|
63
63
|
_ref3$hoverSpeed = _ref3.hoverSpeed,
|
|
64
|
-
hoverSpeed = _ref3$hoverSpeed === void 0 ? 2.77 : _ref3$hoverSpeed
|
|
64
|
+
hoverSpeed = _ref3$hoverSpeed === void 0 ? 2.77 : _ref3$hoverSpeed,
|
|
65
|
+
badge = _ref3.badge;
|
|
65
66
|
var _useState = useState(false),
|
|
66
67
|
_useState2 = _slicedToArray(_useState, 2),
|
|
67
68
|
hovered = _useState2[0],
|
|
@@ -132,6 +133,7 @@ var Fab = /*#__PURE__*/React.forwardRef(function (_ref3, ref) {
|
|
|
132
133
|
position: 'absolute',
|
|
133
134
|
inset: 0,
|
|
134
135
|
borderRadius: 'inherit',
|
|
136
|
+
overflow: 'hidden',
|
|
135
137
|
width: '100%',
|
|
136
138
|
height: '100%',
|
|
137
139
|
opacity: live.opacity
|
|
@@ -139,6 +141,9 @@ var Fab = /*#__PURE__*/React.forwardRef(function (_ref3, ref) {
|
|
|
139
141
|
}), /*#__PURE__*/React.createElement("div", {
|
|
140
142
|
className: "odn-fab-glow",
|
|
141
143
|
"aria-hidden": "true"
|
|
144
|
+
}), badge && /*#__PURE__*/React.createElement("span", {
|
|
145
|
+
"data-odn-fab-badge": true,
|
|
146
|
+
"aria-label": "\u6709\u5F85\u5904\u7406\u4F1A\u8BDD"
|
|
142
147
|
}), icon, /*#__PURE__*/React.createElement("span", {
|
|
143
148
|
className: "odn-fab-label"
|
|
144
149
|
}, label));
|
package/dist/fab/style/index.css
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[data-odn-fab] {
|
|
2
2
|
position: relative;
|
|
3
|
-
overflow:
|
|
3
|
+
overflow: visible;
|
|
4
4
|
display: flex;
|
|
5
5
|
align-items: center;
|
|
6
6
|
justify-content: center;
|
|
@@ -46,6 +46,19 @@
|
|
|
46
46
|
filter: blur(var(--fab-glow-hover-blur, 76px));
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
+
[data-odn-fab-badge] {
|
|
50
|
+
position: absolute;
|
|
51
|
+
top: -4px;
|
|
52
|
+
left: -4px;
|
|
53
|
+
z-index: 20;
|
|
54
|
+
width: 16px;
|
|
55
|
+
height: 16px;
|
|
56
|
+
border-radius: 50%;
|
|
57
|
+
background: var(--odn-color-orange-6);
|
|
58
|
+
box-shadow: 0 0 0 2px #fff;
|
|
59
|
+
pointer-events: none;
|
|
60
|
+
}
|
|
61
|
+
|
|
49
62
|
.odn-fab-icon {
|
|
50
63
|
position: relative;
|
|
51
64
|
z-index: 10;
|