From bb1c0f1c96cd9874235861d85ab26ae198132dc2 Mon Sep 17 00:00:00 2001 From: Mateusz Kadlubowski Date: Fri, 8 Nov 2024 19:27:23 +0800 Subject: [PATCH] update `Story` - add `template` prop & children becomes static --- src/runtime/Story.svelte | 74 +++++++++++++++++++++++++++------------- 1 file changed, 51 insertions(+), 23 deletions(-) diff --git a/src/runtime/Story.svelte b/src/runtime/Story.svelte index 1e39c08..f630908 100644 --- a/src/runtime/Story.svelte +++ b/src/runtime/Story.svelte @@ -8,23 +8,15 @@ import { storyNameToExportName } from '../utils/identifier-utils'; import type { Cmp, StoryAnnotations } from '../types'; + type TemplateSnippet = Snippet< + [StoryRendererContext['args'], StoryRendererContext['storyContext']] + >; type Props = Partial> & { /** * @deprecated * Use `exportName` instead. */ id?: never; - /** - * The content to render in the story, either as: - * 1. A snippet taking args and storyContext as parameters - * 2. Static markup - * - * Can be omitted if a default template is set with [`setTemplate()`](https://github.com/storybookjs/addon-svelte-csf/blob/main/README.md#default-snippet) - */ - children?: Snippet< - /* prettier ignore */ - [StoryRendererContext['args'], StoryRendererContext['storyContext']] - >; /** * Name of the story. Can be omitted if `exportName` is provided. */ @@ -70,16 +62,42 @@ */ name: string; } + ) & + ( + | { + /** + * The content to render in the story as **static** markup. + * + * NOTE: Can be omitted if a default template is set with [`setTemplate()`](https://github.com/storybookjs/addon-svelte-csf/blob/main/README.md#default-snippet) + */ + children?: Snippet; + template?: never; + } + | { + children?: never; + /** + * The content to render in the story with a snippet taking `args` and `storyContext` as parameters + * + * NOTE: Can be omitted if a default template is set with [`setTemplate()`](https://github.com/storybookjs/addon-svelte-csf/blob/main/README.md#default-snippet) + */ + template?: TemplateSnippet; + } ); - - const { children, name, exportName: exportNameProp, play, ...restProps }: Props = $props(); + let { + children, + name, + exportName: exportNameProp, + play, + template, + ...restProps + }: Props = $props(); const exportName = exportNameProp ?? storyNameToExportName(name!); - const extractor = useStoriesExtractor(); - const renderer = useStoryRenderer(); - const template = useStoriesTemplate(); + let extractor = useStoriesExtractor(); + let renderer = useStoryRenderer(); + let storiesTemplate = useStoriesTemplate(); - const isCurrentlyViewed = $derived( + let isCurrentlyViewed = $derived( !extractor.isExtracting && renderer.currentStoryExportName === exportName ); @@ -98,6 +116,12 @@ } } + // TODO: Svelte maintainers is still discussing internally if they want to implement official typeguard function. + // Keep a pulse on this case and then this can be replaced. + function isSnippet(value: unknown): value is Snippet { + return typeof value === 'function'; + } + $effect(() => { if (isCurrentlyViewed) { injectIntoPlayFunction(renderer.storyContext, play); @@ -106,17 +130,21 @@ {#if isCurrentlyViewed} - {#if children} - {@render children(renderer.args, renderer.storyContext)} - {:else if template} + {#if template && isSnippet(template)} {@render template(renderer.args, renderer.storyContext)} + {:else if children && isSnippet(children)} + {@render children()} + {:else if storiesTemplate} + {@render storiesTemplate(renderer.args, renderer.storyContext)} {:else if renderer.storyContext.component} {:else}

- No story rendered. See the docs + {'@dominikg gave up...'} + No story rendered. See + the docs on how to define stories.

{/if}