diff --git a/code/e2e-tests/framework-svelte.spec.ts b/code/e2e-tests/framework-svelte.spec.ts index a208aa982d9c..2b6e447dd232 100644 --- a/code/e2e-tests/framework-svelte.spec.ts +++ b/code/e2e-tests/framework-svelte.spec.ts @@ -50,4 +50,15 @@ test.describe('Svelte', () => { const expectedSource = ''; await expect(sourceCode.textContent()).resolves.toContain(expectedSource); }); + + test('Decorators runs only once', async ({ page }) => { + const sbPage = new SbPage(page); + const lines: string[] = []; + page.on('console', (msg) => { + lines.push(msg.text()); + }); + + await sbPage.navigateToStory('stories/renderers/svelte/decorators-runs-once', 'default'); + expect(lines).toHaveLength(1); + }); }); diff --git a/code/renderers/svelte/template/stories/decorators-runs-once.stories.js b/code/renderers/svelte/template/stories/decorators-runs-once.stories.js new file mode 100644 index 000000000000..649d9f8a18bb --- /dev/null +++ b/code/renderers/svelte/template/stories/decorators-runs-once.stories.js @@ -0,0 +1,16 @@ +import ButtonJavaScript from './views/ButtonJavaScript.svelte'; + +export default { + component: ButtonJavaScript, + args: { + primary: true, + }, + decorators: [ + (Story) => { + console.log('decorator'); + return Story(); + }, + ], +}; + +export const Default = {}; diff --git a/code/renderers/svelte/templates/PreviewRender.svelte b/code/renderers/svelte/templates/PreviewRender.svelte index 7747cd8fcaba..581aa4d78e05 100644 --- a/code/renderers/svelte/templates/PreviewRender.svelte +++ b/code/renderers/svelte/templates/PreviewRender.svelte @@ -17,8 +17,25 @@ on, } = storyFn(); + let firstTime = true; + + // the first time we don't want to call storyFn two times so we just return the values + // we already have from the previous call. If storyFn changes this function will run + // again but this time firstTime will be false + function getStoryFnValue(storyFn){ + if(firstTime){ + firstTime = false; + return { + Component, + props, + on, + } + } + return storyFn(); + } + // reactive, re-render on storyFn change - $: ({ Component, props = {}, on } = storyFn()); + $: ({ Component, props = {}, on } = getStoryFnValue(storyFn)); const eventsFromArgTypes = Object.fromEntries( Object.entries(storyContext.argTypes)