Skip to content

feat: add @rocket.chat/gazzodown-alt package for real-time WYSIWYG rendering#39888

Draft
MartinSchoeler wants to merge 1 commit intopoc/gazzodown-altfrom
cursor/gazzodown-real-time-replacement-bfca
Draft

feat: add @rocket.chat/gazzodown-alt package for real-time WYSIWYG rendering#39888
MartinSchoeler wants to merge 1 commit intopoc/gazzodown-altfrom
cursor/gazzodown-real-time-replacement-bfca

Conversation

@MartinSchoeler
Copy link
Copy Markdown
Member

Proposed changes (including videos or screenshots)

Adds a new @rocket.chat/gazzodown-alt package that provides an alternative to @rocket.chat/gazzodown, optimized for real-time rendering in WYSIWYG text fields (composer/editor contexts).

Problem

The existing gazzodown package renders message markup using block-level elements (<div> for paragraphs, <br> for line breaks), which causes issues with newlines when used inside a WYSIWYG input field for real-time preview rendering.

Solution

The new gazzodown-alt package consumes the same AST produced by @rocket.chat/message-parser (the same grammar.pegjs file), but outputs inline-friendly React elements suitable for real-time rendering as the user types:

Feature gazzodown gazzodown-alt
Paragraph rendering <div> (block) <span> (inline)
Line breaks <br> tags \n characters
Dependencies Fuselage (MessageHighlight, CheckBox, IconButton), hljs, dompurify, date-fns, react-stately Zero runtime deps (only React peer)
Emoji rendering Full EmojiRenderer with DOMPurify Lightweight via context-provided detectEmoji
Mentions Fuselage MessageHighlight + click handlers Simple styled <span> elements
Code blocks hljs syntax highlighting + copy button Plain <code> with monospace styling
Use case Message display (read-only) Composer/editor (real-time WYSIWYG)

Key design decisions

  • Inline-first layout: Everything renders as <span> to avoid disrupting the flow of a WYSIWYG text field
  • Same AST contract: ComposerMarkup accepts tokens: MessageParser.Root just like Markup
  • Customizable via context: ComposerMarkupContext provides emoji detection, mention resolution
  • All components individually exportable: Consumers can compose their own rendering if needed

Exported components

  • ComposerMarkup — Main renderer (drop-in alternative for Markup)
  • ComposerMarkupContext — Context for emoji/mention resolution
  • ComposerInlineElements — Inline element dispatcher
  • Individual elements: ComposerBoldSpan, ComposerItalicSpan, ComposerStrikeSpan, ComposerLinkSpan, ComposerCodeElement, ComposerCodeBlock, ComposerEmojiElement, ComposerMentionUser, ComposerMentionChannel, ComposerSpoilerSpan, ComposerColorElement, ComposerImageElement, ComposerTimestamp, ComposerPlainSpan

Steps to test or reproduce

  1. Import ComposerMarkup from @rocket.chat/gazzodown-alt
  2. Parse input text with @rocket.chat/message-parser's parse() function
  3. Render <ComposerMarkup tokens={parsedTokens} /> inside a WYSIWYG text field
  4. Verify that the output uses inline elements and handles newlines correctly
import { parse } from '@rocket.chat/message-parser';
import { ComposerMarkup } from '@rocket.chat/gazzodown-alt';

const tokens = parse('Hello **world**\nNew line here');
// Renders as inline spans with \n for line breaks
<ComposerMarkup tokens={tokens} />

Further comments

This package intentionally has zero runtime dependencies beyond React (peer dep). It avoids Fuselage components, hljs, dompurify, and other heavy dependencies that gazzodown uses, keeping the bundle lightweight for real-time re-rendering on every keystroke.

Open in Web Open in Cursor 

…ndering

This new package provides an alternative to @rocket.chat/gazzodown that is
optimized for real-time rendering in WYSIWYG text fields.

Key differences from gazzodown:
- Renders paragraphs as <span> instead of <div> for inline layout
- Represents line breaks with newline characters instead of <br> tags
- No heavy Fuselage UI dependencies (MessageHighlight, CheckBox, etc.)
- Minimal footprint suitable for re-rendering on every keystroke
- Consumes the same AST from @rocket.chat/message-parser (grammar.pegjs)

Exported components:
- ComposerMarkup: Main renderer (drop-in for Markup)
- ComposerMarkupContext: Context for emoji/mention resolution
- Individual inline elements (Bold, Italic, Strike, Code, Emoji, etc.)

Co-authored-by: Martin Schoeler <martin.schoeler@rocket.chat>
@dionisio-bot
Copy link
Copy Markdown
Contributor

dionisio-bot bot commented Mar 26, 2026

Looks like this PR is not ready to merge, because of the following issues:

  • This PR is missing the 'stat: QA assured' label
  • This PR is missing the required milestone or project

Please fix the issues and try again

If you have any trouble, please check the PR guidelines

@CLAassistant
Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 26, 2026

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 7b3f365f-8777-4c3e-b46e-eb4e1a599b58

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Mar 26, 2026

⚠️ No Changeset found

Latest commit: 4b0b711

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@codecov
Copy link
Copy Markdown

codecov bot commented Mar 26, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
⚠️ Please upload report for BASE (poc/gazzodown-alt@da43bb9). Learn more about missing BASE report.

Additional details and impacted files

Impacted file tree graph

@@                 Coverage Diff                  @@
##             poc/gazzodown-alt   #39888   +/-   ##
====================================================
  Coverage                     ?   70.85%           
====================================================
  Files                        ?     3196           
  Lines                        ?   113198           
  Branches                     ?    20498           
====================================================
  Hits                         ?    80205           
  Misses                       ?    30943           
  Partials                     ?     2050           
Flag Coverage Δ
unit 71.57% <ø> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

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.

3 participants