0
# Story Decoration
1
2
Story decoration system for wrapping Vue components with additional context, providers, styling, or behavior modification within Storybook stories.
3
4
## Capabilities
5
6
### Decorator Type
7
8
Decorator function type for creating reusable story wrappers with full type safety.
9
10
```typescript { .api }
11
/**
12
* Decorator function for Vue stories
13
* @template TArgs - Story argument types
14
*/
15
type Decorator<TArgs = StrictArgs> = DecoratorFunction<VueRenderer, TArgs>;
16
17
type DecoratorFunction<TRenderer extends Renderer, TArgs> = (
18
storyFn: StoryFunction<TRenderer, TArgs>,
19
context: StoryContext<TRenderer, TArgs>
20
) => StoryFn<TRenderer, TArgs>;
21
```
22
23
**Usage Example:**
24
25
```typescript
26
import type { Decorator, Meta, StoryObj } from "@storybook/vue";
27
import MyButton from "./MyButton.vue";
28
29
// Create a decorator that adds padding
30
const PaddingDecorator: Decorator = (storyFn, context) => {
31
return {
32
components: { Story: storyFn() },
33
template: '<div style="padding: 20px;"><Story /></div>',
34
};
35
};
36
37
const meta: Meta<typeof MyButton> = {
38
title: "Example/Button",
39
component: MyButton,
40
decorators: [PaddingDecorator],
41
};
42
43
export default meta;
44
```
45
46
### Decorate Story Function
47
48
Applies a chain of decorators to a story function, processing them in the correct order.
49
50
```typescript { .api }
51
/**
52
* Apply decorators to Vue stories
53
* @param storyFn - The original story function
54
* @param decorators - Array of decorator functions to apply
55
* @returns Decorated story function
56
*/
57
function decorateStory(
58
storyFn: LegacyStoryFn<VueRenderer>,
59
decorators: DecoratorFunction<VueRenderer>[]
60
): LegacyStoryFn<VueRenderer>;
61
```
62
63
### Wrapper Constants
64
65
Constants used internally by the decoration system for component wrapping.
66
67
```typescript { .api }
68
/**
69
* Vue component wrapper key for decorator chain management
70
*/
71
const WRAPS = 'STORYBOOK_WRAPS';
72
```
73
74
## Common Decorator Patterns
75
76
### Context Provider Decorator
77
78
Wrap stories with Vue context providers like Vuex store or Vue Router.
79
80
```typescript
81
import { createStore } from "vuex";
82
83
const StoreDecorator: Decorator = (storyFn) => {
84
const store = createStore({
85
state: { user: { name: "Test User" } },
86
});
87
88
return {
89
components: { Story: storyFn() },
90
store,
91
template: '<Story />',
92
};
93
};
94
```
95
96
### Theme Decorator
97
98
Apply different themes or styling contexts to stories.
99
100
```typescript
101
const ThemeDecorator: Decorator = (storyFn, context) => {
102
const theme = context.globals.theme || 'light';
103
104
return {
105
components: { Story: storyFn() },
106
template: `
107
<div :class="'theme-' + theme">
108
<Story />
109
</div>
110
`,
111
data() {
112
return { theme };
113
},
114
};
115
};
116
```
117
118
### Layout Decorator
119
120
Add consistent layout styling around stories.
121
122
```typescript
123
const CenterDecorator: Decorator = (storyFn) => ({
124
components: { Story: storyFn() },
125
template: `
126
<div style="display: flex; justify-content: center; align-items: center; min-height: 100vh;">
127
<Story />
128
</div>
129
`,
130
});
131
```
132
133
### Mock Data Decorator
134
135
Provide mock data or API responses to components.
136
137
```typescript
138
const MockDataDecorator: Decorator = (storyFn, context) => {
139
const mockData = {
140
users: [
141
{ id: 1, name: "John Doe" },
142
{ id: 2, name: "Jane Smith" },
143
],
144
};
145
146
return {
147
components: { Story: storyFn() },
148
provide: {
149
apiData: mockData,
150
},
151
template: '<Story />',
152
};
153
};
154
```
155
156
## Decorator Application
157
158
### Global Decorators
159
160
Apply decorators to all stories in your Storybook:
161
162
```typescript
163
// .storybook/preview.js
164
import type { Preview } from "@storybook/vue";
165
166
const preview: Preview = {
167
decorators: [
168
(storyFn) => ({
169
components: { Story: storyFn() },
170
template: '<div class="storybook-wrapper"><Story /></div>',
171
}),
172
],
173
};
174
175
export default preview;
176
```
177
178
### Component-Level Decorators
179
180
Apply decorators to all stories of a specific component:
181
182
```typescript
183
const meta: Meta<typeof MyButton> = {
184
title: "Example/Button",
185
component: MyButton,
186
decorators: [
187
(storyFn) => ({
188
components: { Story: storyFn() },
189
template: '<div style="margin: 3em;"><Story /></div>',
190
}),
191
],
192
};
193
```
194
195
### Story-Level Decorators
196
197
Apply decorators to individual stories:
198
199
```typescript
200
export const Decorated: StoryObj = {
201
decorators: [
202
(storyFn) => ({
203
components: { Story: storyFn() },
204
template: '<div style="border: 2px solid red;"><Story /></div>',
205
}),
206
],
207
args: {
208
label: "Decorated Button",
209
},
210
};
211
```
212
213
## Advanced Decoration Techniques
214
215
### Conditional Decoration
216
217
Apply decorators based on story parameters or context:
218
219
```typescript
220
const ConditionalDecorator: Decorator = (storyFn, context) => {
221
const showBorder = context.parameters.showBorder;
222
223
if (showBorder) {
224
return {
225
components: { Story: storyFn() },
226
template: '<div style="border: 1px solid #ccc;"><Story /></div>',
227
};
228
}
229
230
return storyFn();
231
};
232
```
233
234
### Decorator with Args
235
236
Pass additional props or modify args within decorators:
237
238
```typescript
239
const ArgsDecorator: Decorator = (storyFn, context) => {
240
return {
241
components: { Story: storyFn() },
242
computed: {
243
enhancedArgs() {
244
return {
245
...context.args,
246
timestamp: new Date().toISOString(),
247
};
248
},
249
},
250
template: '<Story v-bind="enhancedArgs" />',
251
};
252
};
253
```