or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

tessl/npm-storybook--addon-notes

Write notes for your Storybook stories.

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/@storybook/addon-notes@5.3.x

To install, run

npx @tessl/cli install tessl/npm-storybook--addon-notes@5.3.0

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

```