or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

decorators.mdhooks.mdindex.mdpreview-system.mdstory-composition.mdstory-store.mdtesting-simulation.md

story-composition.mddocs/

0

# Story Composition & CSF

1

2

Utilities for creating portable stories, composing story configurations, and working with Component Story Format. These tools enable story reuse across different environments, testing scenarios, and documentation systems.

3

4

## Capabilities

5

6

### Story Composition

7

8

Core functions for creating composed, portable stories from CSF exports.

9

10

```typescript { .api }

11

/**

12

* Creates a composed story function from story and component annotations

13

* @param storyAnnotations - Individual story configuration

14

* @param componentAnnotations - Component-level meta configuration

15

* @param projectAnnotations - Global project configuration

16

* @param defaultConfig - Default fallback configuration

17

* @param exportsName - Name of the story export for debugging

18

* @returns Executable story function with metadata

19

*/

20

function composeStory<TRenderer>(

21

storyAnnotations: StoryAnnotations<TRenderer, any>,

22

componentAnnotations: ComponentAnnotations<TRenderer, any>,

23

projectAnnotations?: ProjectAnnotations<TRenderer>,

24

defaultConfig?: ProjectAnnotations<TRenderer>,

25

exportsName?: string

26

): ComposedStoryFn<TRenderer, any>;

27

28

/**

29

* Composes all stories from a story module

30

* @param storiesImport - Imported stories module (*.stories.js)

31

* @param globalConfig - Global project annotations

32

* @param composeStoryFn - Custom compose function (defaults to composeStory)

33

* @returns Object mapping story names to composed story functions

34

*/

35

function composeStories<TModule>(

36

storiesImport: TModule,

37

globalConfig: ProjectAnnotations<any>,

38

composeStoryFn?: Function

39

): Record<string, ComposedStoryFn<any, any>>;

40

41

interface ComposedStoryFn<TRenderer = any, TArgs = any> {

42

/** Execute the story with optional args override */

43

(args?: Partial<TArgs>): any;

44

/** Story display name */

45

storyName?: string;

46

/** Default story args */

47

args?: TArgs;

48

/** Story parameters */

49

parameters?: Parameters;

50

/** Story arg types */

51

argTypes?: ArgTypes;

52

/** Story ID */

53

id?: string;

54

}

55

```

56

57

**Usage Examples:**

58

59

```typescript

60

import { composeStory, composeStories } from "@storybook/preview-api";

61

import { render, screen } from "@testing-library/react";

62

import type { Meta, StoryObj } from '@storybook/react';

63

64

// Import your stories

65

import * as ButtonStories from './Button.stories';

66

import globalConfig from '../.storybook/preview';

67

68

// Compose individual story

69

const meta: Meta<typeof Button> = ButtonStories.default;

70

const Primary = composeStory(ButtonStories.Primary, meta, globalConfig);

71

72

// Use in tests

73

test('Primary button renders correctly', () => {

74

render(<Primary />);

75

expect(screen.getByRole('button')).toBeInTheDocument();

76

});

77

78

test('Primary button with custom args', () => {

79

render(<Primary args={{ label: 'Custom Label', disabled: true }} />);

80

expect(screen.getByRole('button')).toBeDisabled();

81

});

82

83

// Compose all stories from module

84

const composedStories = composeStories(ButtonStories, globalConfig);

85

86

// Iterate through all stories

87

Object.entries(composedStories).forEach(([name, Story]) => {

88

test(`${name} story renders without errors`, () => {

89

render(<Story />);

90

expect(screen.getByRole('button')).toBeInTheDocument();

91

});

92

});

93

```

94

95

### Project Configuration

96

97

Functions for setting global project annotations and default configurations.

98

99

```typescript { .api }

100

/**

101

* Sets global project annotations for story composition

102

* @param projectAnnotations - Global configuration for all stories

103

*/

104

function setProjectAnnotations<TRenderer>(projectAnnotations: ProjectAnnotations<TRenderer>): void;

105

106

/**

107

* Sets default project annotations as fallback configuration

108

* @param defaultProjectAnnotations - Default configuration when none provided

109

*/

110

function setDefaultProjectAnnotations<TRenderer>(

111

defaultProjectAnnotations: ProjectAnnotations<TRenderer>

112

): void;

113

114

interface ProjectAnnotations<TRenderer = any> {

115

/** Global parameters applied to all stories */

116

parameters?: Parameters;

117

/** Global decorators applied to all stories */

118

decorators?: DecoratorFunction<TRenderer>[];

119

/** Global args applied to all stories */

120

args?: Args;

121

/** Global arg types applied to all stories */

122

argTypes?: ArgTypes;

123

/** Global values available to all stories */

124

globals?: Args;

125

/** Global controls for globals */

126

globalTypes?: GlobalTypes;

127

/** Story rendering function */

128

render?: (args: Args, context: StoryContext<TRenderer>) => any;

129

/** Component rendering function for autodocs */

130

component?: any;

131

}

132

```

