one-design-next 0.0.97 → 0.0.99

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.
@@ -0,0 +1,387 @@
1
+ @charset "UTF-8";
2
+ [data-odn-chat-group] {
3
+ display: flex;
4
+ flex-direction: column;
5
+ gap: 2px;
6
+ min-width: 0;
7
+ }
8
+
9
+ [data-odn-chat-group-header-fill] {
10
+ min-width: 0;
11
+ width: 100%;
12
+ }
13
+
14
+ .odn-chat-group-header-bg {
15
+ border-radius: 6px;
16
+ }
17
+
18
+ [data-odn-chat-group-header] {
19
+ display: flex;
20
+ align-items: center;
21
+ gap: 0;
22
+ min-width: 0;
23
+ padding: 0 4px 0 12px;
24
+ }
25
+ [data-odn-chat-group-header]:hover, [data-odn-chat-group-header]:has(:focus-visible) {
26
+ gap: 4px;
27
+ }
28
+ [data-odn-chat-group-header]:hover [data-odn-chat-group-extra], [data-odn-chat-group-header]:has(:focus-visible) [data-odn-chat-group-extra] {
29
+ flex-basis: auto;
30
+ width: auto;
31
+ max-width: none;
32
+ overflow: visible;
33
+ opacity: 1;
34
+ pointer-events: auto;
35
+ }
36
+
37
+ [data-odn-chat-group-extra-visible] [data-odn-chat-group-header] {
38
+ gap: 4px;
39
+ }
40
+
41
+ [data-odn-chat-group-extra-visible] [data-odn-chat-group-extra] {
42
+ flex-basis: auto;
43
+ width: auto;
44
+ max-width: none;
45
+ overflow: visible;
46
+ opacity: 1;
47
+ pointer-events: auto;
48
+ }
49
+
50
+ [data-odn-chat-group-folder-icon] {
51
+ flex-shrink: 0;
52
+ color: var(--odn-color-black-10);
53
+ }
54
+
55
+ [data-odn-chat-group-trigger] {
56
+ display: flex;
57
+ align-items: center;
58
+ gap: 2px;
59
+ flex: 1 1 auto;
60
+ min-width: 0;
61
+ margin: 0;
62
+ padding: 8px 4px 8px 0;
63
+ border: none;
64
+ border-radius: 6px;
65
+ background: transparent;
66
+ color: var(--odn-color-black-10);
67
+ font: inherit;
68
+ font-size: 14px;
69
+ font-weight: 400;
70
+ line-height: 22px;
71
+ text-align: left;
72
+ cursor: pointer;
73
+ }
74
+ [data-odn-chat-group-trigger]:hover {
75
+ background: transparent;
76
+ color: var(--odn-color-black-10);
77
+ }
78
+ [data-odn-chat-group-trigger]:focus-visible {
79
+ outline: none;
80
+ background: transparent;
81
+ color: var(--odn-color-black-10);
82
+ }
83
+
84
+ [data-odn-chat-group-title-row] {
85
+ display: flex;
86
+ align-items: center;
87
+ gap: 2px;
88
+ flex: 1 1 auto;
89
+ min-width: 0;
90
+ padding: 8px 4px 8px 0;
91
+ }
92
+
93
+ [data-odn-chat-group-chevron] {
94
+ flex-shrink: 0;
95
+ opacity: 1;
96
+ transition: transform 0.15s ease;
97
+ color: var(--odn-color-black-10);
98
+ }
99
+
100
+ [data-odn-chat-group]:not([data-odn-chat-group-collapsed]) [data-odn-chat-group-chevron] {
101
+ transform: rotate(90deg);
102
+ }
103
+
104
+ [data-odn-chat-group-title] {
105
+ /* 与 ChatItem 相同:短标题按内容,长标题收缩省略;右侧 extra 闲时不占位 */
106
+ flex: 0 1 auto;
107
+ min-width: 0;
108
+ color: var(--odn-color-black-10);
109
+ font-size: 14px;
110
+ font-weight: 400;
111
+ line-height: 22px;
112
+ overflow: hidden;
113
+ text-overflow: ellipsis;
114
+ white-space: nowrap;
115
+ }
116
+
117
+ [data-odn-chat-group-extra] {
118
+ flex: 0 0 0;
119
+ display: flex;
120
+ align-items: center;
121
+ gap: 2px;
122
+ width: 0;
123
+ min-width: 0;
124
+ max-width: 0;
125
+ overflow: hidden;
126
+ opacity: 0;
127
+ pointer-events: none;
128
+ transition: opacity 0.15s ease;
129
+ }
130
+ [data-odn-chat-group-extra] [data-odn-hover-fill] {
131
+ flex-shrink: 0;
132
+ width: 24px;
133
+ height: 24px;
134
+ }
135
+
136
+ [data-odn-chat-group-rename] {
137
+ display: flex;
138
+ align-items: center;
139
+ gap: 2px;
140
+ flex: 1 1 auto;
141
+ min-width: 0;
142
+ padding: 8px 4px 8px 0;
143
+ }
144
+
145
+ [data-odn-chat-group-folder] [data-odn-chat-group-trigger],
146
+ [data-odn-chat-group-folder] [data-odn-chat-group-title-row],
147
+ [data-odn-chat-group-folder] [data-odn-chat-group-rename] {
148
+ gap: 4px;
149
+ }
150
+
151
+ [data-odn-chat-group-rename-input] {
152
+ display: block;
153
+ box-sizing: border-box;
154
+ width: 100%;
155
+ height: 22px;
156
+ margin: 0;
157
+ padding: 0;
158
+ border: none;
159
+ background: transparent;
160
+ color: var(--odn-color-black-10);
161
+ font: inherit;
162
+ font-size: 14px;
163
+ font-weight: 400;
164
+ line-height: 22px;
165
+ outline: none;
166
+ box-shadow: none;
167
+ appearance: none;
168
+ }
169
+ [data-odn-chat-group-rename-input]::selection {
170
+ background: var(--odn-color-brand-3, rgba(0, 160, 200, 0.25));
171
+ }
172
+
173
+ [data-odn-chat-group-section] [data-odn-chat-group-header] {
174
+ padding: 4px 4px 2px 12px;
175
+ }
176
+
177
+ [data-odn-chat-group-section] [data-odn-chat-group-trigger],
178
+ [data-odn-chat-group-section] [data-odn-chat-group-title-row],
179
+ [data-odn-chat-group-section] [data-odn-chat-group-rename] {
180
+ padding: 2px 4px 2px 0;
181
+ font-size: 12px;
182
+ line-height: 18px;
183
+ color: var(--odn-color-black-9);
184
+ }
185
+
186
+ [data-odn-chat-group-section] [data-odn-chat-group-trigger]:hover,
187
+ [data-odn-chat-group-section] [data-odn-chat-group-trigger]:focus-visible {
188
+ color: var(--odn-color-black-9);
189
+ }
190
+
191
+ [data-odn-chat-group-section] [data-odn-chat-group-title],
192
+ [data-odn-chat-group-section] [data-odn-chat-group-rename-input] {
193
+ color: var(--odn-color-black-9);
194
+ font-size: 12px;
195
+ line-height: 18px;
196
+ }
197
+
198
+ [data-odn-chat-group-section] [data-odn-chat-group-rename-input] {
199
+ height: 18px;
200
+ }
201
+
202
+ [data-odn-chat-group-section] [data-odn-chat-group-chevron] {
203
+ color: var(--odn-color-black-9);
204
+ }
205
+
206
+ [data-odn-chat-group-collapse] {
207
+ display: grid;
208
+ grid-template-rows: 1fr;
209
+ width: 100%;
210
+ min-width: 0;
211
+ overflow-anchor: none;
212
+ transition: grid-template-rows 280ms cubic-bezier(0.22, 1, 0.36, 1);
213
+ }
214
+
215
+ [data-odn-chat-group-collapsed] [data-odn-chat-group-collapse] {
216
+ grid-template-rows: 0fr;
217
+ }
218
+
219
+ [data-odn-chat-group-body] {
220
+ display: flex;
221
+ flex-direction: column;
222
+ gap: 2px;
223
+ min-width: 0;
224
+ min-height: 0;
225
+ overflow: hidden;
226
+ opacity: 1;
227
+ transition: opacity 0.2s ease;
228
+ }
229
+
230
+ [data-odn-chat-group]:not([data-odn-chat-group-collapsed]) [data-odn-chat-group-body] {
231
+ overflow: visible;
232
+ }
233
+
234
+ [data-odn-chat-group-collapsed] [data-odn-chat-group-body] {
235
+ opacity: 0;
236
+ pointer-events: none;
237
+ }
238
+
239
+ [data-odn-chat-group-folder] [data-odn-chat-item-btn],
240
+ [data-odn-chat-group-folder] [data-odn-chat-group-hint-inner] {
241
+ padding-left: 30px;
242
+ }
243
+
244
+ [data-odn-chat-group-slot] {
245
+ min-width: 0;
246
+ }
247
+
248
+ [data-odn-chat-group-slot-inner] {
249
+ min-width: 0;
250
+ }
251
+
252
+ [data-odn-chat-group-slot][data-odn-chat-group-enter],
253
+ [data-odn-chat-group-slot][data-odn-chat-group-leave] {
254
+ pointer-events: none;
255
+ overflow-anchor: none;
256
+ }
257
+
258
+ [data-odn-chat-group-slot][data-odn-chat-group-enter=shift] {
259
+ display: grid;
260
+ grid-template-rows: 0fr;
261
+ animation: odn-chat-group-enter-shift 180ms ease-out forwards;
262
+ }
263
+
264
+ [data-odn-chat-group-slot][data-odn-chat-group-enter=shift] [data-odn-chat-group-slot-inner] {
265
+ min-height: 0;
266
+ overflow: hidden;
267
+ opacity: 0;
268
+ animation: odn-chat-group-enter-fade 160ms ease-out 180ms both;
269
+ }
270
+
271
+ [data-odn-chat-group-slot][data-odn-chat-group-enter=fade] [data-odn-chat-group-slot-inner] {
272
+ opacity: 0;
273
+ animation: odn-chat-group-enter-fade 160ms ease-out both;
274
+ }
275
+
276
+ [data-odn-chat-group-slot][data-odn-chat-group-leave=shift] {
277
+ display: grid;
278
+ grid-template-rows: 1fr;
279
+ animation: odn-chat-group-leave-shift 180ms ease-out 160ms forwards;
280
+ }
281
+
282
+ [data-odn-chat-group-slot][data-odn-chat-group-leave=shift] [data-odn-chat-group-slot-inner] {
283
+ min-height: 0;
284
+ overflow: hidden;
285
+ animation: odn-chat-group-leave-fade 160ms ease-out both;
286
+ }
287
+
288
+ [data-odn-chat-group-slot][data-odn-chat-group-leave=fade] [data-odn-chat-group-slot-inner] {
289
+ animation: odn-chat-group-leave-fade 160ms ease-out both;
290
+ }
291
+
292
+ [data-odn-chat-group-slot][data-odn-chat-group-leave=swap] {
293
+ display: grid;
294
+ grid-template-rows: 1fr;
295
+ animation: odn-chat-group-leave-shift 180ms ease-out forwards;
296
+ }
297
+
298
+ [data-odn-chat-group-slot][data-odn-chat-group-leave=swap] [data-odn-chat-group-slot-inner] {
299
+ min-height: 0;
300
+ overflow: hidden;
301
+ animation: odn-chat-group-leave-fade 160ms ease-out both;
302
+ }
303
+
304
+ @keyframes odn-chat-group-enter-shift {
305
+ from {
306
+ grid-template-rows: 0fr;
307
+ }
308
+ to {
309
+ grid-template-rows: 1fr;
310
+ }
311
+ }
312
+ @keyframes odn-chat-group-enter-fade {
313
+ from {
314
+ opacity: 0;
315
+ }
316
+ to {
317
+ opacity: 1;
318
+ }
319
+ }
320
+ @keyframes odn-chat-group-leave-shift {
321
+ from {
322
+ grid-template-rows: 1fr;
323
+ }
324
+ to {
325
+ grid-template-rows: 0fr;
326
+ }
327
+ }
328
+ @keyframes odn-chat-group-leave-fade {
329
+ from {
330
+ opacity: 1;
331
+ }
332
+ to {
333
+ opacity: 0;
334
+ }
335
+ }
336
+ /* 与 ChatItem 同行高 / 内边距;文案 black-8。empty 不可点,expand 可点。 */
337
+ [data-odn-chat-group-hint] {
338
+ min-width: 0;
339
+ }
340
+
341
+ [data-odn-chat-group-hint-inner] {
342
+ display: flex;
343
+ align-items: center;
344
+ width: 100%;
345
+ margin: 0;
346
+ padding: 8px 12px;
347
+ border: none;
348
+ border-radius: 6px;
349
+ background: transparent;
350
+ color: var(--odn-color-black-8);
351
+ font: inherit;
352
+ font-size: 14px;
353
+ line-height: inherit;
354
+ text-align: left;
355
+ }
356
+
357
+ [data-odn-chat-group-hint-kind=empty] {
358
+ pointer-events: none;
359
+ user-select: none;
360
+ }
361
+
362
+ [data-odn-chat-group-hint-kind=expand] [data-odn-chat-group-hint-inner] {
363
+ cursor: pointer;
364
+ }
365
+ [data-odn-chat-group-hint-kind=expand] [data-odn-chat-group-hint-inner]:focus-visible {
366
+ outline: none;
367
+ background: rgba(33, 34, 38, 0.05);
368
+ }
369
+
370
+ .odn-chat-group-hint-bg {
371
+ border-radius: 6px;
372
+ }
373
+
374
+ @media (prefers-reduced-motion: reduce) {
375
+ [data-odn-chat-group-collapse],
376
+ [data-odn-chat-group-body],
377
+ [data-odn-chat-group-chevron] {
378
+ transition-duration: 0.01ms !important;
379
+ }
380
+ [data-odn-chat-group-slot][data-odn-chat-group-enter],
381
+ [data-odn-chat-group-slot][data-odn-chat-group-enter] [data-odn-chat-group-slot-inner],
382
+ [data-odn-chat-group-slot][data-odn-chat-group-leave],
383
+ [data-odn-chat-group-slot][data-odn-chat-group-leave] [data-odn-chat-group-slot-inner] {
384
+ animation-duration: 0.01ms !important;
385
+ animation-delay: 0s !important;
386
+ }
387
+ }
@@ -0,0 +1,2 @@
1
+ import '../../style';
2
+ import './index.scss';
@@ -0,0 +1,2 @@
1
+ import "../../style";
2
+ import "./index.css";
@@ -2,6 +2,10 @@
2
2
  import './style';
