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/storybookpnpm add -D @praxisjs/storybookyarn add -D @praxisjs/storybookbun add -d @praxisjs/storybookSetup
.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 configThe 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 configEach 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
| Export | Description |
|---|---|
Meta | Type for the default story export (ComponentAnnotations) |
StoryObj | Type for named story exports (StoryAnnotations) |
StorybookConfig | Type for .storybook/main.ts |
StorybookRefs | Type for the refs field — see Composition |
PraxisRenderer | Low-level renderer type (rarely used directly) |
How it works
renderToCanvas— mounts the component via@praxisjs/runtime'srender()and stores a cleanup function. OnforceRemount, the previous component is unmounted before the new one mounts.viteFinal— merges@praxisjs/vite-plugin(with HMR) into Vite's config and injects astorySourceplugin that embeds the raw story file source for the source preview panel.managerEntries— registers the custom manager panel.