one-design-next 0.0.117 → 0.0.119

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,3 +1,4 @@
1
+ import _extends from "@babel/runtime/helpers/esm/extends";
1
2
  import _regeneratorRuntime from "@babel/runtime/helpers/esm/regeneratorRuntime";
2
3
  import _asyncToGenerator from "@babel/runtime/helpers/esm/asyncToGenerator";
3
4
  import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
@@ -36,12 +37,7 @@ export var CodeBlock = /*#__PURE__*/forwardRef(function (_ref, ref) {
36
37
  return _ref2.apply(this, arguments);
37
38
  };
38
39
  }(), []);
39
- return /*#__PURE__*/React.createElement("div", {
40
- ref: ref,
41
- "data-odn-code-block": true
42
- }, /*#__PURE__*/React.createElement("div", {
43
- "data-odn-code-block-header": true
44
- }, /*#__PURE__*/React.createElement("span", null, language !== null && language !== void 0 ? language : 'code'), /*#__PURE__*/React.createElement(HoverFill, {
40
+ var copyControl = /*#__PURE__*/React.createElement(HoverFill, {
45
41
  "data-odn-code-block-copy-wrap": true,
46
42
  bgClassName: "odn-code-block-copy-bg"
47
43
  }, /*#__PURE__*/React.createElement("button", {
@@ -59,7 +55,17 @@ export var CodeBlock = /*#__PURE__*/forwardRef(function (_ref, ref) {
59
55
  }, "\u5DF2\u590D\u5236")) : /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Icon, {
60
56
  name: "copy",
61
57
  size: 14
62
- }), /*#__PURE__*/React.createElement("span", null, "\u590D\u5236"))))), /*#__PURE__*/React.createElement("pre", {
58
+ }), /*#__PURE__*/React.createElement("span", null, "\u590D\u5236"))));
59
+ return /*#__PURE__*/React.createElement("div", _extends({
60
+ ref: ref,
61
+ "data-odn-code-block": true
62
+ }, language ? {} : {
63
+ 'data-odn-code-block-plain': ''
64
+ }), language ? /*#__PURE__*/React.createElement("div", {
65
+ "data-odn-code-block-header": true
66
+ }, /*#__PURE__*/React.createElement("span", null, language), copyControl) : /*#__PURE__*/React.createElement("div", {
67
+ "data-odn-code-block-copy-anchor": true
68
+ }, copyControl), /*#__PURE__*/React.createElement("pre", {
63
69
  "data-odn-code-block-pre": true
64
70
  }, /*#__PURE__*/React.createElement("code", null, code)));
65
71
  });
@@ -15,6 +15,15 @@
15
15
  color: var(--odn-color-black-9);
16
16
  }
17
17
 
18
+ [data-odn-code-block-copy-anchor] {
19
+ position: absolute;
20
+ top: 4px;
21
+ right: 8px;
22
+ z-index: 1;
23
+ font-size: 12px;
24
+ color: var(--odn-color-black-9);
25
+ }
26
+
18
27
  [data-odn-code-block-copy-wrap] {
19
28
  display: inline-flex;
20
29
  }
@@ -62,5 +71,9 @@
62
71
  background: transparent;
63
72
  }
64
73
  [data-odn-code-block-pre] code {
65
- font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace;
74
+ font-family: SFMono-Regular, Consolas, "Liberation Mono", Menlo, monospace;
75
+ }
76
+
77
+ [data-odn-code-block-plain] [data-odn-code-block-pre] {
78
+ padding-right: 84px;
66
79
  }
@@ -25,7 +25,7 @@ type CollapsibleContentProps = Omit<HTMLMotionProps<'div'>, 'children' | 'ref' |
25
25
  children?: React.ReactNode;
26
26
  transition?: Transition;
27
27
  };
