From a4dfb9ff61330620614c2faa0b6547a38f386368 Mon Sep 17 00:00:00 2001
From: atanasster
Date: Sun, 15 Nov 2020 17:37:57 -0500
Subject: [PATCH] feat: bind templates to stories
---
.vscode/launch.json | 2 +-
core/core/src/document.ts | 4 +-
core/instrument/src/babel/esm-stories.ts | 27 +-
.../__snapshots__/esm-stories.test.ts.snap | 309 ++++++++++++++++--
core/instrument/test/esm-stories.test.ts | 6 +-
.../test/fixtures/components/button-props.tsx | 8 +
.../fixtures/esm/stories/template-bind.tsx | 22 ++
core/store/src/serialization/load-store.ts | 4 +-
.../src/serialization/transform-controls.ts | 68 ++--
examples/stories/src/components/Button.tsx | 3 +-
.../src/stories/stories-async.stories.tsx | 2 +-
.../src/stories/template-bind.stories.tsx | 43 +++
.../dynamic-stories.stories.tsx | 6 +-
ui/blocks/src/Description/Description.tsx | 37 ++-
ui/blocks/src/DocumentItem/DocumentItem.tsx | 6 +-
ui/blocks/src/Search/Search.tsx | 2 +-
16 files changed, 466 insertions(+), 83 deletions(-)
create mode 100644 core/instrument/test/fixtures/components/button-props.tsx
create mode 100644 core/instrument/test/fixtures/esm/stories/template-bind.tsx
create mode 100644 examples/stories/src/stories/template-bind.stories.tsx
diff --git a/.vscode/launch.json b/.vscode/launch.json
index 5f855fd4b..614427259 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -139,7 +139,7 @@
"program": "${workspaceFolder}/node_modules/.bin/jest",
"cwd": "${workspaceFolder}/core/instrument",
"args": [
- "esm-doc",
+ "esm-stories",
],
"console": "integratedTerminal",
"internalConsoleOptions": "neverOpen",
diff --git a/core/core/src/document.ts b/core/core/src/document.ts
index 54bbac966..50ca12eb2 100644
--- a/core/core/src/document.ts
+++ b/core/core/src/document.ts
@@ -187,7 +187,7 @@ export type Example = {
any,
any
> | null;
- bind: (props: any) => Example;
+ bind: (props?: Story) => Example;
} & Omit, 'controls'> & {
controls?: ExampleControls;
};
@@ -250,7 +250,7 @@ export type Document = {
/**
* documentation file description
*/
- description?: string;
+ description?: string | JSX.Element;
/**
* link to an image for the document, will be used for SEO
*/
diff --git a/core/instrument/src/babel/esm-stories.ts b/core/instrument/src/babel/esm-stories.ts
index 161f0a124..acb52200d 100644
--- a/core/instrument/src/babel/esm-stories.ts
+++ b/core/instrument/src/babel/esm-stories.ts
@@ -18,7 +18,7 @@ export const extractCSFStories = (
{ source, filePath }: { source: string; filePath: string },
): ParseStorieReturnType => {
const globals: Stories = {};
- const localStories: Stories = {};
+ const localFunctions: Stories = {};
const extractFunction = (path: any, declaration: any): Story | undefined => {
if (declaration.init) {
@@ -44,6 +44,25 @@ export const extractCSFStories = (
ast,
);
}
+ case 'CallExpression': {
+ //template.bind
+ if (declaration.init.callee?.property?.name === 'bind') {
+ const callee = declaration.init.callee?.object;
+ if (callee?.name) {
+ const template = localFunctions[callee.name];
+ if (template) {
+ const name = declaration.id.name;
+ const story: Story = {
+ loc: template.loc,
+ name,
+ id: name,
+ arguments: template.arguments,
+ };
+ return story;
+ }
+ }
+ }
+ }
}
} else if (declaration.type === 'FunctionDeclaration') {
const name = declaration.id.name;
@@ -134,7 +153,7 @@ export const extractCSFStories = (
if (!store.stories[name]) {
const story = extractFunction(path, declaration);
if (story && story.name) {
- localStories[story.name] = story;
+ localFunctions[story.name] = story;
}
}
}
@@ -144,11 +163,11 @@ export const extractCSFStories = (
const { node } = path;
const localName = node.local.name;
const exportedName = node.exported.name;
- const story = localStories[localName];
+ const story = localFunctions[localName];
if (story) {
const global = globals[localName];
if (global) {
- localStories[localName] = {
+ localFunctions[localName] = {
...story,
...global,
};
diff --git a/core/instrument/test/__snapshots__/esm-stories.test.ts.snap b/core/instrument/test/__snapshots__/esm-stories.test.ts.snap
index a4a68598f..5b41c73e1 100644
--- a/core/instrument/test/__snapshots__/esm-stories.test.ts.snap
+++ b/core/instrument/test/__snapshots__/esm-stories.test.ts.snap
@@ -17,7 +17,7 @@ Object {
"@babel/generator": "^7.9.4",
"@babel/parser": "^7.9.4",
"@babel/traverse": "^7.9.0",
- "@component-controls/core": "^1.39.3",
+ "@component-controls/core": "^1.39.4",
"@hutson/parse-repository-url": "^5.0.0",
"@mdx-js/loader": "^1.5.5",
"@mdx-js/react": "^1.6.5",
@@ -53,7 +53,7 @@ Object {
"docs": "https://github.com/ccontrols/component-controls/tree/master#readme",
"issues": "https://github.com/ccontrols/component-controls/issues",
},
- "version": "1.39.3",
+ "version": "1.39.4",
},
},
"stories": Object {},
@@ -82,7 +82,7 @@ Object {
"@babel/generator": "^7.9.4",
"@babel/parser": "^7.9.4",
"@babel/traverse": "^7.9.0",
- "@component-controls/core": "^1.39.3",
+ "@component-controls/core": "^1.39.4",
"@hutson/parse-repository-url": "^5.0.0",
"@mdx-js/loader": "^1.5.5",
"@mdx-js/react": "^1.6.5",
@@ -118,7 +118,7 @@ Object {
"docs": "https://github.com/ccontrols/component-controls/tree/master#readme",
"issues": "https://github.com/ccontrols/component-controls/issues",
},
- "version": "1.39.3",
+ "version": "1.39.4",
},
},
"stories": Object {
@@ -162,7 +162,7 @@ Object {
"@babel/generator": "^7.9.4",
"@babel/parser": "^7.9.4",
"@babel/traverse": "^7.9.0",
- "@component-controls/core": "^1.39.3",
+ "@component-controls/core": "^1.39.4",
"@hutson/parse-repository-url": "^5.0.0",
"@mdx-js/loader": "^1.5.5",
"@mdx-js/react": "^1.6.5",
@@ -198,7 +198,7 @@ Object {
"docs": "https://github.com/ccontrols/component-controls/tree/master#readme",
"issues": "https://github.com/ccontrols/component-controls/issues",
},
- "version": "1.39.3",
+ "version": "1.39.4",
},
},
"stories": Object {},
@@ -215,7 +215,7 @@ Object {
"components": Object {},
"componentsLookup": Object {},
"date": 2020-10-21T01:23:26.432Z,
- "dateModified": 2020-10-21T01:23:26.432Z,
+ "dateModified": 2020-11-15T16:38:06.844Z,
"package": "c525e04e9beb03220dd4fa6d09af4958",
"title": "Story",
},
@@ -225,7 +225,7 @@ Object {
"@babel/generator": "^7.9.4",
"@babel/parser": "^7.9.4",
"@babel/traverse": "^7.9.0",
- "@component-controls/core": "^1.39.3",
+ "@component-controls/core": "^1.39.4",
"@hutson/parse-repository-url": "^5.0.0",
"@mdx-js/loader": "^1.5.5",
"@mdx-js/react": "^1.6.5",
@@ -261,7 +261,7 @@ Object {
"docs": "https://github.com/ccontrols/component-controls/tree/master#readme",
"issues": "https://github.com/ccontrols/component-controls/issues",
},
- "version": "1.39.3",
+ "version": "1.39.4",
},
},
"stories": Object {
@@ -303,6 +303,277 @@ export const myStory = props => {};
}
`;
+exports[`esm-stories template-bind.tsx 1`] = `
+Object {
+ "components": Object {
+ "fbea66d4bd64ea2b935855efa5d522a1": Object {
+ "from": "../../components/button-props",
+ "importedName": "Button",
+ "imports": Object {
+ "react": Array [
+ Object {
+ "importedName": "default",
+ "name": "React",
+ },
+ Object {
+ "importedName": "FC",
+ "name": "FC",
+ },
+ ],
+ },
+ "loc": Object {
+ "end": Object {
+ "column": 1,
+ "line": 8,
+ },
+ "start": Object {
+ "column": 39,
+ "line": 6,
+ },
+ },
+ "name": "Button",
+ "package": "fbea66d4bd64ea2b935855efa5d522a1",
+ "request": "/Users/atanasster/component-controls/core/instrument/test/fixtures/components/button-props.tsx",
+ "source": "import React, { FC } from 'react';
+
+export interface ButtonProps {
+ name: string;
+}
+export const Button: FC = props => (
+
+);
+",
+ },
+ },
+ "doc": Object {
+ "component": "Button",
+ "components": Object {},
+ "componentsLookup": Object {
+ "Button": "fbea66d4bd64ea2b935855efa5d522a1",
+ },
+ "date": 2020-11-15T16:47:23.994Z,
+ "dateModified": 2020-11-15T19:31:09.255Z,
+ "package": "43299b3f0d3e0b156df31ed88d68174e",
+ "title": "Components/Button",
+ },
+ "packages": Object {
+ "43299b3f0d3e0b156df31ed88d68174e": Object {
+ "dependencies": Object {
+ "@babel/generator": "^7.9.4",
+ "@babel/parser": "^7.9.4",
+ "@babel/traverse": "^7.9.0",
+ "@component-controls/core": "^1.39.4",
+ "@hutson/parse-repository-url": "^5.0.0",
+ "@mdx-js/loader": "^1.5.5",
+ "@mdx-js/react": "^1.6.5",
+ "camelcase": "^6.0.0",
+ "deepmerge": "^4.2.2",
+ "find-cache-dir": "^3.3.1",
+ "gray-matter": "^4.0.2",
+ "hosted-git-info": "^3.0.4",
+ "js-string-escape": "^1.0.1",
+ "prettier": "^1.19.1",
+ "read-package-json": "^2.1.1",
+ "remark-emoji": "^2.1.0",
+ "remark-images": "^2.0.0",
+ "resolve": "^1.15.1",
+ "typescript": "^4.0.5",
+ },
+ "devDependencies": Object {
+ "@babel/types": "^7.9.0",
+ "@component-controls/ts-markdown-docs": "^1.37.0",
+ "@rollup/plugin-node-resolve": "^7.1.1",
+ "@types/find-cache-dir": "^3.2.0",
+ "@types/hosted-git-info": "^3.0.0",
+ "@types/jest": "^26.0.10",
+ "cross-env": "^5.2.1",
+ "eslint": "^6.5.1",
+ "jest": "^26.4.2",
+ },
+ "fileHash": "43299b3f0d3e0b156df31ed88d68174e",
+ "name": "@component-controls/instrument",
+ "peerDependencies": undefined,
+ "repository": Object {
+ "browse": "https://github.com/ccontrols/component-controls/tree/master/core/instrument/test/fixtures/esm/stories/template-bind.tsx",
+ "docs": "https://github.com/ccontrols/component-controls/tree/master#readme",
+ "issues": "https://github.com/ccontrols/component-controls/issues",
+ },
+ "version": "1.39.4",
+ },
+ "fbea66d4bd64ea2b935855efa5d522a1": Object {
+ "dependencies": Object {
+ "@babel/generator": "^7.9.4",
+ "@babel/parser": "^7.9.4",
+ "@babel/traverse": "^7.9.0",
+ "@component-controls/core": "^1.39.4",
+ "@hutson/parse-repository-url": "^5.0.0",
+ "@mdx-js/loader": "^1.5.5",
+ "@mdx-js/react": "^1.6.5",
+ "camelcase": "^6.0.0",
+ "deepmerge": "^4.2.2",
+ "find-cache-dir": "^3.3.1",
+ "gray-matter": "^4.0.2",
+ "hosted-git-info": "^3.0.4",
+ "js-string-escape": "^1.0.1",
+ "prettier": "^1.19.1",
+ "read-package-json": "^2.1.1",
+ "remark-emoji": "^2.1.0",
+ "remark-images": "^2.0.0",
+ "resolve": "^1.15.1",
+ "typescript": "^4.0.5",
+ },
+ "devDependencies": Object {
+ "@babel/types": "^7.9.0",
+ "@component-controls/ts-markdown-docs": "^1.37.0",
+ "@rollup/plugin-node-resolve": "^7.1.1",
+ "@types/find-cache-dir": "^3.2.0",
+ "@types/hosted-git-info": "^3.0.0",
+ "@types/jest": "^26.0.10",
+ "cross-env": "^5.2.1",
+ "eslint": "^6.5.1",
+ "jest": "^26.4.2",
+ },
+ "fileHash": "fbea66d4bd64ea2b935855efa5d522a1",
+ "name": "@component-controls/instrument",
+ "peerDependencies": undefined,
+ "repository": Object {
+ "browse": "https://github.com/ccontrols/component-controls/tree/master/core/instrument/test/fixtures/components/button-props.tsx",
+ "docs": "https://github.com/ccontrols/component-controls/tree/master#readme",
+ "issues": "https://github.com/ccontrols/component-controls/issues",
+ },
+ "version": "1.39.4",
+ },
+ },
+ "stories": Object {
+ "John": Object {
+ "arguments": Array [
+ Object {
+ "loc": Object {
+ "end": Object {
+ "column": 5,
+ "line": 0,
+ },
+ "start": Object {
+ "column": 0,
+ "line": 0,
+ },
+ },
+ "name": "props",
+ "usage": Array [
+ Object {
+ "loc": Object {
+ "end": Object {
+ "column": 19,
+ "line": 1,
+ },
+ "start": Object {
+ "column": 14,
+ "line": 1,
+ },
+ },
+ "shorthand": undefined,
+ },
+ ],
+ "value": "props",
+ },
+ ],
+ "controls": Object {
+ "name": "john",
+ },
+ "id": "John",
+ "loc": Object {
+ "end": Object {
+ "column": 1,
+ "line": 12,
+ },
+ "start": Object {
+ "column": 39,
+ "line": 10,
+ },
+ },
+ "name": "John",
+ "source": "props => (
+
+)",
+ },
+ "Mary": Object {
+ "arguments": Array [
+ Object {
+ "loc": Object {
+ "end": Object {
+ "column": 5,
+ "line": 0,
+ },
+ "start": Object {
+ "column": 0,
+ "line": 0,
+ },
+ },
+ "name": "props",
+ "usage": Array [
+ Object {
+ "loc": Object {
+ "end": Object {
+ "column": 19,
+ "line": 1,
+ },
+ "start": Object {
+ "column": 14,
+ "line": 1,
+ },
+ },
+ "shorthand": undefined,
+ },
+ ],
+ "value": "props",
+ },
+ ],
+ "controls": Object {
+ "name": "mary",
+ },
+ "id": "Mary",
+ "loc": Object {
+ "end": Object {
+ "column": 1,
+ "line": 12,
+ },
+ "start": Object {
+ "column": 39,
+ "line": 10,
+ },
+ },
+ "name": "Mary",
+ "source": "props => (
+
+)",
+ },
+ },
+ "transformed": "import React from 'react';
+import { Example, Document } from '@component-controls/core';
+import { ButtonProps, Button } from '../../components/button-props';
+
+export default {
+ title: 'Components/Button',
+ component: Button,
+} as Document;
+
+const Template: Example = props => (
+
+);
+
+export const John = Template.bind({});
+John.controls = {
+ name: 'john',
+};
+
+export const Mary = Template.bind({});
+Mary.controls = {
+ name: 'mary',
+};
+",
+}
+`;
+
exports[`esm-stories three-levels-alias.js 1`] = `
Object {
"components": Object {},
@@ -320,7 +591,7 @@ Object {
"@babel/generator": "^7.9.4",
"@babel/parser": "^7.9.4",
"@babel/traverse": "^7.9.0",
- "@component-controls/core": "^1.39.3",
+ "@component-controls/core": "^1.39.4",
"@hutson/parse-repository-url": "^5.0.0",
"@mdx-js/loader": "^1.5.5",
"@mdx-js/react": "^1.6.5",
@@ -356,7 +627,7 @@ Object {
"docs": "https://github.com/ccontrols/component-controls/tree/master#readme",
"issues": "https://github.com/ccontrols/component-controls/issues",
},
- "version": "1.39.3",
+ "version": "1.39.4",
},
},
"stories": Object {
@@ -473,7 +744,7 @@ Object {
"@babel/generator": "^7.9.4",
"@babel/parser": "^7.9.4",
"@babel/traverse": "^7.9.0",
- "@component-controls/core": "^1.39.3",
+ "@component-controls/core": "^1.39.4",
"@hutson/parse-repository-url": "^5.0.0",
"@mdx-js/loader": "^1.5.5",
"@mdx-js/react": "^1.6.5",
@@ -509,7 +780,7 @@ Object {
"docs": "https://github.com/ccontrols/component-controls/tree/master#readme",
"issues": "https://github.com/ccontrols/component-controls/issues",
},
- "version": "1.39.3",
+ "version": "1.39.4",
},
},
"stories": Object {
@@ -582,7 +853,7 @@ Object {
"@babel/generator": "^7.9.4",
"@babel/parser": "^7.9.4",
"@babel/traverse": "^7.9.0",
- "@component-controls/core": "^1.39.3",
+ "@component-controls/core": "^1.39.4",
"@hutson/parse-repository-url": "^5.0.0",
"@mdx-js/loader": "^1.5.5",
"@mdx-js/react": "^1.6.5",
@@ -618,7 +889,7 @@ Object {
"docs": "https://github.com/ccontrols/component-controls/tree/master#readme",
"issues": "https://github.com/ccontrols/component-controls/issues",
},
- "version": "1.39.3",
+ "version": "1.39.4",
},
},
"stories": Object {
@@ -706,7 +977,7 @@ Object {
"@babel/generator": "^7.9.4",
"@babel/parser": "^7.9.4",
"@babel/traverse": "^7.9.0",
- "@component-controls/core": "^1.39.3",
+ "@component-controls/core": "^1.39.4",
"@hutson/parse-repository-url": "^5.0.0",
"@mdx-js/loader": "^1.5.5",
"@mdx-js/react": "^1.6.5",
@@ -742,7 +1013,7 @@ Object {
"docs": "https://github.com/ccontrols/component-controls/tree/master#readme",
"issues": "https://github.com/ccontrols/component-controls/issues",
},
- "version": "1.39.3",
+ "version": "1.39.4",
},
},
"stories": Object {
@@ -830,7 +1101,7 @@ Object {
"@babel/generator": "^7.9.4",
"@babel/parser": "^7.9.4",
"@babel/traverse": "^7.9.0",
- "@component-controls/core": "^1.39.3",
+ "@component-controls/core": "^1.39.4",
"@hutson/parse-repository-url": "^5.0.0",
"@mdx-js/loader": "^1.5.5",
"@mdx-js/react": "^1.6.5",
@@ -866,7 +1137,7 @@ Object {
"docs": "https://github.com/ccontrols/component-controls/tree/master#readme",
"issues": "https://github.com/ccontrols/component-controls/issues",
},
- "version": "1.39.3",
+ "version": "1.39.4",
},
},
"stories": Object {
diff --git a/core/instrument/test/esm-stories.test.ts b/core/instrument/test/esm-stories.test.ts
index 51e9a4e56..106d43453 100644
--- a/core/instrument/test/esm-stories.test.ts
+++ b/core/instrument/test/esm-stories.test.ts
@@ -1,5 +1,9 @@
import { loadStoriesTests } from './loadTestFiles';
describe('esm-stories', () => {
- loadStoriesTests(undefined, ['esm', 'stories']);
+ loadStoriesTests(
+ undefined,
+ ['esm', 'stories'],
+ //['template-bind.tsx']
+ );
});
diff --git a/core/instrument/test/fixtures/components/button-props.tsx b/core/instrument/test/fixtures/components/button-props.tsx
new file mode 100644
index 000000000..5d66ca661
--- /dev/null
+++ b/core/instrument/test/fixtures/components/button-props.tsx
@@ -0,0 +1,8 @@
+import React, { FC } from 'react';
+
+export interface ButtonProps {
+ name: string;
+}
+export const Button: FC = props => (
+
+);
diff --git a/core/instrument/test/fixtures/esm/stories/template-bind.tsx b/core/instrument/test/fixtures/esm/stories/template-bind.tsx
new file mode 100644
index 000000000..6b656bd50
--- /dev/null
+++ b/core/instrument/test/fixtures/esm/stories/template-bind.tsx
@@ -0,0 +1,22 @@
+import React from 'react';
+import { Example, Document } from '@component-controls/core';
+import { ButtonProps, Button } from '../../components/button-props';
+
+export default {
+ title: 'Components/Button',
+ component: Button,
+} as Document;
+
+const Template: Example = props => (
+
+);
+
+export const John = Template.bind();
+John.controls = {
+ name: 'john',
+};
+
+export const Mary = Template.bind();
+Mary.controls = {
+ name: 'mary',
+};
diff --git a/core/store/src/serialization/load-store.ts b/core/store/src/serialization/load-store.ts
index ee0f0cb86..07ae2df33 100644
--- a/core/store/src/serialization/load-store.ts
+++ b/core/store/src/serialization/load-store.ts
@@ -18,7 +18,7 @@ import {
} from '@component-controls/core';
import { LoadingStore } from '@component-controls/loader';
import { render as reactRender } from '@component-controls/render/react';
-import { transformControls } from './transform-controls';
+import { getControls } from './transform-controls';
export { LoadingStore };
@@ -80,7 +80,7 @@ export const loadStore = (store: LoadingStore, building?: boolean): Store => {
stories.forEach(story => {
story.id = story.id || story.name;
Object.assign(story, deepMerge(docStoryProps, story));
- story.controls = transformControls(story, doc, loadedComponents);
+ story.controls = getControls(story, doc, loadedComponents);
if (doc.title && story.id) {
const id = docStoryToId(doc.title, story.id);
if (!doc.stories) {
diff --git a/core/store/src/serialization/transform-controls.ts b/core/store/src/serialization/transform-controls.ts
index 9c66d166f..3cc2ca0de 100644
--- a/core/store/src/serialization/transform-controls.ts
+++ b/core/store/src/serialization/transform-controls.ts
@@ -3,7 +3,6 @@ import {
ComponentControl,
ControlTypes,
Story,
- deepMergeReplaceArrays,
Document,
Components,
getComponentName,
@@ -13,22 +12,30 @@ import {
} from '@component-controls/core';
const controlShortcuts = (
- control: ComponentControl | any,
+ name: string,
+ controls: ComponentControls,
+ propControls?: ComponentControls,
): ComponentControl => {
+ const control: ComponentControl | any = controls[name];
+ const propControl = propControls?.[name] || {};
const valueType = typeof control;
switch (valueType) {
case 'boolean':
- return { type: ControlTypes.BOOLEAN, value: control };
+ return {
+ type: ControlTypes.BOOLEAN,
+ ...propControl,
+ value: control,
+ };
case 'string':
- return { type: ControlTypes.TEXT, value: control };
+ return { type: ControlTypes.TEXT, ...propControl, value: control };
case 'number':
- return { type: ControlTypes.NUMBER, value: control };
+ return { type: ControlTypes.NUMBER, ...propControl, value: control };
case 'object': {
if (control instanceof Date) {
- return { type: ControlTypes.DATE, value: control };
+ return { type: ControlTypes.DATE, ...propControl, value: control };
}
if (Array.isArray(control)) {
- return { type: ControlTypes.OPTIONS, options: control };
+ return { type: ControlTypes.OPTIONS, ...propControl, options: control };
}
if (
control.type === ControlTypes.OBJECT &&
@@ -36,30 +43,30 @@ const controlShortcuts = (
) {
return {
...control,
+ ...propControl,
value: Object.keys(control.value).reduce(
(acc, name) => ({
...acc,
- [name]: controlShortcuts(control.value[name]),
+ [name]: controlShortcuts(name, control.value, propControl),
}),
{},
),
};
}
- return control;
+ return { ...propControl, ...control };
}
default:
- return control;
+ return { ...propControl, ...control };
}
};
-export const transformControls = (
- story: Story,
- doc: Document,
- components: Components,
-): ComponentControls | undefined => {
- const { controls: storyControls } = story;
- const controls: ComponentControls | undefined = storyControls
- ? Object.keys(storyControls).reduce((acc, key) => {
- const control = controlShortcuts(storyControls[key]);
+
+const transformControls = (
+ controls?: ComponentControls,
+ propControls?: ComponentControls,
+) => {
+ return controls
+ ? Object.keys(controls).reduce((acc, key) => {
+ const control = controlShortcuts(key, controls, propControls);
if (control.defaultValue === undefined) {
const defaultValue = getControlValue(control);
if (typeof defaultValue !== 'function') {
@@ -69,22 +76,25 @@ export const transformControls = (
return { ...acc, [key]: control };
}, {})
: undefined;
+};
+export const getControls = (
+ story: Story,
+ doc: Document,
+ components: Components,
+): ComponentControls | undefined => {
+ const { controls: storyControls } = story;
if (!story.arguments || story.arguments.length < 1) {
//story has no arguments
- return controls;
+ return transformControls(storyControls);
}
const smartControls: SmartControls = story.smartControls || {};
const { smart = true } = smartControls;
- if (!smart || story.smartControls === false) {
- return controls;
+ if (!story.component || !smart || story.smartControls === false) {
+ return transformControls(storyControls);
}
- const storyComponent = story.component;
- if (!storyComponent) {
- return controls;
- }
- let componentName = getComponentName(storyComponent);
+ let componentName = getComponentName(story.component);
if (
!componentName ||
((!doc.componentsLookup ||
@@ -120,8 +130,8 @@ export const transformControls = (
return true;
})
.reduce((acc, key) => ({ ...acc, [key]: newControls[key] }), {});
- return deepMergeReplaceArrays(filteredControls, controls || {});
+ return transformControls(storyControls, filteredControls);
}
}
- return controls;
+ return transformControls(storyControls);
};
diff --git a/examples/stories/src/components/Button.tsx b/examples/stories/src/components/Button.tsx
index 5fd2b8122..da616f21e 100644
--- a/examples/stories/src/components/Button.tsx
+++ b/examples/stories/src/components/Button.tsx
@@ -1,6 +1,7 @@
+/* eslint-disable @typescript-eslint/no-empty-function */
import React, { FC } from 'react';
-interface ButtonProps {
+export interface ButtonProps {
/**
* Boolean indicating whether the button should render as disabled
*/
diff --git a/examples/stories/src/stories/stories-async.stories.tsx b/examples/stories/src/stories/stories-async.stories.tsx
index 02fb58ec5..f4174975f 100644
--- a/examples/stories/src/stories/stories-async.stories.tsx
+++ b/examples/stories/src/stories/stories-async.stories.tsx
@@ -5,7 +5,7 @@ import { useAsync } from '@component-controls/core';
export default {
title: 'Introduction/Async stories',
author: 'atanasster',
- order: 8,
+ order: 9,
};
const fetchData = async () => {
diff --git a/examples/stories/src/stories/template-bind.stories.tsx b/examples/stories/src/stories/template-bind.stories.tsx
new file mode 100644
index 000000000..ce0029457
--- /dev/null
+++ b/examples/stories/src/stories/template-bind.stories.tsx
@@ -0,0 +1,43 @@
+/* eslint-disable react/display-name */
+import React from 'react';
+import { Example, Document } from '@component-controls/core';
+import { EditPage } from '@component-controls/blocks';
+import { ButtonProps, Button } from '../components/Button';
+
+export default {
+ title: 'Introduction/Template bind',
+ author: 'atanasster',
+ component: Button,
+ order: 8,
+ description: ((
+
+ You can bind stories to templates to reduce the amount of repetitive code.
+ Click on the
+
+
+
+ button above to see how the templates are linked to the stories.
+
+ ) as unknown) as string,
+} as Document;
+
+const Template: Example = props => ;
+
+export const John = Template.bind();
+John.controls = {
+ children: 'john',
+ type: 'reset',
+};
+
+export const Mary = Template.bind();
+Mary.controls = {
+ children: 'mary',
+ type: 'submit',
+};
diff --git a/examples/stories/src/stories_native/dynamic-stories.stories.tsx b/examples/stories/src/stories_native/dynamic-stories.stories.tsx
index d9a8805a2..6494c0941 100644
--- a/examples/stories/src/stories_native/dynamic-stories.stories.tsx
+++ b/examples/stories/src/stories_native/dynamic-stories.stories.tsx
@@ -1,18 +1,18 @@
/* eslint-disable react/display-name */
/** @jsx jsx */
import { jsx, Button } from 'theme-ui';
-import { Example } from '@component-controls/core';
+import { DynamicExamples } from '@component-controls/core';
import { theme } from '@component-controls/components';
export default {
title: 'Introduction/Dynamic stories',
author: 'atanasster',
- order: 9,
+ order: 10,
description:
"You can create 'dynamic' stories - below are created separate stories for each theme color.",
};
-export const buttonColors = (): Example => {
+export const buttonColors = (): DynamicExamples => {
return Object.keys(theme.colors)
.filter(color => typeof theme.colors[color] === 'string')
.map(color => {
diff --git a/ui/blocks/src/Description/Description.tsx b/ui/blocks/src/Description/Description.tsx
index dc39abeb1..5ca349b01 100644
--- a/ui/blocks/src/Description/Description.tsx
+++ b/ui/blocks/src/Description/Description.tsx
@@ -20,23 +20,24 @@ export type DescriptionProps = Omit &
export const Description: FC = ({ of, ...rest }) => {
const components = useComponents({ of });
const doc = useCurrentDocument();
- return (
- <>
-
- {component => {
- if (!component || !component.info || !component.info.description) {
- return null;
- }
- return (
-
- {component.info.description}
-
- );
- }}
-
- {doc && doc.description && (
- {doc.description}
- )}
- >
+ return doc && doc.description ? (
+ typeof doc.description === 'string' ? (
+ {doc.description}
+ ) : (
+ doc.description
+ )
+ ) : (
+
+ {component => {
+ if (!component || !component.info || !component.info.description) {
+ return null;
+ }
+ return (
+
+ {component.info.description}
+
+ );
+ }}
+
);
};
diff --git a/ui/blocks/src/DocumentItem/DocumentItem.tsx b/ui/blocks/src/DocumentItem/DocumentItem.tsx
index b9a1b2ab4..02722f692 100644
--- a/ui/blocks/src/DocumentItem/DocumentItem.tsx
+++ b/ui/blocks/src/DocumentItem/DocumentItem.tsx
@@ -59,7 +59,11 @@ export const DocumentItem: FC = ({ doc, link }) => {
- {doc.description && {doc.description}}
+ {doc.description && typeof doc.description === 'string' ? (
+ {doc.description}
+ ) : (
+ doc.description
+ )}
{(tagsNode || dateNode) && (
{dateNode || }
diff --git a/ui/blocks/src/Search/Search.tsx b/ui/blocks/src/Search/Search.tsx
index fedba77e6..63813af49 100644
--- a/ui/blocks/src/Search/Search.tsx
+++ b/ui/blocks/src/Search/Search.tsx
@@ -15,7 +15,7 @@ interface SearchObject {
id: string;
title: string;
type: string;
- description?: string;
+ description?: string | JSX.Element;
body?: string;
author?: string;
stories?: string[];