Skip to content

Commit

Permalink
PATCH: extend renderers/react/renderToCanvas to do lit/react hydratio…
Browse files Browse the repository at this point in the history
…n for hydratable elements
  • Loading branch information
eins78 committed Jul 4, 2024
1 parent 37a407a commit 5b1e26c
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 1 deletion.
24 changes: 24 additions & 0 deletions code/renderers/react/src/react-dom-hydrate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import type { ReactElement } from 'react';
import { type Root, hydrateRoot } from 'react-dom/client';

// A map of all rendered React 18 nodes
const nodes = new Map<Element, Root>();

// similar to renderElement from code/lib/react-dom-shim/src/react-18.tsx
// but perform hydration not rendering
export const hydrateElement = async (node: ReactElement, el: Element) => {
return new Promise((resolve) => {
const root = hydrateRoot(el, node);
nodes.set(el, root);
resolve(null);
});
};

export const unmountElement = (el: Element) => {
const root = nodes.get(el);

if (root) {
root.unmount();
nodes.delete(el);
}
};
9 changes: 8 additions & 1 deletion code/renderers/react/src/renderToCanvas.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import type { FC } from 'react';
import React, { Component as ReactComponent, StrictMode, Fragment } from 'react';
import { renderElement, unmountElement } from '@storybook/react-dom-shim';

import { hydrateElement } from './react-dom-hydrate';

import type { RenderContext } from '@storybook/types';

import type { ReactRenderer, StoryContext } from './types';
Expand Down Expand Up @@ -74,7 +76,12 @@ export async function renderToCanvas(
unmountElement(canvasElement);
}

await renderElement(element, canvasElement, storyContext?.parameters?.react?.rootOptions);
const ssrEnabled = canvasElement.firstElementChild?.hasAttribute('hydratable') || false;
if (ssrEnabled) {
await hydrateElement(element, canvasElement);
} else {
await renderElement(element, canvasElement);
}

return () => unmountElement(canvasElement);
}

0 comments on commit 5b1e26c

Please sign in to comment.