PraxisJS

Storybook

@praxisjs/storybook — Storybook framework adapter for PraxisJS. Write stories with full reactivity, HMR, and source preview.

Storybook

@praxisjs/storybook is a Storybook framework adapter that mounts PraxisJS components into the canvas with full reactivity, HMR, and source preview. Requires Storybook ≥ 8 and @storybook/builder-vite.

npm install -D @praxisjs/storybook
pnpm add -D @praxisjs/storybook
yarn add -D @praxisjs/storybook
bun add -d @praxisjs/storybook

Setup

.storybook/main.ts

import type { StorybookConfig } from '@praxisjs/storybook'

const config: StorybookConfig = {
  stories: ['../src/**/*.stories.tsx'],
  addons: ['@storybook/addon-essentials'],
  framework: {
    name: '@praxisjs/storybook',
  },
}

export default config

The adapter automatically wires up @praxisjs/vite-plugin with HMR enabled. You do not need to add the Vite plugin separately in .storybook/main.ts.

.storybook/preview.ts

No extra setup needed — the adapter handles mounting automatically.


Writing stories

Import Meta and StoryObj from @praxisjs/storybook for full type safety:

import { StatefulComponent } from '@praxisjs/core'
import { Component, State } from '@praxisjs/decorators'
import type { Meta, StoryObj } from '@praxisjs/storybook'

@Component()
class Counter extends StatefulComponent {
  @State() count = 0

  render() {
    return (
      <div>
        <p>{() => this.count}</p>
        <button onClick={() => { this.count++ }}>+</button>
      </div>
    )
  }
}

const meta: Meta = {
  title: 'Components/Counter',
  tags: ['autodocs'],
}
export default meta

type Story = StoryObj

export const Default: Story = {
  render: () => <Counter />,
}

export const StartAt10: Story = {
  render: () => <Counter />,
  // Pass props via render args:
  // render: (args) => <Counter initialCount={args.count} />,
}

Type reference

ExportDescription
MetaType for the default story export (ComponentAnnotations)
StoryObjType for named story exports (StoryAnnotations)
StorybookConfigType for .storybook/main.ts
PraxisRendererLow-level renderer type (rarely used directly)

How it works

  • renderToCanvas — mounts the component via @praxisjs/runtime's render() and stores a cleanup function. On forceRemount, the previous component is unmounted before the new one mounts.
  • viteFinal — merges @praxisjs/vite-plugin (with HMR) into Vite's config and injects a storySource plugin that embeds the raw story file source for the source preview panel.
  • managerEntries — registers the custom manager panel.

On this page