fix: adjust alignment and sizing for reference icons and tokens in Markdown rendering

This commit is contained in:
Yoan Huang committed 2026-09-26 10:26:20 +08:00
1 parent 0a93fbb2f5
commit 36271b52eb
6 files changed
+22 -17

No files matched your search

+2 -2
View File
@@ -321,7 +321,7 @@
- `WB-COMPOSER-003-AC1` 智能模式发送后,主区先可见用户消息与 assistant 占位消息。
- `WB-COMPOSER-003-AC2` AI 运行成功启动后,assistant 过程流通过事件逐步追加更新,而不是一次性静态替换。
- `WB-COMPOSER-003-AC3` assistant 在 Brain 思考阶段于过程流最下方展示“让俺想想”并带有微光流动视觉反馈。运行未结束且尚无最终回答时预留同高占位,避免文案显隐导致消息区上挤抖动。当思考请求发起时展示文案;当收到输出、思考结束、出现“正在重试”过程组、已有可见流式 Thought / 最终回答、或 run 已结束(完成 / 失败 / 取消)时,必须隐藏“让俺想想”。
- `WB-COMPOSER-003-AC4` assistant turn 中 brain 最终输出始终位于过程流下方,并按 markdown 渲染;最终回答在内容分片到达后直接流式渲染,不展示独立收尾等待层;金额等普通文本中的单个 `$` 不作为公式边界,数学公式使用 `$$...$$` 语法;无序和有序列表分别显示圆点和序号;内部文件链接打开右侧文件预览,网页链接打开右侧内置浏览器;若当前伙伴已有浏览器 Tab 正停留在同一 URL,则激活该 Tab,不新开。
- `WB-COMPOSER-003-AC4` assistant turn 中 brain 最终输出始终位于过程流下方,并按 markdown 渲染;最终回答在内容分片到达后直接流式渲染,不展示独立收尾等待层;金额等普通文本中的单个 `$` 不作为公式边界,数学公式使用 `$$...$$` 语法;无序和有序列表分别显示圆点和序号;链接图标和链接文字与周围正文沿基线对齐;内部文件链接打开右侧文件预览,网页链接打开右侧内置浏览器;若当前伙伴已有浏览器 Tab 正停留在同一 URL,则激活该 Tab,不新开。
- `WB-COMPOSER-003-AC5` 决策层(Thought)只展示面向用户的短摘要,不得展示模型原始长篇推理;决策层出现时,当前“让俺想想”必须立即隐藏;已落地的 Thought 使用浅灰色(#787774)文本呈现思考状态;未超出单行时不展示折叠图标,超出单行时默认以单行省略号截断展示且不常驻图标,鼠标悬浮时显示展开图标,点击展开后常驻浅灰卡片背景并展示收起图标,展开内容受最大高度限制(超出纵向滚动),流式阶段平铺展开。
- `WB-COMPOSER-003-AC6` 过程流使用用户可理解的文案,不直接暴露内部 tool 名或底层事件名;两次 Thought 之间的工具调用(含 `learn_skill`)合并为一个 Activity 面板,展开后按时间平铺自然语言说明;压缩与重试单独成行。Activity header 汇总规则见 `WB-COMPOSER-009-AC5`;等待审批时的 header 与审后工具行图标见 `WB-BLOCKER-001-AC6` / `WB-BLOCKER-001-AC7`。
- `WB-COMPOSER-003-AC7` AI 输出中切到 Settings 或触发界面重新挂载后,回到 Workbench 能通过伙伴消息记录投影恢复过程流、partial answer、最终回答或等待审批状态。
@@ -479,7 +479,7 @@
#### WB-SCOPE-002 `@` 插入与删除规则
- 系统行为:候选可通过键盘或鼠标插入为内联 token;目录、文件和网页资料都可作为合法 token 插入;输入区支持多个已插入 token 共存;token 使用无边框的紧凑图标加名称样式展示。目录、网页、PDF、DOCX、PPT/PPTX、Excel 使用各自的专属样式;Markdown、TXT 和其他文件统一使用普通文件样式。文字与图标保持同色。按 `Backspace` 可移除参考资料;发送后,用户消息中保留本轮参考资料 token 回显,样式与输入区 token 保持一致。
- 系统行为:候选可通过键盘或鼠标插入为内联 token;目录、文件和网页资料都可作为合法 token 插入;输入区支持多个已插入 token 共存;token 使用无边框的紧凑图标加名称样式展示。目录、网页、PDF、DOCX、PPT/PPTX、Excel 使用各自的专属样式;Markdown、TXT 和其他文件统一使用普通文件样式。文字与图标保持同色,token 名称基线与相邻正文对齐。按 `Backspace` 可移除参考资料;发送后,用户消息中保留本轮参考资料 token 回显,样式与输入区 token 保持一致。
- 验收:
- `WB-SCOPE-002-AC1` 目录、文件或网页资料插入成功后,参考资料以 token 形式保留在输入流中,并进入后续发送参数。
- `WB-SCOPE-002-AC2` 输入区支持多个已插入 token 共存,而不是后插入覆盖前一个范围。
+13 -8
View File
@@ -1739,12 +1739,7 @@ mark {
}
.markdown-body .markdown-reference-link {
display: inline-flex;
align-items: baseline;
gap: 0.35rem;
max-width: 100%;
min-width: 0;
vertical-align: middle;
vertical-align: baseline;
color: var(--notion-accent-blue);
text-decoration: none;
text-underline-offset: 3px;
@@ -1753,18 +1748,28 @@ mark {
.markdown-body .markdown-reference-icon {
display: inline-flex;
align-items: baseline;
align-items: center;
justify-content: center;
flex-shrink: 0;
width: 0.95em;
height: 0.95em;
margin-right: 0.35rem;
color: var(--notion-accent-blue);
line-height: 1;
vertical-align: -0.12em;
}
.markdown-body .markdown-reference-icon svg {
display: block;
width: 0.9em;
height: 0.9em;
}
.markdown-body .markdown-normal-link {
color: var(--notion-accent-blue);
text-decoration: none;
text-underline-offset: 3px;
vertical-align: middle;
vertical-align: baseline;
word-break: break-word;
overflow-wrap: anywhere;
}
@@ -990,7 +990,7 @@ const WorkbenchComposer: React.FC<WorkbenchComposerProps> = ({
aria-multiline="true"
tabIndex={0}
spellCheck={false}
className="block min-h-[32px] w-full whitespace-pre-wrap break-words bg-transparent text-[15px] leading-6 text-[#37352F] outline-none [&_[data-role='scope-token']]:align-middle"
className="block min-h-[32px] w-full whitespace-pre-wrap break-words bg-transparent text-[15px] leading-6 text-[#37352F] outline-none [&_[data-role='scope-token']]:align-baseline"
data-testid={workbenchSelectors.input}
onInput={handleEditorInput}
onKeyDown={handleEditorKeyDown}
@@ -10,13 +10,13 @@ type ReferenceIconProps = {
const iconSizeClassName = {
sm: 'h-[18px] w-[18px]',
md: 'h-[21px] w-[21px]',
inline: 'h-[1.22em] w-[1.22em]'
inline: 'h-[0.9em] w-[0.9em]'
} as const
const containerSizeClassName = {
sm: 'h-[22px] w-[22px]',
md: 'h-8 w-8',
inline: 'h-[1.34em] w-[1.34em]'
inline: 'relative top-[0.1em] h-[1em] w-[1em]'
} as const
const DocumentGlyph: React.FC<{
@@ -18,7 +18,7 @@ export const ReferenceInlineToken: React.FC<ReferenceInlineTokenProps> = ({
return (
<span
className={`inline-flex max-w-full items-center gap-[2px] align-[-0.08em] text-[0.9em] font-medium leading-[inherit] ${visualSpec.labelClassName} ${className}`}
className={`inline-flex max-w-full items-baseline gap-[2px] align-baseline text-[0.9em] font-medium leading-[inherit] ${visualSpec.labelClassName} ${className}`}
data-role={role}
>
<ReferenceIcon reference={reference} size="inline" />
@@ -133,7 +133,7 @@ export const readComposerNodesFromEditor = (
const appendReferenceIcon = (container: HTMLElement, scope: SelectedReference): void => {
const visualSpec = getReferenceVisualSpec(scope)
const icon = document.createElement('span')
icon.className = `inline-flex h-[1.34em] w-[1.34em] shrink-0 items-center justify-center ${visualSpec.iconClassName}`
icon.className = `relative top-[0.1em] inline-flex h-[1em] w-[1em] shrink-0 items-center justify-center ${visualSpec.iconClassName}`
icon.dataset.referenceIconKind = visualSpec.kind
const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')
@@ -142,7 +142,7 @@ const appendReferenceIcon = (container: HTMLElement, scope: SelectedReference):
visualSpec.kind === 'directory' || visualSpec.kind === 'web' ? '0 0 24 24' : '0 0 18 18'
)
svg.setAttribute('aria-hidden', 'true')
svg.setAttribute('class', `h-[1.22em] w-[1.22em] ${visualSpec.iconClassName}`)
svg.setAttribute('class', `h-[0.9em] w-[0.9em] ${visualSpec.iconClassName}`)
if (visualSpec.kind === 'directory' || visualSpec.kind === 'web') {
svg.setAttribute('fill', 'none')
@@ -215,7 +215,7 @@ const appendReferenceIcon = (container: HTMLElement, scope: SelectedReference):
export const createScopeTokenElement = (scope: SelectedReference): HTMLElement => {
const visualSpec = getReferenceVisualSpec(scope)
const token = document.createElement('span')
token.className = `inline-flex max-w-full items-center gap-[2px] align-[-0.08em] text-[0.9em] font-medium leading-[inherit] ${visualSpec.labelClassName}`
token.className = `inline-flex max-w-full items-baseline gap-[2px] align-baseline text-[0.9em] font-medium leading-[inherit] ${visualSpec.labelClassName}`
token.contentEditable = 'false'
token.dataset.role = 'scope-token'
token.dataset.scopeKey = getScopeKey(scope)