or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

actions-links.mdaddons.mdcli-commands.mdconfiguration.mddecorators.mdindex.mdstory-management.md
tile.json

addons.mddocs/

0

# Addons

1

2

Extensible plugin system for adding custom functionality to the Storybook interface and development workflow. Addons provide additional methods to the Story API and can integrate with the Storybook UI.

3

4

## Capabilities

5

6

### Set Addon

7

8

Registers addon methods to the Story API, making them available as chainable methods on story collections.

9

10

```javascript { .api }

11

/**

12

* Registers addon methods to the Story API

13

* @param addon - Object containing methods to add to Story instances

14

*/

15

function setAddon(addon: Object): void;

16

```

17

18

**Usage Examples:**

19

20

```javascript

21

import { setAddon, storiesOf } from '@kadira/storybook';

22

23

// Simple addon that adds a method to stories

24

setAddon({

25

addWithInfo(storyName, info, storyFn) {

26

return this.add(storyName, () => (

27

<div>

28

<div style={{ padding: '10px', backgroundColor: '#f0f0f0' }}>

29

<strong>Info:</strong> {info}

30

</div>

31

{storyFn()}

32

</div>

33

));

34

}

35

});

36

37

// Now use the addon method on any story collection

38

storiesOf('Button', module)

39

.addWithInfo('default', 'A basic button component', () =>

40

<Button>Click me</Button>

41

)

42

.addWithInfo('primary', 'Primary variant of the button', () =>

43

<Button primary>Primary</Button>

44

);

45

46

// Multiple addon methods

47

setAddon({

48

addWithProps(name, props, component) {

49

return this.add(name, () => React.createElement(component, props));

50

},

51

52

addVariants(baseName, variants, component) {

53

variants.forEach(variant => {

54

this.add(`${baseName} - ${variant.name}`, () =>

55

React.createElement(component, variant.props)

56

);

57

});

58

return this;

59

}

60

});

61

62

// Usage of multiple addon methods

63

storiesOf('Input', module)

64

.addWithProps('disabled', { disabled: true, value: 'Disabled' }, Input)

65

.addVariants('sizes', [

66

{ name: 'small', props: { size: 'small' } },

67

{ name: 'large', props: { size: 'large' } }

68

], Input);

69

```

70

71

### Built-in Addons

72

73

Storybook comes with several built-in addons that provide common functionality.

74

75

#### Storybook Addons Core

76

77

The core addon system that manages addon registration and communication.

78

79

```javascript

80

import addons from '@kadira/storybook-addons';

81

82

// Access the addon channel for custom communication

83

const channel = addons.getChannel();

84

channel.emit('my-event', { data: 'example' });

85

```

86

87

#### Actions Addon

88

89

Built-in addon for logging component interactions and events.

90

91

```javascript

92

import { action } from '@kadira/storybook-addon-actions';

93

94

// Available as re-export from main package

95

import { action } from '@kadira/storybook';

96

97

storiesOf('Interactive Button', module)

98

.add('with click handler', () => (

99

<Button onClick={action('button-clicked')}>

100

Click me to see action log

101

</Button>

102

))

103

.add('with multiple events', () => (

104

<Input

105

onChange={action('input-changed')}

106

onFocus={action('input-focused')}

107

onBlur={action('input-blurred')}

108

/>

109

));

110

```

111

112

#### Links Addon

113

114

Built-in addon for creating navigation links between stories.

115

116

```javascript

117

import { linkTo } from '@kadira/storybook-addon-links';

118

119

// Available as re-export from main package

120

import { linkTo } from '@kadira/storybook';

121

122

storiesOf('Navigation', module)

123

.add('go to button', () => (

124

<div>

125

<p>Click below to navigate to Button stories</p>

126

<button onClick={linkTo('Button', 'default')}>

127

Go to Button Default

128

</button>

129

</div>

130

))

131

.add('conditional navigation', () => (

132

<Button onClick={linkTo('Form', 'input')}>

133

Go to Form Input Story

134

</Button>

135

));

136

```

137

138

### Custom Addon Development

139

140

Creating custom addons for specific project needs.

141

142

**Basic Custom Addon:**

143

144

```javascript

145

// Define the addon object

146

const myCustomAddon = {

147

addWithWrapper(storyName, wrapperStyle, storyFn) {

148

return this.add(storyName, () => (

149

<div style={wrapperStyle}>

150

{storyFn()}

151

</div>

152

));

153

},

154

155

addWithBackground(storyName, backgroundColor, storyFn) {

156

return this.addWithWrapper(storyName, { backgroundColor }, storyFn);

157

}

158

};

159

160

// Register the addon

161

setAddon(myCustomAddon);

162

163

// Use the addon methods

164

storiesOf('Styled Components', module)

165

.addWithBackground('on blue', '#e3f2fd', () => <Card />)

166

.addWithBackground('on green', '#e8f5e8', () => <Card />);

167

```

168

169

**Advanced Custom Addon with State:**

170

171

```javascript

172

const stateAddon = {

173

addWithState(storyName, initialState, storyFn) {

174

return this.add(storyName, () => {

175

const [state, setState] = React.useState(initialState);

176

return storyFn(state, setState);

177

});

178

}

179

};

180

181

setAddon(stateAddon);

182

183

storiesOf('Stateful Components', module)

184

.addWithState('counter', { count: 0 }, (state, setState) => (

185

<div>

186

<p>Count: {state.count}</p>

187

<button onClick={() => setState({ count: state.count + 1 })}>

188

Increment

189

</button>

190

</div>

191

));

192

```

193

194

### Addon File Structure

195

196

Standard addon development typically follows this structure:

197

198

```

199

my-custom-addon/

200

├── package.json

201

├── src/

202

│ ├── index.js # Main addon logic

203

│ ├── register.js # UI panel registration

204

│ └── components/ # Addon UI components

205

└── README.md

206

```

207

208

**Example Addon Entry Point:**

209

210

```javascript

211

// src/index.js

212

export const myAddon = {

213

addWithCustomLayout(storyName, layoutProps, storyFn) {

214

return this.add(storyName, () => (

215

<CustomLayout {...layoutProps}>

216

{storyFn()}

217

</CustomLayout>

218

));

219

}

220

};

221

222

// Auto-register if imported

223

import { setAddon } from '@kadira/storybook';

224

setAddon(myAddon);

225

```

226

227

## Types

228

229

```javascript { .api }

230

interface AddonObject {

231

/** Custom methods to add to Story API */

232

[methodName: string]: Function;

233

}

234

235

interface StoryAPI {

236

/** Add a story to this collection */

237

add(storyName: string, storyFunction: Function): StoryAPI;

238

/** Add a decorator to this collection */

239

addDecorator(decorator: Function): StoryAPI;

240

/** The story collection name */

241

kind: string;

242

/** Any addon methods registered via setAddon */

243

[addonMethod: string]: Function;

244

}

245

```