Stories

Source file extensions: .stories.(js|jsx|ts|tsx)

Stories are expresssed in Storybook’s Component Story Format (CSF) .

Backlight.dev supports Storybook 6.x improvements.

In CSF, stories and component metadata are defined as ES Modules. Every component story file consists of a required default export and one or more named exports.

Stories

Stories are named exports returning a function.

export const BasicButton = () => story;

The rendering of story depends on his type.

String
export const BasicButton = () => '<button>Basic</button>';
HTMLElement
var element = document.createElement('button');
element.appendChild(document.createTextNode('Click Me!'));
export const BasicButton = () => element;
lit-html
import { html } from 'lit-html';
import './my-button.js';

const name = 'World';
export const BasicButton = () => html`<button>Hello ${name}</button>`;
FAST
import { html } from '@microsoft/fast-element';
import './my-button.js';

const name = 'World';
export const BasicButton = () => html`<button>Hello ${name}</button>`;
uhtml
import { html } from 'uhtml';
import './my-button.js';

const name = 'World';
export const BasicButton = () => html`<button>Hello ${name}</button>`;
lighterhtml
import { html } from 'lighterhtml';
import './my-button.js';

const name = 'World';
export const BasicButton = () => html`<button>Hello ${name}</button>`;
Omi (JSX)
/** @jsx h */
import './index.js';
import { h } from 'omi';

export const story1 = () => <my-counter></my-counter>;
Stencil (JSX)
/* @jsx h */
import { h } from '@stencil/core';
import './my-counter.tsx';

export const story1 = () => <my-counter></my-counter>;
Preact (JSX)
/** @jsx h */
import { h } from 'preact';
import MyCounter from './index.js';

export const story1 = () => <MyCounter></MyCounter>;
React (JSX)
import React from 'react';
import MyCounter from './index.js';

export const story1 = () => <MyCounter></MyCounter>;
Riot
import Counter from './index.riot';

export const story1 = () => Counter;

export const story2 = () => ({
  Component: Counter,
  props: {
    count: 5,
  },
});
Sinuous
import { html } from 'sinuous';
import MyCounter from './index.js';

export const story1 = () => html`<div><${MyCounter}></${MyCounter}></div>`;
Solid (JSX)
import MyCounter from './index.js';

export const story1 = () => MyCounter;
export const jsx = () => () => <MyCounter />; // Double function
Svelte
import Counter from './index.svelte';

export const story1 = () => Counter;

export const story2 = () => ({
  Component: Counter,
  props: {
    count: 5,
  },
});
Vue 3
import MyCounter from './index.vue';

export const story1 = () => ({
  components: { MyCounter },
  template: '<my-counter></my-counter>',
});

Stories are rendered using our open source universal-story-renderer .

Parameters

Supported parameters are:

parameters: {
  backgrounds: {
    default: "light" | "dark",
  },
  layout: "centered" | "padded" | "fullscreen",
}

You can default the parameters of all stories in export default

export default {
  parameters: {
    backgrounds: {
      default: 'dark',
    },
    layout: 'centered',
  },
};

Or setup for a specific story

export const BasicButton = () => html`<button>Hello ${name}</button>`;
BasicButton.parameters = {
    backgrounds: {
      default: "dark",
    },
    layout: "centered",
  }
};

Args

Args allows stories to receive dynamic data as input arguments.

const Template = (args) => <Button {...args} />;

export const Text = Template.bind({});
Text.args = { label: 'hello', background: '#ff0' };

export const Emoji = Template.bind({});
Emoji.args = { ...Text.args, label: '😀 😎 👍 💯' };

For more details see Introducing Storybook Args .

References

Quick example

index.stories.js

import './index.ts';
import { html } from 'lit-html';

export default {
  parameters: {
    backgrounds: {
      default: 'dark',
    },
    layout: 'centered',
  },
};

export const story1 = () => html` <name-tag>John Foo</name-tag> `;
export const story2 = () => html` <name-tag>John Bar</name-tag> `;
story2.parameters = { backgrounds: { default: 'light' } };