one-design-next 0.0.70 → 0.0.72

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 (52) hide show
  1. package/dist/artifact/actions.d.ts +17 -0
  2. package/dist/artifact/actions.js +29 -0
  3. package/dist/artifact/glow.d.ts +7 -0
  4. package/dist/artifact/glow.js +17 -0
  5. package/dist/artifact/icons/ArtifactFileIcon.d.ts +17 -0
  6. package/dist/artifact/icons/ArtifactFileIcon.js +72 -0
  7. package/dist/artifact/icons/file-icons.d.ts +80 -0
  8. package/dist/artifact/icons/file-icons.js +86 -0
  9. package/dist/artifact/icons/index.d.ts +2 -0
  10. package/dist/artifact/icons/index.js +2 -0
  11. package/dist/artifact/icons/medium/csv.svg +25 -0
  12. package/dist/artifact/icons/medium/docx.svg +25 -0
  13. package/dist/artifact/icons/medium/file.svg +25 -0
  14. package/dist/artifact/icons/medium/html.svg +25 -0
  15. package/dist/artifact/icons/medium/md.svg +25 -0
  16. package/dist/artifact/icons/medium/pdf.svg +25 -0
  17. package/dist/artifact/icons/medium/pptx.svg +25 -0
  18. package/dist/artifact/icons/medium/xlsx.svg +25 -0
  19. package/dist/artifact/icons/small/csv.svg +19 -0
  20. package/dist/artifact/icons/small/docx.svg +19 -0
  21. package/dist/artifact/icons/small/file.svg +19 -0
  22. package/dist/artifact/icons/small/html.svg +19 -0
  23. package/dist/artifact/icons/small/md.svg +19 -0
  24. package/dist/artifact/icons/small/pdf.svg +19 -0
  25. package/dist/artifact/icons/small/pptx.svg +19 -0
  26. package/dist/artifact/icons/small/xlsx.svg +19 -0
  27. package/dist/artifact/index.d.ts +34 -15
  28. package/dist/artifact/index.js +187 -180
  29. package/dist/artifact/style/index.css +194 -162
  30. package/dist/chat-item/index.js +39 -7
  31. package/dist/dialog/style/index.css +1 -1
  32. package/dist/drawer/style/index.css +2 -0
  33. package/dist/dropdown/index.js +5 -2
  34. package/dist/icon/svg-data.d.ts +4 -0
  35. package/dist/icon/svg-data.js +1 -1
  36. package/dist/icon/types.d.ts +1 -1
  37. package/dist/index.d.ts +1 -1
  38. package/dist/index.js +1 -1
  39. package/dist/preview-panel/index.js +55 -8
  40. package/dist/preview-panel/style/index.css +84 -6
  41. package/dist/stream-text/highlight-query-text.d.ts +8 -0
  42. package/dist/stream-text/highlight-query-text.js +44 -0
  43. package/dist/stream-text/index.d.ts +4 -2
  44. package/dist/stream-text/index.js +21 -16
  45. package/dist/stream-text/style/index.css +16 -0
  46. package/dist/style/base.css +1 -1
  47. package/dist/tooltip/index.js +25 -9
  48. package/dist/user-bubble/index.d.ts +4 -2
  49. package/dist/user-bubble/index.js +5 -3
  50. package/dist/user-bubble/render-segments.d.ts +1 -1
  51. package/dist/user-bubble/render-segments.js +7 -4
  52. package/package.json +1 -1
