feat: add jsonToHtmlAsync and jsonToReact output modes#100
Draft
glassdimlygr wants to merge 2 commits intocontentstack:masterfrom
Draft
feat: add jsonToHtmlAsync and jsonToReact output modes#100glassdimlygr wants to merge 2 commits intocontentstack:masterfrom
glassdimlygr wants to merge 2 commits intocontentstack:masterfrom
Conversation
6cbbd2d to
c2200a4
Compare
Add toRedactorAsync (exported as jsonToHtmlAsync) that supports customElementTypes handlers returning string | Promise<string>. Enables dynamic component resolution (e.g. await import()) before serialization. Children are resolved via Promise.all concurrently. Refactors shared logic (text processing, attr building, element node processing) into toRedactorHelpers.ts so both sync and async versions are thin recursive shells with no duplicated code. The existing sync jsonToHtml behavior is unchanged. New types: IJsonToHtmlAsyncElementTags, IJsonToHtmlAsyncOptions.
c2200a4 to
44da5fa
Compare
Add toReactTree.tsx which walks the JSON RTE document and returns ReactNode instead of HTML strings. Handlers receive (jsonBlock, children) and return ReactNode directly, enabling real React component rendering without renderToStaticMarkup. - New exports: jsonToReact, IJsonToReactOptions, IJsonToReactElementHandler, IJsonToReactTextHandler - React is a peer dependency (optional) and externalized from the bundle - Default handlers map all standard element types to JSX equivalents - Text mark handlers (bold, italic, etc.) wrap children in semantic elements
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
Adds two new output modes to the serializer, both purely additive — existing
jsonToHtml/htmlToJson/jsonToMarkdownare untouched.jsonToHtmlAsync— async variant ofjsonToHtmlwherecustomElementTypeshandlers can returnPromise<string>jsonToReact— React element tree output mode where handlers returnReactNodedirectlyBoth modes are opt-in: consumers import the one they need.
jsonToHtmlAsyncMotivation
Frameworks like Next.js use dynamic imports (
next/dynamic,React.lazy) for code-splitting. When rendering JSON RTE content that contains embedded component references, the component modules may not be available synchronously. Currently,jsonToHtmlrequires all handlers to return strings synchronously, making it impossible toawait import()a component before rendering it.Changes
toRedactorAsync(exported asjsonToHtmlAsync): Async version oftoRedactor. Children are resolved concurrently viaPromise.all. Handler results areawaited, so both sync (string) and async (Promise<string>) return values work.IJsonToHtmlAsyncElementTags: Handler signature where return type isstring | Promise<string>IJsonToHtmlAsyncOptions: Options interface using the async element tags typeUsage
jsonToReactMotivation
jsonToHtmlserializes JSON RTE to an HTML string, which then needsdangerouslySetInnerHTMLto render in React. This has several downsides:renderToStaticMarkuplimitations: Can't resolve lazy/dynamic imports on the client, breaks hydrationdangerouslySetInnerHTMLbypasses React's XSS protectionsjsonToReactreturns a real React element tree instead. Custom handlers receive the JSON block and pre-rendered children asReactNode, and returnReactNodedirectly.Changes
toReactTree.tsx(exported asjsonToReact): Walks the JSON RTE document and composes React elements. Default handlers map all standard types to JSX equivalents (p→<p>,h1→<h1>,a→<a>, etc.)IJsonToReactElementHandler:(jsonBlock, children: ReactNode) => ReactNode— cleaner than the string mode signature since handlers get the full JSON block (no pre-serialized attrs string) and real React childrenIJsonToReactTextHandler:(children: ReactNode, value?) => ReactNode— for text marks (bold, italic, etc.)IJsonToReactOptions:{ customElementTypes?, customTextMarks? }react >= 16inpeerDependencieswithoptional: true. Externalized from the esbuild bundle so it's not bundled into the output.Handler signature comparison
Usage
What's NOT changed
jsonToHtml/toRedactor— completely untouchedhtmlToJson/fromRedactor— completely untouchedjsonToMarkdown— completely untouchedTests
jsonToHtmlAsyncjsonToHtmlfor all existing test casesjsonToReact