From 163633406d85850d32d68b00442fc42829ef9003 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Fri, 26 Nov 2021 16:12:05 +1100 Subject: [PATCH 1/3] Wait for the story component to render before emitting --- addons/docs/src/blocks/Story.tsx | 36 ++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/addons/docs/src/blocks/Story.tsx b/addons/docs/src/blocks/Story.tsx index 65fdb19c1e72..2d7de49a1014 100644 --- a/addons/docs/src/blocks/Story.tsx +++ b/addons/docs/src/blocks/Story.tsx @@ -111,6 +111,14 @@ export const getStoryProps = ( }; }; +function makeGate(): [Promise, () => void] { + let open; + const gate = new Promise((r) => { + open = r; + }); + return [gate, open]; +} + const Story: FunctionComponent = (props) => { const context = useContext(DocsContext); const channel = addons.getChannel(); @@ -145,16 +153,32 @@ const Story: FunctionComponent = (props) => { return () => cleanup && cleanup(); }, [story]); - if (!story) { - return ; - } + const [storyFnRan, onStoryFnRan] = makeGate(); + const [rendered, onRendered] = makeGate(); + useEffect(onRendered); // If we are rendering a old-style inline Story via `PureStory` below, we want to emit // the `STORY_RENDERED` event when it renders. The modern mode below calls out to // `Preview.renderStoryToDom()` which itself emits the event. - const storyProps = getStoryProps(props, story, context, () => - channel.emit(Events.STORY_RENDERED, storyId) - ); + if (story && !global?.FEATURES?.modernInlineRender) { + // We need to wait for two things before we can consider the story rendered: + // (a) React's `useEffect` hook needs to fire. This is needed for React stories, as + // decorators of the form `` will not actually execute `B` in the first + // call to the story function. + // (b) The story function needs to acutally have been called. + // Certain frameworks (i.e.angular) don't actually render the component in the very first + // React render cycle, so we need to wait for the framework to actually do that + Promise.all([storyFnRan, rendered]).then(() => { + console.log('called story fn', story.id); + channel.emit(Events.STORY_RENDERED, storyId); + }); + } + + if (!story) { + return ; + } + + const storyProps = getStoryProps(props, story, context, onStoryFnRan); if (!storyProps) { return null; } From 809b59efd86a68a672e97464bdc2bef41b04f60e Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Fri, 26 Nov 2021 16:17:09 +1100 Subject: [PATCH 2/3] Remove console log --- addons/docs/src/blocks/Story.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/addons/docs/src/blocks/Story.tsx b/addons/docs/src/blocks/Story.tsx index 2d7de49a1014..97c6b2e102cb 100644 --- a/addons/docs/src/blocks/Story.tsx +++ b/addons/docs/src/blocks/Story.tsx @@ -169,7 +169,6 @@ const Story: FunctionComponent = (props) => { // Certain frameworks (i.e.angular) don't actually render the component in the very first // React render cycle, so we need to wait for the framework to actually do that Promise.all([storyFnRan, rendered]).then(() => { - console.log('called story fn', story.id); channel.emit(Events.STORY_RENDERED, storyId); }); } From 068ee391a2b88c1ff11faaa9228b9eec41748e89 Mon Sep 17 00:00:00 2001 From: Tom Coleman Date: Fri, 26 Nov 2021 16:17:55 +1100 Subject: [PATCH 3/3] Fix typo --- addons/docs/src/blocks/Story.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/docs/src/blocks/Story.tsx b/addons/docs/src/blocks/Story.tsx index 97c6b2e102cb..9e0ef93c17d4 100644 --- a/addons/docs/src/blocks/Story.tsx +++ b/addons/docs/src/blocks/Story.tsx @@ -165,7 +165,7 @@ const Story: FunctionComponent = (props) => { // (a) React's `useEffect` hook needs to fire. This is needed for React stories, as // decorators of the form `` will not actually execute `B` in the first // call to the story function. - // (b) The story function needs to acutally have been called. + // (b) The story function needs to actually have been called. // Certain frameworks (i.e.angular) don't actually render the component in the very first // React render cycle, so we need to wait for the framework to actually do that Promise.all([storyFnRan, rendered]).then(() => {