@@ -1,243 +1,275 @@
1
+ @charset "UTF-8";
1
2
  html {
2
- --odn-artifact-padding-y: 20px;
3
- --odn-artifact-padding-left: 24px;
4
- --odn-artifact-padding-right: 0px;
3
+ /* medium / Card */
4
+ --odn-artifact-padding-y: 16px;
5
+ --odn-artifact-padding-x: 16px;
5
6
  --odn-artifact-radius: 12px;
6
- --odn-artifact-content-gap: 24px;
7
- --odn-artifact-copy-width: 216px;
8
- --odn-artifact-copy-height: 120px;
9
- --odn-artifact-visual-width: 136px;
10
- --odn-artifact-visual-inner-width: 96px;
11
- --odn-artifact-visual-height: 120px;
7
+ --odn-artifact-gap: 14px;
8
+ --odn-artifact-copy-gap: 2px;
9
+ --odn-artifact-meta-gap: 8px;
10
+ --odn-artifact-max-width: 320px;
11
+ --odn-artifact-icon-width: 32px;
12
+ --odn-artifact-icon-height: 36px;
13
+ --odn-artifact-min-height: 68px;
14
+ --odn-artifact-title-size: var(--odn-font-size-text-md);
15
+ --odn-artifact-title-leading: var(--odn-font-leading-text-md);
16
+ --odn-artifact-meta-size: var(--odn-font-size-text-mn);
17
+ --odn-artifact-meta-leading: var(--odn-font-leading-text-mn);
18
+ /* Card hover:对齐即梦 banner 卡(0.3s / ease-out) */
19
+ --odn-artifact-hover-duration: 0.3s;
20
+ --odn-artifact-hover-ease: cubic-bezier(0.4, 0, 0.2, 1);
21
+ --odn-artifact-hover-shift: calc(
22
+ var(--odn-artifact-icon-width) + var(--odn-artifact-gap)
23
+ );
24
+ --odn-artifact-hover-icon-scale: 0.73;
12
25
  }
13
26
 