133

134

**Usage Examples:**

135

136

```typescript

137

import { setProjectAnnotations } from "@storybook/preview-api";

138

139

// Set global configuration for portable stories

140

setProjectAnnotations({

141

parameters: {

142

actions: { argTypesRegex: '^on[A-Z].*' },

143

controls: {

144

matchers: {

145

color: /(background|color)$/i,

146

date: /Date$/,

147

},

148

},

149

},

150

decorators: [

151

(Story) => (

152

<div style={{ margin: '3rem' }}>

153

<Story />

154

</div>

155

),

156

],

157

globals: {

158

theme: 'light',

159

locale: 'en'

160

}

161

});

162

```

163

164

### Story Processing & Normalization

165

166

Low-level utilities for story preparation, normalization, and processing.

167

168

```typescript { .api }

169

/**

170

* Prepares a story for rendering by processing annotations

171

* @param storyAnnotations - Raw story annotations

172

* @param componentAnnotations - Component meta annotations

173

* @param projectAnnotations - Project-level annotations

174

* @returns Prepared story ready for rendering

175

*/

176

function prepareStory<TRenderer>(

177

storyAnnotations: StoryAnnotations<TRenderer, any>,

178

componentAnnotations: ComponentAnnotations<TRenderer, any>,

179

projectAnnotations: ProjectAnnotations<TRenderer>

180

): PreparedStory<TRenderer>;

181

182

/**

183

* Prepares component meta information

184

* @param componentAnnotations - Raw component annotations

185

* @param projectAnnotations - Project-level annotations

186

* @returns Prepared component meta

187

*/

188

function prepareMeta<TRenderer>(

189

componentAnnotations: ComponentAnnotations<TRenderer, any>,

190

projectAnnotations: ProjectAnnotations<TRenderer>

191

): PreparedMeta<TRenderer>;

192

193

/**

194

* Normalizes story annotations to standard format

195

* @param storyAnnotations - Raw story annotations

196

* @param componentAnnotations - Component meta annotations

197

* @param projectAnnotations - Project-level annotations

198

* @returns Normalized story annotations

199

*/

200

function normalizeStory<TRenderer>(

201

storyAnnotations: StoryAnnotations<TRenderer, any>,

202

componentAnnotations: ComponentAnnotations<TRenderer, any>,

203

projectAnnotations: ProjectAnnotations<TRenderer>

204

): NormalizedStoryAnnotations<TRenderer>;

205

206

/**

207

* Normalizes project annotations to standard format

208

* @param projectAnnotations - Raw project annotations

209

* @returns Normalized project annotations

210

*/

211

function normalizeProjectAnnotations<TRenderer>(

212

projectAnnotations: ProjectAnnotations<TRenderer>

213

): NormalizedProjectAnnotations<TRenderer>;

214

```

215

216

### Configuration Composition

217

218

Utilities for combining and composing multiple configuration objects.

219

220

```typescript { .api }

221

/**

222

* Composes multiple configuration objects safely

223

* @param configs - Configuration objects to combine

224

* @returns Combined configuration object

225

*/

226

function composeConfigs(...configs: any[]): any;

227

228

/**

229

* Composes step runner functions for play function execution

230

* @param runners - Step runner functions to combine

231

* @returns Combined step runner function

232

*/

233

function composeStepRunners(...runners: Function[]): Function;

234

```

235

236

### Args & Parameters Utilities

237

238

Functions for working with story arguments and parameters.

239

240

```typescript { .api }

241

/**

242

* Safely combines argument objects, handling special cases

243

* @param value - Base args object

244

* @param update - Args update to apply

245

* @returns Combined args object

246

*/

247

function combineArgs(value: Args, update: Args): Args;

248

249

/**

250

* Safely combines parameter objects with proper merging

251

* @param parameterSets - Parameter objects to combine

252

* @returns Combined parameters object

253

*/

254

function combineParameters(...parameterSets: Parameters[]): Parameters;

255

256

/**

257

* Filters argTypes based on include/exclude criteria

258

* @param argTypes - ArgTypes object to filter

259

* @param include - Properties to include (RegExp or string array)

260

* @param exclude - Properties to exclude (RegExp or string array)

261

* @returns Filtered argTypes object

262

*/

263

function filterArgTypes(

264

argTypes: ArgTypes,

265

include?: PropDescriptor,

266

exclude?: PropDescriptor

267

): ArgTypes;

268

269

/**

270

* Infers control types from argTypes definitions

271

* @param argTypes - ArgTypes to process

272

* @returns ArgTypes with inferred controls

273

*/

274

function inferControls(argTypes: ArgTypes): ArgTypes;

275

276

/**

277

* Normalizes project annotations to standard format

278

* @param projectAnnotations - Raw project annotations

279

* @returns Normalized project annotations

280

*/

281

function normalizeProjectAnnotations<TRenderer>(

282

projectAnnotations: ProjectAnnotations<TRenderer>

283

): NormalizedProjectAnnotations<TRenderer>;

284

285

type PropDescriptor = string[] | RegExp;

286

```

