0
# Storybook Addon Centered
1
2
A Storybook decorator that centers stories in the preview area using CSS flexbox layout. This addon provides consistent centering behavior across nine different frontend frameworks, making it easy to showcase components with uniform visual presentation regardless of their natural size or positioning.
3
4
## Package Information
5
6
- **Package Name**: @storybook/addon-centered
7
- **Package Type**: npm
8
- **Language**: JavaScript/TypeScript
9
- **Installation**: `npm install @storybook/addon-centered --save-dev`
10
11
## Core Imports
12
13
**ES6 Modules (Framework-specific - Recommended):**
14
```typescript
15
import centered from '@storybook/addon-centered/react';
16
import centered from '@storybook/addon-centered/vue';
17
import { centered } from '@storybook/addon-centered/angular';
18
import centered from '@storybook/addon-centered/preact';
19
import Centered from '@storybook/addon-centered/svelte';
20
import centered from '@storybook/addon-centered/mithril';
21
import centered from '@storybook/addon-centered/ember';
22
import centered from '@storybook/addon-centered/html';
23
import centered from '@storybook/addon-centered/rax';
24
```
25
26
**Deprecated Main Export (Auto-detects React/Vue):**
27
```typescript
28
import centered from '@storybook/addon-centered';
29
```
30
31
**CommonJS (Framework-specific):**
32
```javascript
33
const centered = require('@storybook/addon-centered/react');
34
const centered = require('@storybook/addon-centered/vue');
35
const { centered } = require('@storybook/addon-centered/angular');
36
const centered = require('@storybook/addon-centered/preact');
37
const Centered = require('@storybook/addon-centered/svelte');
38
const centered = require('@storybook/addon-centered/mithril');
39
const centered = require('@storybook/addon-centered/ember');
40
const centered = require('@storybook/addon-centered/html');
41
const centered = require('@storybook/addon-centered/rax');
42
```
43
44
## Basic Usage
45
46
**Local Decorator Usage:**
47
```typescript
48
import { storiesOf } from '@storybook/react';
49
import centered from '@storybook/addon-centered/react';
50
51
storiesOf('Button', module)
52
.addDecorator(centered)
53
.add('primary', () => <Button primary>Primary Button</Button>)
54
.add('secondary', () => <Button>Secondary Button</Button>);
55
```
56
57
**Global Decorator Usage:**
58
```typescript
59
import { configure, addDecorator } from '@storybook/react';
60
import centered from '@storybook/addon-centered/react';
61
62
addDecorator(centered);
63
64
configure(() => {
65
// Your story loading logic
66
}, module);
67
```
68
69
**Disabling for Specific Stories:**
70
```typescript
71
storiesOf('Button', module)
72
.add('uncentered example', () => <Button>Not Centered</Button>, {
73
centered: { disable: true }
74
});
75
```
76
77
## Architecture
78
79
The addon uses Storybook's `makeDecorator` API to create framework-specific decorators that wrap story components in centered containers. Each framework implementation applies the same CSS flexbox-based centering styles while adapting to the framework's specific rendering patterns:
80
81
- **Shared Configuration**: Common parameters and styles defined centrally
82
- **Framework Adapters**: Specialized implementations for each supported framework
83
- **CSS-in-JS Styling**: Consistent flexbox layout with framework-appropriate application
84
- **Parameter System**: Integration with Storybook's parameter system for configuration
85
86
## React Decorator
87
88
Provides centering functionality for React components using JSX wrapper elements.
89
90
```typescript { .api }
91
/**
92
* React decorator function that centers components in the Storybook preview
93
* @param storyFn - Function that returns the React component to be centered
94
* @returns JSX element with the component wrapped in centered container divs
95
*/
96
function centered(storyFn: () => ReactNode): JSX.Element;
97
98
// React types
99
type ReactNode = React.ReactNode;
100
101
interface CenteredStyles {
102
style: {
103
position: 'fixed';
104
top: '0';
105
left: '0';
106
bottom: '0';
107
right: '0';
108
display: 'flex';
109
alignItems: 'center';
110
overflow: 'auto';
111
};
112
innerStyle: {
113
margin: 'auto';
114
maxHeight: '100%';
115
};
116
}
117
```
118
119
**Usage:**
120
```typescript
121
import { storiesOf } from '@storybook/react';
122
import centered from '@storybook/addon-centered/react';
123
124
storiesOf('MyComponent', module)
125
.addDecorator(centered)
126
.add('default', () => <MyComponent />);
127
```
128
129
## Vue Decorator
130
131
Provides centering functionality for Vue components using template-based wrapping.
132
133
```typescript { .api }
134
/**
135
* Vue decorator that creates a wrapper component to center the story
136
* @returns Vue component with template and data for centering styles
137
*/
138
function centered(): {
139
template: string;
140
data(): CenteredStyles;
141
};
142
143
interface VueDecoratorConfig {
144
template: `
145
<div :style="style">
146
<div :style="innerStyle">
147
<story/>
148
</div>
149
</div>
150
`;
151
data(): CenteredStyles;
152
}
153
```
154
155
**Usage:**
156
```typescript
157
import { storiesOf } from '@storybook/vue';
158
import centered from '@storybook/addon-centered/vue';
159
160
storiesOf('MyComponent', module)
161
.addDecorator(centered)
162
.add('default', () => ({
163
components: { MyComponent },
164
template: '<my-component />'
165
}));
166
```
167
168
## Angular Decorator
169
170
Provides centering functionality for Angular components with support for both component and template-based stories.
171
172
```typescript { .api }
173
/**
174
* Angular decorator that wraps components with centered styling
175
* @param metadataFn - Function returning Angular story metadata
176
* @returns Enhanced story metadata with centering template and styles
177
*/
178
function centered(metadataFn: StoryFn<IStory>): IStory;
179
180
interface IStory {
181
component?: any;
182
props?: { [key: string]: any };
183
moduleMetadata?: NgModuleMetadata;
184
template?: string;
185
styles?: string[];
186
}
187
188
interface NgModuleMetadata {
189
declarations?: any[];
190
entryComponents?: any[];
191
imports?: any[];
192
schemas?: any[];
193
providers?: any[];
194
}
195
```
196
197
**Component Usage:**
198
```typescript
199
import { storiesOf } from '@storybook/angular';
200
import { centered } from '@storybook/addon-centered/angular';
201
import { AppComponent } from './app.component';
202
203
storiesOf('App', module)
204
.addDecorator(centered)
205
.add('default', () => ({
206
component: AppComponent,
207
props: { title: 'My App' }
208
}));
209
```
210
211
**Template Usage:**
212
```typescript
213
storiesOf('Button', module)
214
.addDecorator(centered)
215
.add('with template', () => ({
216
template: '<button>Click me</button>',
217
moduleMetadata: {
218
declarations: [ButtonComponent]
219
}
220
}));
221
```
222
223
## Preact Decorator
224
225
Provides centering functionality for Preact components using h() function and JSX.
226
227
```typescript { .api }
228
/**
229
* Preact decorator that centers components using Preact's h function
230
* @param storyFn - Function that returns the Preact component to center
231
* @returns Preact VNode with centered wrapper elements
232
*/
233
function centered(storyFn: () => Component): JSX.Element;
234
235
// Preact types
236
type Component = preact.Component;
237
```
238
239
**Usage:**
240
```typescript
241
import { storiesOf } from '@storybook/preact';
242
import centered from '@storybook/addon-centered/preact';
243
244
storiesOf('MyComponent', module)
245
.addDecorator(centered)
246
.add('default', () => <MyComponent />);
247
```
248
249
## Svelte Decorator
250
251
Provides centering functionality for Svelte components using a wrapper component approach.
252
253
```typescript { .api }
254
/**
255
* Svelte decorator that wraps components with a centering Svelte component
256
* @param storyFn - Function returning Svelte component configuration
257
* @returns Enhanced component configuration with centering wrapper
258
*/
259
function centered(storyFn: () => SvelteStoryConfig): SvelteStoryConfig;
260
261
interface SvelteStoryConfig {
262
Component: any;
263
props?: { [key: string]: any };
264
on?: { [key: string]: Function };
265
Wrapper?: any;
266
WrapperData?: {
267
style: string;
268
innerStyle: string;
269
};
270
}
271
```
272
273
**Usage:**
274
```typescript
275
import { storiesOf } from '@storybook/svelte';
276
import Centered from '@storybook/addon-centered/svelte';
277
import Component from './Component.svelte';
278
279
storiesOf('Component', module)
280
.addDecorator(Centered)
281
.add('default', () => ({
282
Component,
283
props: { text: 'Hello World' }
284
}));
285
```
286
287
## Mithril Decorator
288
289
Provides centering functionality for Mithril components using the framework's view function pattern.
290
291
```typescript { .api }
292
/**
293
* Mithril decorator that creates a view function wrapper for centering
294
* @param storyFn - Function returning Mithril component types
295
* @returns Mithril component with view function that renders centered content
296
*/
297
function centered(storyFn: () => ComponentTypes): {
298
view(): m.Vnode;
299
};
300
301
// Mithril types
302
type ComponentTypes = m.ComponentTypes;
303
```
304
305
**Usage:**
306
```typescript
307
import { storiesOf } from '@storybook/mithril';
308
import centered from '@storybook/addon-centered/mithril';
309
310
storiesOf('MyComponent', module)
311
.addDecorator(centered)
312
.add('default', () => ({
313
view: () => m(MyComponent, { text: 'Hello' })
314
}));
315
```
316
317
## Ember Decorator
318
319
Provides centering functionality for Ember components using DOM manipulation and appendTo pattern.
320
321
```typescript { .api }
322
/**
323
* Ember decorator that manipulates DOM elements to center story content
324
* @param storyFn - Function returning Ember story configuration
325
* @returns Story configuration with modified DOM element for centering
326
*/
327
function centered(storyFn: () => EmberStoryConfig): EmberStoryConfig;
328
329
interface EmberStoryConfig {
330
template: any;
331
context: any;
332
element?: HTMLElement;
333
}
334
```
335
336
**Usage:**
337
```typescript
338
import { storiesOf } from '@storybook/ember';
339
import centered from '@storybook/addon-centered/ember';
340
341
storiesOf('MyComponent', module)
342
.addDecorator(centered)
343
.add('default', () => ({
344
template: hbs`{{my-component}}`,
345
context: {}
346
}));
347
```
348
349
## HTML Decorator
350
351
Provides centering functionality for HTML strings and DOM nodes with automatic type detection.
352
353
```typescript { .api }
354
/**
355
* HTML decorator that handles both string HTML and DOM nodes for centering
356
* @param storyFn - Function returning HTML string or DOM node
357
* @returns Centered wrapper element containing the story content
358
*/
359
function centered(storyFn: () => string | Node): HTMLDivElement | any;
360
```
361
362
**Usage:**
363
```typescript
364
import { storiesOf } from '@storybook/html';
365
import centered from '@storybook/addon-centered/html';
366
367
storiesOf('HTML', module)
368
.addDecorator(centered)
369
.add('string', () => '<button>Click me</button>')
370
.add('dom node', () => {
371
const button = document.createElement('button');
372
button.textContent = 'Dynamic Button';
373
return button;
374
});
375
```
376
377
## Rax Decorator
378
379
Provides centering functionality for Rax components using Rax View components and JSX.
380
381
```typescript { .api }
382
/**
383
* Rax decorator that wraps components with Rax View components for centering
384
* @param storyFn - Function returning Rax components
385
* @returns Rax View elements with centered layout
386
*/
387
function centered(storyFn: () => any): JSX.Element;
388
```
389
390
**Usage:**
391
```javascript
392
import { storiesOf } from '@storybook/rax';
393
import centered from '@storybook/addon-centered/rax';
394
395
storiesOf('MyComponent', module)
396
.addDecorator(centered)
397
.add('default', () => <MyComponent />);
398
```
399
400
## Configuration and Parameters
401
402
All decorators support the same parameter configuration for consistent behavior across frameworks.
403
404
```typescript { .api }
405
interface CenteredParameters {
406
/**
407
* Configuration options for the centered addon
408
*/
409
centered?: {
410
/**
411
* Disable centering for this specific story
412
* @default false
413
*/
414
disable?: boolean;
415
};
416
}
417
```
418
419
**Disabling Centering:**
420
```typescript
421
// Disable centering for a specific story
422
.add('uncentered', () => <Component />, {
423
centered: { disable: true }
424
});
425
```
426
427
## Styling Details
428
429
The addon uses consistent CSS-in-JS styling across all frameworks:
430
431
```typescript { .api }
432
interface CenteredStyles {
433
/**
434
* Outer wrapper styles for full-viewport positioning and flexbox layout
435
*/
436
style: {
437
position: 'fixed';
438
top: '0';
439
left: '0';
440
bottom: '0';
441
right: '0';
442
display: 'flex';
443
alignItems: 'center';
444
overflow: 'auto';
445
};
446
447
/**
448
* Inner container styles for centering content with IE11 compatibility
449
*/
450
innerStyle: {
451
margin: 'auto';
452
maxHeight: '100%';
453
};
454
}
455
```
456
457
The centering approach uses CSS flexbox with `alignItems: 'center'` for vertical centering and `margin: 'auto'` for horizontal centering, ensuring compatibility across different browsers and frameworks while maintaining consistent visual presentation.
458
459
## Deprecated Main Export
460
461
The main export provides automatic framework detection but is deprecated in favor of explicit framework imports.
462
463
```typescript { .api }
464
/**
465
* @deprecated Use framework-specific imports instead
466
* Main export that auto-detects between React and Vue based on STORYBOOK_ENV
467
* @returns React centered decorator for React environments, Vue for Vue environments
468
*/
469
declare const Centered: () => any;
470
export default Centered;
471
```
472
473
**Usage (Deprecated):**
474
```typescript
475
import centered from '@storybook/addon-centered';
476
477
// Automatically uses React decorator in React Storybook
478
// or Vue decorator in Vue Storybook
479
storiesOf('MyComponent', module)
480
.addDecorator(centered)
481
.add('default', () => <MyComponent />);
482
```
483
484
## Helper Functions
485
486
### JSON to CSS Converter
487
488
Utility function for converting CSS-in-JS objects to CSS strings, used internally by framework implementations.
489
490
```typescript { .api }
491
/**
492
* Converts CSS-in-JS style objects to CSS string format
493
* @param jsonStyles - Object with CSS properties as keys and values
494
* @returns CSS string representation of the styles
495
*/
496
function json2CSS(jsonStyles: Partial<CSSStyleDeclaration>): string | null;
497
```
498
499
**Usage:**
500
```typescript
501
import json2CSS from '@storybook/addon-centered/dist/helpers/json2CSS';
502
503
const styles = {
504
display: 'flex',
505
alignItems: 'center',
506
justifyContent: 'center'
507
};
508
509
const cssString = json2CSS(styles);
510
// Returns: "display: flex; align-items: center; justify-content: center;"
511
```