14
27
  [data-odn-artifact] {
28
+ box-sizing: border-box;
15
29
  position: relative;
16
- width: min(100%, 376px);
17
- height: var(--odn-artifact-copy-height);
18
- display: grid;
19
- grid-template-columns: minmax(0, 1fr) var(--odn-artifact-visual-width);
20
- align-items: stretch;
21
- gap: 0;
22
- text-align: left;
23
- padding: 0;
24
- border: 1px solid transparent;
30
+ display: inline-flex;
31
+ align-items: center;
32
+ gap: var(--odn-artifact-gap);
33
+ width: 100%;
34
+ max-width: var(--odn-artifact-max-width);
35
+ min-height: var(--odn-artifact-min-height);
36
+ margin: 0;
37
+ padding: var(--odn-artifact-padding-y) var(--odn-artifact-padding-x);
38
+ border: 1px solid var(--odn-color-black-4);
25
39
  border-radius: var(--odn-artifact-radius);
26
- background: radial-gradient(91.56% 103.35% at 86.39% 100%, #deeaff 0%, #ecf4ff 100%);
27
- background: radial-gradient(91.56% 103.35% at 86.39% 100%, color(display-p3 0.8789 0.9166 0.9924) 0%, color(display-p3 0.9319 0.9547 0.9956) 100%);
28
- color: var(--odn-color-black-11);
29
- overflow: hidden;
40
+ background: var(--odn-color-bg-elevated);
41
+ color: var(--odn-color-black-12);
42
+ text-align: left;
43
+ vertical-align: top;
30
44
  transition: border-color 0.15s ease, background-color 0.15s ease, box-shadow 0.15s ease;
31
45
  }
32
46
 
33
- [data-odn-artifact][data-odn-artifact-width-mode=fixed-354] {
34
- width: 354px;
35
- max-width: 354px;
47
+ /* small / Small:仅 Icon + 标题;默认无底色/描边;hover 由 HoverFill 叠灰底 */
48
+ [data-odn-artifact-small-wrap] {
49
+ width: 100%;
50
+ max-width: 280px;
36
51
  }
37
52
 
38
- [data-odn-artifact][data-odn-artifact-width-mode=fill-min-354] {
39
- width: 100%;
40
- min-width: 354px;
41
- max-width: none;
53
+ .odn-artifact-small-bg {
54
+ border-radius: 8px;
55
+ }
56
+
57
+ [data-odn-artifact][data-odn-artifact-size=small] {
58
+ --odn-artifact-padding-y: 7px;
59
+ --odn-artifact-padding-x: 12px;
60
+ --odn-artifact-radius: 8px;
61
+ --odn-artifact-gap: 8px;
62
+ --odn-artifact-copy-gap: 0px;
63
+ --odn-artifact-max-width: 280px;
64
+ --odn-artifact-icon-width: 14px;
65
+ --odn-artifact-icon-height: 16px;
66
+ --odn-artifact-min-height: 0;
67
+ --odn-artifact-title-size: var(--odn-font-size-text-sm);
68
+ --odn-artifact-title-leading: var(--odn-font-leading-text-sm);
69
+ border: none;
70
+ background: transparent;
71
+ box-shadow: none;
72
+ transition: none;
42
73
  }
43
74
 
44
75
  button[data-odn-artifact] {
45
76
  cursor: pointer;
46
77
  font: inherit;
47
- height: 120px;
78
+ appearance: none;
79
+ }
80
+
81
+ [data-odn-artifact][data-odn-artifact-clickable]:not([data-odn-artifact-size=small]):hover {
82
+ border-color: var(--odn-color-black-6);
83
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);
84
+ }
85
+
86
+ [data-odn-artifact][data-odn-artifact-clickable]:focus {
87
+ outline: none;
88
+ }
89
+
90
+ [data-odn-artifact][data-odn-artifact-clickable]:focus-visible {
91
+ outline: 2px solid color-mix(in srgb, var(--odn-color-primary) 55%, transparent);
92
+ outline-offset: 2px;
48
93
  }
49
94
 
50
- [data-odn-artifact][data-odn-artifact-clickable]:hover {
51
- border-color: var(--odn-color-blue-2);
52
- box-shadow: 0 4px 16px color-mix(in srgb, var(--odn-color-blue-2) 18%, transparent);
95
+ [data-odn-artifact-icon] {
96
+ display: inline-flex;
97
+ flex-shrink: 0;
98
+ width: var(--odn-artifact-icon-width);
99
+ height: var(--odn-artifact-icon-height);
100
+ line-height: 0;
101
+ overflow: visible;
53
102
  }
54
103
 
55
104
  [data-odn-artifact-copy] {
56
- position: relative;
57
- z-index: 1;
58
- width: 100%;
59
- height: var(--odn-artifact-copy-height);
60
- padding: var(--odn-artifact-padding-y) var(--odn-artifact-padding-right) var(--odn-artifact-padding-y) var(--odn-artifact-padding-left);
61
- box-sizing: border-box;
62
105
  display: flex;
63
106
  flex-direction: column;
64
- justify-content: flex-start;
107
+ justify-content: center;
108
+ gap: var(--odn-artifact-copy-gap);
65
109
  min-width: 0;
110
+ flex: 1;
66
111
  }
67
112
 
68
113
  [data-odn-artifact-title] {
114
+ display: flex;
115
+ align-items: baseline;
116
+ min-width: 0;
69
117
  margin: 0;
70
- font-size: var(--odn-font-size-headline-6);
71
- line-height: var(--odn-font-leading-headline-6);
118
+ font-size: var(--odn-artifact-title-size);
119
+ line-height: var(--odn-artifact-title-leading);
72
120
  font-weight: 500;
73
121
  color: var(--odn-color-black-12);
74
- overflow: hidden;
75
- text-overflow: ellipsis;
76
122
  white-space: nowrap;
77
123
  }
78
124
 
79
- [data-odn-artifact-stat-range] {
80
- margin: 0;
81
- margin-top: 0;
82
- font-size: var(--odn-font-size-text-sm);
83
- line-height: var(--odn-font-leading-text-sm);
84
- color: var(--odn-color-black-12);
85
- white-space: nowrap;
125
+ /* 主名前缀可省略;末尾 4 位 + 扩展名始终完整可见(前缀…后四位.ext) */
126
+ [data-odn-artifact-title-name] {
127
+ min-width: 0;
86
128
  overflow: hidden;
87
129
  text-overflow: ellipsis;
88
- }
89
-
90
- [data-odn-artifact-created-at] {
91
- margin: 0;
92
- margin-top: 14px;
93
- font-size: var(--odn-font-size-text-mn);
94
- line-height: var(--odn-font-leading-text-mn);
95
- color: var(--odn-color-black-8);
96
- display: inline-flex;
97
- align-items: center;
98
- gap: 4px;
99
130
  white-space: nowrap;
100
- overflow: hidden;
101
- text-overflow: ellipsis;
102
- }
103
-
104
- [data-odn-artifact][data-odn-artifact-status=Done] [data-odn-artifact-created-at] {
105
- color: var(--odn-color-brand-6);
106
- font-size: 14px;
107
- }
108
-
109
- [data-odn-artifact][data-odn-artifact-status=Generating] [data-odn-artifact-created-at] {
110
- font-size: 14px;
111
- }
112
-
113
- [data-odn-artifact-detail-icon] {
114
- display: inline-flex;
115
- align-items: center;
116
- transform: translateX(-6px);
117
- opacity: 0;
118
- transition: transform 0.2s ease, opacity 0.2s ease;
119
131
  }
120
132
 
121
- [data-odn-artifact][data-odn-artifact-status=Done]:hover [data-odn-artifact-detail-icon] {
122
- transform: translateX(0);
123
- opacity: 1;
133
+ [data-odn-artifact-title-tail],
134
+ [data-odn-artifact-title-ext] {
135
+ flex-shrink: 0;
124
136
  }
125
137
 
126
- [data-odn-artifact-visual-wrap] {
127
- position: relative;
128
- z-index: 1;
129
- width: var(--odn-artifact-visual-width);
130
- height: var(--odn-artifact-visual-height);
138
+ [data-odn-artifact-meta] {
131
139
  display: flex;
132
- align-items: stretch;
133
- justify-content: center;
140
+ align-items: center;
141
+ flex-wrap: wrap;
142
+ gap: var(--odn-artifact-meta-gap);
143
+ min-width: 0;
144
+ font-size: var(--odn-artifact-meta-size);
145
+ line-height: var(--odn-artifact-meta-leading);
146
+ color: var(--odn-color-black-8);
147
+ font-variant-numeric: tabular-nums;
134
148
  }
135
149
 
136
- [data-odn-artifact-visual] {
137
- position: relative;
138
- width: var(--odn-artifact-visual-inner-width);
139
- min-width: var(--odn-artifact-visual-inner-width);
140
- height: var(--odn-artifact-visual-height);
141
- margin-top: 20px;
142
- margin-right: 0;
143
- display: flex;
144
- align-items: center;
145
- justify-content: center;
146
- border-radius: 8px;
147
- border: 0;
148
- background: #fff;
150
+ [data-odn-artifact-meta-item] {
151
+ min-width: 0;
149
152
  overflow: hidden;
150
- transition: transform 0.2s ease;
153
+ text-overflow: ellipsis;
154
+ white-space: nowrap;
151
155
  }
152
156
 
153
- [data-odn-artifact][data-odn-artifact-clickable]:hover [data-odn-artifact-visual] {
154
- transform: rotate(5deg) scale(1.05);
157
+ /* —— Card hover(参考即梦 button-CB5lvW)——
158
+ * 1. 左侧大椭圆色光(background ::after radial-gradient,hover opacity .12)
159
+ * 2. Icon scale(0.73) + 淡出,形成后退感
160
+ * 3. 文案模块 translateX 至左 padding 16(半透明,让色光透出)
161
+ */
162
+ [data-odn-artifact]:not([data-odn-artifact-size=small]) {
163
+ overflow: hidden;
155
164
  }
156
165
 
157
- [data-odn-artifact-spotlight] {
166
+ /* 即梦 .background-EkKhlS:全卡裁切层 + 左侧大椭圆 glow */
167
+ [data-odn-artifact-glow] {
158
168
  position: absolute;
159
169
  inset: 0;
160
170
  z-index: 0;
171
+ border-radius: inherit;
172
+ overflow: hidden;
161
173
  pointer-events: none;
162
- opacity: var(--odn-artifact-spot-opacity, 0);
163
- transition: opacity 0.2s ease;
164
- background: radial-gradient(280px circle at var(--odn-artifact-spot-x, 50%) var(--odn-artifact-spot-y, 50%), color-mix(in srgb, var(--odn-color-blue-2) 42%, transparent) 0%, transparent 62%);
174
+ opacity: 0;
175
+ transition: opacity var(--odn-artifact-hover-duration) var(--odn-artifact-hover-ease);
165
176
  }
166
177
 
167
- [data-odn-artifact-visual-image] {
168
- width: 100%;
169
- height: 100%;
170
- object-fit: cover;
178
+ [data-odn-artifact-glow]::after {
179
+ content: "";
180
+ position: absolute;
181
+ /* 尺寸/位置对齐即梦:230×130、左偏 -65、上偏 -30、微旋 -8.4deg */
182
+ left: -65px;
183
+ top: -30px;
184
+ width: 230px;
185
+ height: 130px;
186
+ transform: rotate(-8.4deg);
187
+ background-image: radial-gradient(ellipse at center, var(--odn-artifact-glow-color, #fa8e00), transparent 60%);
188
+ }
189
+
190
+ [data-odn-artifact][data-odn-artifact-clickable]:not([data-odn-artifact-size=small]):hover > [data-odn-artifact-glow],
191
+ [data-odn-artifact][data-odn-artifact-clickable]:not([data-odn-artifact-size=small]):focus-visible > [data-odn-artifact-glow] {
192
+ opacity: 0.12;
171
193
  }
172
194
 
173
- [data-odn-artifact-generating-icon] {
195
+ [data-odn-artifact]:not([data-odn-artifact-size=small]) [data-odn-artifact-icon] {
196
+ position: relative;
197
+ z-index: 1;
198
+ transform: scale(1);
199
+ opacity: 1;
200
+ transform-origin: center center;
201
+ transition: transform var(--odn-artifact-hover-duration) var(--odn-artifact-hover-ease), opacity var(--odn-artifact-hover-duration) var(--odn-artifact-hover-ease);
202
+ }
203
+
204
+ [data-odn-artifact-main] {
174
205
  position: absolute;
175
- left: 50%;
176
- top: 48px;
177
- transform: translate(-50%, -50%);
206
+ inset: 0;
178
207
  z-index: 2;
179
- color: #95a0b0;
208
+ overflow: hidden;
180
209
  pointer-events: none;
181
210
  }
182
211
 
183
- [data-odn-artifact-visual-block] {
212
+ [data-odn-artifact]:not([data-odn-artifact-size=small]) [data-odn-artifact-copy] {
184
213
  position: absolute;
185
- border-radius: 2px;
186
- background: #ecf2fe;
187
- z-index: 1;
214
+ top: 0;
215
+ bottom: 0;
216
+ left: calc(var(--odn-artifact-padding-x) + var(--odn-artifact-icon-width) + var(--odn-artifact-gap));
217
+ right: var(--odn-artifact-padding-x);
218
+ z-index: 2;
219
+ flex: none;
220
+ box-sizing: border-box;
221
+ /* 不铺不透明底,让左侧色光大面积透出(同即梦文案层) */
222
+ transform: translateX(0);
223
+ will-change: transform;
224
+ transition: transform var(--odn-artifact-hover-duration) var(--odn-artifact-hover-ease);
225
+ pointer-events: none;
188
226
  }
189
227
 
190
- [data-odn-artifact-visual-block-a] {
191
- width: 40px;
192
- height: 6px;
193
- left: 12px;
194
- top: 12px;
228
+ [data-odn-artifact]:not([data-odn-artifact-size=small]) [data-odn-artifact-title] {
229
+ pointer-events: auto;
195
230
  }
196
231
 
197
- [data-odn-artifact-visual-block-b] {
198
- width: 24px;
199
- height: 6px;
200
- left: 12px;
201
- top: 22px;
232
+ [data-odn-artifact][data-odn-artifact-clickable]:not([data-odn-artifact-size=small]):hover [data-odn-artifact-icon],
233
+ [data-odn-artifact][data-odn-artifact-clickable]:not([data-odn-artifact-size=small]):focus-visible [data-odn-artifact-icon] {
234
+ transform: scale(var(--odn-artifact-hover-icon-scale));
235
+ opacity: 0;
202
236
  }
203
237
 
204
- [data-odn-artifact-visual-block-e] {
205
- width: 16px;
206
- height: 16px;
207
- left: 68px;
208
- top: 12px;
209
- border-radius: 3.2px;
238
+ [data-odn-artifact][data-odn-artifact-clickable]:not([data-odn-artifact-size=small]):hover [data-odn-artifact-copy],
239
+ [data-odn-artifact][data-odn-artifact-clickable]:not([data-odn-artifact-size=small]):focus-visible [data-odn-artifact-copy] {
240
+ /* 左移 icon+gap,使文案左缘落到 padding-x(16) */
241
+ transform: translateX(calc(-1 * var(--odn-artifact-hover-shift)));
210
242
  }
211
243
 
212
- [data-odn-artifact-visual-logo] {
244
+ /* Card:操作预期仅 Icon;右侧间距 20 */
245
+ [data-odn-artifact-action] {
213
246
  position: absolute;
247
+ right: 20px;
248
+ top: 50%;
249
+ z-index: 3;
250
+ display: inline-flex;
251
+ align-items: center;
252
+ justify-content: center;
253
+ flex-shrink: 0;
214
254
  width: 16px;
215
255
  height: 16px;
216
- left: 68px;
217
- top: 12px;
218
- border-radius: 3.2px;
219
- overflow: hidden;
220
- z-index: 1;
221
- background: #ecf2fe;
256
+ color: var(--odn-color-black-10);
257
+ pointer-events: none;
258
+ opacity: 0;
259
+ transform: translate(4px, -50%);
260
+ transition: opacity var(--odn-artifact-hover-duration) var(--odn-artifact-hover-ease), transform var(--odn-artifact-hover-duration) var(--odn-artifact-hover-ease);
222
261
  }
223
262
 
224
- [data-odn-artifact-visual-logo-image] {
225
- width: 100%;
226
- height: 100%;
227
- display: block;
228
- object-fit: cover;
263
+ [data-odn-artifact][data-odn-artifact-clickable]:hover > [data-odn-artifact-action],
264
+ [data-odn-artifact][data-odn-artifact-clickable]:focus-visible > [data-odn-artifact-action] {
265
+ opacity: 1;
266
+ transform: translate(0, -50%);
229
267
  }
230
268
 
231
- [data-odn-artifact-visual-block-c] {
232
- width: 72px;
233
- height: 32px;
234
- left: 12px;
235
- top: 40px;
269
+ [data-odn-artifact][data-odn-artifact-status=Generating] {
270
+ opacity: 0.85;
236
271
  }
237
272
 
238
- [data-odn-artifact-visual-block-d] {
239
- width: 72px;
240
- height: 32px;
241
- left: 12px;
242
- top: 78px;
273
+ [data-odn-artifact][data-odn-artifact-status=Generating] [data-odn-artifact-meta] {
274
+ color: var(--odn-color-black-7);
243
275
  }
@@ -17,17 +17,23 @@ var ELLIPSIS = '…';
17
17
 
18
18
  /** 可用宽度变化小于该值时跳过重算(与二分容差同量级) */
19
19
  var FIT_WIDTH_EPS = 0.5;
20
+ /**
21
+ * 可用宽度低于该阈值时视为测量不可靠(布局未完成 / 被瞬时压扁)。
22
+ * 此时保留上一帧可读结果或原文,避免把标题裁成单独的「…」。
23
+ */
24
+ var FIT_MIN_RELIABLE_WIDTH = 24;
20
25
 
21
26
  /**
22
27
  * 有 trailing(客服 icon / status / 时间)时,用 DOM 实测把标题裁到可用宽度。
23
28
  * 解决 CSS text-overflow 按字符边界截断后,省略号右侧留白把 trailing 顶开的问题。
24
29
  *
25
- * 性能:只监听整行(btn)宽度;RO 回调经 rAF 合并(每行每帧最多 fit 一次);
26
- * 缓存 maxWidth / trailingWidth / 裁切结果,宽度几乎不变或结果不变则跳过更新。
30
+ * 性能:RO 监听行 / label / trailing(active 时时间让位不改变行宽,必须听内部);
31
+ * 回调经 rAF 合并;缓存 maxWidth / trailingWidth / 裁切结果。
27
32
  */
28
33
  function useFittedTitle(title, enabled, labelRef, titleRef, /** 右对齐区(状态 / 时间),量宽预留 */
29
34
  trailingRef, /** 紧跟标题的类型 icon,量宽预留 */
30
- typeIconRef) {
35
+ typeIconRef, /** active 时时间让位 / 字重变化,需强制重测 */
36
+ layoutKey) {
31
37
  var _useState = useState(title),
32
38
  _useState2 = _slicedToArray(_useState, 2),
33
39
  fitted = _useState2[0],
@@ -41,11 +47,14 @@ typeIconRef) {
41
47
  var label = labelRef.current;
42
48
  var titleEl = titleRef.current;
43
49
  if (!label || !titleEl) return;
50
+
51
+ // 标题变更时先回到原文,避免沿用上一会话裁成的「…」
52
+ setFitted(title);
44
53
  var cancelled = false;
45
54
  var rafId = 0;
46
55
  var lastMaxWidth = Number.NaN;
47
56
  var lastTrailingWidth = Number.NaN;
48
- var lastFitted = '';
57
+ var lastFitted = title;
49
58
  var probe = document.createElement('span');
50
59
  probe.setAttribute('aria-hidden', 'true');
51
60
  probe.style.cssText = 'position:absolute;visibility:hidden;pointer-events:none;white-space:nowrap;left:-9999px;top:0;';
@@ -80,13 +89,24 @@ typeIconRef) {
80
89
  if (Number.isFinite(lastMaxWidth) && Math.abs(maxWidth - lastMaxWidth) < FIT_WIDTH_EPS && Math.abs(trailingWidth - lastTrailingWidth) < FIT_WIDTH_EPS) {
81
90
  return;
82
91
  }
92
+
93
+ // 布局未就绪时不要写成单独的「…」,否则行宽不变时 RO 不触发会永久卡住
94
+ if (maxWidth < FIT_MIN_RELIABLE_WIDTH) {
95
+ lastMaxWidth = Number.NaN;
96
+ lastTrailingWidth = Number.NaN;
97
+ if (lastFitted !== title) {
98
+ lastFitted = title;
99
+ setFitted(title);
100
+ }
101
+ return;
102
+ }
83
103
  lastMaxWidth = maxWidth;
84
104
  lastTrailingWidth = trailingWidth;
85
105
  var next = title;
86
106
  if (measure(title) > maxWidth + FIT_WIDTH_EPS) {
87
107
  var lo = 0;
88
108
  var hi = title.length;
89
- next = ELLIPSIS;
109
+ next = title;
90
110
  while (lo <= hi) {
91
111
  var mid = lo + hi >> 1;
92
112
  var candidate = "".concat(title.slice(0, mid)).concat(ELLIPSIS);
@@ -97,6 +117,11 @@ typeIconRef) {
97
117
  hi = mid - 1;
98
118
  }
99
119
  }
120
+ // 极端窄宽仍放不下「字+…」时交给 CSS ellipsis,保留原文
121
+ if (next === ELLIPSIS || next === title && measure(title) > maxWidth + FIT_WIDTH_EPS) {
122
+ var withEllipsis = "".concat(title.slice(0, 1)).concat(ELLIPSIS);
123
+ next = measure(withEllipsis) <= maxWidth + FIT_WIDTH_EPS ? withEllipsis : title;
124
+ }
100
125
  }
101
126
  if (next === lastFitted) return;
102
127
  lastFitted = next;
@@ -121,13 +146,18 @@ typeIconRef) {
121
146
  var row = (_label$closest = label.closest('[data-odn-chat-item-btn]')) !== null && _label$closest !== void 0 ? _label$closest : label;
122
147
  var ro = new ResizeObserver(scheduleFit);
123
148
  ro.observe(row);
149
+ ro.observe(label);
150
+ var trailing = trailingRef.current;
151
+ if (trailing) ro.observe(trailing);
152
+ var typeIcon = typeIconRef.current;
153
+ if (typeIcon) ro.observe(typeIcon);
124
154
  return function () {
125
155
  cancelled = true;
126
156
  if (rafId) window.cancelAnimationFrame(rafId);
127
157
  ro.disconnect();
128
158
  probe.remove();
129
159
  };
130
- }, [title, enabled, labelRef, titleRef, trailingRef, typeIconRef]);
160
+ }, [title, enabled, layoutKey, labelRef, titleRef, trailingRef, typeIconRef]);
131
161
  return enabled ? fitted : title;
132
162
  }
133
163
  function ChatItemStatus(_ref) {
@@ -248,7 +278,8 @@ export function ChatItem(_ref2) {
248
278
  var showTime = Boolean(timeLabel);
249
279
  var showTrailing = showStatus || showTime;
250
280
  var fitTitle = showTypeIcon || showTrailing;
251
- var displayTitle = useFittedTitle(title, fitTitle, labelRef, titleRef, trailingRef, typeIconRef);
281
+ var displayTitle = useFittedTitle(title, fitTitle, labelRef, titleRef, trailingRef, typeIconRef, // active / 菜单开合都会改时间让位与字重,行宽可能不变
282
+ "".concat(active ? 1 : 0, ":").concat(menuOpen ? 1 : 0));
252
283
  useEffect(function () {
253
284
  if (!renaming) setDraft(title);
254
285
  }, [title, renaming]);
@@ -300,6 +331,7 @@ export function ChatItem(_ref2) {
300
331
  }] : []));
301
332
  return /*#__PURE__*/React.createElement(HoverFill, {
302
333
  "data-odn-chat-item": true,
334
+ "data-odn-chat-item-id": id,
303
335
  "data-odn-chat-item-pinned": pinned || undefined,
304
336
  bgClassName: "odn-chat-item-btn-bg",
305
337
  disabled: active || renaming
@@ -4,7 +4,7 @@ html {
4
4
  --odn-dialog-footer-padding: 24px;
5
5
  --odn-dialog-footer-gap: 12px;
6
6
  --odn-dialog-footer-justify: flex-end;
7
- --odn-dialog-overlay-background: rgba(0, 0, 0, 0.45);
7
+ --odn-dialog-overlay-background: rgba(0, 0, 0, 0.2);
8
8
  --odn-dialog-border-radius: 10px;
9
9
  --odn-dialog-close-top: 16px;
10
10
  --odn-dialog-close-right: 16px;
@@ -1,6 +1,7 @@
1
1
  @charset "UTF-8";
2
2
  html {
3
3
  --odn-drawer-overlay-background: rgba(0, 0, 0, 0.45);
4
+ --odn-drawer-shadow: var(--odn-shadow-2);
4
5
  --odn-drawer-header-padding-inline: 20px;
5
6
  --odn-drawer-header-height: 64px;
6
7
  --odn-drawer-header-border: 1px solid var(--odn-color-black-4);
@@ -79,6 +80,7 @@ html {
79
80
  display: flex;
80
81
  flex-direction: column;
81
82
  background-color: #fff;
83
+ box-shadow: var(--odn-drawer-shadow);
82
84
  pointer-events: initial;
83
85
  overflow: auto;
84
86
  }
@@ -886,10 +886,13 @@ var Dropdown = function Dropdown(props) {
886
886
  }))));
887
887
  }
888
888
 
889
- // click 模式的默认渲染
889
+ // click 模式:与 hover 一致使用 modal={false}。
890
+ // 默认 modal 会铺内部 backdrop,挂在 Drawer/Dialog 内时菜单项看起来可点但点不中
891
+ //(ChatItem 修改名称 / 置顶 / 删除即踩中此问题)。
890
892
  return /*#__PURE__*/React.createElement(DropdownMenu, {
891
893
  open: disabled ? false : finalOpen,
892
- onOpenChange: handleOpenChange
894
+ onOpenChange: handleOpenChange,
895
+ modal: false
893
896
  }, /*#__PURE__*/React.createElement(DropdownMenuTrigger, {
894
897
  asChild: true,
895
898
  disabled: disabled
@@ -4250,6 +4250,10 @@ export declare const svgData: {
4250
4250
  readonly viewBox: "0 0 24 24";
4251
4251
  readonly content: "<g fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M3 7V5a2 2 0 0 1 2-2h2\"></path><path d=\"M17 3h2a2 2 0 0 1 2 2v2\"></path><path d=\"M21 17v2a2 2 0 0 1-2 2h-2\"></path><path d=\"M7 21H5a2 2 0 0 1-2-2v-2\"></path></g>";
4252
4252
  };
4253
+ readonly 'menu-line': {
4254
+ readonly viewBox: "0 0 24 24";
4255
+ readonly content: "<g fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M4 5h16\"></path><path d=\"M4 12h16\"></path><path d=\"M4 19h16\"></path></g>";
4256
+ };
4253
4257
  readonly 'search-line': {
4254
4258
  readonly viewBox: "0 0 24 24";
4255
4259
  readonly content: "<g fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"11\" cy=\"11\" r=\"8\"></circle><path d=\"m21 21-4.3-4.3\"></path></g>";