Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Svelte: Fix decorators always running twice #24921

11 changes: 11 additions & 0 deletions code/e2e-tests/framework-svelte.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,15 @@ test.describe('Svelte', () => {
const expectedSource = '<ButtonJavaScript primary/>';
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);
});
});
Original file line number Diff line number Diff line change
@@ -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 = {};
19 changes: 18 additions & 1 deletion code/renderers/svelte/templates/PreviewRender.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down