Hover cards copy their primary value on activation
悬浮卡片激活时复制主要值
Workspace and Session rows clip the two values their hover cards expose in full: the Workspace directory path and Session title. The [reachable card](../bug-fix/2026-07-30-hover-popup-pointer-grace.md) permits text selection, but selecting and copying a single known value is a needlessly precise gesture, and the card gives no confirmation that the clipboard accepted it.
English
Problem
Workspace and Session rows clip the two values their hover cards expose in full: the Workspace directory path and Session title. The reachable card permits text selection, but selecting and copying a single known value is a needlessly precise gesture, and the card gives no confirmation that the clipboard accepted it.
Decision
HoverCard accepts an optional copyText plus copyLabel and copiedLabel. With copyText, the whole card has button semantics for pointer and keyboard activation; its accessible name combines the localized action prefix with the exact value, it writes that value through the shared clipboard helper, and it replaces its content with the success label for up to one second only after the host accepts the write. The feedback retains the pre-copy card height and clears with the card. Without copyText, the atom retains its read/select-only behavior.
The Workspace browser chooses the payload rather than making the primitive infer it from rendered text: a Workspace card passes the full directory path, and a non-blank Session card passes the full display title. A provisional blank New Session card remains read-only because its localized label is a placeholder, not session content. The browser's locale seat supplies Copy/复制 and the success state Copied/已复制.
Press and activation remain separate contracts. A pointer press inside the card keeps it mounted so text selection can begin; a completed non-collapsed selection intersecting the card suppresses pointer-click activation, while a plain click or button key activates copy. Anchor-region presses still dismiss immediately, and clipboard rejection leaves the original content visible without claiming success.
Alternatives considered
Copy the card's rendered textContent. That would concatenate the primary value with creation time or running status, making the clipboard payload depend on presentation and localization.
Implement clipboard state in both Workspace card bodies. The two consumers would duplicate host fallback, keyboard behavior, timer ownership, and success rendering even though the card owns the activation surface.
Change the common Chinese copied label from 复制成功 to 已复制. That would alter every existing copy control to satisfy one card interaction. The Workspace dictionary owns the card-specific wording instead.
Consequences
Both non-placeholder hover-card variants gain the same click and keyboard affordance while retaining consumer-owned payload semantics and localized feedback. The generic atom adds one optional behavior path and a one-second timer; it clears copied state on close, ignores completion after close or unmount, and never reports a rejected write as success. Focused component coverage pins pointer selection precedence, activation, failure, feedback geometry and expiry, and cleanup, while the real-browser Workspace scenario verifies the English label, stable feedback height, and browser clipboard.
中文
问题
Workspace 与 Session 行会截断对应悬浮卡片完整展示的两个值:Workspace 目录路径和 Session 标题。这张可抵达的卡片支持文本选择,但复制单个已知值仍需精确选择,操作没有必要地繁琐;卡片也不会确认剪贴板是否接受了写入。
决策
HoverCard 接收可选的 copyText,以及 copyLabel 和 copiedLabel。传入 copyText 后,整个卡片都会为指针与键盘激活提供按钮语义;其无障碍名称由本地化操作前缀和原值组成,卡片通过共享剪贴板辅助函数写入该值,并且只有宿主接受写入后,才会用成功标签替换内容最长一秒。反馈保持复制前的卡片高度,并会随卡片关闭一同清除。未传入 copyText 时,该原子组件维持只读且可选择文本的行为。
Workspace 浏览器选择复制载荷,不让基础组件从渲染文本中推断:Workspace 卡片传入完整目录路径,非空白 Session 卡片传入完整显示标题。临时的空白「新会话」卡片保持只读,因为其本地化标签是占位文案,并非会话内容。浏览器的 locale 席位提供 Copy/复制,成功状态则使用 Copied/已复制。
按下与激活仍是两份独立契约。卡片内发生指针按下时,卡片保持挂载,以便用户开始选择文本;文本选择完成后,若非折叠选区与卡片相交,就会阻止指针点击激活,而普通点击或按钮激活键会激活复制。锚点区域内发生指针按下时,卡片仍会立即消失;剪贴板拒绝写入时,卡片继续显示原内容,不会声称复制成功。
备选方案
复制卡片渲染后的 textContent。 这会把主要值与创建时间或运行状态拼接起来,使剪贴板载荷依赖表现形式和本地化结果。
在两个 Workspace 卡片主体中分别实现剪贴板状态。 两个消费方会重复实现宿主回退、键盘行为、计时器所有权和成功状态渲染,尽管激活表层由卡片持有。
将通用中文 copied 标签从 复制成功 改为 已复制。 这样会为了满足一种卡片交互而改变所有现有复制控件。卡片专用文案应由 Workspace 字典持有。
后果
两种非占位悬浮卡片都获得相同的点击与键盘操作能力,同时保留由消费方决定载荷的语义和本地化反馈。通用原子组件增加一条可选行为路径和一个一秒计时器;卡片关闭时会清除已复制状态,关闭或卸载后到达的完成结果会被忽略,写入被拒绝时绝不会报告成功。聚焦组件测试会固定指针选择文本的优先级、激活、失败、反馈尺寸与到期清除以及清理行为,真实浏览器中的 Workspace 场景则验证英文标签、反馈期间高度稳定和浏览器剪贴板。