or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

argtypes-enhancement.mdcomponent-extraction.mdconstants.mdindex.mdjsdoc-processing.mdtype-conversion.mdutilities.md

utilities.mddocs/

0

# Utility Functions

1

2

Helper functions for string manipulation, value summarization, length validation, and formatting within the Storybook documentation system.

3

4

## Capabilities

5

6

### Summary Value Creation

7

8

Core utility for creating structured summary objects with optional detailed information.

9

10

```typescript { .api }

11

/**

12

* Creates a structured summary value with optional detail

13

* @param summary - Brief summary text

14

* @param detail - Optional detailed information

15

* @returns PropSummaryValue object with summary and optional detail

16

*/

17

function createSummaryValue(summary?: string, detail?: string): PropSummaryValue;

18

19

interface PropSummaryValue {

20

/** Brief summary text */

21

summary?: string;

22

/** Optional detailed information */

23

detail?: string;

24

}

25

```

26

27

This function handles the common pattern of providing both brief and detailed representations of type information.

28

29

**Usage Examples:**

30

31

```typescript

32

import { createSummaryValue } from "@storybook/docs-tools";

33

34

// Create simple summary

35

const basicSummary = createSummaryValue('string');

36

console.log(basicSummary);

37

// { summary: 'string' }

38

39

// Create summary with detail

40

const detailedSummary = createSummaryValue('union', 'string | number | boolean');

41

console.log(detailedSummary);

42

// { summary: 'union', detail: 'string | number | boolean' }

43

44

// Handle identical summary and detail

45

const identicalSummary = createSummaryValue('CustomType', 'CustomType');

46

console.log(identicalSummary);

47

// { summary: 'CustomType' } - detail omitted when identical

48

49

// Use in type processing

50

function processTypeInfo(typeData: any) {

51

const { name, raw } = typeData;

52

53

if (raw && raw !== name) {

54

return createSummaryValue(name, raw);

55

}

56

57

return createSummaryValue(name);

58

}

59

60

// Create summary for complex types

61

const complexType = createSummaryValue(

62

'Array<T>',

63

'Array<{ id: string; name: string; active: boolean }>'

64

);

65

```

66

67

### Length Validation Functions

68

69

Utilities for checking whether strings exceed recommended display length limits.

70

71

```typescript { .api }

72

/**

73

* Maximum recommended length for type summaries

74

*/

75

const MAX_TYPE_SUMMARY_LENGTH: 90;

76

77

/**

78

* Maximum recommended length for default value summaries

79

*/

80

const MAX_DEFAULT_VALUE_SUMMARY_LENGTH: 50;

81

82

/**

83

* Checks if a value exceeds the type summary length limit

84

* @param value - String to check

85

* @returns true if value is too long for type summary display

86

*/

87

function isTooLongForTypeSummary(value: string): boolean;

88

89

/**

90

* Checks if a value exceeds the default value summary length limit

91

* @param value - String to check

92

* @returns true if value is too long for default value display

93

*/

94

function isTooLongForDefaultValueSummary(value: string): boolean;

95

```

96

97

These functions help determine when to truncate or show detailed views of type and value information.

98

99

**Usage Examples:**

100

101

```typescript

102

import {

103

isTooLongForTypeSummary,

104

isTooLongForDefaultValueSummary,

105

MAX_TYPE_SUMMARY_LENGTH,

106

MAX_DEFAULT_VALUE_SUMMARY_LENGTH

107

} from "@storybook/docs-tools";

108

109

// Check type summary length

110

const longType = 'Array<{ id: string; name: string; description: string; tags: string[]; metadata: Record<string, any> }>';

111

112

if (isTooLongForTypeSummary(longType)) {

113

console.log('Type summary too long, showing truncated version');

114

const truncated = longType.substring(0, MAX_TYPE_SUMMARY_LENGTH) + '...';

115

console.log(truncated);

116

}

117

118

// Check default value length

119

const longDefaultValue = '{ name: "John Doe", email: "john.doe@example.com", preferences: { theme: "dark", notifications: true } }';

120

121

if (isTooLongForDefaultValueSummary(longDefaultValue)) {

122

console.log('Default value too long for inline display');

123

// Show in collapsible detail section instead

124

}

125

126

// Smart display logic

127

function formatForDisplay(value: string, type: 'type' | 'defaultValue') {

128

const isTooLong = type === 'type'

129

? isTooLongForTypeSummary(value)

130

: isTooLongForDefaultValueSummary(value);

131

132

if (isTooLong) {

133

const maxLength = type === 'type'

134

? MAX_TYPE_SUMMARY_LENGTH

135

: MAX_DEFAULT_VALUE_SUMMARY_LENGTH;

136

137

return {

138

summary: value.substring(0, maxLength) + '...',

139

detail: value,

140

truncated: true

141

};

142

}

143

144

return {

145

summary: value,

146

truncated: false

147

};

148

}

149

150

// Usage in UI components

151

function TypeDisplay({ typeString }: { typeString: string }) {

152

const formatted = formatForDisplay(typeString, 'type');

153

154

return (

155

<span title={formatted.truncated ? formatted.detail : undefined}>

156

{formatted.summary}

157

</span>

158

);

159

}

160

```

161

162

### String Normalization

163

164

Utility for normalizing newline characters in strings for consistent display.

165

166

