Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions code/frameworks/svelte-vite/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,13 @@
"@storybook/builder-vite": "workspace:*",
"@storybook/svelte": "workspace:*",
"magic-string": "^0.30.0",
"svelte2tsx": "^0.7.35",
"svelte2tsx": "^0.7.44",
"typescript": "^4.9.4 || ^5.0.0"
},
"devDependencies": {
"@sveltejs/vite-plugin-svelte": "^5.0.3",
"@sveltejs/vite-plugin-svelte": "^6.2.0",
"@types/node": "^22.0.0",
"svelte": "^5.0.5",
"svelte": "^5.39.5",
"sveltedoc-parser": "^4.2.1",
"typescript": "^5.8.3",
"vite": "^7.0.4"
Expand Down
1 change: 0 additions & 1 deletion code/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,6 @@
"sort-package-json": "^2.14.0",
"storybook": "workspace:^",
"storybook-addon-pseudo-states": "workspace:*",
"svelte": "^5.0.0-next.268",
"ts-dedent": "^2.0.0",
"typescript": "^5.8.3",
"uuid": "^11.1.0",
Expand Down
6 changes: 3 additions & 3 deletions code/renderers/svelte/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,11 @@
"type-fest": "~2.19"
},
"devDependencies": {
"@sveltejs/vite-plugin-svelte": "^5.0.3",
"@sveltejs/vite-plugin-svelte": "^6.2.0",
"@testing-library/svelte": "^5.2.4",
"expect-type": "^1.1.0",
"svelte": "^5.20.5",
"svelte-check": "^4.1.4",
"svelte": "^5.39.5",
"svelte-check": "^4.3.2",
"sveltedoc-parser": "^4.2.1",
"typescript": "^5.8.3",
"vite": "^7.0.4"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
exports[`Renders CSF2Secondary story 1`] = `
<body>
<div>
<!---->
<!---->
<!---->
<button
Expand All @@ -16,6 +17,7 @@ exports[`Renders CSF2Secondary story 1`] = `




</div>
</body>
`;
Expand All @@ -27,6 +29,7 @@ exports[`Renders CSF2StoryWithParamsAndDecorator story 1`] = `
<!---->
<!---->
<!---->
<!---->
<div
data-testid="local-decorator"
style="margin: 3em;"
Expand All @@ -48,13 +51,15 @@ exports[`Renders CSF2StoryWithParamsAndDecorator story 1`] = `




</div>
</body>
`;

exports[`Renders CSF3Button story 1`] = `
<body>
<div>
<!---->
<!---->
<!---->
<button
Expand All @@ -68,13 +73,15 @@ exports[`Renders CSF3Button story 1`] = `




</div>
</body>
`;

exports[`Renders CSF3ButtonWithRender story 1`] = `
<body>
<div>
<!---->
<!---->
<!---->
<div>
Expand All @@ -97,13 +104,15 @@ exports[`Renders CSF3ButtonWithRender story 1`] = `




</div>
</body>
`;

exports[`Renders CSF3InputFieldFilled story 1`] = `
<body>
<div>
<!---->
<!---->
<!---->
<input
Expand All @@ -112,13 +121,15 @@ exports[`Renders CSF3InputFieldFilled story 1`] = `




</div>
</body>
`;

exports[`Renders CSF3Primary story 1`] = `
<body>
<div>
<!---->
<!---->
<!---->
<button
Expand All @@ -132,13 +143,15 @@ exports[`Renders CSF3Primary story 1`] = `




</div>
</body>
`;

exports[`Renders LoaderStory story 1`] = `
<body>
<div>
<!---->
<!---->
<!---->
<div>
Expand All @@ -157,6 +170,7 @@ exports[`Renders LoaderStory story 1`] = `




</div>
</body>
`;
Expand All @@ -168,6 +182,7 @@ exports[`Renders NewStory story 1`] = `
<!---->
<!---->
<!---->
<!---->
<div
data-testid="local-decorator"
style="margin: 3em;"
Expand All @@ -189,6 +204,7 @@ exports[`Renders NewStory story 1`] = `




</div>
</body>
`;
4 changes: 3 additions & 1 deletion code/renderers/svelte/src/render.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ const componentsByDomElement = new Map<
{ mountedComponent: ReturnType<(typeof svelte)['mount']>; props: RenderContext }
>();

export function renderToCanvas(
export async function renderToCanvas(
{
storyFn,
title,
Expand Down Expand Up @@ -81,6 +81,7 @@ export function renderToCanvas(
props,
});
componentsByDomElement.set(canvasElement, { mountedComponent, props });
await svelte.tick();
} else {
// We need to mutate the existing props for Svelte reactivity to work, we can't just re-assign them
Object.assign(existingComponent.props, {
Expand All @@ -90,6 +91,7 @@ export function renderToCanvas(
title,
showError,
});
await svelte.tick();
}

showMain();
Expand Down
7 changes: 6 additions & 1 deletion code/renderers/svelte/static/PreviewRender.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,9 @@
});
</script>

<DecoratorHandler {Component} {props} />
<svelte:boundary>
{#snippet pending()}
<div id="sb-pending-async-component-notice">Pending async component...</div>
{/snippet}
<DecoratorHandler {Component} {props} />
</svelte:boundary>
16 changes: 16 additions & 0 deletions code/renderers/svelte/svelte.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//! this config isn't actually used, it's just here to tell svelte-check that we have async enabled

const config = {
kit: {
experimental: {
remoteFunctions: true,
},
},
compilerOptions: {
experimental: {
async: true,
},
},
};

export default config;
17 changes: 17 additions & 0 deletions code/renderers/svelte/template/stories/AsyncComponent.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<script lang="ts">
let shown = $state(false);

let { onEffect }: { onEffect?: () => void } = $props();

await new Promise<void>((resolve) => {
setTimeout(() => {
onEffect?.();
shown = true;
resolve();
}, 100);
});
</script>

{#if shown}
<div data-testid="after-effect">This element is shown after the component's effect runs</div>
{/if}
14 changes: 14 additions & 0 deletions code/renderers/svelte/template/stories/SyncComponent.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<script lang="ts">
let shown = $state(false);

let { onEffect }: { onEffect?: () => void } = $props();

$effect(() => {
onEffect?.();
shown = true;
});
</script>

{#if shown}
<div data-testid="after-effect">This element is shown after the component's effect runs</div>
{/if}
51 changes: 51 additions & 0 deletions code/renderers/svelte/template/stories/settled.stories.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import type { StoryObj } from '@storybook/svelte';

import { expect, fn, waitFor } from 'storybook/test';

import AsyncComponent from './AsyncComponent.svelte';
import SyncComponent from './SyncComponent.svelte';

export default {
title: 'stories/renderers/svelte/settled',
};

export const Sync: StoryObj<typeof SyncComponent> = {
render: (args) => ({
Component: SyncComponent,
props: args,
}),
args: {
onEffect: fn(),
},
play: async ({ canvas, args }) => {
await expect(args.onEffect).toHaveBeenCalledOnce();
await expect(canvas.getByTestId('after-effect')).toBeInTheDocument();
},
};

export const Async: StoryObj<typeof AsyncComponent> = {
render: (args) => ({
Component: AsyncComponent,
props: args,
}),
args: {
onEffect: fn(),
},
play: async ({ canvas, canvasElement, args }) => {
await expect(args.onEffect).not.toHaveBeenCalled();
await expect(
canvasElement.querySelector('#sb-pending-async-component-notice')
).toBeInTheDocument();

// TODO: Ideally we should be able to call await svelte.settled() here instead of waitFor, but currently there's a bug making it never resolve
// await svelte.settled();

await waitFor(async () => {
await expect(args.onEffect).toHaveBeenCalledOnce();
await expect(canvas.getByTestId('after-effect')).toBeInTheDocument();
await expect(
canvasElement.querySelector('#sb-pending-async-component-notice')
).not.toBeInTheDocument();
});
},
};
Loading