From dca97a1f91b2577b0d1ddb1ff780e3837c12cc09 Mon Sep 17 00:00:00 2001 From: paoloricciuti Date: Fri, 10 Nov 2023 00:31:46 +0100 Subject: [PATCH 01/20] feat: tighter integration with sveltekit --- code/frameworks/sveltekit/package.json | 15 +++++- .../src/components/LinkListener.svelte | 43 ++++++++++++++++ .../sveltekit/src/mocks/app/forms.ts | 19 +++++++ .../sveltekit/src/mocks/app/navigation.ts | 49 +++++++++++++++++++ .../sveltekit/src/mocks/app/stores.ts | 20 ++++++++ .../sveltekit/src/plugins/config-overrides.ts | 31 +++++++++--- code/frameworks/sveltekit/src/preset.ts | 4 ++ code/frameworks/sveltekit/src/preview.ts | 19 +++++++ 8 files changed, 191 insertions(+), 9 deletions(-) create mode 100644 code/frameworks/sveltekit/src/components/LinkListener.svelte create mode 100644 code/frameworks/sveltekit/src/mocks/app/forms.ts create mode 100644 code/frameworks/sveltekit/src/mocks/app/navigation.ts create mode 100644 code/frameworks/sveltekit/src/mocks/app/stores.ts create mode 100644 code/frameworks/sveltekit/src/preview.ts diff --git a/code/frameworks/sveltekit/package.json b/code/frameworks/sveltekit/package.json index 632b552869f7..9eb5088313d5 100644 --- a/code/frameworks/sveltekit/package.json +++ b/code/frameworks/sveltekit/package.json @@ -29,6 +29,17 @@ "require": "./dist/index.js", "import": "./dist/index.mjs" }, + "./src/components/LinkListener.svelte": "./src/components/LinkListener.svelte", + "./preview": { + "types": "./dist/preview.d.ts", + "require": "./dist/preview.js", + "import": "./dist/preview.mjs" + }, + "./dist/preview.js": { + "types": "./dist/preview.d.ts", + "require": "./dist/preview.js", + "import": "./dist/preview.mjs" + }, "./preset": { "types": "./dist/preset.d.ts", "require": "./dist/preset.js" @@ -43,7 +54,8 @@ "README.md", "*.js", "*.d.ts", - "!src/**/*" + "!src/**/*", + "src/components/**/*" ], "scripts": { "check": "../../../scripts/prepare/check.ts", @@ -72,6 +84,7 @@ "bundler": { "entries": [ "./src/index.ts", + "./src/preview.ts", "./src/preset.ts" ], "platform": "node" diff --git a/code/frameworks/sveltekit/src/components/LinkListener.svelte b/code/frameworks/sveltekit/src/components/LinkListener.svelte new file mode 100644 index 000000000000..fafe78951db3 --- /dev/null +++ b/code/frameworks/sveltekit/src/components/LinkListener.svelte @@ -0,0 +1,43 @@ + + + diff --git a/code/frameworks/sveltekit/src/mocks/app/forms.ts b/code/frameworks/sveltekit/src/mocks/app/forms.ts new file mode 100644 index 000000000000..ed68853479ca --- /dev/null +++ b/code/frameworks/sveltekit/src/mocks/app/forms.ts @@ -0,0 +1,19 @@ +export function enhance(form: HTMLFormElement) { + // import('@storybook/addon-actions') + // .then(({ action }) => { + // action('sveltekit.enhance')(); + // }) + // .catch(console.log); +} + +export function applyAction() {} + +export function deserialize() { + return deserializeResponse; +} + +let deserializeResponse: any; + +export function setDeserializeResponse(answer: any) { + deserializeResponse = answer; +} diff --git a/code/frameworks/sveltekit/src/mocks/app/navigation.ts b/code/frameworks/sveltekit/src/mocks/app/navigation.ts new file mode 100644 index 000000000000..6d4af0ac87df --- /dev/null +++ b/code/frameworks/sveltekit/src/mocks/app/navigation.ts @@ -0,0 +1,49 @@ +import { getContext, onMount, setContext } from 'svelte'; + +export async function goto(...args: any[]) { + // try { + // const { action } = await import('@storybook/addon-actions'); + // action('sveltekit.goto')(...args); + // } catch (e) { + // console.log(e); + // } +} + +export function setAfterNavigateArgument(afterNavigateArgs: any) { + setContext('after-navigate-args', afterNavigateArgs); +} + +export function afterNavigate(cb: any) { + const argument = getContext('after-navigate-args'); + onMount(() => { + cb(argument); + }); +} + +export function onNavigate() {} + +export function beforeNavigate() {} + +export function disableScrollHandling() {} + +export async function invalidate(...args: any[]) { + // try { + // const { action } = await import('@storybook/addon-actions'); + // action('sveltekit.invalidate')(...args); + // } catch (e) { + // console.log(e); + // } +} + +export async function invalidateAll() { + // try { + // const { action } = await import('@storybook/addon-actions'); + // action('sveltekit.invalidateAll')(); + // } catch (e) { + // console.log(e); + // } +} + +export function preloadCode() {} + +export function preloadData() {} diff --git a/code/frameworks/sveltekit/src/mocks/app/stores.ts b/code/frameworks/sveltekit/src/mocks/app/stores.ts new file mode 100644 index 000000000000..bd7ce8e9120e --- /dev/null +++ b/code/frameworks/sveltekit/src/mocks/app/stores.ts @@ -0,0 +1,20 @@ +import { getContext, setContext } from 'svelte'; + +function createMockedStore(contextName: string) { + return [ + { + subscribe(runner: any) { + const page = getContext(contextName); + runner(page); + return () => {}; + }, + }, + (value: unknown) => { + setContext(contextName, value); + }, + ] as const; +} + +export const [page, setPage] = createMockedStore('page-ctx'); +export const [navigating, setNavigating] = createMockedStore('navigating-ctx'); +export const [updated, setUpdated] = createMockedStore('updated-ctx'); diff --git a/code/frameworks/sveltekit/src/plugins/config-overrides.ts b/code/frameworks/sveltekit/src/plugins/config-overrides.ts index db5294a13242..d1dfcc09919e 100644 --- a/code/frameworks/sveltekit/src/plugins/config-overrides.ts +++ b/code/frameworks/sveltekit/src/plugins/config-overrides.ts @@ -1,12 +1,27 @@ -import type { Plugin } from 'vite'; +import { resolve } from 'node:path'; +import { mergeConfig, type Plugin } from 'vite'; export function configOverrides() { - return { - // SvelteKit sets SSR, we need it to be false when building - name: 'storybook:sveltekit-overrides', - apply: 'build', - config: () => { - return { build: { ssr: false } }; + return [ + { + // SvelteKit sets SSR, we need it to be false when building + name: 'storybook:sveltekit-overrides', + apply: 'build', + config: () => { + return { build: { ssr: false } }; + }, }, - } satisfies Plugin; + { + name: 'storybook:sveltekit-mock-stores', + enforce: 'post', + config: (config) => + mergeConfig(config, { + resolve: { + alias: { + $app: resolve(__dirname, '../src/mocks/app/'), + }, + }, + }), + }, + ] satisfies Plugin[]; } diff --git a/code/frameworks/sveltekit/src/preset.ts b/code/frameworks/sveltekit/src/preset.ts index e92e45079f63..4e765d1631cc 100644 --- a/code/frameworks/sveltekit/src/preset.ts +++ b/code/frameworks/sveltekit/src/preset.ts @@ -13,6 +13,10 @@ export const core: PresetProperty<'core', StorybookConfig> = { builder: getAbsolutePath('@storybook/builder-vite'), renderer: getAbsolutePath('@storybook/svelte'), }; +export const previewAnnotations: StorybookConfig['previewAnnotations'] = (entry = []) => [ + ...entry, + require.resolve('@storybook/sveltekit/preview'), +]; export const viteFinal: NonNullable = async (config, options) => { const baseConfig = await svelteViteFinal(config, options); diff --git a/code/frameworks/sveltekit/src/preview.ts b/code/frameworks/sveltekit/src/preview.ts new file mode 100644 index 000000000000..dbb0786be689 --- /dev/null +++ b/code/frameworks/sveltekit/src/preview.ts @@ -0,0 +1,19 @@ +import type { Decorator } from '@storybook/svelte'; + +// eslint-disable-next-line import/no-extraneous-dependencies +import LinkListener from '@storybook/sveltekit/src/components/LinkListener.svelte'; +import { setDeserializeResponse } from './mocks/app/forms'; +import { setAfterNavigateArgument } from './mocks/app/navigation'; +import { setNavigating, setPage, setUpdated } from './mocks/app/stores'; + +export const decorators: Decorator[] = [ + (Story, ctx) => { + setPage(ctx.parameters?.sveltekit?.stores?.page); + setUpdated(ctx.parameters?.sveltekit?.stores?.updated); + setNavigating(ctx.parameters?.sveltekit?.stores?.navigating); + setDeserializeResponse(ctx.parameters?.sveltekit?.forms?.deserializeResponse); + setAfterNavigateArgument(ctx.parameters?.sveltekit?.navigation?.afterNavigate); + return Story(); + }, + (_, ctx) => ({ Component: LinkListener, props: { ctx } }), +]; From 0a103b1e237880aaad6005d52ee8c20af3934c1f Mon Sep 17 00:00:00 2001 From: paoloricciuti Date: Fri, 10 Nov 2023 11:20:39 +0100 Subject: [PATCH 02/20] fix callbacks for goto, enhance, invalidate, invalidateAll add getStores export --- code/frameworks/sveltekit/package.json | 2 +- .../src/components/LinkListener.svelte | 43 ------------- .../src/components/SvelteDecorator.svelte | 60 +++++++++++++++++++ .../sveltekit/src/mocks/app/forms.ts | 7 +-- .../sveltekit/src/mocks/app/navigation.ts | 28 ++++----- .../sveltekit/src/mocks/app/stores.ts | 8 +++ code/frameworks/sveltekit/src/preview.ts | 8 +-- 7 files changed, 85 insertions(+), 71 deletions(-) delete mode 100644 code/frameworks/sveltekit/src/components/LinkListener.svelte create mode 100644 code/frameworks/sveltekit/src/components/SvelteDecorator.svelte diff --git a/code/frameworks/sveltekit/package.json b/code/frameworks/sveltekit/package.json index 9eb5088313d5..afa20320e9b7 100644 --- a/code/frameworks/sveltekit/package.json +++ b/code/frameworks/sveltekit/package.json @@ -29,7 +29,7 @@ "require": "./dist/index.js", "import": "./dist/index.mjs" }, - "./src/components/LinkListener.svelte": "./src/components/LinkListener.svelte", + "./src/components/SvelteDecorator.svelte": "./src/components/SvelteDecorator.svelte", "./preview": { "types": "./dist/preview.d.ts", "require": "./dist/preview.js", diff --git a/code/frameworks/sveltekit/src/components/LinkListener.svelte b/code/frameworks/sveltekit/src/components/LinkListener.svelte deleted file mode 100644 index fafe78951db3..000000000000 --- a/code/frameworks/sveltekit/src/components/LinkListener.svelte +++ /dev/null @@ -1,43 +0,0 @@ - - - diff --git a/code/frameworks/sveltekit/src/components/SvelteDecorator.svelte b/code/frameworks/sveltekit/src/components/SvelteDecorator.svelte new file mode 100644 index 000000000000..fe337afe1815 --- /dev/null +++ b/code/frameworks/sveltekit/src/components/SvelteDecorator.svelte @@ -0,0 +1,60 @@ + + + diff --git a/code/frameworks/sveltekit/src/mocks/app/forms.ts b/code/frameworks/sveltekit/src/mocks/app/forms.ts index ed68853479ca..73a9eaefc044 100644 --- a/code/frameworks/sveltekit/src/mocks/app/forms.ts +++ b/code/frameworks/sveltekit/src/mocks/app/forms.ts @@ -1,9 +1,6 @@ export function enhance(form: HTMLFormElement) { - // import('@storybook/addon-actions') - // .then(({ action }) => { - // action('sveltekit.enhance')(); - // }) - // .catch(console.log); + const event = new CustomEvent('storybook:enhance'); + window.dispatchEvent(event); } export function applyAction() {} diff --git a/code/frameworks/sveltekit/src/mocks/app/navigation.ts b/code/frameworks/sveltekit/src/mocks/app/navigation.ts index 6d4af0ac87df..aeaf586ae0ca 100644 --- a/code/frameworks/sveltekit/src/mocks/app/navigation.ts +++ b/code/frameworks/sveltekit/src/mocks/app/navigation.ts @@ -1,12 +1,10 @@ import { getContext, onMount, setContext } from 'svelte'; export async function goto(...args: any[]) { - // try { - // const { action } = await import('@storybook/addon-actions'); - // action('sveltekit.goto')(...args); - // } catch (e) { - // console.log(e); - // } + const event = new CustomEvent('storybook:goto', { + detail: args, + }); + window.dispatchEvent(event); } export function setAfterNavigateArgument(afterNavigateArgs: any) { @@ -27,21 +25,15 @@ export function beforeNavigate() {} export function disableScrollHandling() {} export async function invalidate(...args: any[]) { - // try { - // const { action } = await import('@storybook/addon-actions'); - // action('sveltekit.invalidate')(...args); - // } catch (e) { - // console.log(e); - // } + const event = new CustomEvent('storybook:invalidate', { + detail: args, + }); + window.dispatchEvent(event); } export async function invalidateAll() { - // try { - // const { action } = await import('@storybook/addon-actions'); - // action('sveltekit.invalidateAll')(); - // } catch (e) { - // console.log(e); - // } + const event = new CustomEvent('storybook:invalidateAll'); + window.dispatchEvent(event); } export function preloadCode() {} diff --git a/code/frameworks/sveltekit/src/mocks/app/stores.ts b/code/frameworks/sveltekit/src/mocks/app/stores.ts index bd7ce8e9120e..e291f4d42ca1 100644 --- a/code/frameworks/sveltekit/src/mocks/app/stores.ts +++ b/code/frameworks/sveltekit/src/mocks/app/stores.ts @@ -18,3 +18,11 @@ function createMockedStore(contextName: string) { export const [page, setPage] = createMockedStore('page-ctx'); export const [navigating, setNavigating] = createMockedStore('navigating-ctx'); export const [updated, setUpdated] = createMockedStore('updated-ctx'); + +export function getStores() { + return { + page, + navigating, + updated, + }; +} diff --git a/code/frameworks/sveltekit/src/preview.ts b/code/frameworks/sveltekit/src/preview.ts index dbb0786be689..09c5578a6980 100644 --- a/code/frameworks/sveltekit/src/preview.ts +++ b/code/frameworks/sveltekit/src/preview.ts @@ -1,7 +1,7 @@ import type { Decorator } from '@storybook/svelte'; // eslint-disable-next-line import/no-extraneous-dependencies -import LinkListener from '@storybook/sveltekit/src/components/LinkListener.svelte'; +import SvelteDecorator from '@storybook/sveltekit/src/components/SvelteDecorator.svelte'; import { setDeserializeResponse } from './mocks/app/forms'; import { setAfterNavigateArgument } from './mocks/app/navigation'; import { setNavigating, setPage, setUpdated } from './mocks/app/stores'; @@ -11,9 +11,9 @@ export const decorators: Decorator[] = [ setPage(ctx.parameters?.sveltekit?.stores?.page); setUpdated(ctx.parameters?.sveltekit?.stores?.updated); setNavigating(ctx.parameters?.sveltekit?.stores?.navigating); - setDeserializeResponse(ctx.parameters?.sveltekit?.forms?.deserializeResponse); - setAfterNavigateArgument(ctx.parameters?.sveltekit?.navigation?.afterNavigate); + setDeserializeResponse(ctx.parameters?.sveltekit?.stores?.forms?.deserializeResponse); + setAfterNavigateArgument(ctx.parameters?.sveltekit?.stores?.navigation?.afterNavigate); return Story(); }, - (_, ctx) => ({ Component: LinkListener, props: { ctx } }), + (_, ctx) => ({ Component: SvelteDecorator, props: { ctx } }), ]; From a19c1e43f30cfa520f18b452c97ffb9cc0a41a81 Mon Sep 17 00:00:00 2001 From: paoloricciuti Date: Fri, 10 Nov 2023 16:26:46 +0100 Subject: [PATCH 03/20] add tests --- .../src/components/SvelteDecorator.svelte | 5 +- .../sveltekit/src/mocks/app/forms.ts | 23 ++-- code/frameworks/sveltekit/src/preview.ts | 4 +- .../Forms.svelte | 7 ++ .../Links.svelte | 1 + .../Navigation.svelte | 25 ++++ .../Stores.svelte | 15 +++ .../forms.stories.js | 26 ++++ .../links.stories.js | 26 ++++ .../navigation.stories.js | 83 +++++++++++++ .../stores.stories.js | 116 ++++++++++++++++++ .../Forms.svelte | 7 ++ .../Links.svelte | 1 + .../Navigation.svelte | 25 ++++ .../Stores.svelte | 15 +++ .../forms.stories.js | 26 ++++ .../links.stories.js | 26 ++++ .../navigation.stories.js | 83 +++++++++++++ .../stores.stories.js | 116 ++++++++++++++++++ 19 files changed, 614 insertions(+), 16 deletions(-) create mode 100644 code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-js/Forms.svelte create mode 100644 code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-js/Links.svelte create mode 100644 code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-js/Navigation.svelte create mode 100644 code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-js/Stores.svelte create mode 100644 code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-js/forms.stories.js create mode 100644 code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-js/links.stories.js create mode 100644 code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-js/navigation.stories.js create mode 100644 code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-js/stores.stories.js create mode 100644 code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-ts/Forms.svelte create mode 100644 code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-ts/Links.svelte create mode 100644 code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-ts/Navigation.svelte create mode 100644 code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-ts/Stores.svelte create mode 100644 code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-ts/forms.stories.js create mode 100644 code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-ts/links.stories.js create mode 100644 code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-ts/navigation.stories.js create mode 100644 code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-ts/stores.stories.js diff --git a/code/frameworks/sveltekit/src/components/SvelteDecorator.svelte b/code/frameworks/sveltekit/src/components/SvelteDecorator.svelte index fe337afe1815..025ec47e2074 100644 --- a/code/frameworks/sveltekit/src/components/SvelteDecorator.svelte +++ b/code/frameworks/sveltekit/src/components/SvelteDecorator.svelte @@ -30,8 +30,9 @@ for(let func of functions){ if(ctx?.parameters?.sveltekit?.[baseModule]?.[func] && ctx.parameters.sveltekit[baseModule][func] instanceof Function){ const listener = ({ detail = [] })=>{ - console.log("event", ctx); - ctx.parameters.sveltekit[baseModule][func](...detail); + console.log("event", func, ctx); + const args = Array.isArray(detail) ? detail : []; + ctx.parameters.sveltekit[baseModule][func](...args); } const eventType = `storybook:${func}`; toRemove.push({ eventType, listener }); diff --git a/code/frameworks/sveltekit/src/mocks/app/forms.ts b/code/frameworks/sveltekit/src/mocks/app/forms.ts index 73a9eaefc044..d1b26867c7d6 100644 --- a/code/frameworks/sveltekit/src/mocks/app/forms.ts +++ b/code/frameworks/sveltekit/src/mocks/app/forms.ts @@ -1,16 +1,17 @@ export function enhance(form: HTMLFormElement) { - const event = new CustomEvent('storybook:enhance'); - window.dispatchEvent(event); + const listener = (e: Event) => { + e.preventDefault(); + const event = new CustomEvent('storybook:enhance'); + window.dispatchEvent(event); + }; + form.addEventListener('submit', listener); + return { + destroy() { + form.removeEventListener('submit', listener); + }, + }; } export function applyAction() {} -export function deserialize() { - return deserializeResponse; -} - -let deserializeResponse: any; - -export function setDeserializeResponse(answer: any) { - deserializeResponse = answer; -} +export function deserialize() {} diff --git a/code/frameworks/sveltekit/src/preview.ts b/code/frameworks/sveltekit/src/preview.ts index 09c5578a6980..54914221f91c 100644 --- a/code/frameworks/sveltekit/src/preview.ts +++ b/code/frameworks/sveltekit/src/preview.ts @@ -2,7 +2,6 @@ import type { Decorator } from '@storybook/svelte'; // eslint-disable-next-line import/no-extraneous-dependencies import SvelteDecorator from '@storybook/sveltekit/src/components/SvelteDecorator.svelte'; -import { setDeserializeResponse } from './mocks/app/forms'; import { setAfterNavigateArgument } from './mocks/app/navigation'; import { setNavigating, setPage, setUpdated } from './mocks/app/stores'; @@ -11,8 +10,7 @@ export const decorators: Decorator[] = [ setPage(ctx.parameters?.sveltekit?.stores?.page); setUpdated(ctx.parameters?.sveltekit?.stores?.updated); setNavigating(ctx.parameters?.sveltekit?.stores?.navigating); - setDeserializeResponse(ctx.parameters?.sveltekit?.stores?.forms?.deserializeResponse); - setAfterNavigateArgument(ctx.parameters?.sveltekit?.stores?.navigation?.afterNavigate); + setAfterNavigateArgument(ctx.parameters?.sveltekit?.navigation?.afterNavigate); return Story(); }, (_, ctx) => ({ Component: SvelteDecorator, props: { ctx } }), diff --git a/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-js/Forms.svelte b/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-js/Forms.svelte new file mode 100644 index 000000000000..371a17656bea --- /dev/null +++ b/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-js/Forms.svelte @@ -0,0 +1,7 @@ + + +
+ +
\ No newline at end of file diff --git a/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-js/Links.svelte b/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-js/Links.svelte new file mode 100644 index 000000000000..3470b6b0e6f8 --- /dev/null +++ b/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-js/Links.svelte @@ -0,0 +1 @@ +Storybook \ No newline at end of file diff --git a/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-js/Navigation.svelte b/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-js/Navigation.svelte new file mode 100644 index 000000000000..d97b6fe8a2df --- /dev/null +++ b/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-js/Navigation.svelte @@ -0,0 +1,25 @@ + + + + + + + diff --git a/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-js/Stores.svelte b/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-js/Stores.svelte new file mode 100644 index 000000000000..479239610a6b --- /dev/null +++ b/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-js/Stores.svelte @@ -0,0 +1,15 @@ + + +

Directly importing

+
{JSON.stringify($page, null, 2)}
+
{JSON.stringify($navigating, null, 2)}
+
{JSON.stringify($updated, null, 2)}
+ +

With getStores

+
{JSON.stringify($pageStore, null, 2)}
+
{JSON.stringify($navigatingStore, null, 2)}
+
{JSON.stringify($updatedStore, null, 2)}
diff --git a/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-js/forms.stories.js b/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-js/forms.stories.js new file mode 100644 index 000000000000..fadda8554ac5 --- /dev/null +++ b/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-js/forms.stories.js @@ -0,0 +1,26 @@ +import { expect, fn, within } from '@storybook/test'; +import Forms from './Forms.svelte'; + +export default { + title: 'stories/sveltekit/modules/Forms', + component: Forms, + tags: ['autodocs'], +}; + +const enhance = fn(); + +export const Enhance = { + async play({ canvasElement }) { + const canvas = within(canvasElement); + const button = canvas.getByText('enhance'); + button.click(); + expect(enhance).toHaveBeenCalled(); + }, + parameters: { + sveltekit: { + forms: { + enhance, + }, + }, + }, +}; diff --git a/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-js/links.stories.js b/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-js/links.stories.js new file mode 100644 index 000000000000..c293245fc698 --- /dev/null +++ b/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-js/links.stories.js @@ -0,0 +1,26 @@ +import { expect, fn, within } from '@storybook/test'; +import Links from './Links.svelte'; + +export default { + title: 'stories/sveltekit/modules/Links', + component: Links, + tags: ['autodocs'], +}; + +const link = fn(); + +export const Link = { + async play({ canvasElement }) { + const canvas = within(canvasElement); + const button = canvas.getByText('Storybook'); + button.click(); + expect(link).toHaveBeenCalled(); + }, + parameters: { + sveltekit: { + linkOverrides: { + '/storybook': link, + }, + }, + }, +}; diff --git a/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-js/navigation.stories.js b/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-js/navigation.stories.js new file mode 100644 index 000000000000..14fe338749f4 --- /dev/null +++ b/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-js/navigation.stories.js @@ -0,0 +1,83 @@ +import { expect, fn, within } from '@storybook/test'; +import Navigation from './Navigation.svelte'; + +export default { + title: 'stories/sveltekit/modules/Navigation', + component: Navigation, + tags: ['autodocs'], +}; + +const goto = fn(); + +export const Goto = { + async play({ canvasElement }) { + const canvas = within(canvasElement); + const button = canvas.getByText('goto'); + button.click(); + expect(goto).toHaveBeenCalledWith('/storybook'); + }, + parameters: { + sveltekit: { + navigation: { + goto, + }, + }, + }, +}; + +const invalidate = fn(); + +export const Invalidate = { + async play({ canvasElement }) { + const canvas = within(canvasElement); + const button = canvas.getByText('invalidate', { exact: true }); + button.click(); + expect(invalidate).toHaveBeenCalledWith('/storybook'); + }, + parameters: { + sveltekit: { + navigation: { + invalidate, + }, + }, + }, +}; + +const invalidateAll = fn(); + +export const InvalidateAll = { + async play({ canvasElement }) { + const canvas = within(canvasElement); + const button = canvas.getByText('invalidateAll'); + button.click(); + console.log({ button }); + expect(invalidateAll).toHaveBeenCalledWith(); + }, + parameters: { + sveltekit: { + navigation: { + invalidateAll, + }, + }, + }, +}; + +const afterNavigateFn = fn(); + +export const AfterNavigate = { + async play() { + expect(afterNavigateFn).toHaveBeenCalledWith({ test: 'passed' }); + }, + args: { + afterNavigateFn, + }, + parameters: { + sveltekit: { + navigation: { + afterNavigate: { + test: 'passed', + }, + }, + }, + }, +}; diff --git a/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-js/stores.stories.js b/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-js/stores.stories.js new file mode 100644 index 000000000000..9ad83fe1bd87 --- /dev/null +++ b/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-js/stores.stories.js @@ -0,0 +1,116 @@ +import Stores from './Stores.svelte'; + +export default { + title: 'stories/sveltekit/modules/Stores', + component: Stores, + tags: ['autodocs'], +}; + +export const AllUndefined = {}; + +export const PageStore = { + parameters: { + sveltekit: { + stores: { + page: { + data: { + test: 'passed', + }, + }, + }, + }, + }, +}; + +export const NavigatingStore = { + parameters: { + sveltekit: { + stores: { + navigating: { + route: { + id: '/storybook', + }, + }, + }, + }, + }, +}; + +export const UpdatedStore = { + parameters: { + sveltekit: { + stores: { + updated: true, + }, + }, + }, +}; + +export const PageAndNavigatingStore = { + parameters: { + sveltekit: { + stores: { + page: { + data: { + test: 'passed', + }, + }, + navigating: { + route: { + id: '/storybook', + }, + }, + }, + }, + }, +}; + +export const PageAndUpdatedStore = { + parameters: { + sveltekit: { + stores: { + page: { + data: { + test: 'passed', + }, + }, + updated: true, + }, + }, + }, +}; + +export const NavigatingAndUpdatedStore = { + parameters: { + sveltekit: { + stores: { + navigating: { + route: { + id: '/storybook', + }, + }, + updated: true, + }, + }, + }, +}; + +export const AllThreeStores = { + parameters: { + sveltekit: { + stores: { + page: { + data: { + test: 'passed', + }, + }, + navigating: { + route: { + id: '/storybook', + }, + }, + updated: true, + }, + }, + }, +}; diff --git a/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-ts/Forms.svelte b/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-ts/Forms.svelte new file mode 100644 index 000000000000..371a17656bea --- /dev/null +++ b/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-ts/Forms.svelte @@ -0,0 +1,7 @@ + + +
+ +
\ No newline at end of file diff --git a/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-ts/Links.svelte b/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-ts/Links.svelte new file mode 100644 index 000000000000..3470b6b0e6f8 --- /dev/null +++ b/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-ts/Links.svelte @@ -0,0 +1 @@ +Storybook \ No newline at end of file diff --git a/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-ts/Navigation.svelte b/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-ts/Navigation.svelte new file mode 100644 index 000000000000..d97b6fe8a2df --- /dev/null +++ b/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-ts/Navigation.svelte @@ -0,0 +1,25 @@ + + + + + + + diff --git a/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-ts/Stores.svelte b/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-ts/Stores.svelte new file mode 100644 index 000000000000..479239610a6b --- /dev/null +++ b/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-ts/Stores.svelte @@ -0,0 +1,15 @@ + + +

Directly importing

+
{JSON.stringify($page, null, 2)}
+
{JSON.stringify($navigating, null, 2)}
+
{JSON.stringify($updated, null, 2)}
+ +

With getStores

+
{JSON.stringify($pageStore, null, 2)}
+
{JSON.stringify($navigatingStore, null, 2)}
+
{JSON.stringify($updatedStore, null, 2)}
diff --git a/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-ts/forms.stories.js b/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-ts/forms.stories.js new file mode 100644 index 000000000000..fadda8554ac5 --- /dev/null +++ b/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-ts/forms.stories.js @@ -0,0 +1,26 @@ +import { expect, fn, within } from '@storybook/test'; +import Forms from './Forms.svelte'; + +export default { + title: 'stories/sveltekit/modules/Forms', + component: Forms, + tags: ['autodocs'], +}; + +const enhance = fn(); + +export const Enhance = { + async play({ canvasElement }) { + const canvas = within(canvasElement); + const button = canvas.getByText('enhance'); + button.click(); + expect(enhance).toHaveBeenCalled(); + }, + parameters: { + sveltekit: { + forms: { + enhance, + }, + }, + }, +}; diff --git a/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-ts/links.stories.js b/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-ts/links.stories.js new file mode 100644 index 000000000000..c293245fc698 --- /dev/null +++ b/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-ts/links.stories.js @@ -0,0 +1,26 @@ +import { expect, fn, within } from '@storybook/test'; +import Links from './Links.svelte'; + +export default { + title: 'stories/sveltekit/modules/Links', + component: Links, + tags: ['autodocs'], +}; + +const link = fn(); + +export const Link = { + async play({ canvasElement }) { + const canvas = within(canvasElement); + const button = canvas.getByText('Storybook'); + button.click(); + expect(link).toHaveBeenCalled(); + }, + parameters: { + sveltekit: { + linkOverrides: { + '/storybook': link, + }, + }, + }, +}; diff --git a/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-ts/navigation.stories.js b/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-ts/navigation.stories.js new file mode 100644 index 000000000000..14fe338749f4 --- /dev/null +++ b/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-ts/navigation.stories.js @@ -0,0 +1,83 @@ +import { expect, fn, within } from '@storybook/test'; +import Navigation from './Navigation.svelte'; + +export default { + title: 'stories/sveltekit/modules/Navigation', + component: Navigation, + tags: ['autodocs'], +}; + +const goto = fn(); + +export const Goto = { + async play({ canvasElement }) { + const canvas = within(canvasElement); + const button = canvas.getByText('goto'); + button.click(); + expect(goto).toHaveBeenCalledWith('/storybook'); + }, + parameters: { + sveltekit: { + navigation: { + goto, + }, + }, + }, +}; + +const invalidate = fn(); + +export const Invalidate = { + async play({ canvasElement }) { + const canvas = within(canvasElement); + const button = canvas.getByText('invalidate', { exact: true }); + button.click(); + expect(invalidate).toHaveBeenCalledWith('/storybook'); + }, + parameters: { + sveltekit: { + navigation: { + invalidate, + }, + }, + }, +}; + +const invalidateAll = fn(); + +export const InvalidateAll = { + async play({ canvasElement }) { + const canvas = within(canvasElement); + const button = canvas.getByText('invalidateAll'); + button.click(); + console.log({ button }); + expect(invalidateAll).toHaveBeenCalledWith(); + }, + parameters: { + sveltekit: { + navigation: { + invalidateAll, + }, + }, + }, +}; + +const afterNavigateFn = fn(); + +export const AfterNavigate = { + async play() { + expect(afterNavigateFn).toHaveBeenCalledWith({ test: 'passed' }); + }, + args: { + afterNavigateFn, + }, + parameters: { + sveltekit: { + navigation: { + afterNavigate: { + test: 'passed', + }, + }, + }, + }, +}; diff --git a/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-ts/stores.stories.js b/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-ts/stores.stories.js new file mode 100644 index 000000000000..9ad83fe1bd87 --- /dev/null +++ b/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-ts/stores.stories.js @@ -0,0 +1,116 @@ +import Stores from './Stores.svelte'; + +export default { + title: 'stories/sveltekit/modules/Stores', + component: Stores, + tags: ['autodocs'], +}; + +export const AllUndefined = {}; + +export const PageStore = { + parameters: { + sveltekit: { + stores: { + page: { + data: { + test: 'passed', + }, + }, + }, + }, + }, +}; + +export const NavigatingStore = { + parameters: { + sveltekit: { + stores: { + navigating: { + route: { + id: '/storybook', + }, + }, + }, + }, + }, +}; + +export const UpdatedStore = { + parameters: { + sveltekit: { + stores: { + updated: true, + }, + }, + }, +}; + +export const PageAndNavigatingStore = { + parameters: { + sveltekit: { + stores: { + page: { + data: { + test: 'passed', + }, + }, + navigating: { + route: { + id: '/storybook', + }, + }, + }, + }, + }, +}; + +export const PageAndUpdatedStore = { + parameters: { + sveltekit: { + stores: { + page: { + data: { + test: 'passed', + }, + }, + updated: true, + }, + }, + }, +}; + +export const NavigatingAndUpdatedStore = { + parameters: { + sveltekit: { + stores: { + navigating: { + route: { + id: '/storybook', + }, + }, + updated: true, + }, + }, + }, +}; + +export const AllThreeStores = { + parameters: { + sveltekit: { + stores: { + page: { + data: { + test: 'passed', + }, + }, + navigating: { + route: { + id: '/storybook', + }, + }, + updated: true, + }, + }, + }, +}; From a42fc78297d4b7a65ab17d284a8a5134aad7b4af Mon Sep 17 00:00:00 2001 From: paoloricciuti Date: Fri, 10 Nov 2023 16:52:24 +0100 Subject: [PATCH 04/20] add check field to update store and write README --- code/frameworks/sveltekit/README.md | 49 +++++++++++++++++-- .../sveltekit/src/mocks/app/stores.ts | 8 ++- .../Stores.svelte | 2 + .../Stores.svelte | 2 + 4 files changed, 57 insertions(+), 4 deletions(-) diff --git a/code/frameworks/sveltekit/README.md b/code/frameworks/sveltekit/README.md index fd103c8764b1..45ba57592377 100644 --- a/code/frameworks/sveltekit/README.md +++ b/code/frameworks/sveltekit/README.md @@ -26,10 +26,10 @@ However SvelteKit has some [Kit-specific modules](https://kit.svelte.dev/docs/mo | **Module** | **Status** | **Note** | | ---------------------------------------------------------------------------------- | ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | | [`$app/environment`](https://kit.svelte.dev/docs/modules#$app-environment) | ✅ Supported | `version` is always empty in Storybook. | -| [`$app/forms`](https://kit.svelte.dev/docs/modules#$app-forms) | ⏳ Future | Will use mocks. Tracked in [#20999](https://github.com/storybookjs/storybook/issues/20999) | -| [`$app/navigation`](https://kit.svelte.dev/docs/modules#$app-navigation) | ⏳ Future | Will use mocks. Tracked in [#20999](https://github.com/storybookjs/storybook/issues/20999) | +| [`$app/forms`](https://kit.svelte.dev/docs/modules#$app-forms) | ✅ Supported | See [How to mock](#how-to-mock) | +| [`$app/navigation`](https://kit.svelte.dev/docs/modules#$app-navigation) | ✅ Supported | See [How to mock](#how-to-mock) | | [`$app/paths`](https://kit.svelte.dev/docs/modules#$app-paths) | ✅ Supported | Requires SvelteKit 1.4.0 or newer | -| [`$app/stores`](https://kit.svelte.dev/docs/modules#$app-stores) | ✅ Supported | Mocks planned, so you can set different store values per story. | +| [`$app/stores`](https://kit.svelte.dev/docs/modules#$app-stores) | ✅ Supported | See [How to mock](#how-to-mock) | | [`$env/dynamic/private`](https://kit.svelte.dev/docs/modules#$env-dynamic-private) | ⛔ Not supported | They are meant to only be available server-side, and Storybook renders all components on the client. | | [`$env/dynamic/public`](https://kit.svelte.dev/docs/modules#$env-dynamic-public) | 🚧 Partially supported | Only supported in development mode. Storybook is built as a static app with no server-side API so cannot dynamically serve content. | | [`$env/static/private`](https://kit.svelte.dev/docs/modules#$env-static-private) | ⛔ Not supported | They are meant to only be available server-side, and Storybook renders all components on the client. | @@ -125,3 +125,46 @@ You'll experience this if anything in your story is importing from `$app/forms` ## Acknowledgements Integrating with SvelteKit would not have been possible if it weren't for the fantastic efforts by the Svelte core team - especially [Ben McCann](https://twitter.com/benjaminmccann) - to make integrations with the wider ecosystem possible. + +## How to mock + +To mock a SvelteKit import you can make use of the `parameters.sveltekit` object either on the `Story`, on the `Template` or on the `Meta` + +```ts +export const MyStory = { + parameters: { + sveltekit: { + stores: { + page: { + data: { + test: 'passed', + }, + }, + navigating: { + route: { + id: '/storybook', + }, + }, + updated: true, + }, + }, + }, +}; +``` + +on this object you can add the name of the module you are mocking (in the example above we are mocking the `stores` module which correspond to `$app/stores`) and than pass the following kind of objects + +| Module | Path in parameters | Kind of objects | +| ----------------------------------------------- | ----------------------------------------------- | -------------------------------------------------------------------------------------------------- | +| import { page } from "$app/stores" | `parameters.sveltekit.stores.page` | A Partial of the page store | +| import { navigating } from "$app/stores" | `parameters.sveltekit.stores.navigating` | A Partial of the navigating store | +| import { updated } from "$app/stores" | `parameters.sveltekit.stores.updated` | A boolean representing the value of updated (you can also access `check()` which will be a noop) | +| import { goto } from "$app/navigation" | `parameters.sveltekit.navigation.goto` | A callback that will be called whenever goto is called | +| import { invalidate } from "$app/navigation" | `parameters.sveltekit.navigation.invalidate` | A callback that will be called whenever invalidate is called | +| import { invalidateAll } from "$app/navigation" | `parameters.sveltekit.navigation.invalidateAll` | A callback that will be called whenever invalidateAll is called | +| import { afterNavigate } from "$app/navigation" | `parameters.sveltekit.navigation.afterNavigate` | An object that will be passed to the afterNavigate function (which will be invoked onMount) called | +| import { enhance } from "$app/forms" | `parameters.sveltekit.forms.enhance` | A callback that will called when a form with `use:enhance` is submitted | + +All the other functions are still exported as `noop` from the mocked modules so that your application will still work. There was no way of make them work in a customizable way. + +Additionally you can pass an object to `parameter.sveltekit.linkOverrides` where the keys are regex representing a link and the values are functions. If you have an `` tag inside your code with the `href` attribute that matches one or more regex the corresponding function will be called. diff --git a/code/frameworks/sveltekit/src/mocks/app/stores.ts b/code/frameworks/sveltekit/src/mocks/app/stores.ts index e291f4d42ca1..56c9babaf93d 100644 --- a/code/frameworks/sveltekit/src/mocks/app/stores.ts +++ b/code/frameworks/sveltekit/src/mocks/app/stores.ts @@ -17,7 +17,13 @@ function createMockedStore(contextName: string) { export const [page, setPage] = createMockedStore('page-ctx'); export const [navigating, setNavigating] = createMockedStore('navigating-ctx'); -export const [updated, setUpdated] = createMockedStore('updated-ctx'); +const [updated, setUpdated] = createMockedStore('updated-ctx'); + +Object.defineProperty(updated, 'check', { + value: () => {}, +}); + +export { updated, setUpdated }; export function getStores() { return { diff --git a/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-js/Stores.svelte b/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-js/Stores.svelte index 479239610a6b..164b00f7fa8b 100644 --- a/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-js/Stores.svelte +++ b/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-js/Stores.svelte @@ -2,6 +2,8 @@ import { page, navigating, updated, getStores } from '$app/stores'; let { navigating: navigatingStore, page: pageStore, updated: updatedStore } = getStores(); + + updated.check();

Directly importing

diff --git a/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-ts/Stores.svelte b/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-ts/Stores.svelte index 479239610a6b..164b00f7fa8b 100644 --- a/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-ts/Stores.svelte +++ b/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-ts/Stores.svelte @@ -2,6 +2,8 @@ import { page, navigating, updated, getStores } from '$app/stores'; let { navigating: navigatingStore, page: pageStore, updated: updatedStore } = getStores(); + + updated.check();

Directly importing

From e184135475d78e3c00ebe718fd7510aa99d4dcb5 Mon Sep 17 00:00:00 2001 From: paoloricciuti Date: Fri, 10 Nov 2023 20:56:28 +0100 Subject: [PATCH 05/20] add components to files --- code/frameworks/sveltekit/package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/code/frameworks/sveltekit/package.json b/code/frameworks/sveltekit/package.json index afa20320e9b7..5bcb60c7d5ed 100644 --- a/code/frameworks/sveltekit/package.json +++ b/code/frameworks/sveltekit/package.json @@ -54,7 +54,6 @@ "README.md", "*.js", "*.d.ts", - "!src/**/*", "src/components/**/*" ], "scripts": { From adc9704dfcb40bc1c04ad763ab6170d428400000 Mon Sep 17 00:00:00 2001 From: paoloricciuti Date: Fri, 10 Nov 2023 21:14:44 +0100 Subject: [PATCH 06/20] add mocks files to files --- code/frameworks/sveltekit/package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/code/frameworks/sveltekit/package.json b/code/frameworks/sveltekit/package.json index 5bcb60c7d5ed..fe6bffb011fd 100644 --- a/code/frameworks/sveltekit/package.json +++ b/code/frameworks/sveltekit/package.json @@ -54,7 +54,8 @@ "README.md", "*.js", "*.d.ts", - "src/components/**/*" + "src/components/**/*", + "src/mocks/**/*" ], "scripts": { "check": "../../../scripts/prepare/check.ts", From dddc1c9363a0e2604b89d23b4cd9c8feca91aa08 Mon Sep 17 00:00:00 2001 From: paoloricciuti Date: Fri, 10 Nov 2023 21:48:40 +0100 Subject: [PATCH 07/20] remove logs + fix afternavigate tests --- .../sveltekit/src/components/SvelteDecorator.svelte | 1 - code/frameworks/sveltekit/src/mocks/app/navigation.ts | 4 +++- .../stories_svelte-kit-skeleton-js/Navigation.svelte | 5 +++-- .../stories_svelte-kit-skeleton-js/navigation.stories.js | 1 - .../stories_svelte-kit-skeleton-ts/navigation.stories.js | 1 - 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/code/frameworks/sveltekit/src/components/SvelteDecorator.svelte b/code/frameworks/sveltekit/src/components/SvelteDecorator.svelte index 025ec47e2074..04654a64e3a5 100644 --- a/code/frameworks/sveltekit/src/components/SvelteDecorator.svelte +++ b/code/frameworks/sveltekit/src/components/SvelteDecorator.svelte @@ -30,7 +30,6 @@ for(let func of functions){ if(ctx?.parameters?.sveltekit?.[baseModule]?.[func] && ctx.parameters.sveltekit[baseModule][func] instanceof Function){ const listener = ({ detail = [] })=>{ - console.log("event", func, ctx); const args = Array.isArray(detail) ? detail : []; ctx.parameters.sveltekit[baseModule][func](...args); } diff --git a/code/frameworks/sveltekit/src/mocks/app/navigation.ts b/code/frameworks/sveltekit/src/mocks/app/navigation.ts index aeaf586ae0ca..8d23ddbea46a 100644 --- a/code/frameworks/sveltekit/src/mocks/app/navigation.ts +++ b/code/frameworks/sveltekit/src/mocks/app/navigation.ts @@ -14,7 +14,9 @@ export function setAfterNavigateArgument(afterNavigateArgs: any) { export function afterNavigate(cb: any) { const argument = getContext('after-navigate-args'); onMount(() => { - cb(argument); + if (cb && cb instanceof Function) { + cb(argument); + } }); } diff --git a/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-js/Navigation.svelte b/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-js/Navigation.svelte index d97b6fe8a2df..f857ae36a843 100644 --- a/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-js/Navigation.svelte +++ b/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-js/Navigation.svelte @@ -2,8 +2,9 @@ import { goto, invalidate, invalidateAll, afterNavigate } from '$app/navigation'; export let afterNavigateFn; - - afterNavigate(afterNavigateFn); + if(afterNavigateFn){ + afterNavigate(afterNavigateFn); + }