3
3
  type StatusIndicator = 'generating' | 'waiting' | 'unread' | 'error';
4
4
  type ConversationType = 'ai' | 'human';
5
+ export interface ChatItemGroupOption {
6
+ id: string;
7
+ title: string;
8
+ }
5
9
  export interface ChatItemProps {
6
10
  id: string;
7
11
  title: string;
@@ -16,9 +20,18 @@ export interface ChatItemProps {
16
20
  pinned?: boolean;
17
21
  /**
18
22
  * 对话时间。展示为相对时间(刚刚 / N分钟前 / …),在行右侧;
19
- * 与「…」同槽:hover / 选中常显 / 菜单打开时瞬时让位(无过渡)。
23
+ * 与「…」同槽:hover 隐身但占位;选中常显「…」/ 菜单打开时才让出布局。
20
24
  */
21
25
  time?: number | string | Date;
26
+ /** 当前所属分组。从「移动到」子菜单中排除,不作为可选项。 */
27
+ groupId?: string;
28
+ /**
29
+ * 可移动到的分组列表。与 `onMoveToGroup` 同时传入时展示「移动到」子菜单;
30
+ * 当前 `groupId` 对应项会被排除。
31
+ */
32
+ groupOptions?: ChatItemGroupOption[];
33
+ /** 搜索高亮关键字;匹配段以主题色 mark 展示。 */
34
+ highlightQuery?: string;
22
35
  onClick?: (id: string) => void;
23
36
  onRename?: (id: string, newTitle: string) => void;
24
37
  /**
@@ -26,6 +39,8 @@ export interface ChatItemProps {
26
39
  * 第二个参数为切换后的目标状态。
27
40
  */
28
41
  onPin?: (id: string, pinned: boolean) => void;
42
+ /** 移组回调。第二个参数为目标 `groupId`。 */
43
+ onMoveToGroup?: (id: string, groupId: string) => void;
29
44
  onDelete?: (id: string) => void;
30
45
  actionMenuZIndex?: number | string;
31
46
  renaming?: boolean;
@@ -38,7 +53,7 @@ export interface ChatItemProps {
38
53
  defaultDeleteOpen?: boolean;
39
54
  onDeleteOpenChange?: (open: boolean) => void;
40
55
  }
41
- declare function ChatItemInner({ id, title, active, type, status, pinned, time, onClick, onRename, onPin, onDelete, actionMenuZIndex, renaming: renamingProp, defaultRenaming, onRenamingChange, menuOpen: menuOpenProp, defaultMenuOpen, onMenuOpenChange, deleteOpen: deleteOpenProp, defaultDeleteOpen, onDeleteOpenChange, }: ChatItemProps): import("react").JSX.Element;
56
+ declare function ChatItemInner({ id, title, active, type, status, pinned, time, groupId, groupOptions, highlightQuery, onClick, onRename, onPin, onMoveToGroup, onDelete, actionMenuZIndex, renaming: renamingProp, defaultRenaming, onRenamingChange, menuOpen: menuOpenProp, defaultMenuOpen, onMenuOpenChange, deleteOpen: deleteOpenProp, defaultDeleteOpen, onDeleteOpenChange, }: ChatItemProps): import("react").JSX.Element;
42
57
  /**
43
58
  * 会话列表项。
44
59
  *
@@ -49,16 +49,25 @@ var FIT_MIN_RELIABLE_WIDTH = 24;
49
49
  function useFittedTitle(title, enabled, labelRef, titleRef, /** 右对齐区(状态 / 时间),量宽预留 */
50
50
  trailingRef, /** 紧跟标题的类型 icon,量宽预留 */
51
51
  typeIconRef, /** trailing 宽度 / 字重变化,需强制重测 */
52
- layoutKey) {
52
+ layoutKey, /** 搜索高亮时标题由 React 子节点渲染,禁止 textContent 覆写 */
53
+ skipDomWrite) {
53
54
  useLayoutEffect(function () {
54
55
  var _measure, _document$fonts, _label$closest;
55
56
  var titleEl = titleRef.current;
56
57
  if (!titleEl) return;
57
58
 
59
+ // 高亮态保留 mark 子节点,截断交给 CSS
60
+ if (skipDomWrite) {
61
+ titleEl.removeAttribute(TITLE_FITTED_ATTR);
62
+ titleEl.removeAttribute('title');
63
+ return;
64
+ }
65
+
58
66
  // React 渲染的是完整标题;未启用拟合时保持原样,交给 CSS text-overflow
59
67
  if (!enabled) {
60
68
  titleEl.textContent = title;
61
69
  titleEl.removeAttribute(TITLE_FITTED_ATTR);
70
+ titleEl.removeAttribute('title');
62
71
  return;
63
72
  }
64
73
  var label = labelRef.current;
@@ -86,6 +95,7 @@ layoutKey) {
86
95
  var applyFit = function applyFit(text, accurate) {
87
96
  titleEl.textContent = text;
88
97
  if (accurate) titleEl.setAttribute(TITLE_FITTED_ATTR, '');else titleEl.removeAttribute(TITLE_FITTED_ATTR);
98
+ if (accurate && text !== title) titleEl.setAttribute('title', title);else titleEl.removeAttribute('title');
89
99
  };
90
100
 
91
101
  /**
@@ -98,11 +108,20 @@ layoutKey) {
98
108
  var trailingWidth = 0;
99
109
  var typeWidth = 0;
100
110
  var readStatics = function readStatics() {
101
- var _trailingRef$current$, _trailingRef$current, _typeIconRef$current$, _typeIconRef$current;
111
+ var _trailing$getBounding, _typeIconRef$current$, _typeIconRef$current;
102
112
  var cs = getComputedStyle(label);
103
113
  gap = Number.parseFloat(cs.columnGap || cs.gap) || 0;
104
- trailingWidth = (_trailingRef$current$ = (_trailingRef$current = trailingRef.current) === null || _trailingRef$current === void 0 ? void 0 : _trailingRef$current.getBoundingClientRect().width) !== null && _trailingRef$current$ !== void 0 ? _trailingRef$current$ : 0;
114
+ var trailing = trailingRef.current;
115
+ trailingWidth = (_trailing$getBounding = trailing === null || trailing === void 0 ? void 0 : trailing.getBoundingClientRect().width) !== null && _trailing$getBounding !== void 0 ? _trailing$getBounding : 0;
105
116
  typeWidth = (_typeIconRef$current$ = (_typeIconRef$current = typeIconRef.current) === null || _typeIconRef$current === void 0 ? void 0 : _typeIconRef$current.getBoundingClientRect().width) !== null && _typeIconRef$current$ !== void 0 ? _typeIconRef$current$ : 0;
117
+ var timeEl = trailing === null || trailing === void 0 ? void 0 : trailing.querySelector('[data-odn-chat-item-time]');
118
+ if (trailing instanceof HTMLElement && timeEl instanceof HTMLElement) {
119
+ var timeW = timeEl.getBoundingClientRect().width;
120
+ // 选中让位时时间为 0,保留上次正值,避免 hover 位移用错
121
+ if (timeW > 0) {
122
+ trailing.style.setProperty('--odn-chat-item-time-w', "".concat(timeW, "px"));
123
+ }
124
+ }
106
125
  };
107
126
 
108
127
  /**
@@ -174,7 +193,7 @@ layoutKey) {
174
193
  cancelled = true;
175
194
  stopObserving();
176
195
  };
177
- }, [title, enabled, layoutKey, labelRef, titleRef, trailingRef, typeIconRef]);
196
+ }, [title, enabled, layoutKey, skipDomWrite, labelRef, titleRef, trailingRef, typeIconRef]);
178
197
  }
179
198
  function ChatItemStatus(_ref) {
180
199
  var status = _ref.status;
@@ -219,6 +238,29 @@ function ChatItemStatus(_ref) {
219
238
  "data-odn-chat-item-status-unread-dot": true
220
239
  }));
221
240
  }
241
+ var MOVE_VALUE_PREFIX = 'move-to:';
242
+
243
+ /** 将 query 在 text 中的匹配段用 mark 包起来(主题色由样式控制)。 */
244
+ function highlightMatch(text, query) {
245
+ var q = query === null || query === void 0 ? void 0 : query.trim();
246
+ if (!q) return text;
247
+ var escaped = q.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
248
+ var re = new RegExp("(".concat(escaped, ")"), 'gi');
249
+ var parts = text.split(re);
250
+ if (parts.length === 1) return text;
251
+ return parts.map(function (part, i) {
252
+ if (!part) return null;
253
+ if (part.toLowerCase() === q.toLowerCase()) {
254
+ return /*#__PURE__*/React.createElement("mark", {
255
+ key: i,
256
+ "data-odn-chat-item-title-mark": true
257
+ }, part);
258
+ }
259
+ return /*#__PURE__*/React.createElement("span", {
260
+ key: i
261
+ }, part);
262
+ });
263
+ }
222
264
  function useControllableState(controlled, defaultValue, onChange) {
223
265
  var _useState = useState(defaultValue),
224
266
  _useState2 = _slicedToArray(_useState, 2),
@@ -251,9 +293,13 @@ function ChatItemInner(_ref2) {
251
293
  _ref2$pinned = _ref2.pinned,
252
294
  pinned = _ref2$pinned === void 0 ? false : _ref2$pinned,
253
295
  time = _ref2.time,
296
+ groupId = _ref2.groupId,
297
+ groupOptions = _ref2.groupOptions,
298
+ highlightQuery = _ref2.highlightQuery,
254
299
  _onClick = _ref2.onClick,
255
300
  onRename = _ref2.onRename,
256
301
  onPin = _ref2.onPin,
302
+ onMoveToGroup = _ref2.onMoveToGroup,
257
303
  onDelete = _ref2.onDelete,
258
304
  actionMenuZIndex = _ref2.actionMenuZIndex,
259
305
  renamingProp = _ref2.renaming,
@@ -306,7 +352,7 @@ function ChatItemInner(_ref2) {
306
352
  var fitTitle = showTypeIcon || showTrailing;
307
353
  useFittedTitle(title, fitTitle, labelRef, titleRef, trailingRef, typeIconRef, // trailing / 字重的全部变化来源。这些都会改标题可用宽度而行宽不变,
308
354
  // 提前声明即可,无需为此额外监听 label / trailing / typeIcon 的尺寸。
309
- "".concat(active ? 1 : 0, ":").concat(menuOpen ? 1 : 0, ":").concat(timeLabel, ":").concat(status !== null && status !== void 0 ? status : '', ":").concat(showTypeIcon ? 1 : 0));
355
+ "".concat(active ? 1 : 0, ":").concat(menuOpen ? 1 : 0, ":").concat(timeLabel, ":").concat(status !== null && status !== void 0 ? status : '', ":").concat(showTypeIcon ? 1 : 0), Boolean(highlightQuery === null || highlightQuery === void 0 ? void 0 : highlightQuery.trim()));
310
356
  useEffect(function () {
311
357
  if (!renaming) setDraft(title);
312
358
  }, [title, renaming]);
@@ -343,6 +389,10 @@ function ChatItemInner(_ref2) {
343
389
  setDraft(title);
344
390
  setRenaming(false);
345
391
  };
392
+ var moveTargets = (groupOptions !== null && groupOptions !== void 0 ? groupOptions : []).filter(function (g) {
393
+ return g.id !== groupId;
394
+ });
395
+ var canMove = Boolean(onMoveToGroup) && moveTargets.length > 0;
346
396
  var actionMenu = useMemo(function () {
347
397
  return [].concat(_toConsumableArray(onRename ? [{
348
398
  value: 'rename',
@@ -352,16 +402,27 @@ function ChatItemInner(_ref2) {
352
402
  value: 'pin',
353
403
  label: pinned ? '取消置顶' : '置顶',
354
404
  icon: 'arrow-up-to-line'
405
+ }] : []), _toConsumableArray(canMove ? [{
406
+ value: 'move',
407
+ label: '移动到',
408
+ icon: 'folder-input',
409
+ children: moveTargets.map(function (g) {
410
+ return {
411
+ value: "".concat(MOVE_VALUE_PREFIX).concat(g.id),
412
+ label: g.title
413
+ };
414
+ })
355
415
  }] : []), _toConsumableArray(onDelete ? [{
356
416
  value: 'delete',
357
417
  label: '删除',
358
418
  icon: 'trash-2'
359
419
  }] : []));
360
- }, [onRename, onPin, onDelete, pinned]);
420
+ }, [onRename, onPin, onDelete, pinned, canMove, moveTargets]);
361
421
  return /*#__PURE__*/React.createElement(HoverFill, {
362
422
  "data-odn-chat-item": true,
363
423
  "data-odn-chat-item-id": id,
364
424
  "data-odn-chat-item-pinned": pinned || undefined,
425
+ "data-odn-chat-item-time-yield": active || menuOpen || undefined,
365
426
  bgClassName: "odn-chat-item-btn-bg",
366
427
  disabled: active || renaming
367
428
  }, /*#__PURE__*/React.createElement("div", {
@@ -402,9 +463,8 @@ function ChatItemInner(_ref2) {
402
463
  }, /*#__PURE__*/React.createElement("span", {
403
464
  ref: titleRef,
404
465
  "data-odn-chat-item-title": true,
405
- "data-odn-chat-item-title-bold": active ? '' : undefined,
406
- title: title
407
- }, title), showTypeIcon ? /*#__PURE__*/React.createElement("span", {
466
+ "data-odn-chat-item-title-bold": active ? '' : undefined
467
+ }, highlightQuery ? highlightMatch(title, highlightQuery) : title), showTypeIcon ? /*#__PURE__*/React.createElement("span", {
408
468
  ref: typeIconRef,
409
469
  "data-odn-chat-item-type-icon": true,
410
470
  "aria-label": "\u4EBA\u5DE5\u5BA2\u670D\u4F1A\u8BDD",
@@ -424,7 +484,7 @@ function ChatItemInner(_ref2) {
424
484
  trigger: "click",
425
485
  placement: "bottomRight",
426
486
  zIndex: actionMenuZIndex,
427
- popupClassName: "odn-chat-item-action-menu",
487
+ popupClassName: "odn-dropdown-compact odn-chat-item-action-menu",
428
488
  visible: menuOpen,
429
489
  onVisibleChange: setMenuOpen,
430
490
  menu: actionMenu,
@@ -440,6 +500,14 @@ function ChatItemInner(_ref2) {
440
500
  setMenuOpen(false);
441
501
  return;
442
502
  }
503
+ if (value.startsWith(MOVE_VALUE_PREFIX)) {
504
+ var targetGroupId = value.slice(MOVE_VALUE_PREFIX.length);
505
+ if (targetGroupId && targetGroupId !== groupId) {
506
+ onMoveToGroup === null || onMoveToGroup === void 0 || onMoveToGroup(id, targetGroupId);
507
+ }
508
+ setMenuOpen(false);
509
+ return;
510
+ }
443
511
  if (value === 'delete') {
444
512
  setDeleteOpen(true);
445
513
  setMenuOpen(false);