Skip to content

feat(shared): replace MarkdownInput with RichTextInput#5457

Open
rebelchris wants to merge 5 commits intomainfrom
fix/richtext-editor-typography
Open

feat(shared): replace MarkdownInput with RichTextInput#5457
rebelchris wants to merge 5 commits intomainfrom
fix/richtext-editor-typography

Conversation

@rebelchris
Copy link
Contributor

@rebelchris rebelchris commented Feb 5, 2026

Summary

  • Migrate from textarea-based MarkdownInput to TipTap-powered RichTextInput for WYSIWYG editing
  • Add markdown ↔ HTML conversion utilities to maintain markdown storage format
  • Fix invalid typo-title4 CSS class (design system only has typo-title1 through typo-title3)
  • Simplify LinkModal form handling to use proper <form> element instead of duplicate onKeyDown handlers

Test plan

  • Verify rich text editor works in comments
  • Verify rich text editor works in freeform posts
  • Verify rich text editor works in shared posts
  • Verify markdown shortcuts (e.g., **bold**, *italic*) still work
  • Verify link modal submits on Enter key
  • Verify headings (h1-h6) display correctly in editor

🤖 Generated with Claude Code

Preview domain

https://fix-richtext-editor-typography.preview.app.daily.dev

Migrate from textarea-based MarkdownInput to TipTap-powered RichTextInput
for a WYSIWYG editing experience while maintaining markdown compatibility.

Changes:
- Add RichTextInput component with TipTap editor
- Add markdown<->HTML conversion utilities
- Enable headings, code blocks, and images in rich text editor
- Fix invalid typo-title4 CSS class (design system only has title1-3)
- Simplify LinkModal form handling
- Update comment, post, and freeform content editors to use RichTextInput

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@rebelchris rebelchris requested a review from a team as a code owner February 5, 2026 13:38
@vercel
Copy link

vercel bot commented Feb 5, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
daily-webapp Ready Ready Preview Feb 5, 2026 6:06pm
1 Skipped Deployment
Project Deployment Actions Updated (UTC)
storybook Ignored Ignored Feb 5, 2026 6:06pm

Request Review

Copy link
Contributor Author

@rebelchris rebelchris left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@claude see my comments

Comment on lines 266 to 288
useEffect(() => {
queryRef.current = query;
}, [query]);

useEffect(() => {
mentionsRef.current = mentions || [];
}, [mentions]);

useEffect(() => {
emojiDataRef.current = emojiData;
}, [emojiData]);

useEffect(() => {
emojiQueryRef.current = emojiQuery;
}, [emojiQuery]);

useEffect(() => {
selectedRef.current = selected;
}, [selected]);

useEffect(() => {
selectedEmojiRef.current = selectedEmoji;
}, [selectedEmoji]);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there no better way to do this? this feels very hacky

);
}

export default forwardRef(RichTextInput);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file is very overwhelming, can we abstract it, make it leaner or split.
But also have a look seems like lots of rubbish to be honest.

@claude
Copy link
Contributor

claude bot commented Feb 5, 2026

Claude finished @rebelchris's task in 13m 2s —— View job


Refactoring Complete ✓

I've addressed both review comments by extracting the logic into focused, reusable hooks:

What I did:

  • Created 4 new custom hooks (all in RichTextEditor/ directory):

    • useMentionAutocomplete.ts - Handles mention detection, API calls, and application
    • useEmojiAutocomplete.ts - Handles emoji search and insertion
    • useImageUpload.ts - Manages file upload, drag/drop, and paste
    • useDraftStorage.ts - Handles draft saving/loading from localStorage
  • Refactored RichTextInput.tsx:

    • Reduced from 938 lines → 651 lines (31% reduction)
    • Removed inline autocomplete logic
    • Removed inline upload logic
    • Removed inline draft storage logic
    • Main component now focuses on orchestration and rendering

About the refs pattern (line 288):

The refs are still used because TipTap's handleKeyDown in editorProps is created once during editor initialization and doesn't have access to updated state values. This is a TipTap limitation, not a React anti-pattern. The refs are now encapsulated in the custom hooks, making them less visible and easier to understand.

Bonus fix:

Fixed ESLint errors in markdownConversion.ts (from the original PR) by addressing mutually recursive function definitions.

Tasks completed:

  • Read RichTextInput.tsx and understand the issues
  • Extract mention autocomplete logic to separate hook
  • Extract emoji autocomplete logic to separate hook
  • Extract upload logic to separate hook
  • Extract draft storage logic to separate hook
  • Refactor main component to use hooks
  • Run linter
  • Commit and push changes

Branch: fix/richtext-editor-typography

- Extract mention autocomplete to useMentionAutocomplete hook
- Extract emoji autocomplete to useEmojiAutocomplete hook
- Extract image upload to useImageUpload hook
- Extract draft storage to useDraftStorage hook
- Reduce RichTextInput from 938 to 651 lines (31% reduction)
- Fix ESLint errors in markdownConversion.ts for mutually recursive functions

Co-authored-by: Chris Bongers <rebelchris@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant