Storybook Vue 2.x renderer that enables Vue 2.x component story development and documentation (Note: @storybook/vue3 is separate)
—
Story decoration system for wrapping Vue components with additional context, providers, styling, or behavior modification within Storybook stories.
Decorator function type for creating reusable story wrappers with full type safety.
/**
* Decorator function for Vue stories
* @template TArgs - Story argument types
*/
type Decorator<TArgs = StrictArgs> = DecoratorFunction<VueRenderer, TArgs>;
type DecoratorFunction<TRenderer extends Renderer, TArgs> = (
storyFn: StoryFunction<TRenderer, TArgs>,
context: StoryContext<TRenderer, TArgs>
) => StoryFn<TRenderer, TArgs>;Usage Example:
import type { Decorator, Meta, StoryObj } from "@storybook/vue";
import MyButton from "./MyButton.vue";
// Create a decorator that adds padding
const PaddingDecorator: Decorator = (storyFn, context) => {
return {
components: { Story: storyFn() },
template: '<div style="padding: 20px;"><Story /></div>',
};
};
const meta: Meta<typeof MyButton> = {
title: "Example/Button",
component: MyButton,
decorators: [PaddingDecorator],
};
export default meta;Applies a chain of decorators to a story function, processing them in the correct order.
/**
* Apply decorators to Vue stories
* @param storyFn - The original story function
* @param decorators - Array of decorator functions to apply
* @returns Decorated story function
*/
function decorateStory(
storyFn: LegacyStoryFn<VueRenderer>,
decorators: DecoratorFunction<VueRenderer>[]
): LegacyStoryFn<VueRenderer>;Constants used internally by the decoration system for component wrapping.
/**
* Vue component wrapper key for decorator chain management
*/
const WRAPS = 'STORYBOOK_WRAPS';Wrap stories with Vue context providers like Vuex store or Vue Router.
import { createStore } from "vuex";
const StoreDecorator: Decorator = (storyFn) => {
const store = createStore({
state: { user: { name: "Test User" } },
});
return {
components: { Story: storyFn() },
store,
template: '<Story />',
};
};Apply different themes or styling contexts to stories.
const ThemeDecorator: Decorator = (storyFn, context) => {
const theme = context.globals.theme || 'light';
return {
components: { Story: storyFn() },
template: `
<div :class="'theme-' + theme">
<Story />
</div>
`,
data() {
return { theme };
},
};
};Add consistent layout styling around stories.
const CenterDecorator: Decorator = (storyFn) => ({
components: { Story: storyFn() },
template: `
<div style="display: flex; justify-content: center; align-items: center; min-height: 100vh;">
<Story />
</div>
`,
});Provide mock data or API responses to components.
const MockDataDecorator: Decorator = (storyFn, context) => {
const mockData = {
users: [
{ id: 1, name: "John Doe" },
{ id: 2, name: "Jane Smith" },
],
};
return {
components: { Story: storyFn() },
provide: {
apiData: mockData,
},
template: '<Story />',
};
};Apply decorators to all stories in your Storybook:
// .storybook/preview.js
import type { Preview } from "@storybook/vue";
const preview: Preview = {
decorators: [
(storyFn) => ({
components: { Story: storyFn() },
template: '<div class="storybook-wrapper"><Story /></div>',
}),
],
};
export default preview;Apply decorators to all stories of a specific component:
const meta: Meta<typeof MyButton> = {
title: "Example/Button",
component: MyButton,
decorators: [
(storyFn) => ({
components: { Story: storyFn() },
template: '<div style="margin: 3em;"><Story /></div>',
}),
],
};Apply decorators to individual stories:
export const Decorated: StoryObj = {
decorators: [
(storyFn) => ({
components: { Story: storyFn() },
template: '<div style="border: 2px solid red;"><Story /></div>',
}),
],
args: {
label: "Decorated Button",
},
};Apply decorators based on story parameters or context:
const ConditionalDecorator: Decorator = (storyFn, context) => {
const showBorder = context.parameters.showBorder;
if (showBorder) {
return {
components: { Story: storyFn() },
template: '<div style="border: 1px solid #ccc;"><Story /></div>',
};
}
return storyFn();
};Pass additional props or modify args within decorators:
const ArgsDecorator: Decorator = (storyFn, context) => {
return {
components: { Story: storyFn() },
computed: {
enhancedArgs() {
return {
...context.args,
timestamp: new Date().toISOString(),
};
},
},
template: '<Story v-bind="enhancedArgs" />',
};
};Install with Tessl CLI
npx tessl i tessl/npm-storybook--vue