feat: Rich text editor with formatting toolbar, image ref chips, and TipTap integration#310
Draft
feat: Rich text editor with formatting toolbar, image ref chips, and TipTap integration#310
Conversation
…TipTap integration Replace plain textarea message composer with TipTap-based rich text editor. - Add FormattingToolbar with bold, italic, strikethrough, code, and link controls - Add Toggle UI primitive (shared component) - Integrate image uploads as context chips with autocomplete suggestions (ImageRefAutocomplete, imageRefExtension, useImageRefSuggestions) - New useRichTextEditor hook encapsulating TipTap setup - New ComposerAttachments component for uploaded media display - Remove legacy ComposerMentionOverlay (replaced by TipTap mention/ref system) - Update MessageComposer and MessageComposerToolbar for new editor - Keyboard shortcuts: ⌘B bold, ⌘I italic, ⌘K link, ⌘S sidebar toggle - Update ChannelPane, sidebar, globals.css for layout/style adjustments - Update dependencies (Cargo.toml, package.json, pnpm-lock.yaml)
Move expanded formatting options (B, I, S, Code, Link, Lists, Quote) to sit inline in the bottom toolbar right after the Aa toggle, instead of in a separate row above the editor. File attachment previews remain as the only element above the textarea.
…[Aa ✕ | formatting] Passive state shows ingress buttons (mention, attach, emoji) followed by the Aa formatting toggle. Clicking Aa swaps to expanded mode: Aa toggle, ✕ close button, separator, then all formatting options. Ingress buttons are hidden while formatting is open. Matches the inline-expand design spec from the channel.
…/react - Aa toggle uses layoutId for smooth slide between positions - Ingress buttons (@ 📎 😊) fade out + scale down on expand - Formatting buttons slide in from left + fade in on expand - ✕ close button scales in alongside Aa - Reverse animation on collapse - Uses LayoutGroup + AnimatePresence (popLayout) matching existing ComposerAttachments pattern
…bels - Reset isEmojiPickerOpen when formatting is toggled on (prevents emoji picker remounting open on collapse) - Extract Aa toggle to local variable — single source of truth for the layoutId animation across both toolbar states - Add aria-label to mention button, attach button, and upload spinner
- Pull Aa toggle out of AnimatePresence so it never unmounts — layoutId handles the smooth position slide on its own - Remove React.Fragment wrappers — each branch is a single motion.div so AnimatePresence properly tracks enter/exit per element - popLayout mode pops exiting elements out of flow immediately, letting enter animations start at the same time - Ingress group uses order-[-1] to sit before Aa visually - No staggering, no sequencing — one fluid concurrent transition
* origin/main: Replace inline channel creation with dialog (#312) chore: improve chat message layout to left-aligned design (#309) Add edit dialog for managed agents with relay profile sync (#277) fix(ci): build relay with optimized profile to fix flaky e2e tests (#307) Update actions/checkout action to v6 (#305) Update dependency @tanstack/react-query to v5.98.0 (#304) Update dependency @playwright/test to v1.59.1 (#303) Update react monorepo to v19.2.5 (#302) feat(mobile): scaffold Flutter app with Riverpod & Catppuccin theme (#306) Update dependency @tanstack/react-router to v1.168.13 (#301) feat: Markdown-based persona packs (crate + ACP + desktop) (#297) feat(desktop): improve Agents page UX (#298) feat(desktop): add Pulse social notes surface (#296) Fix flaky desktop smoke tests (#294) Add agent lifecycle controls to channel members sidebar (#291) # Conflicts: # desktop/pnpm-lock.yaml
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.
Summary
Category: new-feature
Replace the plain textarea message composer with a full TipTap-based rich text editor. This adds inline formatting controls, image upload as context chips with autocomplete, and keyboard shortcuts for common actions.
What Changed
useRichTextEditorhook encapsulates editor setup, extensions, and state management, replacing the plain<textarea>inMessageComposerFormattingToolbarcomponent with toggle buttons for bold, italic,strikethrough,code, and link insertionimageRefExtensionTipTap extension,useImageRefSuggestionshook, andImageRefAutocompleteUI allow users to reference uploaded images inline as context chipsComposerAttachmentscomponent displays uploaded media previews beneath the editorTogglecomponent built on Radix UIComposerMentionOverlay(replaced by TipTap-native mention/ref system)globals.cssadditions for TipTap editor styling; minor layout tweaks inChannelPaneandsidebarpackage.json;Cargo.tomlversion bumpFile changes (17 files: +1973 −390)
New files (7)
desktop/src/features/messages/lib/imageRefExtension.ts— TipTap node extension for image ref chipsdesktop/src/features/messages/lib/useImageRefSuggestions.ts— hook for image ref autocomplete suggestionsdesktop/src/features/messages/lib/useRichTextEditor.ts— hook encapsulating TipTap editor setupdesktop/src/features/messages/ui/ComposerAttachments.tsx— uploaded media preview componentdesktop/src/features/messages/ui/FormattingToolbar.tsx— bold/italic/strikethrough/code/link toolbardesktop/src/features/messages/ui/ImageRefAutocomplete.tsx— autocomplete dropdown for image refsdesktop/src/shared/ui/toggle.tsx— Radix-based Toggle primitiveModified files (9)
Cargo.toml— version bumpdesktop/package.json— TipTap + Radix toggle dependenciesdesktop/pnpm-lock.yaml— lockfile updatedesktop/src/features/channels/ui/ChannelPane.tsx— layout adjustmentdesktop/src/features/messages/lib/useMediaUpload.ts— refactored for chip-based uploadsdesktop/src/features/messages/ui/MessageComposer.tsx— rewired to TipTap editordesktop/src/features/messages/ui/MessageComposerToolbar.tsx— updated toolbar integrationdesktop/src/shared/styles/globals.css— TipTap editor stylesdesktop/src/shared/ui/sidebar.tsx— minor tweakDeleted files (1)
desktop/src/features/messages/ui/ComposerMentionOverlay.tsx— replaced by TipTap mention systemHow to Test
tho/richtext-editorand runpnpm install && pnpm tauri devScreenshots
Generated with Goose