home / skills / exceptionless / exceptionless / storybook

storybook skill

/.github/skills/storybook

This skill helps you author and visualize component stories in Storybook for Svelte CSF with defineMeta, argTypes, and snippets.

npx playbooks add skill exceptionless/exceptionless --skill storybook

Review the files below or copy the command above to add this skill to your agents.

Files (1)
SKILL.md
3.6 KB
---
name: Storybook
description: |
  Component stories using Storybook with Svelte CSF. Story patterns, defineMeta, argTypes,
  snippet-based customization, and visual testing.
  Keywords: storybook, stories.svelte, defineMeta, Story, args, argTypes, autodocs
---

# Storybook

> **Documentation:** [storybook.js.org](https://storybook.js.org/docs/svelte)

## Running Storybook

```bash
npm run storybook
```

## File Location

Co-locate stories with components as `*.stories.svelte`.

## Basic Story Pattern

From [stack-status-badge.stories.svelte](src/Exceptionless.Web/ClientApp/src/lib/features/stacks/components/stack-status-badge.stories.svelte):

```svelte
<script module lang="ts">
    import { defineMeta } from '@storybook/addon-svelte-csf';

    import { StackStatus } from '../models';
    import StackStatusBadge from './stack-status-badge.svelte';

    const { Story } = defineMeta({
        argTypes: {
            status: {
                control: { type: 'select' },
                options: [StackStatus.Open, StackStatus.Fixed, StackStatus.Regressed]
            }
        },
        component: StackStatusBadge,
        tags: ['autodocs'],
        title: 'Components/Stacks/StackStatusBadge'
    });
</script>

<Story name="Open" args={{ status: StackStatus.Open }} />
<Story name="Fixed" args={{ status: StackStatus.Fixed }} />
<Story name="Regressed" args={{ status: StackStatus.Regressed }} />
```

## Story with Snippets

From [notification.stories.svelte](src/Exceptionless.Web/ClientApp/src/lib/features/shared/components/notification/notification.stories.svelte):

```svelte
<script module lang="ts">
    import { Button } from '$comp/ui/button';
    import CheckCircle from '@lucide/svelte/icons/check-circle';
    import Ban from '@lucide/svelte/icons/ban';
    import { defineMeta } from '@storybook/addon-svelte-csf';

    import NotificationDescription from './notification-description.svelte';
    import NotificationTitle from './notification-title.svelte';
    import Notification from './notification.svelte';

    const { Story } = defineMeta({
        component: Notification,
        tags: ['autodocs'],
        title: 'Components/Shared/Notification'
    });
</script>

<Story name="Success">
    <Notification variant="success">
        {#snippet icon()}<CheckCircle />{/snippet}
        <NotificationTitle>Operation completed successfully!</NotificationTitle>
        <NotificationDescription>Your changes have been saved.</NotificationDescription>
    </Notification>
</Story>

<Story name="Destructive">
    <Notification variant="destructive">
        {#snippet icon()}<Ban />{/snippet}
        <NotificationTitle>Something went wrong</NotificationTitle>
        <NotificationDescription>An error occurred. Please try again.</NotificationDescription>
    </Notification>
</Story>

<Story name="With Action">
    <Notification variant="information">
        {#snippet action()}
            <Button variant="outline" size="sm">Take Action</Button>
        {/snippet}
        <NotificationTitle>Action required</NotificationTitle>
        <NotificationDescription>Click the button to proceed.</NotificationDescription>
    </Notification>
</Story>
```

## Key Patterns

- **`defineMeta`**: Returns `Story` component, configure `component`, `title`, `tags`
- **`tags: ['autodocs']`**: Auto-generate documentation page
- **`argTypes`**: Configure controls for props (select, text, boolean, etc.)
- **Simple args**: `<Story name="Open" args={{ status: 'open' }} />`
- **Custom content**: Use children with snippets for complex compositions
- **Title hierarchy**: Use `/` for organization (e.g., `Components/Shared/Notification`)

Overview

This skill documents how to write and organize Svelte component stories using Storybook's CSF (Component Story Format). It explains defineMeta, argTypes, snippet-based custom content, and autodocs patterns used in the Exceptionless app. The goal is to make stories that are discoverable, interactive, and suitable for visual testing.

How this skill works

Stories are co-located with components as *.stories.svelte files and use defineMeta from @storybook/addon-svelte-csf to export a Story component. defineMeta configures component, title, tags (for autodocs) and argTypes to generate controls. Simple stories use <Story name="..." args={{...}} /> while complex layouts use children and {#snippet ...}{/snippet} blocks for injecting custom parts of the component.

When to use it

  • Document component variants and states for designers and QA
  • Expose props via argTypes to enable interactive controls in Storybook
  • Create snippet-based stories for components that accept slotted or complex child content
  • Organize stories with hierarchical titles for discoverability
  • Generate autodocs pages automatically for component reference

Best practices

  • Co-locate stories with component source as ComponentName.stories.svelte for easy maintenance
  • Use defineMeta.tags: ['autodocs'] to enable automatic documentation pages
  • Prefer argTypes for props to create controls: select, text, boolean, etc.
  • Keep simple examples with args for common states and use snippet stories for slot or composition examples
  • Use clear title hierarchy like Components/Shared/Notification to group related stories

Example use cases

  • Badge component: define argTypes for status and add separate stories for Open/Fixed/Regressed using args
  • Notification component: show Success/Destructive/With Action variants using snippets for icon and action slots
  • Visual regression testing: render story variants for screenshot comparisons
  • Interactive QA: use controls generated from argTypes to test prop combinations
  • Autodocs: publish a component reference page without extra docs by adding tags: ['autodocs']

FAQ

How do I expose a prop as a control in Storybook?

Define argTypes in defineMeta and specify control type (select, text, boolean) and options if needed.

When should I use snippets instead of args?

Use snippets for components that accept slotted content or complex child elements that cannot be represented by simple args.