Skip to content

Commit

Permalink
Refactor ExternalX to reuse DocsContext
Browse files Browse the repository at this point in the history
Simplifies things down a lot!
  • Loading branch information
tmeasday committed Jul 6, 2022
1 parent d32b6c6 commit 9134925
Show file tree
Hide file tree
Showing 9 changed files with 161 additions and 256 deletions.
67 changes: 0 additions & 67 deletions lib/blocks/src/blocks/ExternalDocsContainer.tsx

This file was deleted.

80 changes: 0 additions & 80 deletions lib/blocks/src/blocks/ExternalPreview.test.ts

This file was deleted.

93 changes: 0 additions & 93 deletions lib/blocks/src/blocks/ExternalPreview.ts

This file was deleted.

22 changes: 22 additions & 0 deletions lib/blocks/src/blocks/external/ExternalDocsContainer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import React from 'react';

import { ThemeProvider, themes, ensure } from '@storybook/theming';
import { AnyFramework } from '@storybook/csf';

import { DocsContext } from '../DocsContext';
import { ExternalPreview } from './ExternalPreview';

let preview: ExternalPreview<AnyFramework>;

export const ExternalDocsContainer: React.FC<{ projectAnnotations: any }> = ({
projectAnnotations,
children,
}) => {
if (!preview) preview = new ExternalPreview(projectAnnotations);

return (
<DocsContext.Provider value={preview.docsContext()}>
<ThemeProvider theme={ensure(themes.light)}>{children}</ThemeProvider>
</DocsContext.Provider>
);
};
31 changes: 31 additions & 0 deletions lib/blocks/src/blocks/external/ExternalDocsContext.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { StoryId, AnyFramework, ComponentTitle, StoryName } from '@storybook/csf';
import { DocsContext, DocsContextProps } from '@storybook/preview-web';
import { CSFFile, ModuleExport, ModuleExports, StoryStore } from '@storybook/store';

export class ExternalDocsContext<TFramework extends AnyFramework> extends DocsContext<TFramework> {
constructor(
public readonly id: StoryId,
public readonly title: ComponentTitle,
public readonly name: StoryName,
protected store: StoryStore<TFramework>,
public renderStoryToElement: DocsContextProps['renderStoryToElement'],
private processMetaExports: (metaExports: ModuleExports) => CSFFile<TFramework>
) {
super(id, title, name, store, renderStoryToElement, [], true);
}

setMeta = (metaExports: ModuleExports) => {
const csfFile = this.processMetaExports(metaExports);
this.referenceCSFFile(csfFile, true);
};

storyIdByModuleExport(storyExport: ModuleExport, metaExports?: ModuleExports) {
if (metaExports) {
const csfFile = this.processMetaExports(metaExports);
this.referenceCSFFile(csfFile, false);
}

// This will end up looking up the story id in the CSF file referenced above or via setMeta()
return super.storyIdByModuleExport(storyExport);
}
}
84 changes: 84 additions & 0 deletions lib/blocks/src/blocks/external/ExternalPreview.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import { Preview } from '@storybook/preview-web';
import { Path, ModuleExports, StoryIndex, composeConfigs } from '@storybook/store';
import { toId, AnyFramework, ComponentTitle, ProjectAnnotations } from '@storybook/csf';
import { ExternalDocsContext } from './ExternalDocsContext';

type MetaExports = ModuleExports;

class ConstantMap<TKey, TValue extends string> {
entries = new Map<TKey, TValue>();

// eslint-disable-next-line no-useless-constructor
constructor(private prefix: string) {}

get(key: TKey) {
if (!this.entries.has(key)) {
this.entries.set(key, `${this.prefix}${this.entries.size}` as TValue);
}
return this.entries.get(key);
}
}

export class ExternalPreview<TFramework extends AnyFramework> extends Preview<TFramework> {
private importPaths = new ConstantMap<MetaExports, Path>('./importPath/');

private titles = new ConstantMap<MetaExports, ComponentTitle>('title-');

private storyIndex: StoryIndex = { v: 4, entries: {} };

private moduleExportsByImportPath: Record<Path, ModuleExports> = {};

constructor(public projectAnnotations: ProjectAnnotations) {
super();

this.initialize({
getStoryIndex: () => this.storyIndex,
importFn: (path: Path) => {
return Promise.resolve(this.moduleExportsByImportPath[path]);
},
getProjectAnnotations: () =>
composeConfigs([
{ parameters: { docs: { inlineStories: true } } },
this.projectAnnotations,
]),
});
}

processMetaExports = (metaExports: MetaExports) => {
const importPath = this.importPaths.get(metaExports);
this.moduleExportsByImportPath[importPath] = metaExports;

const title = metaExports.default.title || this.titles.get(metaExports);

const csfFile = this.storyStore.processCSFFileWithCache<TFramework>(
metaExports,
importPath,
title
);

Object.values(csfFile.stories).forEach(({ id, name }) => {
this.storyIndex.entries[id] = {
id,
importPath,
title,
name,
type: 'story',
};
});

this.onStoriesChanged({ storyIndex: this.storyIndex });

return csfFile;
};

docsContext = () => {
return new ExternalDocsContext(
'storybook--docs',
'Storybook',
'Docs',
this.storyStore,
this.renderStoryToElement.bind(this),
this.processMetaExports.bind(this)
);
};
}
4 changes: 2 additions & 2 deletions lib/blocks/src/blocks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ export * from './DocsRenderer';
export * from './DocsPage';
export * from './DocsContainer';
export * from './DocsStory';
export * from './ExternalDocsContainer';
export * from './ExternalPreview';
export * from './external/ExternalDocsContainer';
export * from './external/ExternalPreview';
export * from './Heading';
export * from './Meta';
export * from './Preview';
Expand Down
Loading

0 comments on commit 9134925

Please sign in to comment.