diff --git a/code/e2e-tests/framework-svelte.spec.ts b/code/e2e-tests/framework-svelte.spec.ts
index ceffacc525d7..40d2b7f817dd 100644
--- a/code/e2e-tests/framework-svelte.spec.ts
+++ b/code/e2e-tests/framework-svelte.spec.ts
@@ -91,4 +91,36 @@ test.describe('SvelteKit', () => {
});
await expect(complexLogItem).toBeVisible();
});
+
+ test('goto are logged in Actions panel', async ({ page }) => {
+ const sbPage = new SbPage(page);
+
+ await sbPage.navigateToStory('stories/sveltekit/modules/navigation', 'default-actions');
+ const root = sbPage.previewRoot();
+ await sbPage.viewAddonPanel('Actions');
+
+ const goto = root.locator('button', { hasText: 'goto' });
+ await goto.click();
+
+ const gotoLogItem = page.locator('#storybook-panel-root #panel-tab-content', {
+ hasText: `/storybook-goto`,
+ });
+ await expect(gotoLogItem).toBeVisible();
+
+ const invalidate = root.getByRole('button', { name: 'invalidate', exact: true });
+ await invalidate.click();
+
+ const invalidateLogItem = page.locator('#storybook-panel-root #panel-tab-content', {
+ hasText: `/storybook-invalidate`,
+ });
+ await expect(invalidateLogItem).toBeVisible();
+
+ const invalidateAll = root.getByRole('button', { name: 'invalidateAll' });
+ await invalidateAll.click();
+
+ const invalidateAllLogItem = page.locator('#storybook-panel-root #panel-tab-content', {
+ hasText: `"invalidateAll"`,
+ });
+ await expect(invalidateAllLogItem).toBeVisible();
+ });
});
diff --git a/code/frameworks/sveltekit/README.md b/code/frameworks/sveltekit/README.md
index d9242efcdbf1..20248ce0d3f3 100644
--- a/code/frameworks/sveltekit/README.md
+++ b/code/frameworks/sveltekit/README.md
@@ -130,16 +130,16 @@ export const MyStory = {
You can add the name of the module you want to mock to `parameters.sveltekit_experimental` (in the example above we are mocking the `stores` module which correspond to `$app/stores`) and then pass the following kind of objects:
-| Module | Path in parameters | Kind of objects |
-| ------------------------------------------------- | ------------------------------------------------------------ | -------------------------------------------------------------------------------------------------- |
-| `import { page } from "$app/stores"` | `parameters.sveltekit_experimental.stores.page` | A Partial of the page store |
-| `import { navigating } from "$app/stores"` | `parameters.sveltekit_experimental.stores.navigating` | A Partial of the navigating store |
-| `import { updated } from "$app/stores"` | `parameters.sveltekit_experimental.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_experimental.navigation.goto` | A callback that will be called whenever goto is called |
-| `import { invalidate } from "$app/navigation"` | `parameters.sveltekit_experimental.navigation.invalidate` | A callback that will be called whenever invalidate is called |
-| `import { invalidateAll } from "$app/navigation"` | `parameters.sveltekit_experimental.navigation.invalidateAll` | A callback that will be called whenever invalidateAll is called |
-| `import { afterNavigate } from "$app/navigation"` | `parameters.sveltekit_experimental.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_experimental.forms.enhance` | A callback that will called when a form with `use:enhance` is submitted |
+| Module | Path in parameters | Kind of objects |
+| ------------------------------------------------- | ------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------- |
+| `import { page } from "$app/stores"` | `parameters.sveltekit_experimental.stores.page` | A Partial of the page store |
+| `import { navigating } from "$app/stores"` | `parameters.sveltekit_experimental.stores.navigating` | A Partial of the navigating store |
+| `import { updated } from "$app/stores"` | `parameters.sveltekit_experimental.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_experimental.navigation.goto` | A callback that will be called whenever goto is called, in no function is provided an action will be logged to the Actions panel |
+| `import { invalidate } from "$app/navigation"` | `parameters.sveltekit_experimental.navigation.invalidate` | A callback that will be called whenever invalidate is called, in no function is provided an action will be logged to the Actions panel |
+| `import { invalidateAll } from "$app/navigation"` | `parameters.sveltekit_experimental.navigation.invalidateAll` | A callback that will be called whenever invalidateAll is called, in no function is provided an action will be logged to the Actions panel |
+| `import { afterNavigate } from "$app/navigation"` | `parameters.sveltekit_experimental.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_experimental.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.
diff --git a/code/frameworks/sveltekit/src/preview.ts b/code/frameworks/sveltekit/src/preview.ts
index a43431b5103d..10affca46fc4 100644
--- a/code/frameworks/sveltekit/src/preview.ts
+++ b/code/frameworks/sveltekit/src/preview.ts
@@ -63,9 +63,14 @@ export const decorators: Decorator[] = [
* eg. storybook:goto, storybook:invalidateAll
* @param baseModule the base module where the function lives (navigation|forms)
* @param functions the list of functions in that module that emit events
+ * @param {boolean} [defaultToAction] the list of functions in that module that emit events
* @returns a function to remove all the listener added
*/
- function createListeners(baseModule: keyof SvelteKitParameters, functions: string[]) {
+ function createListeners(
+ baseModule: keyof SvelteKitParameters,
+ functions: string[],
+ defaultToAction?: boolean
+ ) {
// the array of every added listener, we can use this in the return function
// to clean them
const toRemove: Array<{
@@ -75,10 +80,11 @@ export const decorators: Decorator[] = [
functions.forEach((func) => {
// we loop over every function and check if the user actually passed
// a function in sveltekit_experimental[baseModule][func] eg. sveltekit_experimental.navigation.goto
- if (
+ const hasFunction =
(svelteKitParameters as any)[baseModule]?.[func] &&
- (svelteKitParameters as any)[baseModule][func] instanceof Function
- ) {
+ (svelteKitParameters as any)[baseModule][func] instanceof Function;
+ // if we default to an action we still add the listener (this will be the case for goto, invalidate, invalidateAll)
+ if (hasFunction || defaultToAction) {
// we create the listener that will just get the detail array from the custom element
// and call the user provided function spreading this args in...this will basically call
// the function that the user provide with the same arguments the function is invoked to
@@ -87,7 +93,12 @@ export const decorators: Decorator[] = [
// it provided to storybook will be called with "/my-route"
const listener = ({ detail = [] as any[] }) => {
const args = Array.isArray(detail) ? detail : [];
- (svelteKitParameters as any)[baseModule][func](...args);
+ // if it has a function in the parameters we call that function
+ // otherwise we invoke the action
+ const fnToCall = hasFunction
+ ? (svelteKitParameters as any)[baseModule][func]
+ : action(func);
+ fnToCall(...args);
};
const eventType = `storybook:${func}`;
toRemove.push({ eventType, listener });
@@ -104,11 +115,11 @@ export const decorators: Decorator[] = [
};
}
- const removeNavigationListeners = createListeners('navigation', [
- 'goto',
- 'invalidate',
- 'invalidateAll',
- ]);
+ const removeNavigationListeners = createListeners(
+ 'navigation',
+ ['goto', 'invalidate', 'invalidateAll'],
+ true
+ );
const removeFormsListeners = createListeners('forms', ['enhance']);
window.addEventListener('click', globalClickListener);
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 f857ae36a843..b923b8ee78d8 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
@@ -9,13 +9,13 @@
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
index 529997126f7c..ded12268e03c 100644
--- 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
@@ -14,7 +14,7 @@ export const Goto = {
const canvas = within(canvasElement);
const button = canvas.getByText('goto');
button.click();
- expect(goto).toHaveBeenCalledWith('/storybook');
+ expect(goto).toHaveBeenCalledWith('/storybook-goto');
},
parameters: {
sveltekit_experimental: {
@@ -25,6 +25,8 @@ export const Goto = {
},
};
+export const DefaultActions = {};
+
const invalidate = fn();
export const Invalidate = {
@@ -32,7 +34,7 @@ export const Invalidate = {
const canvas = within(canvasElement);
const button = canvas.getByText('invalidate', { exact: true });
button.click();
- expect(invalidate).toHaveBeenCalledWith('/storybook');
+ expect(invalidate).toHaveBeenCalledWith('/storybook-invalidate');
},
parameters: {
sveltekit_experimental: {
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
index d97b6fe8a2df..4bcb7d0e6fc9 100644
--- a/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-ts/Navigation.svelte
+++ b/code/frameworks/sveltekit/template/stories_svelte-kit-skeleton-ts/Navigation.svelte
@@ -8,13 +8,13 @@
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
index 529997126f7c..ded12268e03c 100644
--- 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
@@ -14,7 +14,7 @@ export const Goto = {
const canvas = within(canvasElement);
const button = canvas.getByText('goto');
button.click();
- expect(goto).toHaveBeenCalledWith('/storybook');
+ expect(goto).toHaveBeenCalledWith('/storybook-goto');
},
parameters: {
sveltekit_experimental: {
@@ -25,6 +25,8 @@ export const Goto = {
},
};
+export const DefaultActions = {};
+
const invalidate = fn();
export const Invalidate = {
@@ -32,7 +34,7 @@ export const Invalidate = {
const canvas = within(canvasElement);
const button = canvas.getByText('invalidate', { exact: true });
button.click();
- expect(invalidate).toHaveBeenCalledWith('/storybook');
+ expect(invalidate).toHaveBeenCalledWith('/storybook-invalidate');
},
parameters: {
sveltekit_experimental: {