28
- declare const CollapsibleContent: React.ForwardRefExoticComponent<Omit<HTMLMotionProps<"div">, "ref" | "children" | "transition"> & {
28
+ declare const CollapsibleContent: React.ForwardRefExoticComponent<Omit<HTMLMotionProps<"div">, "children" | "ref" | "transition"> & {
29
29
  children?: React.ReactNode;
30
30
  transition?: Transition | undefined;
31
31
  } & React.RefAttributes<HTMLDivElement>>;
@@ -32,10 +32,39 @@ export interface ComposerEditorTriggerInfo {
32
32
  }
33
33
  /** 编辑器 10 行真实高度,缩放按钮在内容达到此高度后隐藏。 */
34
34
  export declare const COMPOSER_EDITOR_MAX_ROWS_PX: number;
35
+ /**
36
+ * 退出「高度上限态」的高度:回落到 9 行以下才退出。
37
+ *
38
+ * 顶到上限后缩放按钮隐藏、右侧让位回收,内容区随之变宽,同一段文本可能
39
+ * 从 10 行重排成 9 行。若退出条件也看 10 行,就会「上限 → 变宽 → 9 行 →
40
+ * 退出 → 变窄 → 10 行 → 上限」来回。留一行滞回带即可断开这个环。
41
+ */
42
+ export declare const COMPOSER_EDITOR_HEIGHT_CAP_EXIT_PX: number;
35
43
  export interface ComposerEditorAutoSize {
36
44
  minRows?: number;
37
45
  maxRows?: number;
38
46
  }
47
+ /**
48
+ * editor 尺寸度量。
49
+ *
50
+ * `lineCount` 是「内容占了几行」(含软换行),由自然高度按行高换算,
51
+ * 已吸收各形态的块级 padding 差异。它是 lite 升降格判定的主输入——
52
+ * 不要再退回「像素高度差」判据,原因见 lite-expand.ts 的模块说明。
53
+ */
54
+ export interface ComposerEditorHeightMetrics {
55
+ /** 内容自然高度(scrollHeight,未 clamp 到 maxRows)。 */
56
+ height: number;
57
+ /** 内容占用的行数,最小 1。 */
58
+ lineCount: number;
59
+ /**
60
+ * 内容能否放进「单行态」的可用宽度。
61
+ * 仅在 lineCount <= 1 时可能为 true;lite 用它区分中间区与真正的单行区:
62
+ * 放不进说明切回单行态会被挤成两行(而单行态高度锁死会裁掉第二行)。
63
+ */
64
+ fitsInlineWidth: boolean;
65
+ /** 已超出 maxRows 上限(或整框被 50vh 挤矮后仍放不下)。 */
66
+ overflow: boolean;
67
+ }
39
68
  export interface ComposerEditorProps {
40
69
  /** 受控值。string,未来会含 marker(chip 序列化为 `\u200b\u2063id\u2063\u200b`)。 */
41
70
  value?: string;
@@ -73,7 +102,7 @@ export interface ComposerEditorProps {
73
102
  * 仅当 trigger 处于活动态(triggerRef.current 非空)时调用:
74
103
  * 把 ↑↓ Enter Esc Tab 等导航键先丢给父组件让它驱动浮层选择。
75
104
  * - 返回 `true` → editor 视为父已处理,不再走自身换行 / 提交逻辑
76
- * - 返回 `false / undefined` → editor 走原默认(onPressEnter / 换行 / 删 chip / Tab 采纳 hint 等)
105
+ * - 返回 `false / undefined` → editor 走原默认(onPressEnter / 换行 / 删 chip / Tab 填入 hint 等)
77
106
  *
78
107
  * 带修饰键的 `Tab`(Shift+Tab 反向焦点、Ctrl/Cmd+Tab 切窗口)不转发,
79
108
  * 保持浏览器默认。父组件如需 preventDefault,请在 handler 内自己调用——
@@ -82,11 +111,10 @@ export interface ComposerEditorProps {
82
111
  onTriggerKeyDown?: (e: React.KeyboardEvent<HTMLDivElement>) => boolean | void;
83
112
  /**
84
113
  * 编辑器可视高度变化回调。
85
- * height = 内容自然高度(scrollHeight,未 clamp);atMax 表示已超过 10 行
86
- * 真实高度。若整框被 50vh 挤矮,则以盒内分给编辑器的剩余高度为准。
114
+ * 见 ComposerEditorHeightMetrics:自然高度、行数、是否超出上限。
87
115
  * Composer 的 lite 升格逻辑、scrollbar 显隐都用这个。
88
116
  */
89
- onHeightChange?: (height: number, atMax: boolean) => void;
117
+ onHeightChange?: (metrics: ComposerEditorHeightMetrics) => void;
90
118
  /**
91
119
  * 剪贴板含文件(如截图、资源管理器复制文件)时回调;由上层转为附件等。
92
120
  * 若提供且 `files.length > 0`,编辑器会 `preventDefault` 且不再插入纯文本。
@@ -62,6 +62,10 @@ var scrollCaretIntoView = function scrollCaretIntoView(viewport) {
62
62
  var sel = window.getSelection();
63
63
  if (!sel || sel.rangeCount === 0) return;
64
64
  var originalRange = sel.getRangeAt(0).cloneRange();
65
+ /* caret 必须在输入区内才谈得上「滚进可视区」:菜单点击 / 参数面板抢焦点后
66
+ * selection 可能落在 viewport 外,此时 rect 是页面别处的坐标,照它滚会把
67
+ * 输入区甩到顶部或底部;rect 高度为 0 时补的探针 span 也会插进别人的 DOM。 */
68
+ if (!viewport.contains(originalRange.startContainer)) return;
65
69
  var rect = originalRange.getBoundingClientRect();
66
70
  if (!rect.height) {
67
71
  var probeRange = originalRange.cloneRange();
@@ -99,7 +103,7 @@ var findDirectHint = function findDirectHint(line) {
99
103
  };
100
104
 
101
105
  /**
102
- * hint 末尾的「TAB 采纳」小块:点它 = 按 Tab 采纳这段模板文案。
106
+ * hint 末尾的「按 TAB 键填入」小块:点它 = 按 Tab 填入这段模板文案。
103
107
  *
104
108
  * 与 hint 文本是同级节点(见 `COMPOSER_HINT_ACCEPT_ATTR` 的说明),由
105
109
  * `syncHintNode` 一起插入 / 移除,不进 value / 剪贴板 / segments。
@@ -116,13 +120,16 @@ var createHintAcceptNode = function createHintAcceptNode() {
116
120
  * - aria-label 会盖掉可见文案,反而违反「可见标签即无障碍名」。
117
121
  * - title 是浏览器原生 tooltip:延迟出现、样式不可控、会盖住灰字。 */
118
122
 
123
+ var prefix = document.createElement('span');
124
+ prefix.setAttribute('data-odn-composer-hint-accept-prefix', '');
125
+ prefix.textContent = '按';
119
126
  var key = document.createElement('span');
120
127
  key.setAttribute('data-odn-composer-hint-accept-key', '');
121
128
  key.textContent = 'TAB';
122
129
  var label = document.createElement('span');
123
130
  label.setAttribute('data-odn-composer-hint-accept-label', '');
124
- label.textContent = '采纳';
125
- accept.append(key, label);
131
+ label.textContent = '键填入';
132
+ accept.append(prefix, key, label);
126
133
  return accept;
127
134
  };
128
135
 
@@ -222,6 +229,70 @@ var contentHeightForRows = function contentHeightForRows(rows) {
222
229
 
223
230
  /** 编辑器 10 行真实高度,缩放按钮在内容达到此高度后隐藏。 */
224
231
  export var COMPOSER_EDITOR_MAX_ROWS_PX = contentHeightForRows(10);
232
+
233
+ /**
234
+ * 退出「高度上限态」的高度:回落到 9 行以下才退出。
235
+ *
236
+ * 顶到上限后缩放按钮隐藏、右侧让位回收,内容区随之变宽,同一段文本可能
237
+ * 从 10 行重排成 9 行。若退出条件也看 10 行,就会「上限 → 变宽 → 9 行 →
238
+ * 退出 → 变窄 → 10 行 → 上限」来回。留一行滞回带即可断开这个环。
239
+ */
240
+ export var COMPOSER_EDITOR_HEIGHT_CAP_EXIT_PX = contentHeightForRows(9);
241
+
242
+ /**
243
+ * 内容能否放进「单行态可用宽度」。
244
+ *
245
+ * lite 两种形态的可输入宽度不同:单行态要给左下 / 右下按钮让位,比升格态
246
+ * 窄一截。同一段文本因此可能出现「升格态一行、单行态两行」——两侧都算
247
+ * 合理的那段就是中间区。
248
+ *
249
+ * 宽度基准全部来自 CSS:单行态让位读成对变量(--odn-composer-editor-inline-inset),
250
+ * 容器宽度读 ScrollArea viewport(而不是 editor 自身,避开 content-box /
251
+ * border-box 下 clientWidth 含义不一致的问题)。改样式不需要同步 JS 常量。
252
+ */
253
+ var measureFitsInlineWidth = function measureFitsInlineWidth(el) {
254
+ var computed = window.getComputedStyle(el);
255
+ var inlineInset = Number.parseFloat(computed.getPropertyValue('--odn-composer-editor-inline-inset'));
256
+ // 非 lite 变体没有这个变量:这里不做中间区判定,一律视为放得下。
257
+ if (!Number.isFinite(inlineInset) || inlineInset <= 0) return true;
258
+ var viewport = el.closest('[data-odn-scroll-area-viewport]');
259
+ var containerWidth = viewport instanceof HTMLElement ? viewport.clientWidth : el.clientWidth;
260
+ var inlineContentWidth = containerWidth - inlineInset * 2;
261
+ if (inlineContentWidth <= 0) return true;
262
+
263
+ // 逐个文本节点取 rect:Range 覆盖整棵子树时拿到的是行容器(block)的宽度,
264
+ // 会恒等于一行宽度,量不出「文本真的有多宽」。
265
+ var walker = document.createTreeWalker(el, NodeFilter.SHOW_TEXT);
266
+ var left = Number.POSITIVE_INFINITY;
267
+ var right = Number.NEGATIVE_INFINITY;
268
+ for (var node = walker.nextNode(); node; node = walker.nextNode()) {
269
+ var text = node;
270
+ if (!text.length) continue;
271
+ var range = document.createRange();
272
+ range.selectNodeContents(text);
273
+ var rects = range.getClientRects();
274
+ for (var i = 0; i < rects.length; i += 1) {
275
+ left = Math.min(left, rects[i].left);
276
+ right = Math.max(right, rects[i].right);
277
+ }
278
+ }
279
+ if (!Number.isFinite(left) || !Number.isFinite(right)) return true;
280
+
281
+ // 留 1px 安全边界,方向是「宁可判放不下」:
282
+ // 容差往宽处给的话,文本只要比单行态宽 1px 就会被判成放得下 → 降格 →
283
+ // 单行态下又换行 → 升格,形成一个 1px 宽的来回带。往窄处给则最多让降格
284
+ // 晚半像素发生,用户无感。
285
+ return right - left <= inlineContentWidth - 1;
286
+ };
287
+
288
+ /**
289
+ * editor 尺寸度量。
290
+ *
291
+ * `lineCount` 是「内容占了几行」(含软换行),由自然高度按行高换算,
292
+ * 已吸收各形态的块级 padding 差异。它是 lite 升降格判定的主输入——
293
+ * 不要再退回「像素高度差」判据,原因见 lite-expand.ts 的模块说明。
294
+ */
295
+
225
296
  export var ComposerEditor = /*#__PURE__*/forwardRef(function ComposerEditor(_ref, ref) {
226
297
  var _autoSize$minRows;
227
298
  var valueProp = _ref.value,
@@ -319,12 +390,14 @@ export var ComposerEditor = /*#__PURE__*/forwardRef(function ComposerEditor(_ref
319
390
  * 派生 / 通知
320
391
  *
321
392
  * 为什么 syncHeight 用 scrollHeight:lite 单行态 SCSS 锁 editor.height: 32 +
322
- * overflow: hidden(防止初次 layout 飘动误升格);锁了 height 后 offsetHeight
323
- * 永远 32,无法判定多行。scrollHeight 反映"内容自然高度",不受 height/overflow
324
- * 锁影响——单行 32、多行 56,与升格阈值(>34)配合正常。
393
+ * overflow: hidden(防止初次 layout 飘动);锁了 height 后 offsetHeight 永远
394
+ * 32,量不到内容真实高度。scrollHeight 反映"内容自然高度",不受锁影响。
395
+ *
396
+ * 上报的行数由自然高度按行高换算(round 吸收各形态的块级 padding 差异),
397
+ * 与「能否放进单行态宽度」一起构成 lite 升降格的判据——见 lite-expand.ts。
325
398
  *
326
399
  * RO 监听 border-box,editor.height 被锁时 RO 不触发,所以同时在 fireChange
327
- * 主动调 syncHeight(确保升格判定能拿到 scrollHeight)。
400
+ * 主动调 syncHeight(确保升降格判定能拿到最新行数)。
328
401
  * ───────────────────────────────────── */
329
402
  var syncHeight = useCallback(function () {
330
403
  var _getViewport, _box$getBoundingClien, _onHeightChangeRef$cu;
@@ -338,10 +411,21 @@ export var ComposerEditor = /*#__PURE__*/forwardRef(function ComposerEditor(_ref
338
411
  var vhCap = typeof window === 'undefined' ? Number.POSITIVE_INFINITY : window.innerHeight * 0.5;
339
412
  var boxAtVhCap = boxH > 0 && boxH >= vhCap - 2;
340
413
  var overflow = boxAtVhCap ? allocated !== undefined && allocated > 0 && natural > allocated + 1 : rowContentPx !== undefined && natural > rowContentPx + 1;
414
+ // 行数按行高换算:round 吸收各形态的块级 padding 差异
415
+ // (lite 单行态 4/4、升格态 2/0),结果只反映「内容占了几行」。
416
+ // 升降格判定只读行数与 fitsInlineWidth,不做像素减法——见 lite-expand.ts。
417
+ var lineCount = Math.max(1, Math.round((natural - EDITOR_PADDING_BLOCK) / LINE_HEIGHT));
418
+ // 多行内容必然放不进单行态宽度,省掉一次 Range 测量
419
+ var fitsInlineWidth = lineCount <= 1 ? measureFitsInlineWidth(el) : false;
341
420
  setScrollHeight(function (prev) {
342
421
  return prev === clamped ? prev : clamped;
343
422
  });
344
- (_onHeightChangeRef$cu = onHeightChangeRef.current) === null || _onHeightChangeRef$cu === void 0 || _onHeightChangeRef$cu.call(onHeightChangeRef, natural, overflow);
423
+ (_onHeightChangeRef$cu = onHeightChangeRef.current) === null || _onHeightChangeRef$cu === void 0 || _onHeightChangeRef$cu.call(onHeightChangeRef, {
424
+ height: natural,
425
+ lineCount: lineCount,
426
+ fitsInlineWidth: fitsInlineWidth,
427
+ overflow: overflow
428
+ });
345
429
  }, [getViewport, minHeightPx, maxHeightPx, rowContentPx]);
346
430
  var shouldShowPlaceholder = useCallback(function (el) {
347
431
  if (!isEditorEmpty(el)) return false;
@@ -389,7 +473,7 @@ export var ComposerEditor = /*#__PURE__*/forwardRef(function ComposerEditor(_ref
389
473
  * 它不归 React 管(editor 的 children 由 contenteditable 自治),由 fireChange
390
474
  * 按结构谓词增删/挪位;`getPlainText` 会整棵子树跳过,所以不进 value / 剪贴板。
391
475
  *
392
- * 末尾的「TAB 采纳」小块是 hint 文本的**兄弟节点**(不是子节点):hint 的
476
+ * 末尾的「按 TAB 键填入」小块是 hint 文本的**兄弟节点**(不是子节点):hint 的
393
477
  * textContent 必须保持纯提示文案(采纳时直接落成正文,调试面板也按它读)。 */
394
478
  var hintNodeRef = useRef(null);
395
479
  var hintAcceptNodeRef = useRef(null);
@@ -437,7 +521,7 @@ export var ComposerEditor = /*#__PURE__*/forwardRef(function ComposerEditor(_ref
437
521
  var cur = host.nextSibling;
438
522
  while (cur) {
439
523
  var _cur$textContent;
440
- // 跳过 hint 自身与它的「TAB 采纳」小块:上一轮若排到了锚点前面,
524
+ // 跳过 hint 自身与它的「按 TAB 键填入」小块:上一轮若排到了锚点前面,
441
525
  // 这里顺手挪回末尾
442
526
  if (cur === node || cur === accept) {
443
527
  cur = cur.nextSibling;
@@ -466,7 +550,7 @@ export var ComposerEditor = /*#__PURE__*/forwardRef(function ComposerEditor(_ref
466
550
  if (node.parentNode !== parent || node.previousSibling !== anchor) {
467
551
  parent.insertBefore(node, anchor.nextSibling);
468
552
  }
469
- /* 「TAB 采纳」小块紧跟 hint 文案之后(同一套行内流),顺序必须是
553
+ /* 「按 TAB 键填入」小块紧跟 hint 文案之后(同一套行内流),顺序必须是
470
554
  * hint → 小块:caret 的合法落点只到 hint 之前,块本身
471
555
  * contentEditable=false,不会成为落点。 */
472
556
  if (accept.parentNode !== parent || accept.previousSibling !== node) {
@@ -576,14 +660,14 @@ export var ComposerEditor = /*#__PURE__*/forwardRef(function ComposerEditor(_ref
576
660
  recomputeTriggerRef.current = recomputeTrigger;
577
661
 
578
662
  /* ─────────────────────────────────────
579
- * 采纳 hint(Tab / 点击「TAB 采纳」小块)
663
+ * 采纳 hint(Tab / 点击「按 TAB 键填入」小块)
580
664
  *
581
665
  * hint 只是结构投影(不进 value);caret 恰好停在 chip 与 hint 之间
582
666
  * (= 内容末尾)时按 Tab,表示用户接受这段模板,于是把提示文案落成正文:
583
667
  * chip 之后出现内容 → 结构谓词不再命中 → 灰字自动移除,onChange 抛出的
584
668
  * value 里带上这段文案,与用户自己敲进去的效果一致。
585
669
  *
586
- * 鼠标点末尾的「TAB 采纳」小块走**同一条链路**,只是带 `force`:
670
+ * 鼠标点末尾的「按 TAB 键填入」小块走**同一条链路**,只是带 `force`:
587
671
  * 不要求点击前 caret 就停在 hint 之前,先把 caret 归位到 chip 右侧再落。
588
672
  * ───────────────────────────────────── */
589
673
  var acceptHintAsText = useCallback(function (options) {
@@ -680,6 +764,11 @@ export var ComposerEditor = /*#__PURE__*/forwardRef(function ComposerEditor(_ref
680
764
  }
681
765
  }
682
766
  _insertChip(data, el, cached);
767
+ /* 插入 chip 同样要把 caret 带回可视区:工具栏「技能」菜单 / 外部
768
+ * insertSkill 触发时焦点已离开 editor,浏览器不会替我们滚动页内
769
+ * ScrollArea(focus() 只保证元素本身进视口)。文本顶到高度上限后,
770
+ * 新 chip 会整块落在可视区外,用户得再手动往下滚才看得到。 */
771
+ requestScrollCaretIntoView();
683
772
  },
684
773
  removeChip: removeChip,
685
774
  replaceTriggerWithChip: function replaceTriggerWithChip(data) {
@@ -689,6 +778,7 @@ export var ComposerEditor = /*#__PURE__*/forwardRef(function ComposerEditor(_ref
689
778
  if (!probe) {
690
779
  // 无活动 trigger,退化为最近光标处插入
691
780
  _insertChip(data, el, lastEditorRangeRef.current);
781
+ requestScrollCaretIntoView();
692
782
  return;
693
783
  }
694
784
  // 选中 trigger + query 整段,删掉再插 chip
@@ -704,6 +794,7 @@ export var ComposerEditor = /*#__PURE__*/forwardRef(function ComposerEditor(_ref
704
794
  triggerRef.current = null;
705
795
  onTriggerChange === null || onTriggerChange === void 0 || onTriggerChange(null);
706
796
  _insertChip(data, el);
797
+ requestScrollCaretIntoView();
707
798
  },
708
799
  insertSerializedAtEnd: function insertSerializedAtEnd(value, nextChips, options) {
709
800
  var el = editorRef.current;
@@ -1003,7 +1094,7 @@ export var ComposerEditor = /*#__PURE__*/forwardRef(function ComposerEditor(_ref
1003
1094
  if (onTriggerKeyDown(e) === true) return;
1004
1095
  }
1005
1096
 
1006
- /* Tab 采纳 hint:caret 停在 chip 与派生 hint 之间(内容末尾)时,把提示
1097
+ /* Tab 填入 hint:caret 停在 chip 与派生 hint 之间(内容末尾)时,把提示
1007
1098
  * 文案落成正文。浮层展开时 Tab 已被父组件优先用于选中技能(上面已 return);
1008
1099
  * 走到这里说明浮层没开 / 没有命中,才轮到 hint 采纳。带修饰键的
1009
1100
  * Tab(Shift+Tab 反向焦点、Ctrl/Cmd+Tab 切窗口)不拦,保持浏览器默认。 */
@@ -1128,7 +1219,7 @@ export var ComposerEditor = /*#__PURE__*/forwardRef(function ComposerEditor(_ref
1128
1219
  // shift+click 是扩选,不劫持
1129
1220
  if (e.shiftKey) return;
1130
1221
 
1131
- /* 「TAB 采纳」小块:点它等价于按 Tab(同一条采纳链路),且不要求点击前
1222
+ /* 「按 TAB 键填入」小块:点它等价于按 Tab(同一条采纳链路),且不要求点击前
1132
1223
  * caret 就停在 hint 之前。在 mousedown 阶段接管 + preventDefault,
1133
1224
  * 原生 caret 一帧都不会落到 hint 之后。 */
1134
1225
  if (e.target instanceof Element && e.target.closest(COMPOSER_HINT_ACCEPT_SELECTOR)) {
@@ -271,7 +271,7 @@ onAfterMutate) {
271
271
  setChips(next);
272
272
  }
273
273
 
274
- /* 默认保持原行为(粘贴 / Tab 采纳都发生在已聚焦的编辑器里,focus 是幂等的)。
274
+ /* 默认保持原行为(粘贴 / Tab 填入都发生在已聚焦的编辑器里,focus 是幂等的)。
275
275
  * 首屏还原内容必须显式关掉:mount 期间 focus() 会连带触发页面滚动。 */
276
276
  if ((options === null || options === void 0 ? void 0 : options.focus) !== false) {
277
277
  requestAnimationFrame(function () {
@@ -45,7 +45,8 @@ export interface ComposerRef {
45
45
  * 命令式:在当前光标位置插入一个 skill chip。
46
46
  * 用于"外部面板(Welcome Card / Suggestions)点 skill 后塞进 composer"等场景;
47
47
  * 内部 toolbar 按钮 / `/` trigger 已自带插入路径,无需调用此方法。
48
- * 调用后会自动 focus editor,光标停在 chip 之后。
48
+ * 调用后会自动 focus editor,光标停在 chip 之后;内容超出可视区时会把
49
+ * 输入区滚动到新 chip(与 `insertContent` 一致)。
49
50
  *
50
51
  * 返回插入的 chip 实例 id,可用于后续 `updateChipData` 更新状态。
51
52
  */
@@ -16,9 +16,10 @@ import { Message } from "../message";
16
16
  import Popover from "../popover";
17
17
  import SkillSlot from "../skill-slot";
18
18
  import Tooltip from "../tooltip";
19
- import { COMPOSER_EDITOR_MAX_ROWS_PX, ComposerEditor } from "./editor";
19
+ import { COMPOSER_EDITOR_HEIGHT_CAP_EXIT_PX, COMPOSER_EDITOR_MAX_ROWS_PX, ComposerEditor } from "./editor";
20
20
  import { chipHasEditableParams, isMentionChip } from "./inline-ref";
21
21
  import { buildInsertPayload, createSkillChipData } from "./insert";
22
+ import { resolveComposerLiteExpanded } from "./lite-expand";
22
23
  import { rawValueToSegments, segmentsHasContent } from "./segments";
23
24
  import "./style";
24
25
  import { COMPOSER_SKILL_MENU_DENSITY_CAP_PX, filterSkillsByQuery, resolveComposerSkillMenuMaxHeight, resolveComposerSkillMenuWidth, shouldOpenSlashTriggerMenu } from "./utils";
@@ -184,34 +185,44 @@ export var Composer = /*#__PURE__*/forwardRef(function Composer(_ref, ref) {
184
185
  _useState12 = _slicedToArray(_useState11, 2),
185
186
  fullExpanded = _useState12[0],
186
187
  setFullExpanded = _useState12[1];
187
- /** ComposerEditor 反馈的 editor 自然高度(offsetHeight,未 clamp),用于 lite 升格判断 */
188
+ /** ComposerEditor 反馈的 editor 自然高度(未 clamp),用于 10 行上限判定 */
188
189
  var _useState13 = useState(0),
189
190
  _useState14 = _slicedToArray(_useState13, 2),
190
191
  editorHeight = _useState14[0],
191
192
  setEditorHeight = _useState14[1];
192
- /** 内容已超过 10 行,或整框 50vh 把编辑器挤到放不下当前内容 */
193
- var _useState15 = useState(false),
193
+ /** ComposerEditor 反馈的内容行数(含软换行),lite 升降格的主判据 */
194
+ var _useState15 = useState(0),
194
195
  _useState16 = _slicedToArray(_useState15, 2),
195
- atMax = _useState16[0],
196
- setAtMax = _useState16[1];
196
+ editorLineCount = _useState16[0],
197
+ setEditorLineCount = _useState16[1];
198
+ /** 内容能否放进单行态宽度;false = 处于「两种形态都合理」的中间区 */
199
+ var _useState17 = useState(true),
200
+ _useState18 = _slicedToArray(_useState17, 2),
201
+ editorFitsInlineWidth = _useState18[0],
202
+ setEditorFitsInlineWidth = _useState18[1];
203
+ /** 内容已超过 10 行,或整框 50vh 把编辑器挤到放不下当前内容 */
204
+ var _useState19 = useState(false),
205
+ _useState20 = _slicedToArray(_useState19, 2),
206
+ atMax = _useState20[0],
207
+ setAtMax = _useState20[1];
197
208
  var fileInputRef = useRef(null);
198
209
  var editorRef = useRef(null);
199
210
  var boxRef = useRef(null);
200
211
  var skillTriggerRef = useRef(null);
201
212
  var triggerAnchorRef = useRef(null);
202
- var _useState17 = useState(0),
203
- _useState18 = _slicedToArray(_useState17, 2),
204
- skillMenuCrossAxis = _useState18[0],
205
- setSkillMenuCrossAxis = _useState18[1];
206
- /** composer box 实宽;技能菜单比它略窄。 */
207
- var _useState19 = useState(0),
208
- _useState20 = _slicedToArray(_useState19, 2),
209
- boxWidth = _useState20[0],
210
- setBoxWidth = _useState20[1];
211
- var _useState21 = useState(COMPOSER_SKILL_MENU_DENSITY_CAP_PX),
213
+ var _useState21 = useState(0),
212
214
  _useState22 = _slicedToArray(_useState21, 2),
213
- skillMenuMaxHeight = _useState22[0],
214
- setSkillMenuMaxHeight = _useState22[1];
215
+ skillMenuCrossAxis = _useState22[0],
216
+ setSkillMenuCrossAxis = _useState22[1];
217
+ /** composer box 实宽;技能菜单比它略窄。 */
218
+ var _useState23 = useState(0),
219
+ _useState24 = _slicedToArray(_useState23, 2),
220
+ boxWidth = _useState24[0],
221
+ setBoxWidth = _useState24[1];
222
+ var _useState25 = useState(COMPOSER_SKILL_MENU_DENSITY_CAP_PX),
223
+ _useState26 = _slicedToArray(_useState25, 2),
224
+ skillMenuMaxHeight = _useState26[0],
225
+ setSkillMenuMaxHeight = _useState26[1];
215
226
  useLayoutEffect(function () {
216
227
  var el = boxRef.current;
217
228
  if (!el) return undefined;
@@ -245,10 +256,10 @@ export var Composer = /*#__PURE__*/forwardRef(function Composer(_ref, ref) {
245
256
  preventScroll: true
246
257
  });
247
258
  }, [disabled]);
248
- var _useState23 = useState(null),
249
- _useState24 = _slicedToArray(_useState23, 2),
250
- paramEdit = _useState24[0],
251
- setParamEdit = _useState24[1];
259
+ var _useState27 = useState(null),
260
+ _useState28 = _slicedToArray(_useState27, 2),
261
+ paramEdit = _useState28[0],
262
+ setParamEdit = _useState28[1];
252
263
  var openParamPanel = useCallback(function (chipId) {
253
264
  if (!renderParamPanel) return;
254
265
  requestAnimationFrame(function () {
@@ -396,26 +407,65 @@ export var Composer = /*#__PURE__*/forwardRef(function Composer(_ref, ref) {
396
407
  console.warn('[Composer] 检测到受控 attachments,但未提供 onAttachFiles。' + '内置文件入口(按钮 / 拖入 / 粘贴)将无法把文件写入 attachments。' + '若需让用户继续添加附件,请传入 onAttachFiles 接管 File → Attachment 转换。');
397
408
  }
398
409
 
399
- /* ---- lite 升格判断 ----
400
- * 基准 32px = lite 单行 SCSS 锁定的 min-height(与 ComposerEditor minRows=1
401
- * 算出的 minHeightPx 一致)。直接用常量当基准,不依赖 ResizeObserver 第一次
402
- * report——初次 layout 时序不稳,RO 第一帧可能拿到 0 / 大值,会把基准带偏,
403
- * 后续就永远在错的基准上判定升格。
410
+ /* ---- lite 升格 / 降格(滞回) ----
411
+ * 两种形态的可输入宽度不同,存在「两种宽度都放得下」的中间区。判定只在
412
+ * 越过区间边界时切换,落在中间区保持现状——否则「形态 → 宽度 → 行数 →
413
+ * 形态」会闭合成正反馈,临界点反复振荡。详见 lite-expand.ts。
404
414
  *
405
- * editorHeight 来自 editor.offsetHeight 自然高度(未 clamp);超过基准 2px
406
- * 即视为产生第二行,触发升格。 */
415
+ * 输入只有 ComposerEditor 实测的两个量:行数、能否放进单行态宽度。
416
+ * 不再有任何像素阈值。 */
407
417
  useLayoutEffect(function () {
408
- if (variant !== 'lite') return;
409
- if (!editorHeight) return;
410
- if (!expanded && editorHeight - 32 > 2) {
411
- setExpanded(true);
412
- return;
413
- }
414
- if (expanded && editorHeight - 32 <= 2 && attachments.length === 0) {
415
- setExpanded(false);
416
- setAtMax(false);
418
+ if (variant !== 'lite' || !editorLineCount) return;
419
+ var nextExpanded = resolveComposerLiteExpanded({
420
+ expanded: expanded,
421
+ lineCount: editorLineCount,
422
+ fitsInlineWidth: editorFitsInlineWidth,
423
+ attachmentCount: attachments.length
424
+ });
425
+ if (nextExpanded === expanded) return;
426
+ setExpanded(nextExpanded);
427
+ if (!nextExpanded) setAtMax(false);
428
+ }, [variant, expanded, editorLineCount, editorFitsInlineWidth, attachments.length]);
429
+
430
+ /* ---- 形态切换的过渡窗口 ----
431
+ * 切换时 padding 和高度会同时动:padding 变化先让文本重排(中间区可能
432
+ * 从 2 行变回 1 行),而高度过渡会去追一个「过渡中」的内容高度,追上后
433
+ * 又得回落,观感就是框先鼓起再瘪下去。
434
+ *
435
+ * 这里在切换后开一个 280ms 的窗口,给高度过渡加 padding 时长(150ms)
436
+ * 的延迟:让 padding 先跑完、内容行数定下来,高度再一次性到最终值。
437
+ * 窗口结束后恢复正常过渡。 */
438
+ var previousExpandedRef = useRef(expanded);
439
+ var layoutSwitchTimerRef = useRef(null);
440
+ var _useState29 = useState(false),
441
+ _useState30 = _slicedToArray(_useState29, 2),
442
+ layoutSwitching = _useState30[0],
443
+ setLayoutSwitching = _useState30[1];
444
+ useLayoutEffect(function () {
445
+ if (previousExpandedRef.current === expanded) return;
446
+ previousExpandedRef.current = expanded;
447
+ setLayoutSwitching(true);
448
+ // 定时器自己管,不走 effect cleanup:StrictMode 下 effect 会「执行 →
449
+ // 清理 → 再执行」,第二次因 ref 已更新而提前 return,若 timer 建在
450
+ // cleanup 里就会被清掉却不再重建,layoutSwitching 会永远卡在 true。
451
+ if (layoutSwitchTimerRef.current !== null) {
452
+ window.clearTimeout(layoutSwitchTimerRef.current);
417
453
  }
418
- }, [variant, expanded, editorHeight, attachments.length]);
454
+ layoutSwitchTimerRef.current = window.setTimeout(function () {
455
+ layoutSwitchTimerRef.current = null;
456
+ setLayoutSwitching(false);
457
+ // padding 0.15s + 高度 0.1s,留 30ms 余量
458
+ }, 280);
459
+ }, [expanded]);
460
+ // 卸载时兜底清理(挂载阶段不会建 timer,StrictMode 的二次执行不受影响)
461
+ useEffect(function () {
462
+ return function () {
463
+ if (layoutSwitchTimerRef.current !== null) {
464
+ window.clearTimeout(layoutSwitchTimerRef.current);
465
+ layoutSwitchTimerRef.current = null;
466
+ }
467
+ };
468
+ }, []);
419
469
 
420
470
  // 清空时回到 lite 单行
421
471
  useEffect(function () {
@@ -432,8 +482,28 @@ export var Composer = /*#__PURE__*/forwardRef(function Composer(_ref, ref) {
432
482
  }
433
483
  }, [variant, expanded]);
434
484
 
435
- // 内容已顶满(满 10 行或整框 50vh 溢出)时展开态没有可切换的高度。
436
- var atHeightCap = atMax || editorHeight >= COMPOSER_EDITOR_MAX_ROWS_PX;
485
+ /* 内容是否顶满 10 行高(此时缩放按钮隐藏、右侧让位回收、内容区变宽)。
486
+ *
487
+ * 用滞回而不是直接比大小:顶满后内容区变宽,同一段文本可能从 10 行重排
488
+ * 成 9 行。若退出条件也看 10 行,就会「顶满 → 变宽 → 9 行 → 退出 →
489
+ * 变窄 → 10 行 → 顶满」来回。进入看 10 行,退出要回落到 9 行以下。 */
490
+ var _useState31 = useState(false),
491
+ _useState32 = _slicedToArray(_useState31, 2),
492
+ heightCapReached = _useState32[0],
493
+ setHeightCapReached = _useState32[1];
494
+ useLayoutEffect(function () {
495
+ if (!editorHeight) return;
496
+ setHeightCapReached(function (prev) {
497
+ return prev ? editorHeight >= COMPOSER_EDITOR_HEIGHT_CAP_EXIT_PX : editorHeight >= COMPOSER_EDITOR_MAX_ROWS_PX;
498
+ });
499
+ }, [editorHeight]);
500
+
501
+ /* atMax 覆盖「内容没到 10 行,但整框已被 50vh 挤到放不下」:这时同样
502
+ * 没有可展开的空间,按钮也要隐藏。这一支不能省,否则矮屏 + 多附件时
503
+ * 会出现「按钮可点但点了没反应」。 */
504
+ var atHeightCap = atMax || heightCapReached;
505
+
506
+ // 顶满后展开态没有可切换的高度。
437
507
  useEffect(function () {
438
508
  if (atHeightCap) setFullExpanded(false);
439
509
  }, [atHeightCap]);
@@ -630,10 +700,10 @@ export var Composer = /*#__PURE__*/forwardRef(function Composer(_ref, ref) {
630
700
  * 不夺回焦点时 Enter 会再次激活按钮而不是发送 */
631
701
  (_editorRef$current15 = editorRef.current) === null || _editorRef$current15 === void 0 || _editorRef$current15.focus();
632
702
  };
633
- var _useState25 = useState(false),
634
- _useState26 = _slicedToArray(_useState25, 2),
635
- fileDragOver = _useState26[0],
636
- setFileDragOver = _useState26[1];
703
+ var _useState33 = useState(false),
704
+ _useState34 = _slicedToArray(_useState33, 2),
705
+ fileDragOver = _useState34[0],
706
+ setFileDragOver = _useState34[1];
637
707
  var composerBoxFileDragAttrs = fileDragOver ? {
638
708
  'data-odn-composer-file-drag': ''
639
709
  } : {};
@@ -1172,8 +1242,14 @@ export var Composer = /*#__PURE__*/forwardRef(function Composer(_ref, ref) {
1172
1242
  onTriggerChange: setTriggerInfo,
1173
1243
  onTriggerKeyDown: handleTriggerKeyDown,
1174
1244
  onPasteFiles: addFilesFromList,
1175
- onHeightChange: function onHeightChange(height, overflow) {
1245
+ onHeightChange: function onHeightChange(_ref7) {
1246
+ var height = _ref7.height,
1247
+ lineCount = _ref7.lineCount,
1248
+ fitsInlineWidth = _ref7.fitsInlineWidth,
1249
+ overflow = _ref7.overflow;
1176
1250
  setEditorHeight(height);
1251
+ setEditorLineCount(lineCount);
1252
+ setEditorFitsInlineWidth(fitsInlineWidth);
1177
1253
  // 升格期间禁止 atMax 触发——升格瞬间 ScrollArea root height 与 editor
1178
1254
  // scrollHeight 同步过渡,中间帧可能短暂 overflow,不能让 scrollbar 闪
1179
1255
  if (expanded || !isLite) setAtMax(overflow);
@@ -1253,6 +1329,7 @@ export var Composer = /*#__PURE__*/forwardRef(function Composer(_ref, ref) {
1253
1329
  "data-odn-composer-full-expanded": fullExpanded ? '' : undefined,
1254
1330
  "data-odn-composer-atmax": atMax ? '' : undefined,
1255
1331
  "data-odn-composer-height-cap": atHeightCap ? '' : undefined,
1332
+ "data-odn-composer-layout-switching": layoutSwitching ? '' : undefined,
1256
1333
  "data-odn-composer-disabled": disabled || undefined,
1257
1334
  "data-odn-composer-spacing": spacing === 'drawer' ? 'drawer' : undefined,
1258
1335
  "aria-disabled": disabled || undefined,
@@ -1269,15 +1346,17 @@ export var Composer = /*#__PURE__*/forwardRef(function Composer(_ref, ref) {
1269
1346
  onDragOver: handleComposerDragOver,
1270
1347
  onDragLeave: handleComposerDragLeave,
1271
1348
  onDrop: handleComposerDrop
1272
- }), triggerMenu, showExpandBtn && /*#__PURE__*/React.createElement(Tooltip, {
1349
+ }), triggerMenu, /*#__PURE__*/React.createElement(Tooltip, {
1273
1350
  popup: fullExpandLabel,
1274
1351
  placement: "top"
1275
1352
  }, /*#__PURE__*/React.createElement("button", {
1276
1353
  type: "button",
1277
1354
  tabIndex: -1,
1278
1355
  "data-odn-composer-expand-btn": true,
1356
+ "data-odn-composer-expand-btn-hidden": showExpandBtn ? undefined : '',
1279
1357
  "aria-label": fullExpandLabel,
1280
1358
  "aria-expanded": fullExpanded,
1359
+ "aria-hidden": showExpandBtn ? undefined : true,
1281
1360
  onClick: function onClick() {
1282
1361
  return setFullExpanded(function (current) {
1283
1362
  return !current;
@@ -0,0 +1,44 @@
1
+ /**
2
+ * lite 形态的升格 / 降格判定(滞回)。
3
+ *
4
+ * 为什么会有「中间区」
5
+ * ─────────────────
6
+ * lite 两种形态的可输入宽度不同:单行态要给左下 / 右下按钮让位
7
+ * (--odn-composer-editor-inline-inset),升格态按钮移到底栏、只给右上角
8
+ * 缩放按钮留位,内容区更宽。同一段文本因此可能落在三个区里:
9
+ *
10
+ * A 区 单行态一行、升格态一行 → 只该用单行态(窄宽度够用)
11
+ * 中间区 单行态两行、升格态一行 → 两种宽度都放得下,都合理
12
+ * B 区 单行态两行、升格态两行以上 → 只该用升格态(窄宽度装不下)
13
+ *
14
+ * 中间区必须保持进入前的状态
15
+ * ─────────────────
16
+ * 如果中间区也参与判定,就会闭合成正反馈:
17
+ *
18
+ * 升格 → 变宽 → 两行变一行 → 判「该降格」→ 降格 → 变窄 → 又两行
19
+ * → 判「该升格」→ …… 以动画帧频率反复,表现为输入框持续闪烁跳动,
20
+ * 直到文本长到「升格后仍然 ≥2 行」才停。
21
+ *
22
+ * 因此只在**越过区间边界**时切换,落在中间区一律保持现状:
23
+ *
24
+ * 当前 A:出现第二行 → 升格(中间区 / B 区都属于这一侧)
25
+ * 当前 B:回到一行,且这行在 A 宽度下也放得下 → 降格
26
+ * 放不下说明还在中间区,保持升格——切回 A 会被挤成两行,
27
+ * 而单行态高度锁死 + overflow hidden 会把第二行裁掉。
28
+ *
29
+ * 判据只有「行数」和「能否放进单行态宽度」,都由 ComposerEditor 实测上报,
30
+ * 与像素高度、字体度量无关。区间边界是量出来的,不依赖任何需要随字体 /
31
+ * 宽度 / 语言反复调参的固定阈值、冷却时间或方向性门禁。
32
+ */
33
+ export interface ResolveComposerLiteExpandedOptions {
34
+ /** 当前是否已升格。 */
35
+ expanded: boolean;
36
+ /** 内容占用的行数(含软换行),由 ComposerEditor 上报。 */
37
+ lineCount: number;
38
+ /** 内容能否放进单行态可用宽度(仅 lineCount <= 1 时有意义)。 */
39
+ fitsInlineWidth: boolean;
40
+ /** 附件数量:有附件时按钮要在底栏,保持升格,避免和附件条打架。 */
41
+ attachmentCount: number;
42
+ }
43
+ /** 返回目标升格态;与入参 `expanded` 相同表示维持现状。 */
44
+ export declare function resolveComposerLiteExpanded({ expanded, lineCount, fitsInlineWidth, attachmentCount, }: ResolveComposerLiteExpandedOptions): boolean;
@@ -0,0 +1,50 @@
1
+ /**
2
+ * lite 形态的升格 / 降格判定(滞回)。
3
+ *
4
+ * 为什么会有「中间区」
5
+ * ─────────────────
6
+ * lite 两种形态的可输入宽度不同:单行态要给左下 / 右下按钮让位
7
+ * (--odn-composer-editor-inline-inset),升格态按钮移到底栏、只给右上角
8
+ * 缩放按钮留位,内容区更宽。同一段文本因此可能落在三个区里:
9
+ *
10
+ * A 区 单行态一行、升格态一行 → 只该用单行态(窄宽度够用)
11
+ * 中间区 单行态两行、升格态一行 → 两种宽度都放得下,都合理
12
+ * B 区 单行态两行、升格态两行以上 → 只该用升格态(窄宽度装不下)
13
+ *
14
+ * 中间区必须保持进入前的状态
15
+ * ─────────────────
16
+ * 如果中间区也参与判定,就会闭合成正反馈:
17
+ *
18
+ * 升格 → 变宽 → 两行变一行 → 判「该降格」→ 降格 → 变窄 → 又两行
19
+ * → 判「该升格」→ …… 以动画帧频率反复,表现为输入框持续闪烁跳动,
20
+ * 直到文本长到「升格后仍然 ≥2 行」才停。
21
+ *
22
+ * 因此只在**越过区间边界**时切换,落在中间区一律保持现状:
23
+ *
24
+ * 当前 A:出现第二行 → 升格(中间区 / B 区都属于这一侧)
25
+ * 当前 B:回到一行,且这行在 A 宽度下也放得下 → 降格
26
+ * 放不下说明还在中间区,保持升格——切回 A 会被挤成两行,
27
+ * 而单行态高度锁死 + overflow hidden 会把第二行裁掉。
28
+ *
29
+ * 判据只有「行数」和「能否放进单行态宽度」,都由 ComposerEditor 实测上报,
30
+ * 与像素高度、字体度量无关。区间边界是量出来的,不依赖任何需要随字体 /
31
+ * 宽度 / 语言反复调参的固定阈值、冷却时间或方向性门禁。
32
+ */
33
+
34
+ /** 返回目标升格态;与入参 `expanded` 相同表示维持现状。 */
35
+ export function resolveComposerLiteExpanded(_ref) {
36
+ var expanded = _ref.expanded,
37
+ lineCount = _ref.lineCount,
38
+ fitsInlineWidth = _ref.fitsInlineWidth,
39
+ attachmentCount = _ref.attachmentCount;
40
+ if (!expanded) {
41
+ // 当前 A 态:单行态宽度下已经换行 → 进入中间区或 B 区,升格
42
+ return lineCount > 1;
43
+ }
44
+ // 当前 B 态:仍然多行 = 还在 B 区
45
+ if (lineCount > 1) return true;
46
+ // 只剩一行,但这一行在单行态宽度下放不下 = 中间区,保持升格
47
+ if (!fitsInlineWidth) return true;
48
+ // 真正的 A 区:有附件时按钮仍需要底栏,保持升格
49
+ return attachmentCount > 0;
50
+ }
@@ -26,12 +26,23 @@
26
26
  padding: 0 24px 24px;
27
27
  }
28
28
 
29
- [data-odn-composer][data-odn-composer-variant=full],
30
- [data-odn-composer][data-odn-composer-variant=lite][data-odn-composer-expanded] {
29
+ /* 右上角缩放按钮的让位宽度(展开态的编辑器右侧要避开它)。
30
+ * lite 单行态不用这个值(左右按钮在行内,见 --odn-composer-editor-inline-inset)。 */
31
+ [data-odn-composer][data-odn-composer-variant=full] {
31
32
  --odn-composer-expand-control-offset: 38px;
32
33
  }
33
34
 
34
- /* 满 10 行或溢出后缩放按钮隐藏,右上角不必再给按钮留位。 */
35
+ /* 用 :not() 让 height-cap 的 6px 能盖住 lite 展开态的 38px(否则升格态
36
+ * 3 个属性选择器的优先级会锁死右侧让位,按钮隐藏后宽度也不回收)。 */
37
+ [data-odn-composer][data-odn-composer-variant=lite][data-odn-composer-expanded]:not([data-odn-composer-height-cap]) {
38
+ --odn-composer-expand-control-offset: 38px;
39
+ }
40
+
41
+ /* 满 10 行或溢出后缩放按钮隐藏,右侧不必再给按钮留位,内容区随之变宽。
42
+ *
43
+ * 这条规则让 editor 内容宽度随状态变化(右侧 38px → 6px)。宽度变化会影响
44
+ * 换行行数,行数又参与 atMax 与升降格判定,因此「顶满」这一侧加了滞回:
45
+ * 进入看 10 行,退出要回落到 9 行以下(见 index.tsx · heightCapReached)。 */
35
46
  [data-odn-composer][data-odn-composer-height-cap] {
36
47
  --odn-composer-expand-control-offset: 6px;
37
48
  }
@@ -76,12 +87,22 @@
76
87
  color: var(--odn-color-solid-black-8);
77
88
  background: transparent;
78
89
  cursor: pointer;
90
+ /* 常驻 DOM、靠 hidden 属性切显隐:临界点(刚满 10 行)不再硬切,
91
+ * 与右侧让位回收同步淡出/淡入。 */
92
+ transition: opacity 0.15s ease, transform 0.15s ease, color 0.15s ease, background-color 0.15s ease;
79
93
  }
80
94
  [data-odn-composer-expand-btn]:hover {
81
95
  color: var(--odn-color-solid-black-12);
82
96
  background: var(--odn-color-black-3);
83
97
  }
84
98
 
99
+ /* 隐藏态:内容顶满 / lite 单行态不需要它时收起而不是卸载。 */
100
+ [data-odn-composer-expand-btn][data-odn-composer-expand-btn-hidden] {
101
+ opacity: 0;
102
+ transform: scale(0.85);
103
+ pointer-events: none;
104
+ }
105
+
85
106
  [data-odn-composer-skill-trigger] {
86
107
  display: inline-flex;
87
108
  }
@@ -95,6 +116,11 @@
95
116
  * box 本身 transition min-height(从 52 → 72),textarea 让位 padding 过渡。
96
117
  * ----------------------------------------------------------------- */
97
118
  [data-odn-composer][data-odn-composer-variant=lite] {
119
+ /* 单行态左右按钮让位宽度(左下 tools / 右下 send 都是 absolute)。
120
+ * 它同时是 JS 判定「内容能否放进单行态」的基准宽度:升格态的可输入宽度
121
+ * 比这里宽(见下方「lite 升格态」段),两者之差就是 A / B 都合理的中间区。
122
+ * 改这个值不需要同步任何 JS 常量。 */
123
+ --odn-composer-editor-inline-inset: 40px;
98
124
  /* inner 需要留出 lite 单行态下 box 的最小高度,避免 absolute 脱流后父容器塌陷 */
99
125
  }
100
126
  [data-odn-composer][data-odn-composer-variant=lite] [data-odn-composer-inner] {
@@ -112,12 +138,18 @@
112
138
  * 极短 + 容器同时长高,体感是"瞬切"而不是"穿越"。 */
113
139
  transition: min-height 0.1s ease-out, padding-bottom 0.1s ease-out;
114
140
  }
115
- [data-odn-composer][data-odn-composer-variant=lite] [data-odn-composer-editor] {
116
- transition: padding 0.1s ease-out;
117
- }
118
141
  [data-odn-composer][data-odn-composer-variant=lite] .odn-composer-editor-scroll {
119
142
  transition: height 0.1s ease-out;
120
143
  }
144
+ [data-odn-composer][data-odn-composer-variant=lite] {
145
+ /* 形态切换窗口:padding 先跑完(文本重排、行数定下来),高度再动。
146
+ * 两个过渡同时跑的话,高度会先追上「过渡中」的内容高度再回落,观感是
147
+ * 框鼓起再瘪下去。窗口由 index.tsx 的 data-odn-composer-layout-switching
148
+ * 打开,padding 过渡(0.15s)结束后自动关闭。 */
149
+ }
150
+ [data-odn-composer][data-odn-composer-variant=lite][data-odn-composer-layout-switching] .odn-composer-editor-scroll {
151
+ transition: height 0.1s ease-out 0.15s;
152
+ }
121
153
  [data-odn-composer][data-odn-composer-variant=lite] [data-odn-composer-lite-tools],
122
154
  [data-odn-composer][data-odn-composer-variant=lite] [data-odn-composer-lite-send] {
123
155
  position: absolute;
@@ -137,8 +169,9 @@
137
169
  /* ─────────── lite 单行态(未升格) ───────────
138
170
  * 几何:
139
171
  * - ScrollArea root 物理锁 32 高(!important 覆盖 inline)
140
- * - editor padding-left/right: 40px = 32 按钮宽 + 8 视觉间距(略小于 box
141
- * 左右 10px padding,让文字略贴近按钮但不挤)
172
+ * - editor 水平让位用 --odn-composer-editor-inline-inset(40px = 按钮 32 +
173
+ * 间距 8);升格态更宽(6px / 38px),两个宽度之差就是「中间区」,
174
+ * 判定见 lite-expand.ts
142
175
  * - editor height 锁 32 + overflow hidden,避免初次 layout 飘动误升格
143
176
  * Transition:统一 100ms 同步,定义在 lite 父级 selector,见上方。 */
144
177
  [data-odn-composer][data-odn-composer-variant=lite]:not([data-odn-composer-expanded]) .odn-composer-editor-scroll {
@@ -148,8 +181,8 @@
148
181
  }
149
182
 
150
183
  [data-odn-composer][data-odn-composer-variant=lite]:not([data-odn-composer-expanded]) [data-odn-composer-editor] {
151
- padding-left: 40px;
152
- padding-right: 40px;
184
+ padding-left: var(--odn-composer-editor-inline-inset);
185
+ padding-right: var(--odn-composer-editor-inline-inset);
153
186
  padding-top: 4px;
154
187
  padding-bottom: 4px;
155
188
  margin-top: auto;
@@ -169,6 +202,14 @@
169
202
  width: 100%;
170
203
  }
171
204
 
205
+ /* 升格态不再引用 --odn-composer-editor-inline-inset,走基础规则的
206
+ * 6px / expand-control-offset(38px):按钮移到底栏后,左侧不再需要让位,
207
+ * 可输入宽度比单行态宽 36px —— 这是产品要的 A / B 两种宽度。
208
+ *
209
+ * 由此产生的「宽度差」会让同一段文本在两种形态下行数不同,也就是
210
+ * A / B 都算合理的**中间区**。中间区不能靠反复判定收口(会振荡),
211
+ * 由 lite-expand.ts 的滞回规则处理。这个变量保留给 JS 读取单行态
212
+ * 可用宽度基准(见 editor.tsx · measureFitsInlineWidth)。 */
172
213
  /* 升格态:box 必须回到正常流。
173
214
  * 单行态是 absolute + bottom: 0(贴 inner 底部,inner 只留 52px)。内容一旦
174
215
  * 变高(多行文本 / 派生 hint),绝对定位的 box 会向上溢出 inner 的占位、盖住
@@ -248,6 +289,10 @@
248
289
  outline: none;
249
290
  word-break: break-word;
250
291
  white-space: pre-wrap;
292
+ /* 内容宽度会随状态变化(lite 升降格、满 10 行回收按钮让位)。
293
+ * 过渡放在通用规则里:full 变体原来这一支没有过渡,右侧 padding 一帧
294
+ * 从 38 跳到 6,观感是硬切。 */
295
+ transition: padding 0.15s ease-out;
251
296
  }
252
297
 
253
298
  [data-odn-composer] [data-odn-composer-editor][data-odn-composer-editor-disabled] {
@@ -300,24 +345,26 @@
300
345
  * - hint 之后不允许落 caret(caret.ts · normalizeCollapsedCaretBeforeHint)
301
346
  * - 非内容:getPlainText 整棵子树跳过,不进 value / 剪贴板 / segments
302
347
  * - pre-wrap:skills 的模板文案可含换行
348
+ * - 文案色对齐 Figma 9625:15097(#898B8F,与末尾小块同一档)
303
349
  * ----------------------------------------------------------------- */
304
350
  [data-odn-composer] [data-odn-composer-skill-hint] {
305
351
  margin-left: 4px;
306
- color: var(--odn-color-black-8);
352
+ color: var(--odn-color-solid-black-9);
307
353
  pointer-events: none;
308
354
  user-select: none;
309
355
  white-space: pre-wrap;
310
356
  }
311
357
 
312
358
  /* ------------------------------------------------------------------
313
- * hint 末尾的「TAB 采纳」小块(点击 = 按 Tab 采纳,见 editor.tsx)
359
+ * hint 末尾的「按 TAB 键填入」小块(点击 = 按 Tab 填入,见 editor.tsx)
314
360
  *
315
361
  * 与 hint 文本是同级节点,一起增删。它不是正文:contentEditable=false、
316
362
  * getPlainText 整棵跳过,点它走 force 版 acceptHintAsText。
317
- * 尺寸对齐 Figma 9857:75425(62 × 22 / 圆角 6 / 内层键帽 28 × 16):
363
+ * 尺寸对齐 Figma 9857:75425(90 × 22 / 圆角 6 / 内层键帽 28 × 16):
318
364
  * - 编辑器固定 font-size 14 / line-height 24,块高 22 + top 1 → 视觉居中
319
365
  * 且不撑高行盒(改编辑器行高时要同步调这个 1px)
320
366
  * - 底色 black-2(5%)、键帽 bg-elevated + black-5(12%) 1px 描边
367
+ * - 「按」「键填入」与键帽之间 gap 3,左右内边距 4
321
368
  * ----------------------------------------------------------------- */
322
369
  [data-odn-composer] [data-odn-composer-hint-accept] {
323
370
  display: inline-flex;
@@ -327,7 +374,7 @@
327
374
  box-sizing: border-box;
328
375
  height: 22px;
329
376
  margin: 1px 0 0 4px;
330
- padding: 0 4px 0 3px;
377
+ padding: 0 4px;
331
378
  border-radius: 6px;
332
379
  background: var(--odn-color-black-2);
333
380
  color: var(--odn-color-solid-black-9);
@@ -356,7 +403,10 @@
356
403
  justify-content: center;
357
404
  box-sizing: border-box;
358
405
  height: 16px;
359
- padding: 0 4px;
406
+ /* 设计稿 28 宽:不同平台 Latin 字体宽度有差异(SF / PingFang),
407
+ * 用 min-width 锁住下限,字体更宽时仍可自然撑开,不裁字 */
408
+ min-width: 28px;
409
+ padding: 0 3px;
360
410
  border: 1px solid var(--odn-color-black-5);
361
411
  border-radius: 4px;
362
412
  /* 与 composer box 同为「浮在底层之上的面」,跟随主题变量而不是写死白色 */
@@ -366,6 +416,7 @@
366
416
  letter-spacing: 0;
367
417
  }
368
418
 
419
+ [data-odn-composer] [data-odn-composer-hint-accept-prefix],
369
420
  [data-odn-composer] [data-odn-composer-hint-accept-label] {
370
421
  font-size: 12px;
371
422
  line-height: 20px;
@@ -23,7 +23,7 @@ export declare const LINE_ATTR_NAME = "data-composer-line";
23
23
  export declare const COMPOSER_HINT_ATTR = "data-odn-composer-skill-hint";
24
24
  export declare const COMPOSER_HINT_SELECTOR = "[data-odn-composer-skill-hint]";
25
25
  /**
26
- * 派生 hint 末尾的「TAB 采纳」小块(可点击采纳)。
26
+ * 派生 hint 末尾的「按 TAB 键填入」小块(可点击采纳)。
27
27
  *
28
28
  * 与 hint 文本是**兄弟节点**(不是子节点):hint 自身的 `textContent` 必须
29
29
  * 保持纯提示文案——采纳时直接把这段文字落成正文,且 `getPlainText` /
@@ -40,7 +40,7 @@ export var COMPOSER_HINT_ATTR = 'data-odn-composer-skill-hint';
40
40
  export var COMPOSER_HINT_SELECTOR = "[".concat(COMPOSER_HINT_ATTR, "]");
41
41
 
42
42
  /**
43
- * 派生 hint 末尾的「TAB 采纳」小块(可点击采纳)。
43
+ * 派生 hint 末尾的「按 TAB 键填入」小块(可点击采纳)。
44
44
  *
45
45
  * 与 hint 文本是**兄弟节点**(不是子节点):hint 自身的 `textContent` 必须
46
46
  * 保持纯提示文案——采纳时直接把这段文字落成正文,且 `getPlainText` /
@@ -302,7 +302,7 @@ export function getPlainText(editor) {
302
302
  var out = '';
303
303
  var visit = function visit(node) {
304
304
  if (node instanceof HTMLElement) {
305
- // 派生 hint(含末尾的「TAB 采纳」小块)整棵子树都不是正文,直接跳过
305
+ // 派生 hint(含末尾的「按 TAB 键填入」小块)整棵子树都不是正文,直接跳过
306
306
  if (node.hasAttribute(COMPOSER_HINT_ATTR) || node.hasAttribute(COMPOSER_HINT_ACCEPT_ATTR)) return;
307
307
  var id = node.dataset[chipIdAttr];
308
308
  if (id) {
@@ -1,3 +1,3 @@
1
1
  import { svgData } from './svg-data';
2
2
  export type IconName = keyof typeof svgData;
3
- export declare const iconNames: ("code" | "data" | "form" | "link" | "map" | "menu" | "option" | "search" | "section" | "table" | "template" | "time" | "video" | "filter" | "image" | "stop" | "text" | "view" | "key" | "draggable" | "sort" | "replace" | "split" | "repeat" | "anchor" | "bold" | "send" | "group" | "heading" | "list" | "presentation" | "timer" | "location" | "copy" | "move" | "baseline" | "bottom" | "left" | "right" | "top" | "scroll" | "history" | "type" | "container" | "x" | "radius" | "power" | "custom" | "pointer" | "zoom-in" | "zoom-out" | "italic" | "square" | "underline" | "dot" | "ellipsis" | "sheet" | "toolbox" | "addressBook" | "AIFile" | "alarmClock" | "alert-circle" | "alert-circle-filled" | "alert-triangle" | "archive" | "arrow-down" | "arrow-up" | "arrow-up-right" | "arrowDown" | "arrowDown-filled" | "arrowLeft" | "arrowLeft-filled" | "arrowRight" | "arrowRight-filled" | "arrowUp" | "arrowUp-filled" | "asset-square" | "assetProtecting" | "autoAD-square-filled" | "bar-chart-3" | "bell" | "bell-filled" | "bidding" | "biz-cancel" | "biz-magic" | "biz-send" | "biz-stop" | "biz-time" | "bottom-filled" | "calendar" | "cancel" | "cancel-circle" | "cancel-circle-filled" | "card-distribute" | "channels" | "channels-square-filled" | "chart" | "chatBubble-filled" | "check" | "check-circle" | "check-circle-filled" | "checkBadge" | "chevron-down" | "chevron-left" | "chevron-right" | "clock" | "clock-4" | "comments" | "compare" | "copy-new" | "custom-filled" | "customColumn" | "dataAuth" | "dataBoard" | "dataBox" | "dataFolder" | "dataReport" | "dataReport-filled" | "dataRising" | "delete" | "deleteAD-filled" | "detect" | "doubleLeft" | "doubleLeft-filled" | "doubleRight" | "doubleRight-filled" | "down" | "down-bold" | "down-filled" | "download" | "download-1" | "download-2" | "download-filled" | "edit" | "exchange" | "exposure-filled" | "extendedConfig" | "fall-filled" | "file" | "file-code" | "file-filled" | "file-text" | "filter-filled" | "flag" | "flame" | "fold" | "folderZip" | "folderzip-bold" | "fullScreen" | "globe" | "guideBook" | "help-circle" | "help-circle-filled" | "histogram" | "hosting" | "hot" | "hot-filled" | "icon-outlined" | "idea" | "idea-bold" | "image-bold" | "image-filled" | "images" | "import" | "info" | "info-circle" | "info-circle-filled" | "keyword" | "LandingPage" | "languages" | "layers" | "left-bold" | "left-filled" | "leftFirst" | "leftFirst-filled" | "linkSquare" | "loader" | "lock" | "logout" | "magic" | "magic-filled" | "maxSize" | "menuLeft" | "menuLeft-bold" | "menuRight" | "menuRight-bold" | "message-circle-plus" | "messages-square" | "minigame-filled" | "miniProgram" | "minus" | "minus-circle" | "minus-circle-filled" | "mobile" | "mobile-filled" | "mobilePage" | "modify" | "modify-bold" | "moments-filled" | "more" | "more-vertical" | "mouse-pointer-click" | "multiCreate" | "mute" | "mutiImage" | "mutiImage-filled" | "mutiSelect" | "mutiSelect-filled" | "notepad" | "notepad-bold" | "offiaccount-filled" | "panel-left" | "panel-left-close" | "panel-right" | "paperclip" | "pause-filled" | "play-filled" | "playing" | "plus" | "plus-circle" | "plus-circle-filled" | "pointerLeft-filled" | "pointerRight-filled" | "puzzle" | "QRcode" | "qualification" | "quickFile" | "refresh" | "report" | "reportBook" | "right-bold" | "right-filled" | "rightLast" | "rightLast-filled" | "ringStruckture" | "rise-filled" | "rotate-ccw" | "save" | "search-bold" | "search-filled" | "searchAD" | "searchAD-filled" | "setting" | "share" | "shield" | "shield-filled" | "shop" | "shopping" | "sound" | "sparkle" | "sparkles" | "square-filled" | "star" | "star-filled" | "sticker" | "sticker-filled" | "subdivide" | "support-bold" | "tag" | "tag-filled" | "target" | "targeting" | "task" | "task-filled" | "templateBag" | "thumbDown" | "thumbDown-filled" | "thumbs-down" | "thumbs-up" | "thumbUp" | "thumbUp-filled" | "time-bold" | "top-filled" | "treeStructure" | "unfold" | "unfold-filled" | "up" | "up-bold" | "up-filled" | "user-add" | "user-circle" | "user-edit" | "user-pack" | "userList" | "userPack" | "users" | "users-bold" | "verify" | "videoBag-filled" | "videoScreenshot" | "viewMask" | "wallet" | "wand-sparkles" | "warning" | "warning-filled" | "wechatBubble" | "wechatBubble-filled" | "wechatSearch" | "writing" | "x-circle" | "zap" | "zoomIn" | "zoomOut" | "accessibility" | "baby" | "badge-info" | "badge-question-mark" | "circle-question-mark" | "closed-caption" | "contrast" | "ear" | "ear-off" | "eclipse" | "eye" | "eye-closed" | "eye-off" | "glasses" | "hand" | "life-buoy" | "moon" | "moon-star" | "person-standing" | "scan-eye" | "scan-search" | "speech" | "sun" | "sun-dim" | "sun-medium" | "sun-moon" | "activity" | "at-sign" | "award" | "badge" | "badge-alert" | "ban" | "bell-check" | "bell-dot" | "book-user" | "bookmark" | "bookmark-check" | "bookmark-minus" | "bookmark-off" | "bookmark-plus" | "bookmark-x" | "circle-user" | "circle-user-round" | "cog" | "contact" | "contact-round" | "cookie" | "credit-card" | "file-user" | "fingerprint-pattern" | "flag-off" | "frown" | "gift" | "hand-coins" | "handshake" | "heart-handshake" | "heart-minus" | "heart-plus" | "id-card" | "id-card-lanyard" | "inbox" | "key-round" | "key-square" | "link-2" | "log-in" | "log-out" | "mail" | "map-pin" | "map-pin-check" | "map-pin-check-inside" | "map-pin-house" | "map-pin-minus" | "map-pin-minus-inside" | "map-pin-pen" | "map-pin-plus" | "map-pin-plus-inside" | "map-pin-search" | "map-pin-x" | "map-pin-x-inside" | "map-pinned" | "message-circle-check" | "message-circle-x" | "message-square-check" | "notebook-tabs" | "pin" | "rotate-ccw-key" | "scan-face" | "scan-qr-code" | "settings" | "settings-2" | "share-2" | "shield-alert" | "shield-ban" | "shield-check" | "shield-cog" | "shield-cog-corner" | "shield-ellipsis" | "shield-half" | "shield-minus" | "shield-off" | "shield-plus" | "shield-question-mark" | "shield-user" | "shield-x" | "sliders-horizontal" | "sliders-vertical" | "smile" | "square-user" | "square-user-round" | "tags" | "ticket" | "tickets" | "toggle-left" | "toggle-right" | "user" | "user-check" | "user-cog" | "user-key" | "user-lock" | "user-minus" | "user-pen" | "user-plus" | "user-round" | "user-round-check" | "user-round-cog" | "user-round-key" | "user-round-minus" | "user-round-pen" | "user-round-plus" | "user-round-search" | "user-round-x" | "user-search" | "user-star" | "user-x" | "users-round" | "venetian-mask" | "vibrate" | "vibrate-off" | "wallet-cards" | "wallet-minimal" | "wallpaper" | "waypoints" | "wrench" | "arrow-big-down" | "arrow-big-down-dash" | "arrow-big-left" | "arrow-big-left-dash" | "arrow-big-right" | "arrow-big-right-dash" | "arrow-big-up" | "arrow-big-up-dash" | "arrow-down-0-1" | "arrow-down-1-0" | "arrow-down-a-z" | "arrow-down-from-line" | "arrow-down-left" | "arrow-down-narrow-wide" | "arrow-down-right" | "arrow-down-to-dot" | "arrow-down-to-line" | "arrow-down-up" | "arrow-down-wide-narrow" | "arrow-down-z-a" | "arrow-left" | "arrow-left-from-line" | "arrow-left-right" | "arrow-left-to-line" | "arrow-right" | "arrow-right-from-line" | "arrow-right-left" | "arrow-right-to-line" | "arrow-up-0-1" | "arrow-up-1-0" | "arrow-up-a-z" | "arrow-up-down" | "arrow-up-from-dot" | "arrow-up-from-line" | "arrow-up-left" | "arrow-up-narrow-wide" | "arrow-up-to-line" | "arrow-up-wide-narrow" | "arrow-up-z-a" | "arrows-up-from-line" | "calendar-sync" | "chevron-first" | "chevron-last" | "chevron-up" | "chevrons-down" | "chevrons-down-up" | "chevrons-left" | "chevrons-left-right" | "chevrons-right" | "chevrons-right-left" | "chevrons-up" | "chevrons-up-down" | "circle-arrow-down" | "circle-arrow-left" | "circle-arrow-out-down-left" | "circle-arrow-out-down-right" | "circle-arrow-out-up-left" | "circle-arrow-out-up-right" | "circle-arrow-right" | "circle-arrow-up" | "circle-chevron-down" | "circle-chevron-left" | "circle-chevron-right" | "circle-chevron-up" | "circle-fading-arrow-up" | "clipboard-copy" | "clipboard-paste" | "cloud-backup" | "cloud-download" | "cloud-sync" | "cloud-upload" | "corner-down-left" | "corner-down-right" | "corner-left-down" | "corner-left-up" | "corner-right-down" | "corner-right-up" | "corner-up-left" | "corner-up-right" | "database-backup" | "decimals-arrow-left" | "decimals-arrow-right" | "expand" | "external-link" | "fast-forward" | "file-down" | "file-input" | "file-output" | "file-up" | "fold-horizontal" | "fold-vertical" | "folder-down" | "folder-input" | "folder-output" | "folder-sync" | "folder-up" | "git-compare-arrows" | "git-pull-request-arrow" | "git-pull-request-create-arrow" | "hard-drive-download" | "hard-drive-upload" | "iteration-ccw" | "iteration-cw" | "lasso-select" | "list-chevrons-down-up" | "list-chevrons-up-down" | "maximize-2" | "merge" | "milestone" | "minimize-2" | "mouse-pointer" | "mouse-pointer-2" | "mouse-pointer-2-off" | "mouse-pointer-ban" | "move-diagonal" | "move-diagonal-2" | "move-down" | "move-down-left" | "move-down-right" | "move-horizontal" | "move-left" | "move-right" | "move-up" | "move-up-left" | "move-up-right" | "move-vertical" | "panel-bottom-close" | "panel-bottom-open" | "panel-left-open" | "panel-right-close" | "panel-right-open" | "panel-top-close" | "panel-top-open" | "phone-forwarded" | "phone-incoming" | "phone-outgoing" | "play" | "redo" | "redo-2" | "redo-dot" | "refresh-ccw" | "refresh-ccw-dot" | "refresh-cw" | "refresh-cw-off" | "repeat-2" | "repeat-off" | "rewind" | "rotate-ccw-square" | "rotate-cw" | "rotate-cw-square" | "separator-horizontal" | "separator-vertical" | "shrink" | "shuffle" | "signpost" | "signpost-big" | "skip-back" | "skip-forward" | "spline-pointer" | "square-arrow-down" | "square-arrow-down-left" | "square-arrow-down-right" | "square-arrow-left" | "square-arrow-out-down-left" | "square-arrow-out-down-right" | "square-arrow-out-up-left" | "square-arrow-out-up-right" | "square-arrow-right" | "square-arrow-right-enter" | "square-arrow-right-exit" | "square-arrow-up" | "square-arrow-up-left" | "square-arrow-up-right" | "square-chevron-down" | "square-chevron-left" | "square-chevron-right" | "square-chevron-up" | "square-dashed-mouse-pointer" | "square-mouse-pointer" | "square-play" | "step-back" | "step-forward" | "sunrise" | "sunset" | "text-wrap" | "trending-down" | "trending-up" | "trending-up-down" | "undo" | "undo-2" | "undo-dot" | "unfold-horizontal" | "unfold-vertical" | "upload" | "chart-area" | "chart-bar" | "chart-bar-big" | "chart-bar-decreasing" | "chart-bar-increasing" | "chart-bar-stacked" | "chart-candlestick" | "chart-column" | "chart-column-big" | "chart-column-decreasing" | "chart-column-increasing" | "chart-column-stacked" | "chart-gantt" | "chart-line" | "chart-network" | "chart-no-axes-column" | "chart-no-axes-column-decreasing" | "chart-no-axes-column-increasing" | "chart-no-axes-combined" | "chart-no-axes-gantt" | "chart-pie" | "chart-scatter" | "chart-spline" | "folder-kanban" | "kanban" | "square-chart-gantt" | "square-dashed-kanban" | "square-kanban" | "antenna" | "audio-lines" | "audio-waveform" | "camera" | "camera-off" | "chevrons-left-right-ellipsis" | "circle-fading-plus" | "ethernet-port" | "hand-fist" | "headphone-off" | "mic" | "mic-off" | "newspaper" | "nfc" | "notebook" | "phone" | "phone-call" | "phone-missed" | "phone-off" | "projector" | "radar" | "screen-share" | "screen-share-off" | "send-horizontal" | "smartphone-nfc" | "smile-plus" | "spotlight" | "switch-camera" | "tv" | "video-off" | "volume" | "volume-1" | "volume-2" | "volume-off" | "volume-x" | "webcam" | "airplay" | "battery" | "battery-charging" | "battery-full" | "battery-low" | "battery-medium" | "battery-warning" | "bluetooth" | "bluetooth-connected" | "bluetooth-off" | "bluetooth-searching" | "cable" | "cast" | "circle-power" | "cloud-off" | "globe-off" | "globe-x" | "headphones" | "headset" | "house-wifi" | "monitor" | "monitor-check" | "monitor-cloud" | "monitor-cog" | "monitor-dot" | "monitor-down" | "monitor-off" | "monitor-pause" | "monitor-play" | "monitor-smartphone" | "monitor-speaker" | "monitor-stop" | "monitor-up" | "monitor-x" | "power-off" | "router" | "signal" | "signal-high" | "signal-low" | "signal-medium" | "signal-zero" | "smartphone" | "smartphone-charging" | "square-power" | "voicemail" | "wifi" | "wifi-cog" | "wifi-high" | "wifi-low" | "wifi-off" | "wifi-pen" | "wifi-sync" | "wifi-zero" | "zap-off" | "circle-plus" | "hand-grab" | "lasso" | "loader-circle" | "loader-pinwheel" | "pen-tool" | "pencil" | "pencil-off" | "pointer-off" | "square-dashed-text" | "stamp" | "text-cursor" | "a-arrow-down" | "a-arrow-up" | "a-large-small" | "app-window" | "app-window-mac" | "between-horizontal-end" | "between-horizontal-start" | "between-vertical-end" | "between-vertical-start" | "blend" | "book-type" | "bring-to-front" | "brush" | "brush-cleaning" | "columns-2" | "columns-3" | "columns-3-cog" | "columns-4" | "component" | "crop" | "dock" | "drafting-compass" | "flip-horizontal-2" | "flip-vertical-2" | "frame" | "fullscreen" | "gallery-horizontal" | "gallery-horizontal-end" | "gallery-thumbnails" | "gallery-vertical" | "gallery-vertical-end" | "grid-2x2" | "grid-3x2" | "grid-3x3" | "heart-x" | "highlighter" | "layers-2" | "layers-minus" | "layers-plus" | "layout-dashboard" | "layout-grid" | "layout-list" | "layout-panel-left" | "line-style" | "magnet" | "maximize" | "minimize" | "paint-bucket" | "paint-roller" | "paintbrush" | "paintbrush-vertical" | "palette" | "panel-top" | "panels-top-left" | "pen" | "pen-line" | "pen-off" | "pencil-line" | "pencil-ruler" | "pipette" | "proportions" | "ratio" | "rectangle-horizontal" | "rectangle-vertical" | "rows-2" | "rows-3" | "rows-4" | "ruler" | "scaling" | "scissors" | "scissors-line-dashed" | "send-to-back" | "spray-can" | "square-dashed" | "square-scissors" | "squares-exclude" | "squares-intersect" | "squares-subtract" | "squares-unite" | "swatch-book" | "tablet-smartphone" | "vector-square" | "asterisk" | "astroid" | "binary" | "blocks" | "book" | "book-alert" | "book-check" | "book-copy" | "book-dashed" | "book-down" | "book-key" | "book-lock" | "book-marked" | "book-minus" | "book-open" | "book-open-check" | "book-open-text" | "book-plus" | "book-search" | "book-up" | "book-up-2" | "bot" | "bot-message-square" | "bot-off" | "box" | "boxes" | "braces" | "brackets" | "brain-circuit" | "brain-cog" | "bug" | "bug-off" | "bug-play" | "case-lower" | "case-upper" | "circle-dashed" | "circle-dot" | "circle-ellipsis" | "circle-slash" | "circle-slash-2" | "circle-x" | "circuit-board" | "cloud-alert" | "cloud-check" | "cloud-cog" | "code-xml" | "combine" | "command" | "computer" | "construction" | "database" | "database-search" | "database-zap" | "diff" | "divide" | "earth-lock" | "equal" | "equal-not" | "file-braces" | "file-diff" | "file-digit" | "file-sliders" | "file-stack" | "file-terminal" | "folder-code" | "folder-dot" | "folder-open-dot" | "folder-root" | "gem" | "git-branch" | "git-branch-minus" | "git-branch-plus" | "git-commit-horizontal" | "git-commit-vertical" | "git-compare" | "git-fork" | "git-graph" | "git-merge" | "git-merge-conflict" | "git-pull-request" | "git-pull-request-closed" | "git-pull-request-create" | "git-pull-request-draft" | "globe-lock" | "hard-drive" | "hexagon" | "keyboard" | "keyboard-off" | "library" | "library-big" | "list-indent-decrease" | "list-indent-increase" | "message-circle-code" | "message-square-code" | "message-square-diff" | "network" | "package" | "package-2" | "package-check" | "package-minus" | "package-open" | "package-plus" | "package-search" | "package-x" | "parentheses" | "percent" | "plug" | "plug-2" | "qr-code" | "regex" | "rocket" | "rss" | "scroll-text" | "search-code" | "server" | "server-cog" | "server-crash" | "server-off" | "shell" | "slash" | "spell-check" | "spell-check-2" | "square-code" | "square-dot" | "square-function" | "square-library" | "square-minus" | "square-plus" | "square-slash" | "square-stack" | "square-terminal" | "table-properties" | "terminal" | "tool-case" | "triangle-alert" | "unplug" | "variable" | "webhook" | "webhook-off" | "workflow" | "archive-restore" | "archive-x" | "book-image" | "calendar-fold" | "file-archive" | "file-badge" | "file-box" | "file-chart-column" | "file-chart-column-increasing" | "file-chart-line" | "file-chart-pie" | "file-check" | "file-clock" | "file-cog" | "file-headphone" | "file-image" | "file-key" | "file-lock" | "file-minus" | "file-pen" | "file-pen-line" | "file-play" | "file-plus" | "file-scan" | "file-search" | "file-spreadsheet" | "file-symlink" | "file-type" | "file-x" | "files" | "folder" | "folder-archive" | "folder-bookmark" | "folder-check" | "folder-clock" | "folder-closed" | "folder-cog" | "folder-key" | "folder-lock" | "folder-minus" | "folder-open" | "folder-pen" | "folder-plus" | "folder-search" | "folder-search-2" | "folder-tree" | "folder-x" | "folders" | "image-down" | "image-minus" | "image-off" | "image-play" | "image-plus" | "image-up" | "list-tree" | "music" | "save-all" | "save-off" | "table-cells-merge" | "table-cells-split" | "table-columns-split" | "table-rows-split" | "trash" | "trash-2" | "ungroup" | "align-center-horizontal" | "align-center-vertical" | "align-end-horizontal" | "align-end-vertical" | "align-horizontal-distribute-center" | "align-horizontal-distribute-end" | "align-horizontal-distribute-start" | "align-horizontal-justify-center" | "align-horizontal-justify-end" | "align-horizontal-justify-start" | "align-horizontal-space-around" | "align-horizontal-space-between" | "align-start-horizontal" | "align-start-vertical" | "align-vertical-distribute-center" | "align-vertical-distribute-end" | "align-vertical-distribute-start" | "align-vertical-justify-center" | "align-vertical-justify-end" | "align-vertical-justify-start" | "align-vertical-space-around" | "align-vertical-space-between" | "ellipsis-vertical" | "funnel" | "funnel-plus" | "funnel-x" | "grid-2x2-check" | "grid-2x2-plus" | "grid-2x2-x" | "grip" | "grip-horizontal" | "grip-vertical" | "layout-panel-top" | "layout-template" | "list-filter-plus" | "panel-bottom" | "panels-left-bottom" | "panels-right-bottom" | "square-menu" | "square-split-horizontal" | "square-split-vertical" | "stretch-horizontal" | "stretch-vertical" | "text-cursor-input" | "forward" | "mail-check" | "mail-minus" | "mail-open" | "mail-plus" | "mail-question-mark" | "mail-search" | "mail-warning" | "mail-x" | "mailbox" | "mails" | "reply" | "reply-all" | "alarm-clock" | "alarm-clock-check" | "alarm-clock-minus" | "alarm-clock-off" | "alarm-clock-plus" | "bell-electric" | "bell-minus" | "bell-off" | "bell-plus" | "bell-ring" | "check-check" | "check-line" | "circle-alert" | "circle-check" | "circle-check-big" | "copy-check" | "copy-x" | "laptop-minimal-check" | "megaphone" | "megaphone-off" | "message-circle-warning" | "message-square-dot" | "message-square-warning" | "octagon-alert" | "octagon-x" | "square-check" | "square-check-big" | "square-x" | "badge-check" | "badge-minus" | "badge-percent" | "badge-plus" | "badge-x" | "book-heart" | "circle-percent" | "hand-heart" | "hash" | "heart" | "heart-off" | "message-circle" | "message-circle-dashed" | "message-circle-heart" | "message-circle-more" | "message-circle-off" | "message-circle-question-mark" | "message-circle-reply" | "message-square" | "message-square-dashed" | "message-square-heart" | "message-square-lock" | "message-square-more" | "message-square-off" | "message-square-plus" | "message-square-quote" | "message-square-reply" | "message-square-share" | "message-square-text" | "message-square-x" | "notebook-pen" | "notebook-text" | "notepad-text" | "notepad-text-dashed" | "podcast" | "scan" | "menu-line" | "search-line" | "search-alert" | "search-check" | "search-slash" | "search-x" | "square-activity" | "square-percent" | "star-half" | "star-off" | "sticky-note" | "store" | "shopping-bag" | "vote" | "book-text" | "book-x" | "case-sensitive" | "clipboard" | "clipboard-check" | "clipboard-clock" | "clipboard-list" | "clipboard-minus" | "clipboard-pen" | "clipboard-pen-line" | "clipboard-plus" | "clipboard-type" | "clipboard-x" | "copy-minus" | "copy-plus" | "copyright" | "eraser" | "heading-1" | "heading-2" | "heading-3" | "heading-4" | "heading-5" | "heading-6" | "link-2-off" | "list-check" | "list-checks" | "list-collapse" | "list-end" | "list-filter" | "list-minus" | "list-ordered" | "list-plus" | "list-restart" | "list-start" | "list-todo" | "list-x" | "logs" | "quote" | "remove-formatting" | "replace-all" | "scan-text" | "sigma" | "signature" | "square-pen" | "strikethrough" | "subscript" | "superscript" | "table-of-contents" | "text-align-center" | "text-align-end" | "text-align-justify" | "text-align-start" | "text-quote" | "text-search" | "unlink" | "unlink-2" | "whole-word" | "calendar-1" | "calendar-arrow-down" | "calendar-arrow-up" | "calendar-check" | "calendar-check-2" | "calendar-clock" | "calendar-cog" | "calendar-days" | "calendar-minus" | "calendar-off" | "calendar-plus" | "calendar-range" | "calendar-search" | "calendar-x" | "calendars" | "clock-alert" | "clock-arrow-down" | "clock-arrow-up" | "clock-check" | "clock-plus" | "hourglass" | "timeline" | "timer-off" | "timer-reset" | "watch" | "bolt" | "diamond-minus" | "diamond-plus" | "hammer" | "telescope")[];
3
+ export declare const iconNames: ("history" | "code" | "data" | "form" | "link" | "map" | "menu" | "option" | "search" | "section" | "table" | "template" | "time" | "video" | "filter" | "image" | "stop" | "text" | "view" | "sort" | "group" | "replace" | "split" | "repeat" | "anchor" | "bold" | "scroll" | "type" | "key" | "bottom" | "container" | "left" | "right" | "top" | "x" | "radius" | "power" | "draggable" | "custom" | "heading" | "list" | "presentation" | "timer" | "send" | "location" | "copy" | "move" | "baseline" | "pointer" | "zoom-in" | "zoom-out" | "italic" | "square" | "underline" | "dot" | "ellipsis" | "sheet" | "toolbox" | "addressBook" | "AIFile" | "alarmClock" | "alert-circle" | "alert-circle-filled" | "alert-triangle" | "archive" | "arrow-down" | "arrow-up" | "arrow-up-right" | "arrowDown" | "arrowDown-filled" | "arrowLeft" | "arrowLeft-filled" | "arrowRight" | "arrowRight-filled" | "arrowUp" | "arrowUp-filled" | "asset-square" | "assetProtecting" | "autoAD-square-filled" | "bar-chart-3" | "bell" | "bell-filled" | "bidding" | "biz-cancel" | "biz-magic" | "biz-send" | "biz-stop" | "biz-time" | "bottom-filled" | "calendar" | "cancel" | "cancel-circle" | "cancel-circle-filled" | "card-distribute" | "channels" | "channels-square-filled" | "chart" | "chatBubble-filled" | "check" | "check-circle" | "check-circle-filled" | "checkBadge" | "chevron-down" | "chevron-left" | "chevron-right" | "clock" | "clock-4" | "comments" | "compare" | "copy-new" | "custom-filled" | "customColumn" | "dataAuth" | "dataBoard" | "dataBox" | "dataFolder" | "dataReport" | "dataReport-filled" | "dataRising" | "delete" | "deleteAD-filled" | "detect" | "doubleLeft" | "doubleLeft-filled" | "doubleRight" | "doubleRight-filled" | "down" | "down-bold" | "down-filled" | "download" | "download-1" | "download-2" | "download-filled" | "edit" | "exchange" | "exposure-filled" | "extendedConfig" | "fall-filled" | "file" | "file-code" | "file-filled" | "file-text" | "filter-filled" | "flag" | "flame" | "fold" | "folderZip" | "folderzip-bold" | "fullScreen" | "globe" | "guideBook" | "help-circle" | "help-circle-filled" | "histogram" | "hosting" | "hot" | "hot-filled" | "icon-outlined" | "idea" | "idea-bold" | "image-bold" | "image-filled" | "images" | "import" | "info" | "info-circle" | "info-circle-filled" | "keyword" | "LandingPage" | "languages" | "layers" | "left-bold" | "left-filled" | "leftFirst" | "leftFirst-filled" | "linkSquare" | "loader" | "lock" | "logout" | "magic" | "magic-filled" | "maxSize" | "menuLeft" | "menuLeft-bold" | "menuRight" | "menuRight-bold" | "message-circle-plus" | "messages-square" | "minigame-filled" | "miniProgram" | "minus" | "minus-circle" | "minus-circle-filled" | "mobile" | "mobile-filled" | "mobilePage" | "modify" | "modify-bold" | "moments-filled" | "more" | "more-vertical" | "mouse-pointer-click" | "multiCreate" | "mute" | "mutiImage" | "mutiImage-filled" | "mutiSelect" | "mutiSelect-filled" | "notepad" | "notepad-bold" | "offiaccount-filled" | "panel-left" | "panel-left-close" | "panel-right" | "paperclip" | "pause-filled" | "play-filled" | "playing" | "plus" | "plus-circle" | "plus-circle-filled" | "pointerLeft-filled" | "pointerRight-filled" | "puzzle" | "QRcode" | "qualification" | "quickFile" | "refresh" | "report" | "reportBook" | "right-bold" | "right-filled" | "rightLast" | "rightLast-filled" | "ringStruckture" | "rise-filled" | "rotate-ccw" | "save" | "search-bold" | "search-filled" | "searchAD" | "searchAD-filled" | "setting" | "share" | "shield" | "shield-filled" | "shop" | "shopping" | "sound" | "sparkle" | "sparkles" | "square-filled" | "star" | "star-filled" | "sticker" | "sticker-filled" | "subdivide" | "support-bold" | "tag" | "tag-filled" | "target" | "targeting" | "task" | "task-filled" | "templateBag" | "thumbDown" | "thumbDown-filled" | "thumbs-down" | "thumbs-up" | "thumbUp" | "thumbUp-filled" | "time-bold" | "top-filled" | "treeStructure" | "unfold" | "unfold-filled" | "up" | "up-bold" | "up-filled" | "user-add" | "user-circle" | "user-edit" | "user-pack" | "userList" | "userPack" | "users" | "users-bold" | "verify" | "videoBag-filled" | "videoScreenshot" | "viewMask" | "wallet" | "wand-sparkles" | "warning" | "warning-filled" | "wechatBubble" | "wechatBubble-filled" | "wechatSearch" | "writing" | "x-circle" | "zap" | "zoomIn" | "zoomOut" | "accessibility" | "baby" | "badge-info" | "badge-question-mark" | "circle-question-mark" | "closed-caption" | "contrast" | "ear" | "ear-off" | "eclipse" | "eye" | "eye-closed" | "eye-off" | "glasses" | "hand" | "life-buoy" | "moon" | "moon-star" | "person-standing" | "scan-eye" | "scan-search" | "speech" | "sun" | "sun-dim" | "sun-medium" | "sun-moon" | "activity" | "at-sign" | "award" | "badge" | "badge-alert" | "ban" | "bell-check" | "bell-dot" | "book-user" | "bookmark" | "bookmark-check" | "bookmark-minus" | "bookmark-off" | "bookmark-plus" | "bookmark-x" | "circle-user" | "circle-user-round" | "cog" | "contact" | "contact-round" | "cookie" | "credit-card" | "file-user" | "fingerprint-pattern" | "flag-off" | "frown" | "gift" | "hand-coins" | "handshake" | "heart-handshake" | "heart-minus" | "heart-plus" | "id-card" | "id-card-lanyard" | "inbox" | "key-round" | "key-square" | "link-2" | "log-in" | "log-out" | "mail" | "map-pin" | "map-pin-check" | "map-pin-check-inside" | "map-pin-house" | "map-pin-minus" | "map-pin-minus-inside" | "map-pin-pen" | "map-pin-plus" | "map-pin-plus-inside" | "map-pin-search" | "map-pin-x" | "map-pin-x-inside" | "map-pinned" | "message-circle-check" | "message-circle-x" | "message-square-check" | "notebook-tabs" | "pin" | "rotate-ccw-key" | "scan-face" | "scan-qr-code" | "settings" | "settings-2" | "share-2" | "shield-alert" | "shield-ban" | "shield-check" | "shield-cog" | "shield-cog-corner" | "shield-ellipsis" | "shield-half" | "shield-minus" | "shield-off" | "shield-plus" | "shield-question-mark" | "shield-user" | "shield-x" | "sliders-horizontal" | "sliders-vertical" | "smile" | "square-user" | "square-user-round" | "tags" | "ticket" | "tickets" | "toggle-left" | "toggle-right" | "user" | "user-check" | "user-cog" | "user-key" | "user-lock" | "user-minus" | "user-pen" | "user-plus" | "user-round" | "user-round-check" | "user-round-cog" | "user-round-key" | "user-round-minus" | "user-round-pen" | "user-round-plus" | "user-round-search" | "user-round-x" | "user-search" | "user-star" | "user-x" | "users-round" | "venetian-mask" | "vibrate" | "vibrate-off" | "wallet-cards" | "wallet-minimal" | "wallpaper" | "waypoints" | "wrench" | "arrow-big-down" | "arrow-big-down-dash" | "arrow-big-left" | "arrow-big-left-dash" | "arrow-big-right" | "arrow-big-right-dash" | "arrow-big-up" | "arrow-big-up-dash" | "arrow-down-0-1" | "arrow-down-1-0" | "arrow-down-a-z" | "arrow-down-from-line" | "arrow-down-left" | "arrow-down-narrow-wide" | "arrow-down-right" | "arrow-down-to-dot" | "arrow-down-to-line" | "arrow-down-up" | "arrow-down-wide-narrow" | "arrow-down-z-a" | "arrow-left" | "arrow-left-from-line" | "arrow-left-right" | "arrow-left-to-line" | "arrow-right" | "arrow-right-from-line" | "arrow-right-left" | "arrow-right-to-line" | "arrow-up-0-1" | "arrow-up-1-0" | "arrow-up-a-z" | "arrow-up-down" | "arrow-up-from-dot" | "arrow-up-from-line" | "arrow-up-left" | "arrow-up-narrow-wide" | "arrow-up-to-line" | "arrow-up-wide-narrow" | "arrow-up-z-a" | "arrows-up-from-line" | "calendar-sync" | "chevron-first" | "chevron-last" | "chevron-up" | "chevrons-down" | "chevrons-down-up" | "chevrons-left" | "chevrons-left-right" | "chevrons-right" | "chevrons-right-left" | "chevrons-up" | "chevrons-up-down" | "circle-arrow-down" | "circle-arrow-left" | "circle-arrow-out-down-left" | "circle-arrow-out-down-right" | "circle-arrow-out-up-left" | "circle-arrow-out-up-right" | "circle-arrow-right" | "circle-arrow-up" | "circle-chevron-down" | "circle-chevron-left" | "circle-chevron-right" | "circle-chevron-up" | "circle-fading-arrow-up" | "clipboard-copy" | "clipboard-paste" | "cloud-backup" | "cloud-download" | "cloud-sync" | "cloud-upload" | "corner-down-left" | "corner-down-right" | "corner-left-down" | "corner-left-up" | "corner-right-down" | "corner-right-up" | "corner-up-left" | "corner-up-right" | "database-backup" | "decimals-arrow-left" | "decimals-arrow-right" | "expand" | "external-link" | "fast-forward" | "file-down" | "file-input" | "file-output" | "file-up" | "fold-horizontal" | "fold-vertical" | "folder-down" | "folder-input" | "folder-output" | "folder-sync" | "folder-up" | "git-compare-arrows" | "git-pull-request-arrow" | "git-pull-request-create-arrow" | "hard-drive-download" | "hard-drive-upload" | "iteration-ccw" | "iteration-cw" | "lasso-select" | "list-chevrons-down-up" | "list-chevrons-up-down" | "maximize-2" | "merge" | "milestone" | "minimize-2" | "mouse-pointer" | "mouse-pointer-2" | "mouse-pointer-2-off" | "mouse-pointer-ban" | "move-diagonal" | "move-diagonal-2" | "move-down" | "move-down-left" | "move-down-right" | "move-horizontal" | "move-left" | "move-right" | "move-up" | "move-up-left" | "move-up-right" | "move-vertical" | "panel-bottom-close" | "panel-bottom-open" | "panel-left-open" | "panel-right-close" | "panel-right-open" | "panel-top-close" | "panel-top-open" | "phone-forwarded" | "phone-incoming" | "phone-outgoing" | "play" | "redo" | "redo-2" | "redo-dot" | "refresh-ccw" | "refresh-ccw-dot" | "refresh-cw" | "refresh-cw-off" | "repeat-2" | "repeat-off" | "rewind" | "rotate-ccw-square" | "rotate-cw" | "rotate-cw-square" | "separator-horizontal" | "separator-vertical" | "shrink" | "shuffle" | "signpost" | "signpost-big" | "skip-back" | "skip-forward" | "spline-pointer" | "square-arrow-down" | "square-arrow-down-left" | "square-arrow-down-right" | "square-arrow-left" | "square-arrow-out-down-left" | "square-arrow-out-down-right" | "square-arrow-out-up-left" | "square-arrow-out-up-right" | "square-arrow-right" | "square-arrow-right-enter" | "square-arrow-right-exit" | "square-arrow-up" | "square-arrow-up-left" | "square-arrow-up-right" | "square-chevron-down" | "square-chevron-left" | "square-chevron-right" | "square-chevron-up" | "square-dashed-mouse-pointer" | "square-mouse-pointer" | "square-play" | "step-back" | "step-forward" | "sunrise" | "sunset" | "text-wrap" | "trending-down" | "trending-up" | "trending-up-down" | "undo" | "undo-2" | "undo-dot" | "unfold-horizontal" | "unfold-vertical" | "upload" | "chart-area" | "chart-bar" | "chart-bar-big" | "chart-bar-decreasing" | "chart-bar-increasing" | "chart-bar-stacked" | "chart-candlestick" | "chart-column" | "chart-column-big" | "chart-column-decreasing" | "chart-column-increasing" | "chart-column-stacked" | "chart-gantt" | "chart-line" | "chart-network" | "chart-no-axes-column" | "chart-no-axes-column-decreasing" | "chart-no-axes-column-increasing" | "chart-no-axes-combined" | "chart-no-axes-gantt" | "chart-pie" | "chart-scatter" | "chart-spline" | "folder-kanban" | "kanban" | "square-chart-gantt" | "square-dashed-kanban" | "square-kanban" | "antenna" | "audio-lines" | "audio-waveform" | "camera" | "camera-off" | "chevrons-left-right-ellipsis" | "circle-fading-plus" | "ethernet-port" | "hand-fist" | "headphone-off" | "mic" | "mic-off" | "newspaper" | "nfc" | "notebook" | "phone" | "phone-call" | "phone-missed" | "phone-off" | "projector" | "radar" | "screen-share" | "screen-share-off" | "send-horizontal" | "smartphone-nfc" | "smile-plus" | "spotlight" | "switch-camera" | "tv" | "video-off" | "volume" | "volume-1" | "volume-2" | "volume-off" | "volume-x" | "webcam" | "airplay" | "battery" | "battery-charging" | "battery-full" | "battery-low" | "battery-medium" | "battery-warning" | "bluetooth" | "bluetooth-connected" | "bluetooth-off" | "bluetooth-searching" | "cable" | "cast" | "circle-power" | "cloud-off" | "globe-off" | "globe-x" | "headphones" | "headset" | "house-wifi" | "monitor" | "monitor-check" | "monitor-cloud" | "monitor-cog" | "monitor-dot" | "monitor-down" | "monitor-off" | "monitor-pause" | "monitor-play" | "monitor-smartphone" | "monitor-speaker" | "monitor-stop" | "monitor-up" | "monitor-x" | "power-off" | "router" | "signal" | "signal-high" | "signal-low" | "signal-medium" | "signal-zero" | "smartphone" | "smartphone-charging" | "square-power" | "voicemail" | "wifi" | "wifi-cog" | "wifi-high" | "wifi-low" | "wifi-off" | "wifi-pen" | "wifi-sync" | "wifi-zero" | "zap-off" | "circle-plus" | "hand-grab" | "lasso" | "loader-circle" | "loader-pinwheel" | "pen-tool" | "pencil" | "pencil-off" | "pointer-off" | "square-dashed-text" | "stamp" | "text-cursor" | "a-arrow-down" | "a-arrow-up" | "a-large-small" | "app-window" | "app-window-mac" | "between-horizontal-end" | "between-horizontal-start" | "between-vertical-end" | "between-vertical-start" | "blend" | "book-type" | "bring-to-front" | "brush" | "brush-cleaning" | "columns-2" | "columns-3" | "columns-3-cog" | "columns-4" | "component" | "crop" | "dock" | "drafting-compass" | "flip-horizontal-2" | "flip-vertical-2" | "frame" | "fullscreen" | "gallery-horizontal" | "gallery-horizontal-end" | "gallery-thumbnails" | "gallery-vertical" | "gallery-vertical-end" | "grid-2x2" | "grid-3x2" | "grid-3x3" | "heart-x" | "highlighter" | "layers-2" | "layers-minus" | "layers-plus" | "layout-dashboard" | "layout-grid" | "layout-list" | "layout-panel-left" | "line-style" | "magnet" | "maximize" | "minimize" | "paint-bucket" | "paint-roller" | "paintbrush" | "paintbrush-vertical" | "palette" | "panel-top" | "panels-top-left" | "pen" | "pen-line" | "pen-off" | "pencil-line" | "pencil-ruler" | "pipette" | "proportions" | "ratio" | "rectangle-horizontal" | "rectangle-vertical" | "rows-2" | "rows-3" | "rows-4" | "ruler" | "scaling" | "scissors" | "scissors-line-dashed" | "send-to-back" | "spray-can" | "square-dashed" | "square-scissors" | "squares-exclude" | "squares-intersect" | "squares-subtract" | "squares-unite" | "swatch-book" | "tablet-smartphone" | "vector-square" | "asterisk" | "astroid" | "binary" | "blocks" | "book" | "book-alert" | "book-check" | "book-copy" | "book-dashed" | "book-down" | "book-key" | "book-lock" | "book-marked" | "book-minus" | "book-open" | "book-open-check" | "book-open-text" | "book-plus" | "book-search" | "book-up" | "book-up-2" | "bot" | "bot-message-square" | "bot-off" | "box" | "boxes" | "braces" | "brackets" | "brain-circuit" | "brain-cog" | "bug" | "bug-off" | "bug-play" | "case-lower" | "case-upper" | "circle-dashed" | "circle-dot" | "circle-ellipsis" | "circle-slash" | "circle-slash-2" | "circle-x" | "circuit-board" | "cloud-alert" | "cloud-check" | "cloud-cog" | "code-xml" | "combine" | "command" | "computer" | "construction" | "database" | "database-search" | "database-zap" | "diff" | "divide" | "earth-lock" | "equal" | "equal-not" | "file-braces" | "file-diff" | "file-digit" | "file-sliders" | "file-stack" | "file-terminal" | "folder-code" | "folder-dot" | "folder-open-dot" | "folder-root" | "gem" | "git-branch" | "git-branch-minus" | "git-branch-plus" | "git-commit-horizontal" | "git-commit-vertical" | "git-compare" | "git-fork" | "git-graph" | "git-merge" | "git-merge-conflict" | "git-pull-request" | "git-pull-request-closed" | "git-pull-request-create" | "git-pull-request-draft" | "globe-lock" | "hard-drive" | "hexagon" | "keyboard" | "keyboard-off" | "library" | "library-big" | "list-indent-decrease" | "list-indent-increase" | "message-circle-code" | "message-square-code" | "message-square-diff" | "network" | "package" | "package-2" | "package-check" | "package-minus" | "package-open" | "package-plus" | "package-search" | "package-x" | "parentheses" | "percent" | "plug" | "plug-2" | "qr-code" | "regex" | "rocket" | "rss" | "scroll-text" | "search-code" | "server" | "server-cog" | "server-crash" | "server-off" | "shell" | "slash" | "spell-check" | "spell-check-2" | "square-code" | "square-dot" | "square-function" | "square-library" | "square-minus" | "square-plus" | "square-slash" | "square-stack" | "square-terminal" | "table-properties" | "terminal" | "tool-case" | "triangle-alert" | "unplug" | "variable" | "webhook" | "webhook-off" | "workflow" | "archive-restore" | "archive-x" | "book-image" | "calendar-fold" | "file-archive" | "file-badge" | "file-box" | "file-chart-column" | "file-chart-column-increasing" | "file-chart-line" | "file-chart-pie" | "file-check" | "file-clock" | "file-cog" | "file-headphone" | "file-image" | "file-key" | "file-lock" | "file-minus" | "file-pen" | "file-pen-line" | "file-play" | "file-plus" | "file-scan" | "file-search" | "file-spreadsheet" | "file-symlink" | "file-type" | "file-x" | "files" | "folder" | "folder-archive" | "folder-bookmark" | "folder-check" | "folder-clock" | "folder-closed" | "folder-cog" | "folder-key" | "folder-lock" | "folder-minus" | "folder-open" | "folder-pen" | "folder-plus" | "folder-search" | "folder-search-2" | "folder-tree" | "folder-x" | "folders" | "image-down" | "image-minus" | "image-off" | "image-play" | "image-plus" | "image-up" | "list-tree" | "music" | "save-all" | "save-off" | "table-cells-merge" | "table-cells-split" | "table-columns-split" | "table-rows-split" | "trash" | "trash-2" | "ungroup" | "align-center-horizontal" | "align-center-vertical" | "align-end-horizontal" | "align-end-vertical" | "align-horizontal-distribute-center" | "align-horizontal-distribute-end" | "align-horizontal-distribute-start" | "align-horizontal-justify-center" | "align-horizontal-justify-end" | "align-horizontal-justify-start" | "align-horizontal-space-around" | "align-horizontal-space-between" | "align-start-horizontal" | "align-start-vertical" | "align-vertical-distribute-center" | "align-vertical-distribute-end" | "align-vertical-distribute-start" | "align-vertical-justify-center" | "align-vertical-justify-end" | "align-vertical-justify-start" | "align-vertical-space-around" | "align-vertical-space-between" | "ellipsis-vertical" | "funnel" | "funnel-plus" | "funnel-x" | "grid-2x2-check" | "grid-2x2-plus" | "grid-2x2-x" | "grip" | "grip-horizontal" | "grip-vertical" | "layout-panel-top" | "layout-template" | "list-filter-plus" | "panel-bottom" | "panels-left-bottom" | "panels-right-bottom" | "square-menu" | "square-split-horizontal" | "square-split-vertical" | "stretch-horizontal" | "stretch-vertical" | "text-cursor-input" | "forward" | "mail-check" | "mail-minus" | "mail-open" | "mail-plus" | "mail-question-mark" | "mail-search" | "mail-warning" | "mail-x" | "mailbox" | "mails" | "reply" | "reply-all" | "alarm-clock" | "alarm-clock-check" | "alarm-clock-minus" | "alarm-clock-off" | "alarm-clock-plus" | "bell-electric" | "bell-minus" | "bell-off" | "bell-plus" | "bell-ring" | "check-check" | "check-line" | "circle-alert" | "circle-check" | "circle-check-big" | "copy-check" | "copy-x" | "laptop-minimal-check" | "megaphone" | "megaphone-off" | "message-circle-warning" | "message-square-dot" | "message-square-warning" | "octagon-alert" | "octagon-x" | "square-check" | "square-check-big" | "square-x" | "badge-check" | "badge-minus" | "badge-percent" | "badge-plus" | "badge-x" | "book-heart" | "circle-percent" | "hand-heart" | "hash" | "heart" | "heart-off" | "message-circle" | "message-circle-dashed" | "message-circle-heart" | "message-circle-more" | "message-circle-off" | "message-circle-question-mark" | "message-circle-reply" | "message-square" | "message-square-dashed" | "message-square-heart" | "message-square-lock" | "message-square-more" | "message-square-off" | "message-square-plus" | "message-square-quote" | "message-square-reply" | "message-square-share" | "message-square-text" | "message-square-x" | "notebook-pen" | "notebook-text" | "notepad-text" | "notepad-text-dashed" | "podcast" | "scan" | "menu-line" | "search-line" | "search-alert" | "search-check" | "search-slash" | "search-x" | "square-activity" | "square-percent" | "star-half" | "star-off" | "sticky-note" | "store" | "shopping-bag" | "vote" | "book-text" | "book-x" | "case-sensitive" | "clipboard" | "clipboard-check" | "clipboard-clock" | "clipboard-list" | "clipboard-minus" | "clipboard-pen" | "clipboard-pen-line" | "clipboard-plus" | "clipboard-type" | "clipboard-x" | "copy-minus" | "copy-plus" | "copyright" | "eraser" | "heading-1" | "heading-2" | "heading-3" | "heading-4" | "heading-5" | "heading-6" | "link-2-off" | "list-check" | "list-checks" | "list-collapse" | "list-end" | "list-filter" | "list-minus" | "list-ordered" | "list-plus" | "list-restart" | "list-start" | "list-todo" | "list-x" | "logs" | "quote" | "remove-formatting" | "replace-all" | "scan-text" | "sigma" | "signature" | "square-pen" | "strikethrough" | "subscript" | "superscript" | "table-of-contents" | "text-align-center" | "text-align-end" | "text-align-justify" | "text-align-start" | "text-quote" | "text-search" | "unlink" | "unlink-2" | "whole-word" | "calendar-1" | "calendar-arrow-down" | "calendar-arrow-up" | "calendar-check" | "calendar-check-2" | "calendar-clock" | "calendar-cog" | "calendar-days" | "calendar-minus" | "calendar-off" | "calendar-plus" | "calendar-range" | "calendar-search" | "calendar-x" | "calendars" | "clock-alert" | "clock-arrow-down" | "clock-arrow-up" | "clock-check" | "clock-plus" | "hourglass" | "timeline" | "timer-off" | "timer-reset" | "watch" | "bolt" | "diamond-minus" | "diamond-plus" | "hammer" | "telescope")[];
@@ -13,7 +13,7 @@ export interface StreamTextProps {
13
13
  /** 搜索跳转:在正文中精准高亮关键词(非整块铺底) */
14
14
  highlightQuery?: string;
15
15
  }
16
- export declare function StreamText({ content, isStreaming, simulate, speed, onComplete, typography: t, highlightQuery, }: StreamTextProps): React.JSX.Element;
16
+ export declare function StreamText({ content, isStreaming, simulate, speed, onComplete, highlightQuery, }: StreamTextProps): React.JSX.Element;
17
17
  export declare namespace StreamText {
18
18
  var displayName: string;
19
19
  }
@@ -7,6 +7,9 @@ import remarkGfm from 'remark-gfm';
7
7
  import CodeBlock from "../code-block";
8
8
  import { highlightQueryInNodes } from "./highlight-query-text";
9
9
  import "./style";
10
+
11
+ // eslint-disable-next-line @typescript-eslint/no-empty-interface -- 排版覆盖的占位类型,当前无字段
12
+
10
13
  var FONT_SIZE = 14;
11
14
  var LINE_HEIGHT = 24;
12
15
  var PARAGRAPH_GAP = 8;
@@ -72,7 +75,6 @@ export function StreamText(_ref) {
72
75
  _ref$speed = _ref.speed,
73
76
  speed = _ref$speed === void 0 ? 18 : _ref$speed,
74
77
  onComplete = _ref.onComplete,
75
- t = _ref.typography,
76
78
  highlightQuery = _ref.highlightQuery;
77
79
  var _useState = useState(simulate && isStreaming ? '' : content),
78
80
  _useState2 = _slicedToArray(_useState, 2),
@@ -155,15 +157,12 @@ export function StreamText(_ref) {
155
157
  var child = Array.isArray(children) ? children[0] : children;
156
158
  var codeEl = child && _typeof(child) === 'object' && 'props' in child ? child : null;
157
159
  var className = (_codeEl$props$classNa = codeEl === null || codeEl === void 0 || (_codeEl$props = codeEl.props) === null || _codeEl$props === void 0 ? void 0 : _codeEl$props.className) !== null && _codeEl$props$classNa !== void 0 ? _codeEl$props$classNa : '';
158
- var hasLang = className.includes('language-');
159
- var lang = hasLang ? className.replace('language-', '') : undefined;
160
+ var lang = className.includes('language-') ? className.replace('language-', '') : undefined;
160
161
  var code = String((_codeEl$props$childre = codeEl === null || codeEl === void 0 || (_codeEl$props2 = codeEl.props) === null || _codeEl$props2 === void 0 ? void 0 : _codeEl$props2.children) !== null && _codeEl$props$childre !== void 0 ? _codeEl$props$childre : '').replace(/\n$/, '');
161
- return hasLang ? /*#__PURE__*/React.createElement(CodeBlock, {
162
+ return /*#__PURE__*/React.createElement(CodeBlock, {
162
163
  code: code,
163
164
  language: lang
164
- }) : /*#__PURE__*/React.createElement("pre", {
165
- "data-odn-stream-text-pre": true
166
- }, code);
165
+ });
167
166
  },
168
167
  code: function code(_ref3) {
169
168
  var className = _ref3.className,
@@ -24,22 +24,6 @@
24
24
  background: var(--odn-color-solid-black-1);
25
25
  }
26
26
 
27
- [data-odn-stream-text-pre] {
28
- margin: 16px 0;
29
- padding: 14px 16px;
30
- border-radius: 6px;
31
- background: var(--odn-color-solid-black-1);
32
- font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace;
33
- font-size: var(--st-code-font-size, 13px);
34
- line-height: 1.5;
35
- color: var(--st-code-color, var(--odn-color-black-10));
36
- overflow-x: auto;
37
- white-space: pre;
38
- }
39
- [data-odn-stream-text-pre]:last-child {
40
- margin-bottom: 0;
41
- }
42
-
43
27
  [data-odn-stream-text-list]:last-child {
44
28
  margin-bottom: 0;
45
29
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "one-design-next",
3
- "version": "0.0.117",
3
+ "version": "0.0.119",
4
4
  "description": "One Design Next from TAD@tencent.com",
5
5
  "license": "MIT",
6
6
  "type": "module",