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} />,
}

Composition

Storybook Composition lets you view stories from other published Storybooks — including ones built with other frameworks — inside your PraxisJS Storybook's sidebar. Add refs to .storybook/main.ts:

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

const config: StorybookConfig = {
  stories: ['../src/**/*.stories.tsx'],
  framework: {
    name: '@praxisjs/storybook',
  },
  refs: {
    'design-system': {
      title: 'Design System',
      url: 'https://your-design-system.example.com',
      expanded: false,
      sourceUrl: 'https://github.com/your-org/design-system',
    },
  },
}

export default config

Each key becomes an entry in the sidebar. expanded controls whether the ref's stories are expanded by default (defaults to true), and sourceUrl is an optional link back to the ref's repository. Use { disable: true } instead of { title, url } to turn off a ref that a shared preset registered for you.


Type reference

ExportDescription
MetaType for the default story export (ComponentAnnotations)
StoryObjType for named story exports (StoryAnnotations)
StorybookConfigType for .storybook/main.ts
StorybookRefsType for the refs field — see Composition
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