Skip to content

Commit

Permalink
feat: json renderer and document renderFn
Browse files Browse the repository at this point in the history
  • Loading branch information
atanasster committed May 21, 2021
1 parent 2c8ee72 commit 5f4f2ce
Show file tree
Hide file tree
Showing 27 changed files with 134 additions and 80 deletions.
3 changes: 1 addition & 2 deletions core/core/src/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import {
ReactNode,
DetailedHTMLProps,
LinkHTMLAttributes,
ReactElement,
} from 'react';
import { BuildProps } from './build';
import { StoryProps } from './common';
Expand All @@ -21,7 +20,7 @@ export type FrameworkRenderFn = (props: {
doc?: Document;
values?: ExampleControls;
options?: any;
}) => ReactElement;
}) => any;

/**
* story type pages can have multiple tabs with separate page configurations.
Expand Down
4 changes: 2 additions & 2 deletions core/core/src/document-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -139,8 +139,8 @@ export const mapDynamicStories = (
doc: Document,
building?: boolean,
): Story[] => {
if (story.dynamic && typeof story.renderFn === 'function') {
const stories = story.renderFn(doc);
if (story.dynamic && typeof story.storyFn === 'function') {
const stories = story.storyFn(doc);
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { id, name, ...storyProps } = story;
return Array.isArray(stories)
Expand Down
19 changes: 12 additions & 7 deletions core/core/src/document.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
/* eslint-disable @typescript-eslint/ban-types */
import { PropsWithChildren, ReactElement } from 'react';
import { CodeLocation, PackageInfo, StoryRenderFn } from './utility';
import { Components } from './components';
import { StoryProps } from './common';
import { ComponentControl } from './controls';
import { RunConfiguration, DocType, PageLayoutProps } from './configuration';
import {
RunConfiguration,
DocType,
PageLayoutProps,
FrameworkRenderFn,
} from './configuration';
import { SearchResult } from './search';
/**
* an identifier/variable.argument in the source code
Expand Down Expand Up @@ -94,7 +98,7 @@ export type Story<Props = any> = {
/**
* render function for the story
*/
renderFn?: StoryRenderFn;
storyFn?: StoryRenderFn;

