feat(text-selection): 选中文字弹出引用/复制浮窗#149
Open
SsparKluo wants to merge 1 commit into
Open
Conversation
Surface a floating popup with Quote and Copy buttons when the user selects text inside a chat pane. Quote turns the selection into a Markdown blockquote and inserts it into the pane's input box at the cursor; Copy writes the raw selection to the clipboard. Architecture: - Mounted once in App, renders into document.body via createPortal - selectionchange tracks a pending ref; popup only commits on mouseup/touchend/Shift+arrow keyup — never flickers mid-drag - Positions near the pointer release point (mouse/touch) or the selection rect (keyboard) - Auto-dismisses on outside pointerdown, scroll, resize, Esc - data-pane-id added to ChatPane root so message selections resolve to the correct pane's textarea across split panes Filters out selections inside form controls, contenteditable, and [data-no-selection-popup] opt-out zones. Quote spacing follows Slack/Notion conventions (always at least one blank line around the block). 607 tests pass (34 in this feature). 0 lint warnings.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
概述
在聊天消息区域选中文字后,弹出悬浮工具栏,提供「引用」和「复制」两个操作。
>),插入到当前对话面板的输入框光标位置,并自动聚焦输入框实现细节
交互流程
selectionchange事件实时追踪选区状态到 ref,但不显示浮窗mouseup/touchend/ 键盘Shift+方向键释放时才提交显示——避免拖选过程中浮窗闪烁Esc均自动关闭浮窗定位策略
clientX/Y作为锚点,浮窗显示在指针上方Pane 定位
在
ChatPane根元素上添加了data-pane-id属性。这是必要的——消息 DOM 和输入框是 ChatPane 内部的兄弟子树,之前data-pane-id只挂在 InputBox 容器上,导致从消息文字向上closest('[data-pane-id]')找不到 pane 祖先。现在两者共享同一个data-pane-id祖先,split 模式下也能正确路由到对应 pane 的输入框。过滤规则
以下场景不弹出浮窗:
input、textarea、[contenteditable="true"]内[data-no-selection-popup]标记的区域内data-pane-id容器内(如侧边栏、终端)引用块格式化
>前缀,空行变为单独的>,保持 Markdown blockquote 语义\n,确保引用块始终独占一段(对齐 Slack / Notion 行为)技术实现
App根级,通过createPortal渲染到document.body,position: fixed定位不受父级 transform / overflow 影响valuesetter +dispatchEvent(new Event('input'))驱动,React 受控组件正常同步QuoteIcon复用 lucide-react 已有的Quote图标,通过Icons.tsxbarrel 统一导出en和zh-CN文件变更
src/features/text-selection-popup/src/App.tsx<TextSelectionPopup />src/features/chat/ChatPane.tsxdata-pane-idsrc/components/Icons.tsxQuoteIconsrc/locales/{en,zh-CN}/chat.jsontextSelectionPopupi18n keys测试
typecheck/lint/build全绿截图