```typescript { .api }

167

/**

168

* Normalizes newline characters by converting \r\n to \n

169

* @param string - Input string with potentially mixed newlines

170

* @returns String with normalized newline characters

171

*/

172

function normalizeNewlines(string: string): string;

173

```

174

175

**Usage Examples:**

176

177

```typescript

178

import { normalizeNewlines } from "@storybook/docs-tools";

179

180

// Normalize Windows-style newlines

181

const windowsText = 'First line\r\nSecond line\r\nThird line';

182

const normalized = normalizeNewlines(windowsText);

183

console.log(normalized);

184

// 'First line\nSecond line\nThird line'

185

186

// Handle mixed newline formats

187

const mixedText = 'Line 1\nLine 2\r\nLine 3\rLine 4';

188

const cleanText = normalizeNewlines(mixedText);

189

190

// Use in text processing

191

function processDescription(description: string): string {

192

// Normalize newlines first

193

let processed = normalizeNewlines(description);

194

195

// Additional processing

196

processed = processed.trim();

197

processed = processed.replace(/\n\s*\n/g, '\n\n'); // Normalize paragraph breaks

198

199

return processed;

200

}

201

202

// File content processing

203

function processFileContent(content: string): string {

204

const normalized = normalizeNewlines(content);

205

206

return normalized

207

.split('\n')

208

.map(line => line.trim())

209

.filter(line => line.length > 0)

210

.join('\n');

211

}

212

```

213

214

### Advanced String Utilities

215

216

Additional string processing functions that complement the core utilities.

217

218

```typescript { .api }

219

/**

220

* Removes surrounding quotes from strings

221

* @param str - String that may have quotes

222

* @returns String with quotes removed

223

*/

224

function trimQuotes(str: string): string;

225

226

/**

227

* Checks if a string contains quotes

228

* @param str - String to check

229

* @returns true if string includes quotes

230

*/

231

function includesQuotes(str: string): boolean;

232

233

/**

234

* Parses literal values from strings, converting to appropriate types

235

* @param str - String representation of a literal value

236

* @returns Parsed value as string or number

237

*/

238

function parseLiteral(str: string): string | number;

239

```

240

241

**Usage Examples:**

242

243

```typescript

244

import { trimQuotes, includesQuotes, parseLiteral } from "@storybook/docs-tools";

245

246

// Handle quoted strings from docgen

247

const quotedValue = '"default value"';

248

if (includesQuotes(quotedValue)) {

249

const cleaned = trimQuotes(quotedValue);

250

console.log(cleaned); // "default value"

251

}

252

253

// Parse different literal types

254

const numberValue = parseLiteral("42");

255

console.log(numberValue, typeof numberValue); // 42, "number"

256

257

const stringValue = parseLiteral("'hello world'");

258

console.log(stringValue); // "hello world"

259

260

// Use in default value processing

261

function processDefaultValue(rawValue: string) {

262

let processed = rawValue;

263

264

// Remove quotes if present

265

if (includesQuotes(processed)) {

266

processed = trimQuotes(processed);

267

}

268

269

// Try to parse as literal

270

const parsed = parseLiteral(processed);

271

272

return {

273

raw: rawValue,

274

processed,

275

parsed,

276

type: typeof parsed

277

};

278

}

279

280

// Example with various input types

281

const examples = [

282

'"string value"',

283

"'another string'",

284

"123",

285

"true",

286

"null"

287

];

288

289

examples.forEach(example => {

290

const result = processDefaultValue(example);

291

console.log(`${example} -> ${JSON.stringify(result)}`);

292

});

293

```

294

295

### Common Usage Patterns

296

297

These utilities are commonly used together in documentation processing workflows.

298

299

```typescript

300

import {

301

createSummaryValue,

302

isTooLongForTypeSummary,

303

normalizeNewlines

304

} from "@storybook/docs-tools";

305

306

// Complete type processing workflow

307

function processTypeDefinition(typeInfo: any): PropSummaryValue {

308

const { name, raw, description } = typeInfo;

309

310

// Normalize description text

311

const cleanDescription = description ? normalizeNewlines(description) : '';

312

313

// Determine summary and detail

314

let summary = name || 'unknown';

315

let detail = raw || '';

316

317

// Check if we need to truncate

318

if (detail && isTooLongForTypeSummary(detail)) {

319

// Keep original detail, use shorter summary

320

summary = name || detail.substring(0, 20) + '...';

321

} else if (detail === summary) {

322

// Don't duplicate identical values

323

detail = '';

324

}

325

326

return createSummaryValue(summary, detail || undefined);

327

}

328

329

// Documentation formatting helper

330

function formatDocumentationValue(value: string, maxLength: number): PropSummaryValue {

331

const normalized = normalizeNewlines(value.trim());

332

333

if (normalized.length <= maxLength) {

334

return createSummaryValue(normalized);

335

}

336

337

const truncated = normalized.substring(0, maxLength).trim() + '...';

338

return createSummaryValue(truncated, normalized);

339

}

340

341

// Batch processing utility

342

function processMultipleValues(values: string[]) {

343

return values.map(value => {

344

const normalized = normalizeNewlines(value);

345

const isTooLong = isTooLongForTypeSummary(normalized);

346

347

return {

348

original: value,

349

normalized,

350

summary: createSummaryValue(

351

isTooLong ? normalized.substring(0, 50) + '...' : normalized,

352

isTooLong ? normalized : undefined

353

),

354

truncated: isTooLong

355

};

356

});

357

}

358

```