Skip to content

feat(mdxish): always compile callouts to JSX in mdxishMdastToMd#1498

Open
eaglethrost wants to merge 16 commits into
nextfrom
dimas/rm-16782-update-callout-compiler-to-jsx
Open

feat(mdxish): always compile callouts to JSX in mdxishMdastToMd#1498
eaglethrost wants to merge 16 commits into
nextfrom
dimas/rm-16782-update-callout-compiler-to-jsx

Conversation

@eaglethrost

@eaglethrost eaglethrost commented May 29, 2026

Copy link
Copy Markdown
Contributor
🎫 Resolve RM-16782

Note

This PR is blocking readme PR https://github.com/readmeio/readme/pull/17745 & should be markdown bumped in that PR since it contains breaking change

🎯 What does this PR do?

Updates the mdxish callout serializer (mdxishMdastToMd) to always compile callouts to <Callout> JSX syntax instead of the legacy MD blockquote format.

PR #17745 adds icon + color selection for callouts in the MdxishEditor UI, but the engine always serialized callouts to the legacy blockquote (> 📘 Hey), which dropped any custom icon/theme on round-trip. This PR persists those selections.

  • Adds processor/transform/mdxish/callout-to-jsx.ts — a transform that converts every rdme-callout mdast node into an mdxJsxFlowElement (<Callout icon=… theme=…>), reusing toAttributes and the mdxJsxStringify extension already wired into mdxishMdastToMd.
  • Registers the transform in mdxishMdastToMd (alongside mdxishTablesToJsx). The RMDX (mdx) pipeline and the shared processor/compile/callout.ts blockquote compiler are untouched, so RMDX behavior is unchanged.

Also in order for the Callout to render the far icons, we need to adjust the Icon rendering such that it can properly apply them, so we bring over the work from #1492 where we create a centralised Icon component to support those icons.

Note

But the Icon adjustment is a breaking change if there's custom CSS that specifically targets <span> + callout icon classes, since Icon uses <i> to render font awesome icons instead of <span>. Though I think this is a necessary tradeoff and people should be aware of it.

🧪 QA tips

Note

Test this with the readme PR https://github.com/readmeio/readme/pull/17745 which adds an emoji picker & allows adding font awesome icons to callout

  1. In the readme app, in a project using Mdxish Editor:
  • Insert a callout from the slash menu and add a title & body. During the round trip, the title should get retained. The serializer should convert the title to ### title
  • Paste a block quote callout to the editor, it should serialise them to and the title should be prepend to ###. Use this:
    > 🚧 Title
    > Body
    
  • Round-trips are stable, e.g. > 🚧 It works!<Callout icon="🚧" theme="warn">### It works!…</Callout>, body-only callouts re-derive empty: true, and authored JSX callouts round-trip unchanged in shape.
  • Try out the 3 different types of icons from the icon picker menu: 1) Emoji icons 2) Far icons 3) Duotone in the callout, and make sure they get rendered in the editor, as well as in the view mode
  1. In the local markdown demo app, create callouts with font awesome icons, and they should now render in mdxish and mdx. Example:
<Callout icon="far fa-car-bolt" theme="info">
  ### Title

  Description

  <Callout icon="far fa-circle-chevron-right" theme="success">
    ### Title

    Description

    <Callout icon="far fa-phone-arrow-up-right" theme="warn">
      ### Title

      Description

      <Callout icon="fad fa-wagon-covered" theme="error">
        ### Title

        <Callout icon="far fa-ring-diamond" theme="info">
          ### Title

          This is an MDX-style callout component.
        </Callout>
      </Callout>
    </Callout>
  </Callout>
</Callout>

📸 Screenshot or Loom

Before:

Screen.Recording.2026-06-01.at.6.54.56.pm.mov

After (with the callout editor serializer changed locally):

Screen.Recording.2026-06-01.at.6.56.27.pm.mov

Testing with the callout icon menu change (with the callout editor serializer changed locally):

Screen.Recording.2026-06-01.at.7.05.41.pm.mov

@eaglethrost eaglethrost marked this pull request as ready for review June 1, 2026 09:12
@eaglethrost eaglethrost requested review from kevinports and rafegoldberg and removed request for kevinports June 1, 2026 11:30
@kevinports

Copy link
Copy Markdown
Contributor

So this has a breaking change to the mdxish editor callout serializer in the monorepo? should we take over PR #17745 and make updates there and coordinate them landing at the same time?

@kevinports kevinports left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Overall looks good! Just wanted to chat about the breaking change in the monorepo before we merge this.

@eaglethrost

Copy link
Copy Markdown
Contributor Author

Overall looks good! Just wanted to chat about the breaking change in the monorepo before we merge this.

