or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

config-management.mdcsf-processing.mdindex.mdstory-enhancement.mdtesting-integration.md

story-enhancement.mddocs/

0

# Story Enhancement

1

2

Add metadata, source code information, and descriptions to CSF files for documentation and development tooling integration. This module provides utilities to enrich stories with additional context and information.

3

4

## Capabilities

5

6

### CSF Enhancement

7

8

Enhance CSF files with source code and description metadata for better documentation and tooling support.

9

10

```typescript { .api }

11

/**

12

* Enhance a CSF file with metadata from its source

13

* @param csf - Target CSF file to enhance

14

* @param csfSource - Source CSF file to extract metadata from

15

* @param options - Enhancement options

16

*/

17

function enrichCsf(

18

csf: CsfFile,

19

csfSource: CsfFile,

20

options?: EnrichCsfOptions

21

): void;

22

23

interface EnrichCsfOptions {

24

/** Skip adding source code information to stories */

25

disableSource?: boolean;

26

/** Skip adding description information from comments */

27

disableDescription?: boolean;

28

}

29

```

30

31

**Usage Examples:**

32

33

```typescript

34

import { loadCsf, enrichCsf } from "@storybook/csf-tools";

35

36

// Load source CSF file

37

const sourceCsf = loadCsf(sourceCode, {

38

fileName: 'Button.stories.ts',

39

makeTitle: (title) => title

40

}).parse();

41

42

// Load target CSF file (for enhancement)

43

const targetCsf = loadCsf(targetCode, {

44

fileName: 'Button.stories.ts',

45

makeTitle: (title) => title

46

}).parse();

47

48

// Enhance target with source metadata

49

enrichCsf(targetCsf, sourceCsf, {

50

disableSource: false,

51

disableDescription: false

52

});

53

```

54

55

### Story-Level Enhancement

56

57

Enhance individual stories with metadata and source information.

58

59

```typescript { .api }

60

/**

61

* Enhance a specific story with metadata from its source

62

* @param csf - Target CSF file containing the story

63

* @param csfSource - Source CSF file to extract metadata from

64

* @param key - Export name of the story to enhance

65

* @param options - Enhancement options

66

*/

67

function enrichCsfStory(

68

csf: CsfFile,

69

csfSource: CsfFile,

70

key: string,

71

options?: EnrichCsfOptions

72

): void;

73

```

74

75

**Usage Examples:**

76

77

```typescript

78

// Enhance only specific stories

79

enrichCsfStory(targetCsf, sourceCsf, 'Primary', {

80

disableSource: false,

81

disableDescription: false

82

});

83

84

enrichCsfStory(targetCsf, sourceCsf, 'Secondary');

85

```

86

87

### Meta Enhancement

88

89

Enhance the meta object (default export) with component-level metadata.

90

91

```typescript { .api }

92

/**

93

* Enhance the meta object with component-level metadata

94

* @param csf - Target CSF file containing the meta

95

* @param csfSource - Source CSF file to extract metadata from

96

* @param options - Enhancement options

97

*/

98

function enrichCsfMeta(

99

csf: CsfFile,

100

csfSource: CsfFile,

101

options?: EnrichCsfOptions

102

): void;

103

```

104

105

### Source Code Extraction

106

107

Extract source code from AST nodes for documentation purposes.

108

109

```typescript { .api }

110

/**

111

* Extract source code from an AST node

112

* @param node - AST node to extract source from

113

* @returns Generated source code string

114

*/

115

function extractSource(node: t.Node): string;

116

```

117

118

**Usage Examples:**

119

120

```typescript

121

import { extractSource } from "@storybook/csf-tools";

122

123

// Extract source from a story export

124

const storyExport = csfFile.getStoryExport('Primary');

125

const sourceCode = extractSource(storyExport);

126

console.log(sourceCode); // Generated source code for the story

127

```

128

129

### Description Extraction

130

131

Extract JSDoc-style descriptions from comment blocks in the source code.

132

133

```typescript { .api }

134

/**

135

* Extract description from JSDoc-style comments

136

* @param node - AST node with potential leading comments

137

* @returns Extracted description text or empty string

138

*/

139

function extractDescription(node?: t.Node): string;

140

```

141

142

**Usage Examples:**

143

144

```typescript

145

import { extractDescription } from "@storybook/csf-tools";

146

147

// Extract description from meta statement

148

const metaDescription = extractDescription(csfFile._metaStatement);

149

150

// Extract description from story

151

const storyDescription = extractDescription(

152

csfFile._storyStatements['Primary']

153

);

154

```

155

156

## Enhancement Patterns

157

158

### Full File Enhancement

159

160

Enhance an entire CSF file with all available metadata:

161

162

