Make a start on defineConfig, meta and story factory

This commit is contained in:
Kasper Peulen 2025-01-03 11:15:03 +01:00
parent b9f251a86c
commit 9415e4736b
2 changed files with 83 additions and 0 deletions

View File

@ -0,0 +1,20 @@
import { test } from 'vitest';
import { Button } from './__test__/Button';
import { defineConfig } from './preview';
test('csf factories', () => {
const config = defineConfig({
addons: [
{
decorators: [],
},
],
});
const meta = config.meta({ component: Button, args: { primary: true } });
const MyStory = meta.story({
args: {},
});
});

View File

@ -0,0 +1,63 @@
import type { ComponentProps, ComponentType } from 'react';
import { composeConfigs } from 'storybook/internal/preview-api';
import { prepareStory } from 'storybook/internal/preview-api';
import type { NormalizedProjectAnnotations } from 'storybook/internal/types';
import type {
Args,
ComponentAnnotations,
ProjectAnnotations,
Renderer,
StoryAnnotations,
} from '@storybook/csf';
import type { ReactRenderer } from './types';
export function defineConfig(config: PreviewConfigData<ReactRenderer>) {
return new PreviewConfig(config);
}
interface PreviewConfigData<TRenderer extends Renderer> {
addons: ProjectAnnotations<TRenderer>[];
}
class PreviewConfig<TRenderer extends Renderer> {
readonly annotations: NormalizedProjectAnnotations<TRenderer>;
constructor(data: PreviewConfigData<TRenderer>) {
const { addons, ...rest } = data;
this.annotations = composeConfigs([rest, ...addons]);
}
readonly meta = <TComponent extends ComponentType<any>, TMetaArgs extends Args>(
meta: ComponentAnnotations<TRenderer, any> & { component: TComponent; args: TMetaArgs }
) => {
return new Meta<TRenderer, TMetaArgs>(meta as ComponentAnnotations<TRenderer, TMetaArgs>, this);
};
}
class Meta<TRenderer extends Renderer, TArgs extends Args> {
readonly annotations: ComponentAnnotations<TRenderer, TArgs>;
readonly config: PreviewConfig<TRenderer>;
constructor(
annotations: ComponentAnnotations<TRenderer, TArgs>,
config: PreviewConfig<TRenderer>
) {
this.annotations = annotations;
this.config = config;
}
readonly story = (story: StoryAnnotations<TRenderer, TArgs>) =>
new Story(story, this, this.config);
}
class Story<TRenderer extends Renderer, TArgs extends Args> {
constructor(
public annotations: StoryAnnotations<TRenderer, TArgs>,
public meta: Meta<TRenderer, TArgs>,
public config: PreviewConfig<TRenderer>
) {}
}