287

288

### Story Decoration

289

290

Functions for applying decorators to stories.

291

292

```typescript { .api }

293

/**

294

* Applies a decorator to a story function

295

* @param storyFn - Original story function

296

* @param decorator - Decorator to apply

297

* @param bindWithContext - Whether to bind with story context

298

* @returns Decorated story function

299

*/

300

function decorateStory<TRenderer>(

301

storyFn: StoryFn<TRenderer>,

302

decorator: DecoratorFunction<TRenderer>,

303

bindWithContext?: boolean

304

): StoryFn<TRenderer>;

305

306

/**

307

* Default story decoration implementation

308

* @returns Default decorator function

309

*/

310

function defaultDecorateStory<TRenderer>(): DecoratorFunction<TRenderer>;

311

312

/**

313

* Sanitizes story context updates for safety

314

* @param update - Context update object

315

* @returns Sanitized update object

316

*/

317

function sanitizeStoryContextUpdate(update: Partial<StoryContext>): Partial<StoryContext>;

318

```

319

320

### Naming & Organization

321

322

Utilities for story naming and organization.

323

324

```typescript { .api }

325

/**

326

* Determines story title from user input or auto-generation

327

* @param title - User-provided title

328

* @param specifier - File specifier for auto-title

329

* @returns Final story title

330

*/

331

function userOrAutoTitle(title: string | undefined, specifier: string): string;

332

333

/**

334

* Gets title from file specifier for auto-title generation

335

* @param specifier - File path specifier

336

* @returns Generated title

337

*/

338

function userOrAutoTitleFromSpecifier(specifier: string): string;

339

340

/**

341

* Sorts stories using Storybook v7 algorithm

342

* @param stories - Stories to sort

343

* @param storySort - Sort configuration

344

* @returns Sorted stories array

345

*/

346

function sortStoriesV7(stories: any[], storySort: any): any[];

347

```

348

349

**Usage Examples:**

350

351

```typescript

352

import { userOrAutoTitle, userOrAutoTitleFromSpecifier, sortStoriesV7 } from "@storybook/preview-api";

353

354

// Auto-generate title from file path

355

const autoTitle = userOrAutoTitleFromSpecifier('./components/Button/Button.stories.ts');

356

// Result: 'Components/Button'

357

358

// Use user title or auto-generate

359

const finalTitle = userOrAutoTitle('Custom/Button', './components/Button/Button.stories.ts');

360

// Result: 'Custom/Button'

361

362

// Sort stories with custom configuration

363

const sortedStories = sortStoriesV7(stories, {

364

method: 'alphabetical',

365

order: ['Intro', 'Components', '*', 'Examples']

366

});

367

```

368

369

## Types & Interfaces

370

371

```typescript { .api }

372

interface StoryAnnotations<TRenderer = any, TArgs = any> {

373

args?: Partial<TArgs>;

374

argTypes?: ArgTypes;

375

parameters?: Parameters;

376

decorators?: DecoratorFunction<TRenderer>[];

377

render?: (args: TArgs, context: StoryContext<TRenderer>) => any;

378

play?: (context: PlayFunctionContext<TRenderer, TArgs>) => Promise<void> | void;

379

}

380

381

interface ComponentAnnotations<TRenderer = any, TArgs = any> {

382

title?: string;

383

component?: any;

384

args?: Partial<TArgs>;

385

argTypes?: ArgTypes;

386

parameters?: Parameters;

387

decorators?: DecoratorFunction<TRenderer>[];

388

render?: (args: TArgs, context: StoryContext<TRenderer>) => any;

389

}

390

391

interface PreparedStory<TRenderer = any> {

392

id: string;

393

name: string;

394

title: string;

395

args: Args;

396

argTypes: ArgTypes;

397

parameters: Parameters;

398

component: any;

399

renderFn: Function;

400

}

401

402

interface PlayFunctionContext<TRenderer = any, TArgs = any> {

403

args: TArgs;

404

canvasElement: HTMLElement;

405

step: (label: string, play: Function) => Promise<void>;

406

}

407

408

interface NormalizedProjectAnnotations<TRenderer = any> {

409

parameters: Parameters;

410

decorators: DecoratorFunction<TRenderer>[];

411

args: Args;

412

argTypes: ArgTypes;

413

globals: Args;

414

globalTypes: GlobalTypes;

415

render?: Function;

416

component?: any;

417

}

418

```