Yep added the breaking change in the monorepo PR table serializer! https://github.com/readmeio/readme/pull/17745

@eaglethrost eaglethrost requested a review from kevinports June 4, 2026 08:39

@kevinports kevinports left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code looks good to me.

Noticed one issue QAing locally with the monorepo linked. I'm not seeing some of the font-awesome icon types rendering correctly:

CleanShot.2026-06-04.at.13.48.41.mp4

We may need to make similar changes to my work here https://github.com/readmeio/markdown/pull/1492/changes to support different icon types?

@eaglethrost eaglethrost requested review from a team, jbury and kevinports June 5, 2026 07:40
@eaglethrost eaglethrost requested review from jamestclark and removed request for jbury June 5, 2026 09:05
@eaglethrost

eaglethrost commented Jun 5, 2026

Copy link
Copy Markdown
Contributor Author

Noticed one issue QAing locally with the monorepo linked. I'm not seeing some of the font-awesome icon types rendering correctly

Had a look at this, it seems to only affect "far" icons (fad & others are fine), which are all of the icons in the Icon section in the emoji picker. It looks like this issue comes from the Callout component style itself, particularly:

  &-icon::before {
    content: var(--icon);

It seems to not have caught on the far icon data, we can fix it by adding a fallback variable like content: var(--icon, var(--fa));

But actually using your changes in #1492 works as well, we need to reuse the Icon component in the Callout & that will render the far icons fine. Since we're going to merge that, I'll merge that over here as well & reuse the Icon component.

Demo of it working in monorepo, before the "Icons" emoji would not render, but the duotones would:

Screen.Recording.2026-06-05.at.7.04.25.pm.mov

@eaglethrost eaglethrost Jun 5, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The Callout now renders icons through the Icon component, which emits FA icons as <i> (instead of <span class="callout-icon_fa">), so we need to retarget the icon style to i/span and scope the ::before glyph to span only, which prevents the legacy icon-font glyph from double-stacking on top of Font Awesome's own glyph

@kevinports kevinports left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Sorry one thing just occurred to me for the Icon component --

Some users may target the existing icon markup for custom styles, and these changes could potentially break any custom css targeting these nodes.

Can you take a look at each of the components consuming the Icon and ensure that the DOM and classnames for existing FA icons are retained, and we only add support for emojis and different FA icon styles in an additive way?

@gkoberger gkoberger force-pushed the dimas/rm-16782-update-callout-compiler-to-jsx branch from 6d7654e to 961feaa Compare June 7, 2026 00:20
@jboyens jboyens force-pushed the dimas/rm-16782-update-callout-compiler-to-jsx branch from 961feaa to 6d7654e Compare June 8, 2026 18:00
@eaglethrost

eaglethrost commented Jun 9, 2026

Copy link
Copy Markdown
Contributor Author

Some users may target the existing icon markup for custom styles, and these changes could potentially break any custom css targeting these nodes.

Can you take a look at each of the components consuming the Icon and ensure that the DOM and classnames for existing FA icons are retained, and we only add support for emojis and different FA icon styles in an additive way?

Yep, regarding this there'll be a bit more issue with callouts because before it was using <span> for both emoji & font awesome icon, but now the Icon component uses the <i> tag for font awesome. So in theory, any custom css that specifically targets <span> elements + the callout style classes would no longer apply after this change.

However, using <i> is a necessary fix to allow font awesome icons to render correctly in Callout as before it wasn't rendering it at all, so I think we don't have a choice to avoid this tradeoff. For what it's worth, I do think there should be a low chance of the above custom CSS rule being present because right now there's no way to add a font awesome icon to Callouts from the editor, and it's not working anyway. So I'd say we can still push this adjustment & communicate of the breaking change.

<span className={`callout-icon callout-icon_fa ${icon}`} />
)
) : null}
{icon ? <Icon className="callout-icon" faClassName="callout-icon_fa" icon={icon} /> : null}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Since Icon uses <i> to render font awesome icon, now it'll no longer use <span>, which is a breaking change if there's custom CSS that specifically targets <span> + callout icon classes. But this is a necessary fix to make font awesome icon renderable in Callouts, currently it doesn't render at all.

@eaglethrost eaglethrost requested review from davinhazard and kevinports and removed request for kevinports June 9, 2026 06:58
@gkoberger gkoberger force-pushed the dimas/rm-16782-update-callout-compiler-to-jsx branch from 4a8d854 to 921630d Compare June 11, 2026 07:00
@jboyens jboyens force-pushed the dimas/rm-16782-update-callout-compiler-to-jsx branch from 921630d to 4a8d854 Compare June 11, 2026 07:41
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.

2 participants