0
# Storybook Addon Notes
1
2
Storybook Addon Notes allows you to write notes (text or HTML) for your stories in Storybook. It provides both tab-based and panel-based display modes for documentation, supports Markdown rendering with embedded Giphy support, and enables multiple notes sections for different audiences (design, development).
3
4
## Package Information
5
6
- **Package Name**: @storybook/addon-notes
7
- **Package Type**: npm
8
- **Language**: TypeScript
9
- **Installation**: `npm install -D @storybook/addon-notes`
10
11
## Core Imports
12
13
The addon integrates with Storybook's parameter system rather than providing direct imports for normal usage. For addon registration:
14
15
```javascript
16
// In .storybook/main.js
17
module.exports = {
18
addons: ['@storybook/addon-notes/register'] // or 'register-panel'
19
};
20
```
21
22
Deprecated decorator functions (avoid in new code):
23
24
```typescript
25
import { withNotes, withMarkdownNotes } from '@storybook/addon-notes';
26
```
27
28
## Basic Usage
29
30
### Modern Parameter-based Usage (Recommended)
31
32
Register the addon in your `.storybook/main.js`:
33
34
```javascript
35
module.exports = {
36
addons: ['@storybook/addon-notes/register']
37
}
38
```
39
40
Add notes to stories using the `notes` parameter:
41
42
```javascript
43
export default {
44
title: 'Component',
45
parameters: {
46
notes: 'Simple text notes for this story',
47
},
48
};
49
50
export const BasicStory = () => <Component />;
51
```
52
53
### Panel Mode Registration
54
55
Alternatively, register as a panel instead of a tab:
56
57
```javascript
58
module.exports = {
59
addons: ['@storybook/addon-notes/register-panel']
60
}
61
```
62
63
## Capabilities
64
65
### Basic Text Notes
66
67
Add simple text notes to stories using a string parameter.
68
69
```javascript { .api }
70
// Story configuration with text notes
71
export default {
72
parameters: {
73
notes: 'Simple text notes for this story',
74
},
75
};
76
```
77
78
### Markdown Notes
79
80
Add markdown-formatted notes with rich content support.
81
82
```javascript { .api }
83
import markdownNotes from './notes.md';
84
85
export default {
86
parameters: {
87
notes: { markdown: markdownNotes },
88
},
89
};
90
```
91
92
### Object-based Text Notes
93
94
Add text notes using object format for consistency.
95
96
```javascript { .api }
97
export default {
98
parameters: {
99
notes: { text: 'Text content for the notes panel' },
100
},
101
};
102
```
103
104
### Multiple Notes Sections
105
106
Create multiple named sections for different audiences or topics.
107
108
```javascript { .api }
109
import introNotes from './intro.md';
110
import designNotes from './design.md';
111
112
export default {
113
parameters: {
114
notes: {
115
'Introduction': introNotes,
116
'Design Notes': designNotes
117
},
118
},
119
};
120
```
121
122
### Giphy Integration
123
124
Embed Giphy GIFs in markdown notes using the custom Giphy component. The component fetches the first result from Giphy's search API.
125
126
```typescript { .api }
127
interface GiphyProps {
128
query: string; // Search term for Giphy API
129
}
130
131
class Giphy extends Component<GiphyProps, GiphyState> {
132
componentDidMount(): void;
133
render(): React.ReactElement | null;
134
}
135
```
136
137
**Usage in Markdown:**
138
139
```markdown
140
# Story Notes
141
142
This component handles user interactions.
143
144
<Giphy query="celebration" />
145
146
More documentation content here...
147
```
148
149
### Disable Notes
150
151
Disable notes display for specific stories.
152
153
```javascript { .api }
154
export default {
155
parameters: {
156
notes: { disable: true },
157
},
158
};
159
```
160
161
### Deprecated Decorator Usage
162
163
**Note: These decorators are deprecated and should not be used in new code.**
164
165
```typescript { .api }
166
/**
167
* @deprecated Use parameter-based notes instead
168
*/
169
function withNotes(options: string | NotesOptions): any;
170
171
/**
172
* @deprecated Use parameter-based notes instead
173
*/
174
function withMarkdownNotes(text: string, options: any): void;
175
176
// Internal utility functions
177
function formatter(code: string): string;
178
```
179
180
## Types
181
182
```typescript { .api }
183
// Parameter types
184
type Parameters =
185
| string
186
| TextParameter
187
| MarkdownParameter
188
| DisabledParameter
189
| TabsParameter;
190
191
interface TextParameter {
192
text: string;
193
}
194
195
interface MarkdownParameter {
196
markdown: string;
197
}
198
199
interface DisabledParameter {
200
disable: boolean;
201
}
202
203
type TabsParameter = Record<string, string>;
204
205
// Component props
206
interface PanelProps {
207
active: boolean;
208
api: API;
209
}
210
211
interface GiphyProps {
212
query: string;
213
}
214
215
interface GiphyState {
216
src: string | null;
217
}
218
219
interface SyntaxHighlighterProps {
220
className?: string;
221
children: ReactElement;
222
[key: string]: any;
223
}
224
225
interface NotesLinkProps {
226
href: string;
227
children: ReactElement;
228
}
229
```
230
231
## Constants
232
233
```typescript { .api }
234
const ADDON_ID = 'storybookjs/notes';
235
const PANEL_ID = 'storybookjs/notes/panel';
236
const PARAM_KEY = 'notes';
237
238
// Registration entry points
239
const REGISTER_TAB = '@storybook/addon-notes/register';
240
const REGISTER_PANEL = '@storybook/addon-notes/register-panel';
241
```
242
243
## Advanced Usage
244
245
### Custom Markdown Components
246
247
The addon automatically handles:
248
- **Syntax highlighting** for code blocks with language detection
249
- **Smart links** that distinguish between internal Storybook routes and external URLs
250
- **Giphy components** for embedding GIFs using `<Giphy query="search-term" />`
251
252
### Story-level Configuration
253
254
Notes can be configured at different levels:
255
256
```javascript
257
// Component-level notes (applies to all stories)
258
export default {
259
title: 'Components/Button',
260
parameters: {
261
notes: 'General button component documentation',
262
},
263
};
264
265
// Story-level notes (overrides component-level)
266
export const PrimaryButton = () => <Button primary />;
267
PrimaryButton.story = {
268
parameters: {
269
notes: 'Specific notes for the primary button variant',
270
},
271
};
272
```
273
274
### Integration with CSF Format
275
276
Works seamlessly with Component Story Format (CSF):
277
278
```javascript
279
import Component from './Component';
280
import componentNotes from './Component.notes.md';
281
282
export default {
283
title: 'Component',
284
component: Component,
285
parameters: {
286
notes: { markdown: componentNotes },
287
},
288
};
289
290
export const Default = {};
291
292
export const WithCustomNotes = {
293
parameters: {
294
notes: 'Story-specific notes override component notes',
295
},
296
};
297
```
298
299
### Formatter Function
300
301
The addon includes an internal formatter that normalizes whitespace in template literals:
302
303
```typescript { .api }
304
/**
305
* Formats code strings by removing common indentation from template literals
306
* @param code - Raw code string to format
307
* @returns Formatted code string with normalized whitespace
308
*/
309
function formatter(code: string): string;
310
```
311
312
## Error Handling
313
314
The addon handles various error conditions gracefully:
315
316
- **Missing notes**: Displays placeholder with documentation link
317
- **Invalid parameter format**: Throws descriptive error for debugging
318
- **Markdown parsing errors**: Falls back to raw text display
319
- **Giphy API failures**: Silently handles network errors without breaking the UI
320
321
**Example error scenarios:**
322
323
```javascript
324
// Invalid parameter format - throws error
325
export default {
326
parameters: {
327
notes: { /* missing text or markdown property */ }
328
}
329
};
330
331
// Network error handling - graceful fallback
332
// If Giphy API fails, the component simply doesn't render
333
```
334
335
## Registration Modes
336
337
The addon supports two display modes:
338
339
1. **Tab mode** (`@storybook/addon-notes/register`): Notes appear in a dedicated tab in the addons panel
340
2. **Panel mode** (`@storybook/addon-notes/register-panel`): Notes appear directly in the main addons panel area
341
342
Choose the mode that best fits your Storybook configuration and team preferences.
343
344
### Advanced Configuration
345
346
The addon supports custom markdown component overrides and theming:
347
348
```javascript
349
// Custom markdown components can be registered
350
import { addons, types } from '@storybook/addons';
351
352
// Register custom elements that will be available in markdown
353
addons.getChannel().emit('addElement', {
354
type: types.NOTES_ELEMENT,
355
id: 'my-custom-element',
356
render: ({ children }) => <div className="custom">{children}</div>
357
});
358
```
359
360
**Styling Considerations:**
361
362
The addon uses Storybook's theming system and can be customized via the theme:
363
364
```javascript
365
// In .storybook/manager.js
366
import { themes } from '@storybook/theming';
367
import { addons } from '@storybook/addons';
368
369
addons.setConfig({
370
theme: {
371
...themes.normal,
372
addonNotesTheme: {
373
fontFamily: 'Monaco, monospace',
374
fontSize: '14px'
375
}
376
}
377
});
378
```