@storybook/addon-svelte-csf
Advanced tools
Comparing version 4.1.6 to 4.1.7--canary.205.fe57790.0
@@ -1,86 +0,25 @@ | ||
import type { SvelteComponent } from 'svelte' | ||
import type { Addon_BaseMeta as BaseMeta, Addon_BaseAnnotations as BaseAnnotations, StoryContext, WebRenderer } from '@storybook/types'; | ||
type DecoratorReturnType = void | SvelteComponent | { | ||
Component: any, | ||
props?: any | ||
} | ||
interface StoryProps extends BaseAnnotations<any, DecoratorReturnType, WebRenderer> { | ||
/** | ||
* Id of the story. | ||
* | ||
* Optional, auto-generated from name if not specified. | ||
*/ | ||
id?: string; | ||
/** | ||
* Name of the story. | ||
*/ | ||
name: string; | ||
/** | ||
* Id of the template used by this story. | ||
* | ||
* Optional. Used if the story has no body. | ||
* If not specified, use the 'default' template. | ||
*/ | ||
template?: string; | ||
/** | ||
* Specify which sources should be shown. | ||
* | ||
* By default, sources for an args story are auto-generated. | ||
* If source is true, then the source of the story will be used instead. | ||
* If source is a string, it replaces the source of the story. | ||
*/ | ||
source?: boolean | string | ||
} | ||
interface TemplateProps extends BaseAnnotations<any, DecoratorReturnType> { | ||
/** | ||
* Id of the template. | ||
* | ||
* Optional. Use 'default' if not specified. | ||
*/ | ||
id?: string; | ||
} | ||
interface MetaProps extends BaseMeta<any>, BaseAnnotations<any, DecoratorReturnType> { | ||
/** | ||
* Enable the tag 'autodocs'. | ||
* | ||
* @see [Automatic documentation](https://storybook.js.org/docs/svelte/writing-docs/autodocs) | ||
*/ | ||
autodocs?: boolean; | ||
/** | ||
* List of tags to add to the stories. | ||
* | ||
* It should be a static array of strings. | ||
* | ||
* @example tags={['autodocs']} | ||
*/ | ||
tags?: string[]; | ||
} | ||
interface Slots { | ||
default: { | ||
args: any; | ||
context: StoryContext; | ||
[key: string]: any; | ||
} | ||
} | ||
import type { Args as BaseArgs } from 'storybook/internal/types'; | ||
import type { EmptyObject } from 'type-fest'; | ||
import type { Meta as MetaType, StoryCmp, StoryContext as BaseStoryContext, StoryAnnotations, Cmp } from '#types'; | ||
export { setTemplate } from './runtime/contexts/template.svelte'; | ||
export declare function defineMeta<const TOverrideArgs extends BaseArgs = EmptyObject, const TCmp extends Cmp = Cmp>(meta: MetaType<TCmp>): { | ||
Story: StoryCmp<EmptyObject, TCmp, typeof meta>; | ||
meta: MetaType<TCmp>; | ||
}; | ||
export type Args<TStoryCmp> = TStoryCmp extends StoryCmp<infer _TOverrideArgs, infer TCmpOrArgs, infer TMeta> ? NonNullable<StoryAnnotations<TCmpOrArgs, TMeta>['args']> : never; | ||
export type StoryContext<TStoryCmp> = TStoryCmp extends StoryCmp<infer _TOverrideArgs, infer TCmpOrArgs, infer TMeta> ? BaseStoryContext<TCmpOrArgs, TMeta> : never; | ||
/** | ||
* Meta. | ||
* | ||
* @deprecated Use `export const meta`. See https://github.com/storybookjs/addon-svelte-csf for an example | ||
* @deprecated Use `defineMeta` instead | ||
* @see {@link https://github.com/storybookjs/addon-svelte-csf/blob/main/MIGRATION.md#meta-component-removed-in-favor-of-definemeta} | ||
*/ | ||
export class Meta extends SvelteComponent<MetaProps> { } | ||
export declare const Meta: () => never; | ||
/** | ||
* Story. | ||
* @deprecated Use `Story` component returned from `defineMeta` instead | ||
* @see {@link https://github.com/storybookjs/addon-svelte-csf/blob/main/MIGRATION.md#export-meta-removed-in-favor-of-definemeta} | ||
*/ | ||
export class Story extends SvelteComponent<StoryProps, any, Slots> { } | ||
export declare const Story: () => never; | ||
/** | ||
* Template. | ||
* | ||
* Allow to reuse definition between stories. | ||
* @deprecated Use snippets instead | ||
* @see {@link https://github.com/storybookjs/addon-svelte-csf/blob/main/MIGRATION.md#template-component-removed} | ||
*/ | ||
export class Template extends SvelteComponent<TemplateProps, any, Slots> { } | ||
export declare const Template: () => never; |
@@ -1,7 +0,39 @@ | ||
export { default as Meta } from './components/Meta.svelte'; | ||
export { default as Story } from './components/Story.svelte'; | ||
export { default as Template } from './components/Template.svelte'; | ||
if (module?.hot?.decline) { | ||
module.hot.decline(); | ||
import dedent from 'dedent'; | ||
import StoryComponent from './runtime/Story.svelte'; | ||
export { setTemplate } from './runtime/contexts/template.svelte'; | ||
export function defineMeta(meta) { | ||
return { | ||
Story: StoryComponent, | ||
meta, | ||
}; | ||
} | ||
/** | ||
* @deprecated Use `defineMeta` instead | ||
* @see {@link https://github.com/storybookjs/addon-svelte-csf/blob/main/MIGRATION.md#meta-component-removed-in-favor-of-definemeta} | ||
*/ | ||
export const Meta = () => { | ||
throw new Error(dedent ` | ||
The Meta component has been removed in favor of the defineMeta function. | ||
For more details, see: @link https://github.com/storybookjs/addon-svelte-csf/blob/main/MIGRATION.md#meta-component-removed-in-favor-of-definemeta | ||
`); | ||
}; | ||
/** | ||
* @deprecated Use `Story` component returned from `defineMeta` instead | ||
* @see {@link https://github.com/storybookjs/addon-svelte-csf/blob/main/MIGRATION.md#export-meta-removed-in-favor-of-definemeta} | ||
*/ | ||
export const Story = () => { | ||
throw new Error(dedent ` | ||
The Story component can not be imported anymore, but must be desctructured from the defineMeta() call. | ||
For more details, see: https://github.com/storybookjs/addon-svelte-csf/blob/main/MIGRATION.md#export-meta-removed-in-favor-of-definemeta | ||
`); | ||
}; | ||
/** | ||
* @deprecated Use snippets instead | ||
* @see {@link https://github.com/storybookjs/addon-svelte-csf/blob/main/MIGRATION.md#template-component-removed} | ||
*/ | ||
export const Template = () => { | ||
throw new Error(dedent ` | ||
The Template component has been removed in favor of the snippets syntax. | ||
see: https://github.com/storybookjs/addon-svelte-csf/blob/main/MIGRATION.md#template-component-removed | ||
`); | ||
}; |
147
package.json
{ | ||
"name": "@storybook/addon-svelte-csf", | ||
"version": "4.1.6", | ||
"version": "4.1.7--canary.205.fe57790.0", | ||
"description": "Allows to write stories in Svelte syntax", | ||
"keywords": [ | ||
"storybook-addons", | ||
"csf", | ||
"svelte" | ||
@@ -11,24 +12,32 @@ ], | ||
"type": "git", | ||
"url": "https://github.com/storybookjs/addon-svelte-csf" | ||
"url": "git+https://github.com/storybookjs/addon-svelte-csf.git" | ||
}, | ||
"license": "MIT", | ||
"type": "module", | ||
"imports": { | ||
"#*": { | ||
"development": "./src/*.ts", | ||
"default": "./dist/*.js" | ||
} | ||
}, | ||
"exports": { | ||
".": { | ||
"types": "./dist/index.d.ts", | ||
"svelte": "./dist/index.js", | ||
"default": "./dist/index.js" | ||
}, | ||
"./preset": { | ||
"types": "./dist/preset/index.d.ts", | ||
"default": "./dist/preset/index.js" | ||
"types": "./dist/preset.d.ts", | ||
"default": "./dist/preset.js" | ||
}, | ||
"./internal/create-runtime-stories": { | ||
"types": "./dist/runtime/create-runtime-stories.d.ts", | ||
"default": "./dist/runtime/create-runtime-stories.js" | ||
}, | ||
"./package.json": "./package.json" | ||
}, | ||
"main": "./dist/index.js", | ||
"types": "./dist/index.d.ts", | ||
"files": [ | ||
"dist/**/*", | ||
"README.md", | ||
"*.js", | ||
"*.d.ts" | ||
"!dist/**/*.test.*", | ||
"README.md" | ||
], | ||
@@ -40,76 +49,69 @@ "scripts": { | ||
"chromatic": "chromatic --exit-zero-on-changes", | ||
"clean": "rimraf ./dist", | ||
"clean": "rimraf ./dist ./node_modules/.cache ./storybook-static ./svelte-kit ./.vite-inspect", | ||
"coverage": "vitest run --coverage", | ||
"lint": "eslint --cache --cache-location=.cache/eslint --ext .js,.jsx,.json,.html,.ts,.tsx,.mjs --report-unused-disable-directives", | ||
"format": "prettier --write .", | ||
"lint": "eslint --cache --cache-location=.cache/eslint --ext .js,.json,.html,.svelte,.ts --report-unused-disable-directives", | ||
"prepublish": "pnpm run clean && pnpm run build", | ||
"release": "pnpm run build && auto shipit", | ||
"start": "concurrently \"pnpm run storybook --quiet\" \"pnpm run build --watch\"", | ||
"storybook": "storybook dev --port 6006", | ||
"test": "vitest run" | ||
"storybook": "storybook dev --port 6006 --no-open", | ||
"test": "vitest run", | ||
"test:watch": "vitest watch" | ||
}, | ||
"dependencies": { | ||
"@babel/runtime": "^7.22.6", | ||
"@storybook/types": "^8.0.0", | ||
"dedent": "^1.2.0", | ||
"magic-string": "^0.30.1" | ||
"@storybook/csf": "^0.1.11", | ||
"@storybook/docs-tools": "^8.0.0", | ||
"@storybook/node-logger": "^8.0.0", | ||
"dedent": "^1.5.3", | ||
"esrap": "^1.2.2", | ||
"lodash-es": "^4.17.21", | ||
"magic-string": "^0.30.10", | ||
"zimmerframe": "^1.1.2" | ||
}, | ||
"devDependencies": { | ||
"@auto-it/released": "^10.32.6", | ||
"@storybook/addon-actions": "^8.0.0-rc.2", | ||
"@storybook/addon-essentials": "^8.0.0-rc.2", | ||
"@storybook/addon-interactions": "^8.0.0-rc.2", | ||
"@storybook/blocks": "^8.0.0-rc.2", | ||
"@storybook/client-logger": "^8.0.0-rc.2", | ||
"@storybook/components": "^8.0.0-rc.2", | ||
"@storybook/csf": "^0.1.1", | ||
"@storybook/eslint-config-storybook": "^3.1.2", | ||
"@storybook/preview-api": "^8.0.0-rc.2", | ||
"@storybook/svelte": "^8.0.0-rc.2", | ||
"@storybook/svelte-vite": "^8.0.0-rc.2", | ||
"@storybook/test": "^8.0.0-rc.2", | ||
"@storybook/theming": "^8.0.0-rc.2", | ||
"@sveltejs/kit": "^2.5.7", | ||
"@sveltejs/package": "^2.2.0", | ||
"@sveltejs/vite-plugin-svelte": "^2.4.2", | ||
"@tsconfig/svelte": "^5.0.0", | ||
"@types/estree": "^1.0.1", | ||
"auto": "^11.1.1", | ||
"chromatic": "^11.3.5", | ||
"concurrently": "^8.2.0", | ||
"eslint": "^7.17.0", | ||
"@auto-it/released": "^11.1.6", | ||
"@storybook/addon-actions": "^8.2.2", | ||
"@storybook/addon-essentials": "^8.2.2", | ||
"@storybook/addon-interactions": "^8.2.2", | ||
"@storybook/client-logger": "^8.2.2", | ||
"@storybook/eslint-config-storybook": "^4.0.0", | ||
"@storybook/preview-api": "^8.2.2", | ||
"@storybook/svelte": "^8.2.2", | ||
"@storybook/svelte-vite": "^8.2.2", | ||
"@storybook/test": "^8.2.2", | ||
"@sveltejs/package": "^2.3.2", | ||
"@sveltejs/vite-plugin-svelte": "4.0.0-next.3", | ||
"@tsconfig/svelte": "^5.0.4", | ||
"@types/estree": "^1.0.5", | ||
"@types/node": "^20.14.9", | ||
"@vitest/ui": "^1.6.0", | ||
"auto": "^11.1.6", | ||
"chromatic": "^11.5.4", | ||
"concurrently": "^8.2.2", | ||
"eslint": "^7.32.0", | ||
"eslint-plugin-storybook": "^0.8.0", | ||
"jsdom": "^22.1.0", | ||
"prettier": "^3.0.0", | ||
"react": "^18.2.0", | ||
"react-dom": "^18.2.0", | ||
"rimraf": "^3.0.2", | ||
"storybook": "^8.0.0-rc.2", | ||
"svelte": "^4.2.2", | ||
"svelte-check": "^3.5.0", | ||
"svelte-jester": "^2.3.2", | ||
"svelte-loader": "^3.1.7", | ||
"svelte-package": "^0.1.0", | ||
"typescript": "^5.1.6", | ||
"vite": "^4.4.3", | ||
"jsdom": "^24.1.0", | ||
"prettier": "^3.3.2", | ||
"prettier-plugin-svelte": "^3.2.5", | ||
"rimraf": "^5.0.7", | ||
"rollup": "^4.18.0", | ||
"storybook": "^8.2.2", | ||
"svelte": "5.0.0-next.215", | ||
"svelte-check": "^3.8.4", | ||
"tslib": "^2.6.3", | ||
"type-fest": "^4.20.1", | ||
"typescript": "^5.5.2", | ||
"typescript-svelte-plugin": "^0.3.39", | ||
"vite": "^5.3.2", | ||
"vite-plugin-inspect": "^0.8.4", | ||
"vite-plugin-virtual": "^0.3.0", | ||
"vitest": "^1.6.0" | ||
}, | ||
"peerDependencies": { | ||
"@storybook/svelte": "^7.0.0 || ^8.0.0 || ^8.0.0-beta.0 || ^8.2.0-beta.0", | ||
"@sveltejs/vite-plugin-svelte": "^2.0.0 || ^3.0.0", | ||
"svelte": "^4.0.0", | ||
"svelte-loader": "^3.1.2", | ||
"vite": "^4.0.0 || ^5.0.0" | ||
"@storybook/svelte": "^8.0.0", | ||
"@sveltejs/vite-plugin-svelte": "^4.0.0-next.0 || ^4.0.0", | ||
"svelte": "^5.0.0-next.117 || ^5.0.0", | ||
"vite": "^5.0.0" | ||
}, | ||
"peerDependenciesMeta": { | ||
"@sveltejs/vite-plugin-svelte": { | ||
"optional": true | ||
}, | ||
"svelte-loader": { | ||
"optional": true | ||
}, | ||
"vite": { | ||
"optional": true | ||
} | ||
}, | ||
"packageManager": "pnpm@9.1.1", | ||
"packageManager": "pnpm@9.1.3+sha512.7c2ea089e1a6af306409c4fc8c4f0897bdac32b772016196c469d9428f1fe2d5a21daf8ad6512762654ac645b5d9136bb210ec9a00afa8dbc4677843ba362ecd", | ||
"publishConfig": { | ||
@@ -124,2 +126,7 @@ "access": "public" | ||
}, | ||
"pnpm": { | ||
"overrides": { | ||
"svelte-preprocess": "^6.0.2" | ||
} | ||
}, | ||
"storybook": { | ||
@@ -126,0 +133,0 @@ "displayName": "Svelte CSF", |
342
README.md
@@ -1,109 +0,282 @@ | ||
# Svelte Story Format | ||
# Svelte CSF | ||
Allows you to write your stories in `.svelte` syntax rather than `.js` syntax. | ||
This Storybook addon allows you to write Storybook stories using the Svelte language instead of ESM that regular CSF is based on. | ||
It supports: | ||
```bash | ||
npx storybook@latest add @storybook/addon-svelte-csf | ||
``` | ||
- args stories and stories without args ; | ||
- the "template" pattern for args stories, compatible with a svelte syntax ; | ||
- extractions of sources of the stories and compatible with addon-sources | ||
- decorators | ||
- knobs, actions, controls | ||
- storyshots (with a special jest transformation shipped under `@storybook/addon-svelte-csf/jest-transform`) | ||
Using the Svelte language makes it easier to write stories for composed components that rely on snippets or slots, which aren't easily re-created outside of Svelte files. | ||
## Example | ||
## 🐣 Getting Started | ||
Have a basic button component: | ||
> [!TIP] | ||
> If you've initialized your Storybook project with Storybook version 8.2.0 or above, this addon is already set up for you! | ||
> [!IMPORTANT] | ||
> Not running the latest and greatest versions of Storybook or Svelte? Be sure to check [the version compatibility section below](#version-compatibility). | ||
The easiest way to install the addon is with `storybook add`: | ||
```bash | ||
npx storybook@latest add @storybook/addon-svelte-csf | ||
``` | ||
You can also add the addon manually. First, install the package: | ||
```bash | ||
npm install --save-dev @storybook/addon-svelte-csf | ||
``` | ||
Then modify your `main.ts` Storybook configuration to include the addon and include `*.stories.svelte` files: | ||
```diff | ||
export default { | ||
- stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)', | ||
+ stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx|svelte)'], | ||
addons: [ | ||
+ '@storybook/addon-svelte-csf', | ||
... | ||
], | ||
... | ||
} | ||
``` | ||
Restart your Storybook server for the changes to take effect. | ||
## 🐓 Usage | ||
> [!NOTE] | ||
> The documentation here does not cover all of Storybook's features, only the aspects that are specific to the addon and Svelte CSF. We recommend that you familiarize yourself with Storybook's core concepts at <https://storybook.js.org/docs>. | ||
The [`examples`](./examples/) directory contains examples describing each feature of the addon. The [`Button.stories.svelte` example](./examples/Button.stories.svelte) is a good one to get started with. [The Storybook with all the examples is published on Chromatic here](https://next--667492d3e52064f1d418ec95.chromatic.com). | ||
Svelte CSF stories files must always have the `.stories.svelte` extension. | ||
### Defining the meta | ||
All stories files must have a "meta" (aka. "default export") defined, and its structure follows what's described in [the official docs on the subject](https://storybook.js.org/docs/api/csf#default-export). To define the meta in Svelte CSF, call the `defineMeta` function **within the module context**, with the meta properties you want: | ||
```svelte | ||
<script> | ||
export let rounded = true; | ||
<script context="module"> | ||
// 👆 notice the module context, defineMeta does not work in a regular <script> tag - instance | ||
import { defineMeta } from '@storybook/addon-svelte-csf'; | ||
import MyComponent from './MyComponent.svelte'; | ||
// 👇 Get the Story component from the return value | ||
const { Story } = defineMeta({ | ||
title: 'Path/To/MyComponent', | ||
component: MyComponent, | ||
decorators: [ | ||
/* ... */ | ||
], | ||
parameters: { | ||
/* ... */ | ||
}, | ||
}); | ||
</script> | ||
``` | ||
<style> | ||
.rounded { | ||
border-radius: 35px; | ||
} | ||
`defineMeta` returns an object with a `Story` component (see [Defining stories](#defining-stories) below) that you must destructure out to use. | ||
button { | ||
border: 3px solid; | ||
padding: 10px 20px; | ||
background-color: white; | ||
outline: none; | ||
} | ||
</style> | ||
### Defining stories | ||
<button class="button" class:rounded on:click={onClick}> | ||
<slot /> | ||
</button> | ||
To define stories, you use the `Story` component returned from the `defineMeta` function. Depending on what you want the story to contain, [there are multiple ways to use the `Story` component](./examples/Templating.stories.svelte). Common for all the use case is that all properties of [a regular CSF story](https://storybook.js.org/docs/api/csf#named-story-exports) are passed as props to the `Story` component, with the exception of the `render` function, which does not have any effect in Svelte CSF. | ||
All story requires either the `name` prop or [`exportName` prop](#custom-export-name). | ||
> [!TIP] | ||
> In versions prior to v5 of this addon, it was always required to define a template story with the `<Template>` component. This is no longer required and stories will default to render the component from `meta` if no template is set. | ||
#### Plain Story | ||
If your component only accepts props and doesn't require snippets or slots, you can use the simple form of defining stories, only using args: | ||
```svelte | ||
<Story name="Primary" args={{ primary: true }} /> | ||
``` | ||
And a `button.stories.svelte` file: | ||
This will render the component defined in the meta, with the args passed as props. | ||
#### Static template | ||
If you need more customization of the story, like composing components or defining snippets, you can pass in children to the `Story`, and write whatever component structure you desire: | ||
```svelte | ||
<Story name="Composed"> | ||
<MyComponent> | ||
<AChild label="Hello world!" /> | ||
</MyComponent> | ||
</Story> | ||
``` | ||
> [!IMPORTANT] | ||
> This format completely ignores args, as they are not passed down to any of the child components defined. Even if your story has args and Controls, they won't have an effect. See the snippet-based formats below. | ||
#### Inline snippet | ||
If you need composition/snippets but also want a dynamic story that reacts to args or the story context, you can define a `children` snippet in the `Story` component: | ||
```svelte | ||
<Story name="Simple Children" args={{ simpleChild: true }}> | ||
{#snippet children(args)} | ||
<MyComponent {...args}>Component with args</MyComponent> | ||
{/snippet} | ||
</Story> | ||
``` | ||
#### Shared snippet | ||
Often your stories are very similar and their only differences are args or play-functions. In this case it can be cumbersome to define the same `children` snippet over and over again. You can share snippets by defining them at the top-level and passing them as props to `Story`: | ||
```svelte | ||
{#snippet template(args)} | ||
<MyComponent {...args}> | ||
{#if args.simpleChild} | ||
<AChild data={args.childProps} /> | ||
{:else} | ||
<ComplexChildA data={args.childProps} /> | ||
<ComplexChildB data={args.childProps} /> | ||
{/if} | ||
</MyComponent> | ||
{/snippet} | ||
<Story name="Simple Children" args={{ simpleChild: true }} children={template} /> | ||
<Story name="Complex Children" args={{ simpleChild: false }} children={template} /> | ||
``` | ||
You can also use this pattern to define multiple templates and share the different templates among different stories. | ||
#### Default snippet | ||
If you only need a single template that you want to share, it can be tedious to include `children={template}` in each `Story` component. Like in th example below: | ||
```svelte | ||
<Story name="Primary" args={{ variant: 'primary' }} children={template} /> | ||
<Story name="Secondary" args={{ variant: 'secondary' }} children={template} /> | ||
<Story name="Tertiary" args={{ variant: 'tertiary' }} children={template} /> | ||
<!-- ... more ... --> | ||
<Story name="Denary" args={{ variant: 'denary' }} children={template} /> | ||
``` | ||
In this case you can use the `setTemplate()` helper function that sets a default template for all stories. In regular CSF terms, this is the equivalent of defining a meta-level `render`-function versus story-level `render`-functions: | ||
```svelte | ||
<script context="module"> | ||
import Button from './Button.svelte'; | ||
import { defineMeta, setTemplate } from '@storybook/addon-svelte-csf'; | ||
// 👆 import the function | ||
import MyComponent from './MyComponent.svelte'; | ||
export const meta = { | ||
title: "Button", | ||
component: Button | ||
} | ||
const { Story } = defineMeta({ | ||
/* ... */ | ||
}); | ||
</script> | ||
<script> | ||
import { Story, Template } from '@storybook/addon-svelte-csf'; | ||
let count = 0; | ||
function handleClick() { | ||
count += 1; | ||
} | ||
// 👆 note this must be within a instance (regular) <script> tag as the module context can not reference snippets defined in the markup | ||
setTemplate(template); | ||
// 👆 the name of the snippet as defined below (can be any name) | ||
</script> | ||
<Template let:args> | ||
<!--👇 'on:click' allows to forward event to addon-actions --> | ||
<Button {...args} | ||
on:click | ||
on:click={handleClick}> | ||
You clicked: {count} | ||
</Button> | ||
</Template> | ||
{#snippet template(args)} | ||
<MyComponent {...args}> | ||
{#if args.simpleChild} | ||
<AChild data={args.childProps} /> | ||
{:else} | ||
<ComplexChildA data={args.childProps} /> | ||
<ComplexChildB data={args.childProps} /> | ||
{/if} | ||
</MyComponent> | ||
{/snippet} | ||
<Story name="Rounded" args={{rounded: true}}/> | ||
<Story name="Simple Children" args={{ simpleChild: true }} /> | ||
<Story name="Square" source args={{rounded: false}}/> | ||
<Story name="Complex Children" args={{ simpleChild: false }} /> | ||
``` | ||
<!-- Dynamic snippet should be disabled for this story --> | ||
<Story name="Button No Args"> | ||
<Button>Label</Button> | ||
Stories can still override this default snippet using any of the methods for defining story-level content. | ||
#### Custom export name | ||
Behind-the-scenes, each `<Story />` definition is compiled to a variable export like `export const MyStory = ...;`. In most cases you don't have to care about this detail, however sometimes naming conflicts can arise from this. The variable names are simplifications of the story names - to make them valid JavaScript variables. | ||
This can cause conflicts, eg. two stories with the names _"my story!"_ and _"My Story"_ will both be simplified to `MyStory`. | ||
You can explicitly define the variable name of any story by passing the `exportName` prop: | ||
```svelte | ||
<Story exportName="MyStory1" name="my story!" /> | ||
<Story exportName="MyStory2" name="My Story" /> | ||
``` | ||
At least one of the `name` or `exportName` props must be passed to the `Story` component - passing both is also valid. | ||
#### Accessing Story context | ||
If for some reason you need to access the [Story context](https://storybook.js.org/docs/writing-stories/decorators#context-for-mocking) _(e.g. for mocking)_ while rendering the story, then `<Story />`'s attribute `children` snippet provides an optional second argument. | ||
```svelte | ||
<Story name="Default"> | ||
{#snippet children(args, context)} | ||
<!-- 👆 use the optional second argument to access Story context --> | ||
<MyComponent {...args}> | ||
{/snippet} | ||
</Story> | ||
``` | ||
Actions are automatically registered by Storybook. To be used by this addon, you just have to forward the event (`on:click` in the previous example). | ||
### TypeScript | ||
Story snippets and args can be type-safe when necessary. The type of the args are inferred from the component props passed to `defineMeta`. | ||
## Getting Started | ||
You can make your snippets type-safe with the `Args` and `StoryContext` helper types: | ||
1. `npm install --save-dev @storybook/addon-svelte-csf` or `yarn add --dev @storybook/addon-svelte-csf` | ||
2. In `.storybook/main.js`, add `@storybook/addon-svelte-csf` to the addons array | ||
4. In `.storybook/main.js`, include .stories.svelte files in your stories patterns, eg. by changing the patterns to `'../src/**/*.stories.@(js|jsx|ts|tsx|svelte)'` | ||
```svelte | ||
<script context="module" lang="ts"> | ||
import { defineMeta, type Args, type StoryContext } from '@storybook/addon-svelte-csf'; | ||
// 👆 👆 import those type helpers from this addon --> | ||
An example `main.js` configuration could look like this: | ||
import MyComponent from './MyComponent.svelte'; | ||
```js | ||
module.exports = { | ||
stories: ['../src/**/*.stories.@(js|jsx|ts|tsx|svelte)'], | ||
addons: [ | ||
'@storybook/addon-links', | ||
'@storybook/addon-essentials', | ||
'@storybook/addon-interactions', | ||
'@storybook/addon-svelte-csf', | ||
], | ||
framework: '@storybook/svelte-vite', | ||
}; | ||
const { Story } = defineMeta({ | ||
component: MyComponent, | ||
}); | ||
</script> | ||
<!-- 👇 use to infer `args` type from the `Story` component --> | ||
{#snippet template(args: Args<typeof Story>, context: StoryContext<typeof Story>)} | ||
<!-- 👆 use to infer `context` type from the `Story` component --> | ||
<MyComponent {...args} /> | ||
{/snippet} | ||
``` | ||
## Version Dependencies | ||
If you need to customize the type of the `args`, you can pass in a generic type parameter to `defineMeta` that will override the types inferred from the component: | ||
### 4.0.0 | ||
```svelte | ||
const { Story } = defineMeta<{ anotherProp: boolean }>( ... ); | ||
``` | ||
## Version compatibility | ||
### latest | ||
Version 5 and up of this addon requires _at least_: | ||
| Dependency | Version | | ||
| ---------------------------------------------------------------------------------------------------------------------- | -------- | | ||
| [Storybook](https://github.com/storybookjs/storybook) | `v8.0.0` | | ||
| [Svelte](https://github.com/sveltejs/svelte) | `v5.0.0` | | ||
| [Vite](https://github.com/vitejs/vite) | `v5.0.0` | | ||
| [`@sveltejs/vite-plugin-svelte`](https://github.com/sveltejs/vite-plugin-svelte/tree/main/packages/vite-plugin-svelte) | `v4.0.0` | | ||
> [!IMPORTANT] | ||
> As of `v5` this addon does not support Webpack. | ||
### v4 | ||
```bash | ||
npm install --save-dev @storybook/addon-svelte-csf@^4 | ||
``` | ||
Version 4 of this addon requires _at least_: | ||
@@ -116,8 +289,27 @@ | ||
If you're using Svelte v3 you can use version `^3.0.0` of this addon instead. | ||
### v3 | ||
### 3.0.0 | ||
```bash | ||
npm install --save-dev @storybook/addon-svelte-csf@^3 | ||
``` | ||
Version 3 of this addon requires at least Storybook v7. | ||
Version 3 of this addon requires _at least_: | ||
If you're using Storybook between v6.4.20 and v7.0.0, you should instead use version `^2.0.0` of this addon. | ||
- Storybook v7 | ||
- Svelte v3 | ||
### v2 | ||
```bash | ||
npm install --save-dev @storybook/addon-svelte-csf@^2 | ||
``` | ||
If you're using Storybook between v6.4.20 and v7.0.0, you should use version `^2.0.0` of this addon. | ||
## 🤝 Contributing | ||
This project uses [pnpm](https://pnpm.io/installation) for dependency management. | ||
1. Install dependencies with `pnpm install` | ||
2. Concurrently start the compilation and the internal Storybook with `pnpm start`. | ||
3. Restarting the internal Storybook is often needed for changes to take effect. |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
170066
37
109
3832
315
0
12
2
2
41
+ Added@storybook/csf@^0.1.11
+ Added@storybook/docs-tools@^8.0.0
+ Addedesrap@^1.2.2
+ Addedlodash-es@^4.17.21
+ Addedzimmerframe@^1.1.2
+ Added@storybook/core@8.5.0-alpha.3(transitive)
+ Added@storybook/docs-tools@8.4.2(transitive)
+ Added@storybook/node-logger@8.4.2(transitive)
+ Added@sveltejs/vite-plugin-svelte@4.0.0(transitive)
+ Added@sveltejs/vite-plugin-svelte-inspector@3.0.1(transitive)
+ Addedacorn-typescript@1.4.13(transitive)
+ Addedesm-env@1.1.4(transitive)
+ Addedesrap@1.2.2(transitive)
+ Addedlodash-es@4.17.21(transitive)
+ Addedstorybook@8.5.0-alpha.3(transitive)
+ Addedsvelte@5.1.9(transitive)
+ Addedvitefu@1.0.3(transitive)
+ Addedzimmerframe@1.1.2(transitive)
- Removed@babel/runtime@^7.22.6
- Removed@storybook/types@^8.0.0
- Removed@babel/runtime@7.26.0(transitive)
- Removed@storybook/types@8.4.2(transitive)
- Removed@sveltejs/vite-plugin-svelte@3.1.2(transitive)
- Removed@sveltejs/vite-plugin-svelte-inspector@2.1.0(transitive)
- Removedbig.js@5.2.2(transitive)
- Removedcode-red@1.0.4(transitive)
- Removedcss-tree@2.3.1(transitive)
- Removedemojis-list@3.0.0(transitive)
- Removedestree-walker@3.0.3(transitive)
- Removedjson5@2.2.3(transitive)
- Removedloader-utils@2.0.4(transitive)
- Removedmdn-data@2.0.30(transitive)
- Removedperiscopic@3.1.0(transitive)
- Removedregenerator-runtime@0.14.1(transitive)
- Removedsvelte@4.2.19(transitive)
- Removedsvelte-dev-helper@1.1.9(transitive)
- Removedsvelte-hmr@0.14.120.16.0(transitive)
- Removedsvelte-loader@3.2.4(transitive)
- Removedvitefu@0.2.5(transitive)
Updateddedent@^1.5.3
Updatedmagic-string@^0.30.10