/**
* story extended description. can use markdown.
Expand Down Expand Up @@ -143,10 +147,7 @@ export type ExampleControls = {
* es named export function, excapsulates a contained example code.
*/
export type Example<Props = any> = {
(props: PropsWithChildren<Props>, context?: any): ReactElement<
any,
any
> | null;
(props: Props, context?: any): any;
bind: (props?: Story<Props>) => Example<Props>;
} & Omit<Story<Props>, 'controls'> & {
controls?: ExampleControls;
Expand Down Expand Up @@ -276,6 +277,10 @@ export type Document<Props = any> = {
*/
testData?: string;

/**
* each document can have a different renderer - JSON, react etc.
*/
renderFn: FrameworkRenderFn;
/**
* loaded data associated with the document
*/
Expand Down
4 changes: 2 additions & 2 deletions core/instrument/src/babel/esm-stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ export const extractCSFStories = (
(acc, componentName) => ({ ...acc, [componentName]: undefined }),
components,
);
const doc: Document = {
const doc: Partial<Document> = {
...attributes,
title,
};
Expand All @@ -79,7 +79,7 @@ export const extractCSFStories = (
template.key.name,
) as Document['template'];
}
store.doc = doc;
store.doc = doc as Document;
}
},
AssignmentExpression: (path: any) => {
Expand Down
4 changes: 2 additions & 2 deletions core/instrument/src/babel/mdx-stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ export const extractMDXStories: (
const { title: docTitle, name } = attributes || {};
const title = docTitle || name;
if (title) {
const doc: Document = {
const doc: Partial<Document> = {
componentsLookup: {},
...attributes,
title,
Expand All @@ -192,7 +192,7 @@ export const extractMDXStories: (
if (component !== undefined) {
doc.component = component;
}
store.doc = doc;
store.doc = doc as Document;
}
break;
}
Expand Down
2 changes: 1 addition & 1 deletion core/loader/src/replaceSource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ ${contexts
const exported = exports[key];
const story = s.stories[key];
if (story) {
story.renderFn = typeof exported === 'function' ? exported : (doc.template || exported);
story.storyFn = typeof exported === 'function' ? exported : (doc.template || exported);
assignProps(story, exported);
if (exported.story) {
assignProps(story, exported.story);
Expand Down
1 change: 1 addition & 0 deletions core/render/json.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './dist/json.d';
1 change: 1 addition & 0 deletions core/render/json.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require('./dist/json');
2 changes: 2 additions & 0 deletions core/render/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
"dist/",
"package.json",
"README.md",
"json.js",
"json.d.ts",
"react.js",
"react.d.ts"
],
Expand Down
2 changes: 1 addition & 1 deletion core/render/rollup.config.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { config } from '../../rollup-config';

export default config({
input: ['./src/index.ts', './src/react.tsx'],
input: ['./src/index.ts', './src/react.tsx', './src/json.tsx'],
});
55 changes: 55 additions & 0 deletions core/render/src/compose.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import {
Story,
Document,
StoryRenderFn,
getControlValues,
deepMerge,
FrameworkRenderFn,
ComponentControls,
} from '@component-controls/core';

type ComposeFn = (
props: Parameters<FrameworkRenderFn>[0],
) => {
renderFn: StoryRenderFn | undefined;
values: any;
context: {
story: Story;
doc: Document;
controls: ComponentControls;
} & Record<string, any>;
};
export const composeFn: ComposeFn = ({ story, doc, options }) => {
if (!story) {
throw new Error(`Invalid story`);
}
const controls = story.controls;
const values = getControlValues(controls);
//parameters added to avoid bug in SB6 rc that assumes parameters exist
const context = {
story,
doc,
controls,
...options,
};
const { decorators: globalDecorators = [] } = options || {};
const { decorators: storyDecorators = [] } = story;
const decorators = deepMerge<StoryRenderFn[]>(
globalDecorators,
storyDecorators,
);
const sortedDecorators = decorators.reverse();
let renderFn = story.storyFn;
for (let i = 0; i < sortedDecorators.length; i += 1) {
const decorator = sortedDecorators[i];
const childFn = renderFn;
const nextRenderFn = (_: any, nextContext: any) =>
(childFn as StoryRenderFn)(values, { ...context, ...nextContext });
renderFn = () =>
decorator(nextRenderFn, {
...context,
renderFn: nextRenderFn,
});
}
return { renderFn, values, context };
};
2 changes: 2 additions & 0 deletions core/render/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { FrameworkRenderFn } from '@component-controls/core';
import { render as renderReact } from './react';
import { render as renderJSON } from './json';

//noop
export const renderers: Record<string, FrameworkRenderFn> = {
react: renderReact,
json: renderJSON,
};
11 changes: 11 additions & 0 deletions core/render/src/json.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { StoryRenderFn, FrameworkRenderFn } from '@component-controls/core';
import { composeFn } from './compose';

export const render: FrameworkRenderFn = props => {
const { renderFn, values, context } = composeFn(props);
const result =
typeof renderFn === 'function'
? (renderFn as StoryRenderFn)(values, context)
: 'invalid function';
return JSON.stringify(result, null, 2);
};
43 changes: 5 additions & 38 deletions core/render/src/react.tsx
Original file line number Diff line number Diff line change
@@ -1,44 +1,11 @@
/* eslint-disable react/display-name */
import { createElement } from 'react';
import {
StoryRenderFn,
getControlValues,
deepMerge,
FrameworkRenderFn,
} from '@component-controls/core';
import { StoryRenderFn, FrameworkRenderFn } from '@component-controls/core';
import { composeFn } from './compose';

export const render: FrameworkRenderFn = props => {
const { renderFn, values, context } = composeFn(props);

export const render: FrameworkRenderFn = ({ story, doc, options }) => {
if (!story) {
throw new Error(`Invalid story`);
}
const controls = story.controls;
const values = getControlValues(controls);
//parameters added to avoid bug in SB6 rc that assumes parameters exist
const context = {
story,
doc,
controls,
...options,
};
const { decorators: globalDecorators = [] } = options || {};
const { decorators: storyDecorators = [] } = story;
const decorators = deepMerge<StoryRenderFn[]>(
globalDecorators,
storyDecorators,
);
const sortedDecorators = decorators.reverse();
let renderFn = story.renderFn;
for (let i = 0; i < sortedDecorators.length; i += 1) {
const decorator = sortedDecorators[i];
const childFn = renderFn;
const nextRenderFn = (_: any, nextContext: any) =>
(childFn as StoryRenderFn)(values, { ...context, ...nextContext });
renderFn = () =>
decorator(nextRenderFn, {
...context,
renderFn: nextRenderFn,
});
}
return typeof renderFn === 'function'
? createElement(() => (renderFn as StoryRenderFn)(values, context))
: createElement('div', 'invalid render function');
Expand Down
3 changes: 2 additions & 1 deletion core/routes/src/routes/docs-pages.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {
Store,
Document,
PageConfiguration,
defDocType,
DocType,
Expand Down Expand Up @@ -131,7 +132,7 @@ export const getDocPages = (store?: Store): DocPagesPath[] => {
catKeys.forEach(tag => {
const path = getDocPath(
type as DocType,
{ title: tag, componentsLookup: {} },
{ title: tag, componentsLookup: {} } as Document,
store,
);
docPaths.push({
Expand Down
1 change: 1 addition & 0 deletions core/store/src/serialization/load-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ export const loadStore = (store: LoadingStore, building?: boolean): Store => {
fullPage: page.fullPage,
navSidebar: page.navSidebar,
};
storeDoc.renderFn = storeDoc.renderFn || globalStore.config.renderFn;
//storybook compat
storeDoc.controls = storeDoc.controls || (storeDoc as any).args;
const doc: Document = deepMerge<Document>(
Expand Down
4 changes: 1 addition & 3 deletions core/store/src/serialization/store-local-storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,7 @@ export const readStore = (stories: Stories): Store => {
...newStore,
stories: Object.keys(newStore.stories).reduce((acc, storyId) => {
const story: Story = newStore.stories[storyId];
const renderFn = stories[storyId]
? stories[storyId].renderFn
: story.renderFn;
const renderFn = stories[storyId]?.storyFn || story.storyFn;
return { ...acc, [storyId]: { ...story, renderFn } };
}, {}),
};
Expand Down
5 changes: 4 additions & 1 deletion examples/starter/src/api/sum/sum.docs.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import { Example, FrameworkRenderFn } from '@component-controls/core';
import { render as jsonRender } from '@component-controls/render/json';
import { sum } from './sum';

const doc = {
title: 'Library/api/sum',
order: 3,
component: sum,
renderFn: jsonRender,
};

export const overview = ({ a, b }: { a: number; b: number }) => {
export const overview: Example<{ a: number; b: number }> = ({ a, b }) => {
return sum(a, b);
};
overview.controls = {
Expand Down
9 changes: 8 additions & 1 deletion examples/starter/src/api/sum/sum.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,11 @@
* @param b second parameter to add
* @returns the sum of the two parameters
*/
export const sum = (a: number, b: number): number => a + b;
export const sum = (
a: number,
b: number,
): {
a: number;
b: number;
result: number;
} => ({ a, b, result: a + b });
2 changes: 1 addition & 1 deletion plugins/test-renderers/src/render-example.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export function renderExample<Props = any>({
}
const story = example as Story;
if (typeof example === 'function') {
story.renderFn = example as StoryRenderFn;
story.storyFn = example as StoryRenderFn;
}
Object.assign(
story,
Expand Down
2 changes: 1 addition & 1 deletion plugins/test-renderers/test/enzyme.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ describe('jazmine', () => {
const rendered = renderReact({
story: {
name: 'test',
renderFn: Test,
storyFn: Test,
},
});
const component = mount(rendered);
Expand Down
2 changes: 1 addition & 1 deletion plugins/test-renderers/test/rtl.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ describe('rtl', () => {
const rendered = renderReact({
story: {
name: 'test',
renderFn: Test,
storyFn: Test,
},
});
const { asFragment, getByTestId } = rtlRender(rendered);
Expand Down
2 changes: 1 addition & 1 deletion plugins/test-renderers/test/rtr.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ describe('rtr', () => {
const rendered = renderReact({
story: {
name: 'test',
renderFn: Test,
storyFn: Test,
},
});
const { toJSON, root } = renderer.create(rendered);
Expand Down
2 changes: 1 addition & 1 deletion ui/blocks/src/Story/Story.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export const Story: FC<StoryProps> = forwardRef(function Story(

const { id, name, ...rest } = props;
const story = useStory({ id, name });
if (story && story.id && story.renderFn) {
if (story && story.id && story.storyFn) {
return (
<StoryBlockContainer {...rest} data-testid="story" story={story}>
<StoryRender
Expand Down
Loading

0 comments on commit 5f4f2ce

Please sign in to comment.