```typescript

163

import { readCsf, enrichCsf, writeCsf } from "@storybook/csf-tools";

164

165

// Read original source file

166

const sourceCsf = await readCsf('./src/Button.stories.ts', {

167

makeTitle: (title) => `Components/${title}`

168

});

169

170

// Read compiled/transformed file to enhance

171

const targetCsf = await readCsf('./dist/Button.stories.js', {

172

makeTitle: (title) => `Components/${title}`

173

});

174

175

// Enhance with all metadata

176

enrichCsf(targetCsf, sourceCsf);

177

178

// Write enhanced file

179

await writeCsf(targetCsf, './dist/Button.enhanced.stories.js');

180

```

181

182

### Selective Enhancement

183

184

Enhance only specific aspects or stories:

185

186

```typescript

187

// Enhance only descriptions, skip source code

188

enrichCsf(targetCsf, sourceCsf, {

189

disableSource: true,

190

disableDescription: false

191

});

192

193

// Enhance only the meta object

194

enrichCsfMeta(targetCsf, sourceCsf);

195

196

// Enhance specific stories

197

const storyNames = ['Primary', 'Secondary', 'Large'];

198

storyNames.forEach(name => {

199

enrichCsfStory(targetCsf, sourceCsf, name);

200

});

201

```

202

203

### Custom Enhancement Workflow

204

205

Build custom enhancement workflows with extracted metadata:

206

207

```typescript

208

import {

209

loadCsf,

210

extractSource,

211

extractDescription,

212

formatCsf

213

} from "@storybook/csf-tools";

214

215

const sourceCsf = loadCsf(sourceCode, options).parse();

216

217

// Extract metadata for custom processing

218

const storyData = Object.entries(sourceCsf._storyExports).map(([name, export]) => ({

219

name,

220

source: extractSource(export),

221

description: extractDescription(sourceCsf._storyStatements[name]),

222

parameters: sourceCsf._stories[name].parameters

223

}));

224

225

// Use extracted data for custom documentation generation

226

const documentationData = {

227

title: sourceCsf.meta?.title,

228

component: sourceCsf.meta?.component,

229

stories: storyData

230

};

231

232

console.log(JSON.stringify(documentationData, null, 2));

233

```

234

235

### Batch Processing

236

237

Process multiple CSF files for enhancement:

238

239

```typescript

240

import { glob } from 'glob';

241

import { readCsf, enrichCsf, writeCsf } from "@storybook/csf-tools";

242

243

async function enhanceAllStories(sourcePattern: string, targetDir: string) {

244

const sourceFiles = glob.sync(sourcePattern);

245

246

for (const sourceFile of sourceFiles) {

247

const sourceCsf = await readCsf(sourceFile, {

248

makeTitle: (title) => title

249

});

250

251

// Assume corresponding compiled file exists

252

const targetFile = sourceFile.replace('/src/', '/dist/');

253

const targetCsf = await readCsf(targetFile, {

254

makeTitle: (title) => title

255

});

256

257

// Enhance with metadata

258

enrichCsf(targetCsf, sourceCsf);

259

260

// Write enhanced version

261

const outputFile = targetFile.replace('.stories.js', '.enhanced.stories.js');

262

await writeCsf(targetCsf, outputFile);

263

264

console.log(`Enhanced: ${outputFile}`);

265

}

266

}

267

268

// Enhance all story files

269

await enhanceAllStories('./src/**/*.stories.ts', './dist/enhanced/');

270

```

271

272

## Metadata Types

273

274

The enhancement system works with several metadata structures:

275

276

### Story Parameters

277

278

Enhanced stories receive additional parameters:

279

280

```typescript

281

// Enhanced story parameters include:

282

{

283

__id: string; // Story ID

284

docs: {

285

source: {

286

originalSource: string; // Extracted source code

287

};

288

description: {

289

story: string; // Extracted description

290

};

291

};

292

// ... existing parameters

293

}

294

```

295

296

### Meta Parameters

297

298

Enhanced meta objects receive component-level descriptions:

299

300

```typescript

301

// Enhanced meta parameters include:

302

{

303

parameters: {

304

docs: {

305

description: {

306

component: string; // Component description from comments

307

};

308

};

309

};

310

// ... existing meta properties

311

}

312

```

313

314

## Comment Processing

315

316

The description extraction system processes various comment formats:

317

318

```typescript

319

/**

320

* This is a JSDoc-style comment that will be extracted

321

* as the component description.

322

*/

323

export default { title: 'Button' };

324

325

/**

326

* Primary story showing the default button state.

327

* This description will be extracted for the story.

328

*/

329

export const Primary = { args: { primary: true } };

330

```

331

332

Block comments are processed by:

333

1. Removing leading `*` characters and whitespace

334

2. Joining multiple comment blocks

335

3. Trimming the final result

336

4. Filtering out single-line comments (`//`)