From 70009976c0f0f94cf691324b6deede9822896b0a Mon Sep 17 00:00:00 2001 From: chakir qatab Date: Tue, 7 Feb 2023 02:30:40 +0400 Subject: [PATCH 01/12] fix reactivity call storyFn in vue render function --- code/renderers/vue3/src/decorateStory.ts | 16 +++++++++------- code/renderers/vue3/src/render.ts | 14 ++++++-------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/code/renderers/vue3/src/decorateStory.ts b/code/renderers/vue3/src/decorateStory.ts index f93135251e3b..b8626bc207b2 100644 --- a/code/renderers/vue3/src/decorateStory.ts +++ b/code/renderers/vue3/src/decorateStory.ts @@ -47,13 +47,11 @@ export function decorateStory( return decorators.reduce( (decorated: LegacyStoryFn, decorator) => (context: StoryContext) => { let story: VueRenderer['storyResult'] | undefined; - if (!isReactive(context.args)) context.args = reactive(context.args); + if (!isReactive(context.args)) { + context.args = reactive(context.args); + } const decoratedStory: VueRenderer['storyResult'] = decorator((update) => { - const updatedArgs = - update?.args && !isReactive(update.args) - ? { ...update, args: reactive(update.args) } - : update; - + const updatedArgs = update; story = decorated({ ...context, ...sanitizeStoryContextUpdate(updatedArgs), @@ -68,8 +66,12 @@ export function decorateStory( if (decoratedStory === story) { return story; } + return prepare(decoratedStory, story) as VueRenderer['storyResult']; }, - (context) => prepare(storyFn(context)) as LegacyStoryFn + (context) => { + const story = storyFn(context).props ? h(storyFn(context), context.args) : storyFn(context); + return prepare(story) as LegacyStoryFn; + } ); } diff --git a/code/renderers/vue3/src/render.ts b/code/renderers/vue3/src/render.ts index b05f62796b28..4d3341ed1391 100644 --- a/code/renderers/vue3/src/render.ts +++ b/code/renderers/vue3/src/render.ts @@ -13,7 +13,7 @@ export const render: ArgsStoryFn = (props, context) => { `Unable to render story ${id} as the component annotation is missing from the default export` ); } - + console.log('---render props :', props); return h(Component, props, getSlots(props, context)); }; @@ -40,9 +40,9 @@ export function renderToCanvas( }: RenderContext, canvasElement: VueRenderer['canvasElement'] ) { - let { reactiveArgs } = useReactive(storyContext); - // fetch the story with the updated context (with reactive args) - const element: StoryFnVueReturnType = storyFn(storyContext); + const element: StoryFnVueReturnType = storyFn(); + + const reactiveArgs = reactive((element as any).render?.().props ?? storyContext.args); if (!element) { showError({ @@ -54,9 +54,6 @@ export function renderToCanvas( }); return () => {}; } - // getting the props from the render function - const props = (element as any).render?.().props; - if (props) reactiveArgs = reactive(props); const existingApp = map.get(canvasElement); @@ -70,7 +67,8 @@ export function renderToCanvas( const storybookApp = createApp({ render() { map.set(canvasElement, { vueApp: storybookApp, reactiveArgs }); - return h(element, reactiveArgs); + const story = storyFn(); + return h(story, reactiveArgs); }, }); From 5619096fb8abfe7d26bbbc11a727b0e58bb7bafc Mon Sep 17 00:00:00 2001 From: chakir qatab Date: Tue, 7 Feb 2023 02:53:24 +0400 Subject: [PATCH 02/12] fix reactivity decorated stories+ CSF2 support --- code/renderers/vue3/src/decorateStory.ts | 16 +++++++++------- code/renderers/vue3/src/render.ts | 12 ++++++------ 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/code/renderers/vue3/src/decorateStory.ts b/code/renderers/vue3/src/decorateStory.ts index f93135251e3b..b8626bc207b2 100644 --- a/code/renderers/vue3/src/decorateStory.ts +++ b/code/renderers/vue3/src/decorateStory.ts @@ -47,13 +47,11 @@ export function decorateStory( return decorators.reduce( (decorated: LegacyStoryFn, decorator) => (context: StoryContext) => { let story: VueRenderer['storyResult'] | undefined; - if (!isReactive(context.args)) context.args = reactive(context.args); + if (!isReactive(context.args)) { + context.args = reactive(context.args); + } const decoratedStory: VueRenderer['storyResult'] = decorator((update) => { - const updatedArgs = - update?.args && !isReactive(update.args) - ? { ...update, args: reactive(update.args) } - : update; - + const updatedArgs = update; story = decorated({ ...context, ...sanitizeStoryContextUpdate(updatedArgs), @@ -68,8 +66,12 @@ export function decorateStory( if (decoratedStory === story) { return story; } + return prepare(decoratedStory, story) as VueRenderer['storyResult']; }, - (context) => prepare(storyFn(context)) as LegacyStoryFn + (context) => { + const story = storyFn(context).props ? h(storyFn(context), context.args) : storyFn(context); + return prepare(story) as LegacyStoryFn; + } ); } diff --git a/code/renderers/vue3/src/render.ts b/code/renderers/vue3/src/render.ts index b05f62796b28..38025ce843ea 100644 --- a/code/renderers/vue3/src/render.ts +++ b/code/renderers/vue3/src/render.ts @@ -40,9 +40,11 @@ export function renderToCanvas( }: RenderContext, canvasElement: VueRenderer['canvasElement'] ) { - let { reactiveArgs } = useReactive(storyContext); // fetch the story with the updated context (with reactive args) - const element: StoryFnVueReturnType = storyFn(storyContext); + + const element: StoryFnVueReturnType = storyFn(); + + const reactiveArgs = reactive((element as any).render?.().props ?? storyContext.args); if (!element) { showError({ @@ -54,9 +56,6 @@ export function renderToCanvas( }); return () => {}; } - // getting the props from the render function - const props = (element as any).render?.().props; - if (props) reactiveArgs = reactive(props); const existingApp = map.get(canvasElement); @@ -70,7 +69,8 @@ export function renderToCanvas( const storybookApp = createApp({ render() { map.set(canvasElement, { vueApp: storybookApp, reactiveArgs }); - return h(element, reactiveArgs); + const story = storyFn(); + return h(story, reactiveArgs); }, }); From aabfe9a4dc60ddd1d34a9cd16e6d2e5d02e5b5ac Mon Sep 17 00:00:00 2001 From: chakir qatab Date: Tue, 7 Feb 2023 04:26:28 +0400 Subject: [PATCH 03/12] refactory and optimisation --- code/renderers/vue3/src/render.ts | 41 ++++++------------------------- 1 file changed, 7 insertions(+), 34 deletions(-) diff --git a/code/renderers/vue3/src/render.ts b/code/renderers/vue3/src/render.ts index 4d3341ed1391..136070bc8a2a 100644 --- a/code/renderers/vue3/src/render.ts +++ b/code/renderers/vue3/src/render.ts @@ -1,6 +1,5 @@ /* eslint-disable no-param-reassign */ -import { dedent } from 'ts-dedent'; -import { createApp, h, reactive, toRefs } from 'vue'; +import { createApp, h } from 'vue'; import type { RenderContext, ArgsStoryFn } from '@storybook/types'; import type { Args, StoryContext } from '@storybook/csf'; @@ -13,7 +12,7 @@ export const render: ArgsStoryFn = (props, context) => { `Unable to render story ${id} as the component annotation is missing from the default export` ); } - console.log('---render props :', props); + return h(Component, props, getSlots(props, context)); }; @@ -40,25 +39,10 @@ export function renderToCanvas( }: RenderContext, canvasElement: VueRenderer['canvasElement'] ) { - const element: StoryFnVueReturnType = storyFn(); - - const reactiveArgs = reactive((element as any).render?.().props ?? storyContext.args); - - if (!element) { - showError({ - title: `Expecting a Vue component from the story: "${name}" of "${title}".`, - description: dedent` - Did you forget to return the Vue component from the story? - Use "() => ({ template: '' })" or "() => ({ components: MyComp, template: '' })" when defining the story. - `, - }); - return () => {}; - } - const existingApp = map.get(canvasElement); if (existingApp && !forceRemount) { - updateArgs(existingApp.reactiveArgs, reactiveArgs); + updateArgs(existingApp.reactiveArgs, storyContext.args); return () => { teardown(existingApp.vueApp, canvasElement); }; @@ -66,9 +50,10 @@ export function renderToCanvas( const storybookApp = createApp({ render() { - map.set(canvasElement, { vueApp: storybookApp, reactiveArgs }); - const story = storyFn(); - return h(story, reactiveArgs); + const story: any = storyFn(); + const props = story.render?.().props ?? storyContext.args; + map.set(canvasElement, { vueApp: storybookApp, reactiveArgs: props }); + return h(story, props); }, }); @@ -118,15 +103,3 @@ function teardown( storybookApp?.unmount(); if (map.has(canvasElement)) map.delete(canvasElement); } - -/** - * create a reactive args and return it and the refs to avoid losing reactivity when passing it to the story - * @param storyContext - * @returns - */ - -function useReactive(storyContext: StoryContext) { - const reactiveArgs = reactive(storyContext.args || {}); - storyContext.args = toRefs(reactiveArgs); - return { reactiveArgs, refsArgs: storyContext.args }; -} From 2c806b84f932599b91b11ec4d63a2325815148ca Mon Sep 17 00:00:00 2001 From: chakir qatab Date: Tue, 7 Feb 2023 16:50:16 +0400 Subject: [PATCH 04/12] optimise render code --- code/renderers/vue3/src/render.ts | 19 ++++++------------- code/renderers/vue3/src/types.ts | 2 +- 2 files changed, 7 insertions(+), 14 deletions(-) diff --git a/code/renderers/vue3/src/render.ts b/code/renderers/vue3/src/render.ts index 136070bc8a2a..e0d7681b0766 100644 --- a/code/renderers/vue3/src/render.ts +++ b/code/renderers/vue3/src/render.ts @@ -1,9 +1,9 @@ /* eslint-disable no-param-reassign */ -import { createApp, h } from 'vue'; +import { createApp, h, reactive } from 'vue'; import type { RenderContext, ArgsStoryFn } from '@storybook/types'; import type { Args, StoryContext } from '@storybook/csf'; -import type { StoryFnVueReturnType, VueRenderer } from './types'; +import type { VueRenderer } from './types'; export const render: ArgsStoryFn = (props, context) => { const { id, component: Component } = context; @@ -27,16 +27,7 @@ const map = new Map< >(); export function renderToCanvas( - { - storyFn, - forceRemount, - showMain, - showError, - showException, - name, - title, - storyContext, - }: RenderContext, + { storyFn, forceRemount, showMain, showException, storyContext }: RenderContext, canvasElement: VueRenderer['canvasElement'] ) { const existingApp = map.get(canvasElement); @@ -50,8 +41,9 @@ export function renderToCanvas( const storybookApp = createApp({ render() { + storyContext.args = map.get(canvasElement)?.reactiveArgs ?? storyContext.args; const story: any = storyFn(); - const props = story.render?.().props ?? storyContext.args; + const props = reactive(story.render?.().props ?? storyContext.args); map.set(canvasElement, { vueApp: storybookApp, reactiveArgs: props }); return h(story, props); }, @@ -89,6 +81,7 @@ function getSlots(props: Args, context: StoryContext) { * @returns */ function updateArgs(reactiveArgs: Args, nextArgs: Args) { + console.log('updateArgs', reactiveArgs, nextArgs); if (!nextArgs) return; Object.keys(reactiveArgs).forEach((key) => { delete reactiveArgs[key]; diff --git a/code/renderers/vue3/src/types.ts b/code/renderers/vue3/src/types.ts index 15809f9094e2..5046d554a5d4 100644 --- a/code/renderers/vue3/src/types.ts +++ b/code/renderers/vue3/src/types.ts @@ -1,5 +1,5 @@ import type { StoryContext as StoryContextBase, WebRenderer } from '@storybook/types'; -import type { ConcreteComponent } from 'vue'; +import type { ConcreteComponent, VNode } from 'vue'; export type { RenderContext } from '@storybook/types'; From 2bf7a6beb4214466551daecb0cd5b2eab40d292d Mon Sep 17 00:00:00 2001 From: chakir qatab Date: Tue, 7 Feb 2023 16:50:57 +0400 Subject: [PATCH 05/12] cleanup code --- code/renderers/vue3/src/render.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/code/renderers/vue3/src/render.ts b/code/renderers/vue3/src/render.ts index e0d7681b0766..01be86ca8061 100644 --- a/code/renderers/vue3/src/render.ts +++ b/code/renderers/vue3/src/render.ts @@ -81,7 +81,6 @@ function getSlots(props: Args, context: StoryContext) { * @returns */ function updateArgs(reactiveArgs: Args, nextArgs: Args) { - console.log('updateArgs', reactiveArgs, nextArgs); if (!nextArgs) return; Object.keys(reactiveArgs).forEach((key) => { delete reactiveArgs[key]; From 9d8cd0ad9cd2d205e4ceacc78f900ea385c22971 Mon Sep 17 00:00:00 2001 From: chakir qatab Date: Wed, 8 Feb 2023 06:33:06 +0400 Subject: [PATCH 06/12] cleanup after merging next branch --- code/renderers/vue3/src/decorateStory.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/code/renderers/vue3/src/decorateStory.ts b/code/renderers/vue3/src/decorateStory.ts index b8626bc207b2..f2b429378dc1 100644 --- a/code/renderers/vue3/src/decorateStory.ts +++ b/code/renderers/vue3/src/decorateStory.ts @@ -47,9 +47,8 @@ export function decorateStory( return decorators.reduce( (decorated: LegacyStoryFn, decorator) => (context: StoryContext) => { let story: VueRenderer['storyResult'] | undefined; - if (!isReactive(context.args)) { - context.args = reactive(context.args); - } + if (!isReactive(context.args)) context.args = reactive(context.args); + const decoratedStory: VueRenderer['storyResult'] = decorator((update) => { const updatedArgs = update; story = decorated({ @@ -70,8 +69,9 @@ export function decorateStory( return prepare(decoratedStory, story) as VueRenderer['storyResult']; }, (context) => { - const story = storyFn(context).props ? h(storyFn(context), context.args) : storyFn(context); - return prepare(story) as LegacyStoryFn; + const story = storyFn(context); + const storyPrep = story.props ? h(story, context.args) : story; + return prepare(storyPrep) as LegacyStoryFn; } ); } From 0a4df7782cdfccbbeac0a6cc63f0c24c327c9770 Mon Sep 17 00:00:00 2001 From: chakir qatab Date: Wed, 8 Feb 2023 10:03:45 +0400 Subject: [PATCH 07/12] remove unused import --- code/renderers/vue3/src/types.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/renderers/vue3/src/types.ts b/code/renderers/vue3/src/types.ts index 5046d554a5d4..15809f9094e2 100644 --- a/code/renderers/vue3/src/types.ts +++ b/code/renderers/vue3/src/types.ts @@ -1,5 +1,5 @@ import type { StoryContext as StoryContextBase, WebRenderer } from '@storybook/types'; -import type { ConcreteComponent, VNode } from 'vue'; +import type { ConcreteComponent } from 'vue'; export type { RenderContext } from '@storybook/types'; From 9365da98cc3bb2d70f411ea92a83a01205723b33 Mon Sep 17 00:00:00 2001 From: chakir qatab Date: Wed, 8 Feb 2023 16:54:01 +0400 Subject: [PATCH 08/12] fix issue to pass e2e tests --- code/renderers/vue3/src/render.ts | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/code/renderers/vue3/src/render.ts b/code/renderers/vue3/src/render.ts index 01be86ca8061..0c9a7f4eb237 100644 --- a/code/renderers/vue3/src/render.ts +++ b/code/renderers/vue3/src/render.ts @@ -3,7 +3,7 @@ import { createApp, h, reactive } from 'vue'; import type { RenderContext, ArgsStoryFn } from '@storybook/types'; import type { Args, StoryContext } from '@storybook/csf'; -import type { VueRenderer } from './types'; +import type { StoryFnVueReturnType, VueRenderer } from './types'; export const render: ArgsStoryFn = (props, context) => { const { id, component: Component } = context; @@ -26,11 +26,15 @@ const map = new Map< { vueApp: ReturnType; reactiveArgs: any } >(); +let element: StoryFnVueReturnType; + export function renderToCanvas( { storyFn, forceRemount, showMain, showException, storyContext }: RenderContext, canvasElement: VueRenderer['canvasElement'] ) { const existingApp = map.get(canvasElement); + element = storyFn(); + const reactiveArgs = reactive((element as any).render?.().props ?? storyContext.args); if (existingApp && !forceRemount) { updateArgs(existingApp.reactiveArgs, storyContext.args); @@ -41,11 +45,8 @@ export function renderToCanvas( const storybookApp = createApp({ render() { - storyContext.args = map.get(canvasElement)?.reactiveArgs ?? storyContext.args; - const story: any = storyFn(); - const props = reactive(story.render?.().props ?? storyContext.args); - map.set(canvasElement, { vueApp: storybookApp, reactiveArgs: props }); - return h(story, props); + map.set(canvasElement, { vueApp: storybookApp, reactiveArgs }); + return h(element, reactiveArgs); }, }); From b55ac7fb94d8a63b378c22b954f6ce6253aa20e8 Mon Sep 17 00:00:00 2001 From: chakir qatab Date: Fri, 10 Feb 2023 21:30:15 +0400 Subject: [PATCH 09/12] fix ci-tests issues --- .../template/stories/rendering.stories.ts | 23 ++++++++--- code/renderers/vue3/src/decorateStory.ts | 16 ++++---- code/renderers/vue3/src/render.ts | 40 ++++++------------- 3 files changed, 39 insertions(+), 40 deletions(-) diff --git a/code/lib/store/template/stories/rendering.stories.ts b/code/lib/store/template/stories/rendering.stories.ts index eae4c11f4d9d..85870d8d3483 100644 --- a/code/lib/store/template/stories/rendering.stories.ts +++ b/code/lib/store/template/stories/rendering.stories.ts @@ -2,7 +2,12 @@ import { global as globalThis } from '@storybook/global'; import type { PlayFunctionContext } from '@storybook/types'; import { within, waitFor } from '@storybook/testing-library'; import { expect } from '@storybook/jest'; -import { FORCE_REMOUNT, RESET_STORY_ARGS, UPDATE_STORY_ARGS } from '@storybook/core-events'; +import { + FORCE_REMOUNT, + RESET_STORY_ARGS, + STORY_ARGS_UPDATED, + UPDATE_STORY_ARGS, +} from '@storybook/core-events'; export default { component: globalThis.Components.Button, @@ -40,21 +45,29 @@ export const ForceRemount = { export const ChangeArgs = { play: async ({ canvasElement, id }: PlayFunctionContext) => { const channel = globalThis.__STORYBOOK_ADDONS_CHANNEL__; + + await channel.emit(RESET_STORY_ARGS, { storyId: id }); + await new Promise((resolve) => { + channel.once(STORY_ARGS_UPDATED, resolve); + }); + const button = await within(canvasElement).findByRole('button'); await button.focus(); await expect(button).toHaveFocus(); + await new Promise((resolve) => setTimeout(resolve, 1000)); + // Web-components: https://github.com/storybookjs/storybook/issues/19415 // Preact: https://github.com/storybookjs/storybook/issues/19504 + if (['web-components', 'html', 'preact'].includes(globalThis.storybookRenderer)) return; // When we change the args to the button, it should not remount await channel.emit(UPDATE_STORY_ARGS, { storyId: id, updatedArgs: { label: 'New Text' } }); + await new Promise((resolve) => { + channel.once(STORY_ARGS_UPDATED, resolve); + }); await within(canvasElement).findByText(/New Text/); await expect(button).toHaveFocus(); - - await channel.emit(RESET_STORY_ARGS, { storyId: id }); - await within(canvasElement).findByText(/Click me/); - await expect(button).toHaveFocus(); }, }; diff --git a/code/renderers/vue3/src/decorateStory.ts b/code/renderers/vue3/src/decorateStory.ts index f93135251e3b..e12a70bb666d 100644 --- a/code/renderers/vue3/src/decorateStory.ts +++ b/code/renderers/vue3/src/decorateStory.ts @@ -47,12 +47,10 @@ export function decorateStory( return decorators.reduce( (decorated: LegacyStoryFn, decorator) => (context: StoryContext) => { let story: VueRenderer['storyResult'] | undefined; - if (!isReactive(context.args)) context.args = reactive(context.args); + console.log('1 ----------> context.args:', context.args); + // if (!isReactive(context.args)) context.args = reactive(context.args); const decoratedStory: VueRenderer['storyResult'] = decorator((update) => { - const updatedArgs = - update?.args && !isReactive(update.args) - ? { ...update, args: reactive(update.args) } - : update; + const updatedArgs = update; story = decorated({ ...context, @@ -68,8 +66,12 @@ export function decorateStory( if (decoratedStory === story) { return story; } - return prepare(decoratedStory, story) as VueRenderer['storyResult']; + console.log('story ->', h(story, reactive(context.args))); + return prepare(decoratedStory, h(story, context.args)) as VueRenderer['storyResult']; }, - (context) => prepare(storyFn(context)) as LegacyStoryFn + (context) => { + const story = storyFn(context); + return prepare(story) as LegacyStoryFn; + } ); } diff --git a/code/renderers/vue3/src/render.ts b/code/renderers/vue3/src/render.ts index b05f62796b28..83121750613b 100644 --- a/code/renderers/vue3/src/render.ts +++ b/code/renderers/vue3/src/render.ts @@ -2,7 +2,6 @@ import { dedent } from 'ts-dedent'; import { createApp, h, reactive, toRefs } from 'vue'; import type { RenderContext, ArgsStoryFn } from '@storybook/types'; - import type { Args, StoryContext } from '@storybook/csf'; import type { StoryFnVueReturnType, VueRenderer } from './types'; @@ -13,7 +12,7 @@ export const render: ArgsStoryFn = (props, context) => { `Unable to render story ${id} as the component annotation is missing from the default export` ); } - + console.log(' -*****- render props', props, context); return h(Component, props, getSlots(props, context)); }; @@ -27,6 +26,7 @@ const map = new Map< { vueApp: ReturnType; reactiveArgs: any } >(); +const elementMap = new Map(); export function renderToCanvas( { storyFn, @@ -40,26 +40,18 @@ export function renderToCanvas( }: RenderContext, canvasElement: VueRenderer['canvasElement'] ) { - let { reactiveArgs } = useReactive(storyContext); + let reactiveArgs = reactive(storyContext.args); // useReactive(storyContext); // fetch the story with the updated context (with reactive args) - const element: StoryFnVueReturnType = storyFn(storyContext); + storyContext.args = reactiveArgs; + const element: StoryFnVueReturnType = storyFn(); + reactiveArgs = storyContext.args; + elementMap.set(canvasElement, element); - if (!element) { - showError({ - title: `Expecting a Vue component from the story: "${name}" of "${title}".`, - description: dedent` - Did you forget to return the Vue component from the story? - Use "() => ({ template: '' })" or "() => ({ components: MyComp, template: '' })" when defining the story. - `, - }); - return () => {}; - } // getting the props from the render function const props = (element as any).render?.().props; if (props) reactiveArgs = reactive(props); const existingApp = map.get(canvasElement); - if (existingApp && !forceRemount) { updateArgs(existingApp.reactiveArgs, reactiveArgs); return () => { @@ -67,10 +59,14 @@ export function renderToCanvas( }; } + if (existingApp && forceRemount) teardown(existingApp.vueApp, canvasElement); + const storybookApp = createApp({ render() { + const currentElement: any = elementMap.get(canvasElement); + const current = currentElement && currentElement.template ? currentElement : element; // elementMap.get(canvasElement) ?? map.set(canvasElement, { vueApp: storybookApp, reactiveArgs }); - return h(element, reactiveArgs); + return h(current, reactiveArgs); }, }); @@ -120,15 +116,3 @@ function teardown( storybookApp?.unmount(); if (map.has(canvasElement)) map.delete(canvasElement); } - -/** - * create a reactive args and return it and the refs to avoid losing reactivity when passing it to the story - * @param storyContext - * @returns - */ - -function useReactive(storyContext: StoryContext) { - const reactiveArgs = reactive(storyContext.args || {}); - storyContext.args = toRefs(reactiveArgs); - return { reactiveArgs, refsArgs: storyContext.args }; -} From 24b37f4756e4ac00869d81837fd1a1ef469f98f9 Mon Sep 17 00:00:00 2001 From: chakir qatab Date: Fri, 10 Feb 2023 21:59:29 +0400 Subject: [PATCH 10/12] cleanup after runing tests --- .../store/template/stories/rendering.stories.ts | 6 +----- code/renderers/vue3/src/decorateStory.ts | 16 +++++----------- code/renderers/vue3/src/render.ts | 16 ++++++---------- 3 files changed, 12 insertions(+), 26 deletions(-) diff --git a/code/lib/store/template/stories/rendering.stories.ts b/code/lib/store/template/stories/rendering.stories.ts index 85870d8d3483..8bca2f78f5c9 100644 --- a/code/lib/store/template/stories/rendering.stories.ts +++ b/code/lib/store/template/stories/rendering.stories.ts @@ -55,8 +55,6 @@ export const ChangeArgs = { await button.focus(); await expect(button).toHaveFocus(); - await new Promise((resolve) => setTimeout(resolve, 1000)); - // Web-components: https://github.com/storybookjs/storybook/issues/19415 // Preact: https://github.com/storybookjs/storybook/issues/19504 @@ -64,9 +62,7 @@ export const ChangeArgs = { // When we change the args to the button, it should not remount await channel.emit(UPDATE_STORY_ARGS, { storyId: id, updatedArgs: { label: 'New Text' } }); - await new Promise((resolve) => { - channel.once(STORY_ARGS_UPDATED, resolve); - }); + await within(canvasElement).findByText(/New Text/); await expect(button).toHaveFocus(); }, diff --git a/code/renderers/vue3/src/decorateStory.ts b/code/renderers/vue3/src/decorateStory.ts index e12a70bb666d..e2a56ec7204b 100644 --- a/code/renderers/vue3/src/decorateStory.ts +++ b/code/renderers/vue3/src/decorateStory.ts @@ -1,5 +1,5 @@ import type { ConcreteComponent, Component, ComponentOptions } from 'vue'; -import { h, isReactive, reactive } from 'vue'; +import { h } from 'vue'; import type { DecoratorFunction, StoryContext, LegacyStoryFn } from '@storybook/types'; import { sanitizeStoryContextUpdate } from '@storybook/preview-api'; @@ -47,14 +47,11 @@ export function decorateStory( return decorators.reduce( (decorated: LegacyStoryFn, decorator) => (context: StoryContext) => { let story: VueRenderer['storyResult'] | undefined; - console.log('1 ----------> context.args:', context.args); - // if (!isReactive(context.args)) context.args = reactive(context.args); - const decoratedStory: VueRenderer['storyResult'] = decorator((update) => { - const updatedArgs = update; + const decoratedStory: VueRenderer['storyResult'] = decorator((update) => { story = decorated({ ...context, - ...sanitizeStoryContextUpdate(updatedArgs), + ...sanitizeStoryContextUpdate(update), }); return story; }, context); @@ -66,12 +63,9 @@ export function decorateStory( if (decoratedStory === story) { return story; } - console.log('story ->', h(story, reactive(context.args))); + return prepare(decoratedStory, h(story, context.args)) as VueRenderer['storyResult']; }, - (context) => { - const story = storyFn(context); - return prepare(story) as LegacyStoryFn; - } + (context) => prepare(storyFn(context)) as LegacyStoryFn ); } diff --git a/code/renderers/vue3/src/render.ts b/code/renderers/vue3/src/render.ts index 83121750613b..8bdf95172167 100644 --- a/code/renderers/vue3/src/render.ts +++ b/code/renderers/vue3/src/render.ts @@ -1,6 +1,5 @@ /* eslint-disable no-param-reassign */ -import { dedent } from 'ts-dedent'; -import { createApp, h, reactive, toRefs } from 'vue'; +import { createApp, h, reactive } from 'vue'; import type { RenderContext, ArgsStoryFn } from '@storybook/types'; import type { Args, StoryContext } from '@storybook/csf'; import type { StoryFnVueReturnType, VueRenderer } from './types'; @@ -12,7 +11,7 @@ export const render: ArgsStoryFn = (props, context) => { `Unable to render story ${id} as the component annotation is missing from the default export` ); } - console.log(' -*****- render props', props, context); + return h(Component, props, getSlots(props, context)); }; @@ -40,16 +39,13 @@ export function renderToCanvas( }: RenderContext, canvasElement: VueRenderer['canvasElement'] ) { - let reactiveArgs = reactive(storyContext.args); // useReactive(storyContext); // fetch the story with the updated context (with reactive args) - storyContext.args = reactiveArgs; + storyContext.args = reactive(storyContext.args); const element: StoryFnVueReturnType = storyFn(); - reactiveArgs = storyContext.args; elementMap.set(canvasElement, element); - // getting the props from the render function const props = (element as any).render?.().props; - if (props) reactiveArgs = reactive(props); + const reactiveArgs = props ? reactive(props) : storyContext.args; const existingApp = map.get(canvasElement); if (existingApp && !forceRemount) { @@ -63,8 +59,8 @@ export function renderToCanvas( const storybookApp = createApp({ render() { - const currentElement: any = elementMap.get(canvasElement); - const current = currentElement && currentElement.template ? currentElement : element; // elementMap.get(canvasElement) ?? + const renderedElement: any = elementMap.get(canvasElement); + const current = renderedElement && renderedElement.template ? renderedElement : element; map.set(canvasElement, { vueApp: storybookApp, reactiveArgs }); return h(current, reactiveArgs); }, From 5425d9095c661820c957c6e59e249ef990f9e88d Mon Sep 17 00:00:00 2001 From: chakir qatab Date: Sat, 11 Feb 2023 19:47:11 +0400 Subject: [PATCH 11/12] fix test failure + standard string enum --- code/lib/store/template/stories/args.stories.ts | 6 ++++-- code/renderers/vue3/src/render.ts | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/code/lib/store/template/stories/args.stories.ts b/code/lib/store/template/stories/args.stories.ts index 16b4e7bc0d03..e1e6eb7104f4 100644 --- a/code/lib/store/template/stories/args.stories.ts +++ b/code/lib/store/template/stories/args.stories.ts @@ -3,6 +3,7 @@ import type { PartialStoryFn, PlayFunctionContext, StoryContext } from '@storybo import { within } from '@storybook/testing-library'; import { expect } from '@storybook/jest'; import { pick } from 'lodash'; +import { STORY_ARGS_UPDATED, UPDATE_STORY_ARGS, RESET_STORY_ARGS } from '@storybook/core-events'; export default { component: globalThis.Components.Pre, @@ -71,10 +72,11 @@ export const Events = { const channel = globalThis.__STORYBOOK_ADDONS_CHANNEL__; await within(canvasElement).findByText(/initial/); - await channel.emit('updateStoryArgs', { storyId: id, updatedArgs: { test: 'updated' } }); + await channel.emit(UPDATE_STORY_ARGS, { storyId: id, updatedArgs: { test: 'updated' } }); await within(canvasElement).findByText(/updated/); - await channel.emit('resetStoryArgs', { storyId: id }); + await channel.emit(RESET_STORY_ARGS, { storyId: id }); + await new Promise((resolve) => channel.once(STORY_ARGS_UPDATED, resolve)); await within(canvasElement).findByText(/initial/); }, }; diff --git a/code/renderers/vue3/src/render.ts b/code/renderers/vue3/src/render.ts index 6e8c0b89fadd..6c2c68559812 100644 --- a/code/renderers/vue3/src/render.ts +++ b/code/renderers/vue3/src/render.ts @@ -41,7 +41,7 @@ export function renderToCanvas( const existingApp = map.get(canvasElement); if (existingApp && !forceRemount) { - updateArgs(existingApp.reactiveArgs, storyContext.args); + updateArgs(existingApp.reactiveArgs, reactiveArgs); return () => { teardown(existingApp.vueApp, canvasElement); }; From 2ac51687b192a5eabe9de7849b961d08b88dc254 Mon Sep 17 00:00:00 2001 From: chakir qatab Date: Mon, 13 Feb 2023 11:26:32 +0400 Subject: [PATCH 12/12] revert back rest_story_args to preseve chromatic baseline --- code/lib/store/template/stories/rendering.stories.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/lib/store/template/stories/rendering.stories.ts b/code/lib/store/template/stories/rendering.stories.ts index 8bca2f78f5c9..4b2181bb5ea6 100644 --- a/code/lib/store/template/stories/rendering.stories.ts +++ b/code/lib/store/template/stories/rendering.stories.ts @@ -65,5 +65,7 @@ export const ChangeArgs = { await within(canvasElement).findByText(/New Text/); await expect(button).toHaveFocus(); + + await channel.emit(RESET_STORY_ARGS, { storyId: id }); }, };