Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
67d5780
generate code snippets from csf file
kasperpeulen Oct 9, 2025
5efe183
Lot more cases
kasperpeulen Oct 10, 2025
446abe5
Cleanup code
kasperpeulen Oct 10, 2025
ef96eff
Inline args in JSX
kasperpeulen Oct 10, 2025
2d86537
More test examples
kasperpeulen Oct 10, 2025
3738a60
Add extra tests
kasperpeulen Oct 10, 2025
2442574
Fix type error
kasperpeulen Oct 10, 2025
18aaaf4
Template.bind expressions
kasperpeulen Oct 10, 2025
50ea146
Add componentManifestGenerator preset and implement for react
kasperpeulen Oct 15, 2025
addd229
Merge remote-tracking branch 'origin/10.1' into kasper/code-snippets
kasperpeulen Oct 15, 2025
4ed3856
Fix types
kasperpeulen Oct 15, 2025
a449847
Update code/core/src/core-server/dev-server.ts
kasperpeulen Oct 16, 2025
4ce972a
Update code/core/src/core-server/dev-server.ts
kasperpeulen Oct 16, 2025
1599fac
Update code/core/src/core-server/build-static.ts
kasperpeulen Oct 16, 2025
1bcd00b
Update code/core/src/core-server/build-static.ts
kasperpeulen Oct 16, 2025
bf9a49a
Improve dev server logic
kasperpeulen Oct 16, 2025
f2e3ddb
Merge remote-tracking branch 'origin/kasper/code-snippets' into kaspe…
kasperpeulen Oct 16, 2025
c0df22c
Add type
kasperpeulen Oct 16, 2025
25b197e
Fix lint
kasperpeulen Oct 16, 2025
18c671e
Use node logger
kasperpeulen Oct 16, 2025
11ac914
Fix
kasperpeulen Oct 16, 2025
bd91ab6
Fix typos
kasperpeulen Oct 16, 2025
1e84547
Remove redundant features fetch
kasperpeulen Oct 16, 2025
a6f6673
Apply feedback
kasperpeulen Oct 16, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion code/core/src/core-server/build-static.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { cp, mkdir } from 'node:fs/promises';
import { cp, mkdir, writeFile } from 'node:fs/promises';
import { rm } from 'node:fs/promises';
import { join, relative, resolve } from 'node:path';

Expand All @@ -18,6 +18,7 @@ import { global } from '@storybook/global';
import picocolors from 'picocolors';

import { resolvePackageDir } from '../shared/utils/module';
import { type ComponentManifestGenerator } from '../types';
import { StoryIndexGenerator } from './utils/StoryIndexGenerator';
import { buildOrThrow } from './utils/build-or-throw';
import { copyAllStaticFilesRelativeToMain } from './utils/copy-all-static-files';
Expand Down Expand Up @@ -163,6 +164,19 @@ export async function buildStaticStandalone(options: BuildStaticStandaloneOption
initializedStoryIndexGenerator as Promise<StoryIndexGenerator>
)
);

const features = await presets.apply('features');

if (features?.componentManifestGenerator) {
const componentManifestGenerator: ComponentManifestGenerator = await presets.apply(
'componentManifestGenerator'
);
const indexGenerator = await initializedStoryIndexGenerator;
if (componentManifestGenerator && indexGenerator) {
const manifests = await componentManifestGenerator(indexGenerator);
await writeFile(join(options.outputDir, 'components.json'), JSON.stringify(manifests));
}
}
}

if (!core?.disableProjectJson) {
Expand Down
17 changes: 17 additions & 0 deletions code/core/src/core-server/dev-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import polka from 'polka';
import invariant from 'tiny-invariant';

import { telemetry } from '../telemetry';
import { type ComponentManifestGenerator } from '../types';
import type { StoryIndexGenerator } from './utils/StoryIndexGenerator';
import { doTelemetry } from './utils/doTelemetry';
import { getManagerBuilder, getPreviewBuilder } from './utils/get-builders';
Expand Down Expand Up @@ -135,6 +136,22 @@ export async function storybookDevServer(options: Options) {
throw indexError;
}

app.use('/components.json', async (req, res) => {
const componentManifestGenerator: ComponentManifestGenerator = await options.presets.apply(
'componentManifestGenerator'
);
const indexGenerator = await initializedStoryIndexGenerator;
const features = await options.presets.apply('features');
if (features?.componentManifestGenerator && componentManifestGenerator && indexGenerator) {
const manifest = await componentManifestGenerator(indexGenerator);
res.setHeader('Content-Type', 'application/json');
res.end(JSON.stringify(manifest));
} else {
res.statusCode = 500;
res.end('No component manifest generator configured.');
}
});

// Now the preview has successfully started, we can count this as a 'dev' event.
doTelemetry(app, core, initializedStoryIndexGenerator, options);

Expand Down
2 changes: 1 addition & 1 deletion code/core/src/csf-tools/CsfFile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ export class CsfFile {

_metaStatement: t.Statement | undefined;

_metaNode: t.Expression | undefined;
_metaNode: t.ObjectExpression | undefined;

_metaPath: NodePath<t.ExportDefaultDeclaration> | undefined;

Expand Down
14 changes: 14 additions & 0 deletions code/core/src/types/modules/core-common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import type { Server as NetServer } from 'net';
import type { Options as TelejsonOptions } from 'telejson';
import type { PackageJson as PackageJsonFromTypeFest } from 'type-fest';

import { type StoryIndexGenerator } from '../../core-server';
import type { Indexer, StoriesEntry } from './indexer';

/** ⚠️ This file contains internal WIP types they MUST NOT be exported outside this package for now! */
Expand Down Expand Up @@ -343,6 +344,16 @@ export type TagsOptions = Record<Tag, Partial<TagOptions>>;
* The interface for Storybook configuration used internally in presets The difference is that these
* values are the raw values, AKA, not wrapped with `PresetValue<>`
*/

export interface ComponentManifest {
id: string;
examples: { name: string; snippet: string }[];
}

export type ComponentManifestGenerator = (
storyIndexGenerator: StoryIndexGenerator
) => Promise<Record<string, ComponentManifest>>;

export interface StorybookConfigRaw {
/**
* Sets the addons you want to use with Storybook.
Expand All @@ -356,6 +367,7 @@ export interface StorybookConfigRaw {
*/
addons?: Preset[];
core?: CoreConfig;
componentManifestGenerator?: ComponentManifestGenerator;
staticDirs?: (DirectoryMapping | string)[];
logLevel?: string;
features?: {
Expand Down Expand Up @@ -453,6 +465,8 @@ export interface StorybookConfigRaw {
developmentModeForBuild?: boolean;
/** Only show input controls in Angular */
angularFilterNonInputControls?: boolean;

componentManifestGenerator?: boolean;
};

build?: TestBuildConfig;
Expand Down
1 change: 1 addition & 0 deletions code/core/src/types/modules/indexer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ export interface BaseIndexEntry {
title: ComponentTitle;
tags?: Tag[];
importPath: Path;
componentPath?: Path;
}
export type StoryIndexEntry = BaseIndexEntry & {
type: 'story';
Expand Down
Loading
Loading