or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

core-rendering.mdindex.mdprovider-system.md

provider-system.mddocs/

0

# Provider System

1

2

The provider system is the core abstraction that allows consumers to customize and configure the Storybook UI. It consists of a base Provider class that must be extended, along with React components for custom implementations. The Provider class uses concrete methods that throw errors rather than abstract methods.

3

4

## Capabilities

5

6

### Provider Base Class

7

8

Base class that defines the interface for providing UI elements, handling API initialization, and supplying configuration. All methods throw errors by default and must be implemented by subclasses.

9

10

```typescript { .api }

11

/**

12

* Base class for Storybook UI providers

13

* All consumers must extend this class to use the Storybook UI

14

*/

15

class Provider {

16

/**

17

* Get UI elements by type - must be implemented by subclasses

18

* @param type - Type identifier for the UI elements to retrieve (from @storybook/addons Types enum)

19

* @returns Object containing UI elements for the specified type

20

* @throws Error with message "Provider.getElements() is not implemented!" if not overridden

21

*/

22

getElements(type: Types): any;

23

24

/**

25

* Handle API initialization - must be implemented by subclasses

26

* @param api - The Storybook API instance

27

* @throws Error with message "Provider.handleAPI() is not implemented!" if not overridden

28

*/

29

handleAPI(api: unknown): void;

30

31

/**

32

* Return configuration object - has default implementation that returns empty object

33

* @returns Configuration object for the Storybook UI

34

* @note Logs error "Provider.getConfig() is not implemented!" but doesn't throw, returns {}

35

*/

36

getConfig(): any;

37

}

38

```

39

40

**Usage Examples:**

41

42

```typescript

43

import { Provider } from "@storybook/ui";

44

45

class MyProvider extends Provider {

46

private stories = [];

47

private config = { theme: 'light' };

48

49

getElements(type) {

50

// Must implement - will throw error if not overridden

51

switch (type) {

52

case 'TAB':

53

return {

54

component: MyTabComponent,

55

props: { stories: this.stories }

56

};

57

case 'PANEL':

58

return {

59

component: MyPanelComponent,

60

props: { theme: this.config.theme }

61

};

62

case 'TOOL':

63

return {

64

component: MyToolComponent,

65

props: { addons: this.getAddons() }

66

};

67

default:

68

return {};

69

}

70

}

71

72

handleAPI(api) {

73

// Must implement - will throw error if not overridden

74

console.log('API initialized:', api);

75

76

// Initialize stories if available

77

if (this.stories.length > 0) {

78

api.setStories(this.stories);

79

}

80

}

81

82

getConfig() {

83

// Optional - has default implementation that returns {}

84

return {

85

theme: this.config.theme,

86

showNav: true,

87

showPanel: true

88

};

89

}

90

91

private getAddons() {

92

return [

93

{ name: 'controls', component: ControlsAddon },

94

{ name: 'actions', component: ActionsAddon }

95

];

96

}

97

}

98

99

// Example showing error behavior if methods not implemented

100

class IncompleteProvider extends Provider {

101

// Missing getElements and handleAPI implementations

102

}

103

104

const incomplete = new IncompleteProvider();

105

try {

106

incomplete.getElements('TAB'); // Throws: "Provider.getElements() is not implemented!"

107

} catch (error) {

108

console.error(error.message);

109

}

110

111

try {

112

incomplete.handleAPI({}); // Throws: "Provider.handleAPI() is not implemented!"

113

} catch (error) {

114

console.error(error.message);

115

}

116

117

// getConfig() doesn't throw, but logs error and returns {}

118

const config = incomplete.getConfig(); // Logs: "Provider.getConfig() is not implemented!"

119

console.log(config); // {}

120

```

121

122

### Root Component

123

124

React functional component that serves as the entry point for the Storybook UI application, wrapping the entire interface with necessary providers.

125

126

```typescript { .api }

127

/**

128

* Root component for the Storybook UI application

129

* @param props - RootProps containing provider and optional history

130

*/

131

const Root: FunctionComponent<RootProps>;

132

133

interface RootProps {

134

/** Provider instance that supplies UI elements and configuration */

135

provider: Provider;

136

/** Optional browser history instance for routing (currently unused in implementation) */

137

history?: History;

138

}

139

```

140

141

**Implementation Details:**

142

- Wraps the UI in HelmetProvider for document head management

143

- Uses LocationProvider for routing functionality

144

- Sets up emotion cache and theme providers

145

- Renders the main App component with provider integration

146

147

**Usage Examples:**

148

149

```typescript

150

import { Root, Provider } from "@storybook/ui";

151

152

class CustomProvider extends Provider {

153

getElements(type) {

154

// Must implement

155

return { component: MyComponent };

156

}

157

handleAPI(api) {

158

// Must implement

159

console.log('API ready');

160

}

161

}

162

163

// Basic usage (most common pattern)

164

function App() {

165

const provider = new CustomProvider();

166

return <Root provider={provider} />;

167

}

168

169

// With history parameter (currently unused by implementation)

170

function AppWithHistory() {

171

const provider = new CustomProvider();

172

const history = createBrowserHistory(); // Not currently used by Root component

173

174

return <Root provider={provider} history={history} />;

175

}

176

```

177

178

**Note**: The `history` prop is included in the interface but is not currently used by the Root component implementation. This may be for future compatibility or legacy reasons.

179

180

### Provider Implementation Requirements

181

182

All Provider subclasses must implement the following methods:

183

184

```typescript

185

class MyProvider extends Provider {

186

// REQUIRED: Must override, throws error otherwise

187

getElements(type: Types) {

188

// Return UI elements for the given type

189

// Types include: 'TAB', 'PANEL', 'TOOL', 'TOOLEXTRA', 'PREVIEW', 'NOTES_ELEMENT'

190

return {};

191

}

192

193

// REQUIRED: Must override, throws error otherwise

194

handleAPI(api: unknown) {

195

// Handle API initialization and setup

196

console.log('API initialized');

197

}

198

199

// OPTIONAL: Has default implementation that returns {}

200

getConfig() {

201

// Return configuration for the UI

202

return {};

203

}

204

}

205

```

206

207

## Types

208

209

```typescript { .api }

210

type Types = 'TAB' | 'PANEL' | 'TOOL' | 'TOOLEXTRA' | 'PREVIEW' | 'NOTES_ELEMENT';

211

212

interface History {

213

push(path: string): void;

214

replace(path: string): void;

215

go(delta: number): void;

216

back(): void;

217

forward(): void;

218

listen(listener: Function): Function;

219

}

220

```