@storybook/addon-docs 7.0.0-alpha.4 → 7.0.0-alpha.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/blocks/ArgsTable.js +2 -2
- package/dist/cjs/blocks/Canvas.js +12 -2
- package/dist/cjs/blocks/Description.js +1 -1
- package/dist/cjs/blocks/DocsContainer.js +18 -11
- package/dist/cjs/blocks/DocsContext.js +2 -2
- package/dist/cjs/blocks/DocsRenderer.js +48 -0
- package/dist/cjs/blocks/DocsStory.js +1 -3
- package/dist/cjs/blocks/ExternalDocsContainer.js +64 -0
- package/dist/cjs/blocks/ExternalPreview.js +99 -0
- package/dist/cjs/blocks/Meta.js +17 -3
- package/dist/cjs/blocks/Source.js +16 -20
- package/dist/cjs/blocks/Stories.js +1 -5
- package/dist/cjs/blocks/Story.js +15 -6
- package/dist/cjs/blocks/Subtitle.js +1 -1
- package/dist/cjs/blocks/enhanceSource.js +1 -3
- package/dist/cjs/blocks/index.js +28 -0
- package/dist/cjs/blocks/useStory.js +13 -6
- package/dist/cjs/preset.js +5 -13
- package/dist/cjs/preview.js +6 -2
- package/dist/esm/blocks/Canvas.js +12 -2
- package/dist/esm/blocks/DocsContainer.js +18 -11
- package/dist/esm/blocks/DocsContext.js +2 -2
- package/dist/esm/blocks/DocsRenderer.js +32 -0
- package/dist/esm/blocks/ExternalDocsContainer.js +48 -0
- package/dist/esm/blocks/ExternalPreview.js +89 -0
- package/dist/esm/blocks/Meta.js +17 -3
- package/dist/esm/blocks/Source.js +9 -3
- package/dist/esm/blocks/Story.js +15 -6
- package/dist/esm/blocks/index.js +3 -0
- package/dist/esm/blocks/useStory.js +13 -6
- package/dist/esm/preview.js +6 -2
- package/dist/types/blocks/DocsRenderer.d.ts +7 -0
- package/dist/types/blocks/ExternalDocsContainer.d.ts +4 -0
- package/dist/types/blocks/ExternalPreview.d.ts +19 -0
- package/dist/types/blocks/Meta.d.ts +4 -1
- package/dist/types/blocks/Story.d.ts +3 -1
- package/dist/types/blocks/index.d.ts +2 -0
- package/dist/types/preview.d.ts +1 -2
- package/package.json +15 -15
|
@@ -205,7 +205,7 @@ const StoryTable = props => {
|
|
|
205
205
|
}
|
|
206
206
|
}; // Use the dynamically generated component tabs if there are no controls
|
|
207
207
|
|
|
208
|
-
const storyHasArgsWithControls = argTypes && Object.values(argTypes).find(v => !!
|
|
208
|
+
const storyHasArgsWithControls = argTypes && Object.values(argTypes).find(v => !!v?.control);
|
|
209
209
|
|
|
210
210
|
if (!storyHasArgsWithControls) {
|
|
211
211
|
updateArgs = null;
|
|
@@ -278,7 +278,7 @@ const ArgsTable = props => {
|
|
|
278
278
|
const {
|
|
279
279
|
story: storyName
|
|
280
280
|
} = props;
|
|
281
|
-
const sort = sortProp ||
|
|
281
|
+
const sort = sortProp || controls?.sort;
|
|
282
282
|
const main = getComponent(props, context);
|
|
283
283
|
|
|
284
284
|
if (storyName) {
|
|
@@ -71,8 +71,18 @@ const getPreviewProps = (_ref, docsContext, sourceContext) => {
|
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
const childArray = Array.isArray(children) ? children : [children];
|
|
74
|
-
const storyChildren = childArray.filter(c => c.props && (c.props.id || c.props.name));
|
|
75
|
-
const targetIds = storyChildren.map(
|
|
74
|
+
const storyChildren = childArray.filter(c => c.props && (c.props.id || c.props.name || c.props.of));
|
|
75
|
+
const targetIds = storyChildren.map(({
|
|
76
|
+
props: {
|
|
77
|
+
id,
|
|
78
|
+
of,
|
|
79
|
+
name
|
|
80
|
+
}
|
|
81
|
+
}) => {
|
|
82
|
+
if (id) return id;
|
|
83
|
+
if (of) return docsContext.storyIdByModuleExport(of);
|
|
84
|
+
return (0, _csf.toId)(mdxComponentAnnotations.id || mdxComponentAnnotations.title, (0, _csf.storyNameFromExport)(mdxStoryNameToKey[name]));
|
|
85
|
+
});
|
|
76
86
|
const sourceProps = (0, _Source.getSourceProps)({
|
|
77
87
|
ids: targetIds
|
|
78
88
|
}, docsContext, sourceContext);
|
|
@@ -67,7 +67,7 @@ const getDescriptionProps = ({
|
|
|
67
67
|
} = docs || {};
|
|
68
68
|
const target = of === _types.CURRENT_SELECTION ? component : of; // override component description
|
|
69
69
|
|
|
70
|
-
const componentDescriptionParameter = description
|
|
70
|
+
const componentDescriptionParameter = description?.component;
|
|
71
71
|
|
|
72
72
|
if (componentDescriptionParameter) {
|
|
73
73
|
return {
|
|
@@ -57,23 +57,30 @@ const DocsContainer = ({
|
|
|
57
57
|
}) => {
|
|
58
58
|
const {
|
|
59
59
|
id: storyId,
|
|
60
|
+
type,
|
|
60
61
|
storyById
|
|
61
62
|
} = context;
|
|
62
|
-
const {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
63
|
+
const allComponents = Object.assign({}, defaultComponents);
|
|
64
|
+
let theme = (0, _theming.ensure)(null);
|
|
65
|
+
|
|
66
|
+
if (type === 'legacy') {
|
|
67
|
+
const {
|
|
68
|
+
parameters: {
|
|
69
|
+
options = {},
|
|
70
|
+
docs = {}
|
|
71
|
+
}
|
|
72
|
+
} = storyById(storyId);
|
|
73
|
+
let themeVars = docs.theme;
|
|
74
|
+
|
|
75
|
+
if (!themeVars && options.theme) {
|
|
76
|
+
warnOptionsTheme();
|
|
77
|
+
themeVars = options.theme;
|
|
66
78
|
}
|
|
67
|
-
} = storyById(storyId);
|
|
68
|
-
let themeVars = docs.theme;
|
|
69
79
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
themeVars = options.theme;
|
|
80
|
+
theme = (0, _theming.ensure)(themeVars);
|
|
81
|
+
Object.assign(allComponents, docs.components);
|
|
73
82
|
}
|
|
74
83
|
|
|
75
|
-
const theme = (0, _theming.ensure)(themeVars);
|
|
76
|
-
const allComponents = Object.assign({}, defaultComponents, docs.components);
|
|
77
84
|
(0, _react.useEffect)(() => {
|
|
78
85
|
let url;
|
|
79
86
|
|
|
@@ -17,9 +17,9 @@ var _global = require("global");
|
|
|
17
17
|
|
|
18
18
|
/* eslint-disable no-underscore-dangle */
|
|
19
19
|
if (_global.window && _global.window.__DOCS_CONTEXT__ === undefined) {
|
|
20
|
-
_global.window.__DOCS_CONTEXT__ = /*#__PURE__*/(0, _react.createContext)(
|
|
20
|
+
_global.window.__DOCS_CONTEXT__ = /*#__PURE__*/(0, _react.createContext)(null);
|
|
21
21
|
_global.window.__DOCS_CONTEXT__.displayName = 'DocsContext';
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
const DocsContext = _global.window ? _global.window.__DOCS_CONTEXT__ : /*#__PURE__*/(0, _react.createContext)(
|
|
24
|
+
const DocsContext = _global.window ? _global.window.__DOCS_CONTEXT__ : /*#__PURE__*/(0, _react.createContext)(null);
|
|
25
25
|
exports.DocsContext = DocsContext;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.DocsRenderer = void 0;
|
|
7
|
+
|
|
8
|
+
var _react = _interopRequireDefault(require("react"));
|
|
9
|
+
|
|
10
|
+
var _reactDom = _interopRequireDefault(require("react-dom"));
|
|
11
|
+
|
|
12
|
+
var _DocsContainer = require("./DocsContainer");
|
|
13
|
+
|
|
14
|
+
var _DocsPage = require("./DocsPage");
|
|
15
|
+
|
|
16
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
17
|
+
|
|
18
|
+
class DocsRenderer {
|
|
19
|
+
constructor() {
|
|
20
|
+
this.render = void 0;
|
|
21
|
+
this.unmount = void 0;
|
|
22
|
+
|
|
23
|
+
this.render = (docsContext, docsParameters, element, callback) => {
|
|
24
|
+
renderDocsAsync(docsContext, docsParameters, element).then(callback);
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
this.unmount = element => {
|
|
28
|
+
_reactDom.default.unmountComponentAtNode(element);
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
exports.DocsRenderer = DocsRenderer;
|
|
35
|
+
|
|
36
|
+
async function renderDocsAsync(docsContext, docsParameters, element) {
|
|
37
|
+
const Container = docsParameters.container || (await docsParameters.getContainer?.()) || _DocsContainer.DocsContainer;
|
|
38
|
+
const Page = docsParameters.page || (await docsParameters.getPage?.()) || _DocsPage.DocsPage; // Use `title` as a key so that we force a re-render every time we switch components
|
|
39
|
+
|
|
40
|
+
const docsElement = /*#__PURE__*/_react.default.createElement(Container, {
|
|
41
|
+
key: docsContext.title,
|
|
42
|
+
context: docsContext
|
|
43
|
+
}, /*#__PURE__*/_react.default.createElement(Page, null));
|
|
44
|
+
|
|
45
|
+
await new Promise(resolve => {
|
|
46
|
+
_reactDom.default.render(docsElement, element, resolve);
|
|
47
|
+
});
|
|
48
|
+
}
|
|
@@ -42,9 +42,7 @@ const DocsStory = ({
|
|
|
42
42
|
} = parameters;
|
|
43
43
|
|
|
44
44
|
if (expanded && docs) {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
description = (_docs$description = docs.description) === null || _docs$description === void 0 ? void 0 : _docs$description.story;
|
|
45
|
+
description = docs.description?.story;
|
|
48
46
|
|
|
49
47
|
if (!description) {
|
|
50
48
|
description = docs.storyDescription;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.ExternalDocsContainer = void 0;
|
|
7
|
+
|
|
8
|
+
var _react = _interopRequireDefault(require("react"));
|
|
9
|
+
|
|
10
|
+
var _theming = require("@storybook/theming");
|
|
11
|
+
|
|
12
|
+
var _DocsContext = require("./DocsContext");
|
|
13
|
+
|
|
14
|
+
var _ExternalPreview = require("./ExternalPreview");
|
|
15
|
+
|
|
16
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
17
|
+
|
|
18
|
+
let preview;
|
|
19
|
+
|
|
20
|
+
const ExternalDocsContainer = ({
|
|
21
|
+
projectAnnotations,
|
|
22
|
+
children
|
|
23
|
+
}) => {
|
|
24
|
+
if (!preview) preview = new _ExternalPreview.ExternalPreview(projectAnnotations);
|
|
25
|
+
let pageMeta;
|
|
26
|
+
|
|
27
|
+
const setMeta = m => {
|
|
28
|
+
pageMeta = m;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const docsContext = {
|
|
32
|
+
type: 'external',
|
|
33
|
+
id: 'external-docs',
|
|
34
|
+
title: 'External',
|
|
35
|
+
name: 'Docs',
|
|
36
|
+
storyIdByModuleExport: (storyExport, metaExport) => {
|
|
37
|
+
return preview.storyIdByModuleExport(storyExport, metaExport || pageMeta);
|
|
38
|
+
},
|
|
39
|
+
storyById: id => {
|
|
40
|
+
return preview.storyById(id);
|
|
41
|
+
},
|
|
42
|
+
getStoryContext: () => {
|
|
43
|
+
throw new Error('not implemented');
|
|
44
|
+
},
|
|
45
|
+
componentStories: () => {
|
|
46
|
+
// TODO: could implement in a very similar way to in DocsRender. (TODO: How to share code?)
|
|
47
|
+
throw new Error('not implemented');
|
|
48
|
+
},
|
|
49
|
+
loadStory: async id => {
|
|
50
|
+
return preview.storyById(id);
|
|
51
|
+
},
|
|
52
|
+
renderStoryToElement: (story, element) => {
|
|
53
|
+
return preview.renderStoryToElement(story, element);
|
|
54
|
+
},
|
|
55
|
+
setMeta
|
|
56
|
+
};
|
|
57
|
+
return /*#__PURE__*/_react.default.createElement(_DocsContext.DocsContext.Provider, {
|
|
58
|
+
value: docsContext
|
|
59
|
+
}, /*#__PURE__*/_react.default.createElement(_theming.ThemeProvider, {
|
|
60
|
+
theme: (0, _theming.ensure)(_theming.themes.normal)
|
|
61
|
+
}, children));
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
exports.ExternalDocsContainer = ExternalDocsContainer;
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.ExternalPreview = void 0;
|
|
7
|
+
|
|
8
|
+
var _previewWeb = require("@storybook/preview-web");
|
|
9
|
+
|
|
10
|
+
var _csf = require("@storybook/csf");
|
|
11
|
+
|
|
12
|
+
class ConstantMap {
|
|
13
|
+
// eslint-disable-next-line no-useless-constructor
|
|
14
|
+
constructor(prefix) {
|
|
15
|
+
this.prefix = prefix;
|
|
16
|
+
this.entries = new Map();
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
get(key) {
|
|
20
|
+
if (!this.entries.has(key)) {
|
|
21
|
+
this.entries.set(key, `${this.prefix}${this.entries.size}`);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return this.entries.get(key);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
class ExternalPreview extends _previewWeb.Preview {
|
|
30
|
+
constructor(projectAnnotations) {
|
|
31
|
+
super();
|
|
32
|
+
this.projectAnnotations = projectAnnotations;
|
|
33
|
+
this.initialized = false;
|
|
34
|
+
this.importPaths = new ConstantMap('./importPath/');
|
|
35
|
+
this.titles = new ConstantMap('title-');
|
|
36
|
+
this.storyIds = new Map();
|
|
37
|
+
this.storyIndex = {
|
|
38
|
+
v: 4,
|
|
39
|
+
entries: {}
|
|
40
|
+
};
|
|
41
|
+
this.moduleExportsByImportPath = {};
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
storyIdByModuleExport(storyExport, meta) {
|
|
45
|
+
if (!this.storyIds.has(storyExport)) this.addStoryFromExports(storyExport, meta);
|
|
46
|
+
return this.storyIds.get(storyExport);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
addStoryFromExports(storyExport, meta) {
|
|
50
|
+
const importPath = this.importPaths.get(meta);
|
|
51
|
+
this.moduleExportsByImportPath[importPath] = meta;
|
|
52
|
+
const title = meta.default.title || this.titles.get(meta);
|
|
53
|
+
const exportEntry = Object.entries(meta).find(([_, moduleExport]) => moduleExport === storyExport);
|
|
54
|
+
if (!exportEntry) throw new Error(`Didn't find \`of\` used in Story block in the provided CSF exports`);
|
|
55
|
+
const storyId = (0, _csf.toId)(title, exportEntry[0]);
|
|
56
|
+
this.storyIds.set(storyExport, storyId);
|
|
57
|
+
this.storyIndex.entries[storyId] = {
|
|
58
|
+
id: storyId,
|
|
59
|
+
importPath,
|
|
60
|
+
title,
|
|
61
|
+
name: 'Name',
|
|
62
|
+
type: 'story'
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
if (!this.initialized) {
|
|
66
|
+
this.initialized = true;
|
|
67
|
+
return this.initialize({
|
|
68
|
+
getStoryIndex: () => this.storyIndex,
|
|
69
|
+
importFn: path => {
|
|
70
|
+
return Promise.resolve(this.moduleExportsByImportPath[path]);
|
|
71
|
+
},
|
|
72
|
+
getProjectAnnotations: () => this.projectAnnotations
|
|
73
|
+
});
|
|
74
|
+
} // else
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
return this.onStoriesChanged({
|
|
78
|
+
storyIndex: this.storyIndex
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
storyById(storyId) {
|
|
83
|
+
const entry = this.storyIndex.entries[storyId];
|
|
84
|
+
if (!entry) throw new Error(`Unknown storyId ${storyId}`);
|
|
85
|
+
const {
|
|
86
|
+
importPath,
|
|
87
|
+
title
|
|
88
|
+
} = entry;
|
|
89
|
+
const moduleExports = this.moduleExportsByImportPath[importPath];
|
|
90
|
+
const csfFile = this.storyStore.processCSFFileWithCache(moduleExports, importPath, title);
|
|
91
|
+
return this.storyStore.storyFromCSFFile({
|
|
92
|
+
storyId,
|
|
93
|
+
csfFile
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
exports.ExternalPreview = ExternalPreview;
|
package/dist/cjs/blocks/Meta.js
CHANGED
|
@@ -30,6 +30,11 @@ function getFirstStoryId(docsContext) {
|
|
|
30
30
|
|
|
31
31
|
function renderAnchor() {
|
|
32
32
|
const context = (0, _react.useContext)(_DocsContext.DocsContext);
|
|
33
|
+
|
|
34
|
+
if (context.type !== 'legacy') {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
|
|
33
38
|
const anchorId = getFirstStoryId(context) || context.id;
|
|
34
39
|
return /*#__PURE__*/_react.default.createElement(_Anchor.Anchor, {
|
|
35
40
|
storyId: anchorId
|
|
@@ -41,9 +46,18 @@ function renderAnchor() {
|
|
|
41
46
|
*/
|
|
42
47
|
|
|
43
48
|
|
|
44
|
-
const Meta = (
|
|
45
|
-
|
|
46
|
-
|
|
49
|
+
const Meta = ({
|
|
50
|
+
of
|
|
51
|
+
}) => {
|
|
52
|
+
let isDocs = true;
|
|
53
|
+
|
|
54
|
+
if (document) {
|
|
55
|
+
const params = new URL(document.location).searchParams;
|
|
56
|
+
isDocs = params.get('viewMode') === 'docs';
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const context = (0, _react.useContext)(_DocsContext.DocsContext);
|
|
60
|
+
if (of) context.setMeta(of);
|
|
47
61
|
return isDocs ? renderAnchor() : null;
|
|
48
62
|
};
|
|
49
63
|
|
|
@@ -35,11 +35,7 @@ exports.SourceState = SourceState;
|
|
|
35
35
|
})(SourceState || (exports.SourceState = SourceState = {}));
|
|
36
36
|
|
|
37
37
|
const getSourceState = stories => {
|
|
38
|
-
const states = stories.map(story =>
|
|
39
|
-
var _story$parameters$doc, _story$parameters$doc2;
|
|
40
|
-
|
|
41
|
-
return (_story$parameters$doc = story.parameters.docs) === null || _story$parameters$doc === void 0 ? void 0 : (_story$parameters$doc2 = _story$parameters$doc.source) === null || _story$parameters$doc2 === void 0 ? void 0 : _story$parameters$doc2.state;
|
|
42
|
-
}).filter(Boolean);
|
|
38
|
+
const states = stories.map(story => story.parameters.docs?.source?.state).filter(Boolean);
|
|
43
39
|
if (states.length === 0) return SourceState.CLOSED; // FIXME: handling multiple stories is a pain
|
|
44
40
|
|
|
45
41
|
return states[0];
|
|
@@ -51,15 +47,13 @@ const getStorySource = (storyId, sourceContext) => {
|
|
|
51
47
|
} = sourceContext; // source rendering is async so source is unavailable at the start of the render cycle,
|
|
52
48
|
// so we fail gracefully here without warning
|
|
53
49
|
|
|
54
|
-
return
|
|
50
|
+
return sources?.[storyId] || {
|
|
55
51
|
code: '',
|
|
56
52
|
format: false
|
|
57
53
|
};
|
|
58
54
|
};
|
|
59
55
|
|
|
60
56
|
const getSnippet = (snippet, story) => {
|
|
61
|
-
var _parameters$docs, _parameters$docs$sour, _parameters$docs2, _parameters$docs2$sou, _enhanced$docs, _enhanced$docs$source;
|
|
62
|
-
|
|
63
57
|
if (!story) {
|
|
64
58
|
return snippet;
|
|
65
59
|
}
|
|
@@ -69,9 +63,9 @@ const getSnippet = (snippet, story) => {
|
|
|
69
63
|
} = story; // eslint-disable-next-line no-underscore-dangle
|
|
70
64
|
|
|
71
65
|
const isArgsStory = parameters.__isArgsStory;
|
|
72
|
-
const type =
|
|
66
|
+
const type = parameters.docs?.source?.type || _shared.SourceType.AUTO; // if user has hard-coded the snippet, that takes precedence
|
|
73
67
|
|
|
74
|
-
const userCode =
|
|
68
|
+
const userCode = parameters.docs?.source?.code;
|
|
75
69
|
|
|
76
70
|
if (userCode !== undefined) {
|
|
77
71
|
return userCode;
|
|
@@ -79,21 +73,17 @@ const getSnippet = (snippet, story) => {
|
|
|
79
73
|
|
|
80
74
|
|
|
81
75
|
if (type === _shared.SourceType.DYNAMIC) {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
return ((_parameters$docs3 = parameters.docs) === null || _parameters$docs3 === void 0 ? void 0 : (_parameters$docs3$tra = _parameters$docs3.transformSource) === null || _parameters$docs3$tra === void 0 ? void 0 : _parameters$docs3$tra.call(_parameters$docs3, snippet, story)) || snippet;
|
|
76
|
+
return parameters.docs?.transformSource?.(snippet, story) || snippet;
|
|
85
77
|
} // if this is an args story and there's a snippet
|
|
86
78
|
|
|
87
79
|
|
|
88
80
|
if (type === _shared.SourceType.AUTO && snippet && isArgsStory) {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
return ((_parameters$docs4 = parameters.docs) === null || _parameters$docs4 === void 0 ? void 0 : (_parameters$docs4$tra = _parameters$docs4.transformSource) === null || _parameters$docs4$tra === void 0 ? void 0 : _parameters$docs4$tra.call(_parameters$docs4, snippet, story)) || snippet;
|
|
81
|
+
return parameters.docs?.transformSource?.(snippet, story) || snippet;
|
|
92
82
|
} // otherwise, use the source code logic
|
|
93
83
|
|
|
94
84
|
|
|
95
85
|
const enhanced = (0, _enhanceSource.enhanceSource)(story) || parameters;
|
|
96
|
-
return
|
|
86
|
+
return enhanced?.docs?.source?.code || '';
|
|
97
87
|
};
|
|
98
88
|
|
|
99
89
|
const getSourceProps = (props, docsContext, sourceContext) => {
|
|
@@ -101,9 +91,15 @@ const getSourceProps = (props, docsContext, sourceContext) => {
|
|
|
101
91
|
id: currentId,
|
|
102
92
|
storyById
|
|
103
93
|
} = docsContext;
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
94
|
+
let parameters = {};
|
|
95
|
+
|
|
96
|
+
try {
|
|
97
|
+
({
|
|
98
|
+
parameters
|
|
99
|
+
} = storyById(currentId));
|
|
100
|
+
} catch (err) {// TODO: in external mode, there is no "current"
|
|
101
|
+
}
|
|
102
|
+
|
|
107
103
|
const codeProps = props;
|
|
108
104
|
const singleProps = props;
|
|
109
105
|
const multiProps = props;
|
|
@@ -27,11 +27,7 @@ const Stories = ({
|
|
|
27
27
|
componentStories
|
|
28
28
|
} = (0, _react.useContext)(_DocsContext.DocsContext);
|
|
29
29
|
let stories = componentStories();
|
|
30
|
-
stories = stories.filter(story =>
|
|
31
|
-
var _story$parameters, _story$parameters$doc;
|
|
32
|
-
|
|
33
|
-
return !((_story$parameters = story.parameters) !== null && _story$parameters !== void 0 && (_story$parameters$doc = _story$parameters.docs) !== null && _story$parameters$doc !== void 0 && _story$parameters$doc.disable);
|
|
34
|
-
});
|
|
30
|
+
stories = stories.filter(story => !story.parameters?.docs?.disable);
|
|
35
31
|
if (!includePrimary) stories = stories.slice(1);
|
|
36
32
|
|
|
37
33
|
if (!stories || stories.length === 0) {
|
package/dist/cjs/blocks/Story.js
CHANGED
|
@@ -36,8 +36,15 @@ exports.lookupStoryId = lookupStoryId;
|
|
|
36
36
|
|
|
37
37
|
const getStoryId = (props, context) => {
|
|
38
38
|
const {
|
|
39
|
-
id
|
|
39
|
+
id,
|
|
40
|
+
of,
|
|
41
|
+
meta
|
|
40
42
|
} = props;
|
|
43
|
+
|
|
44
|
+
if (of) {
|
|
45
|
+
return context.storyIdByModuleExport(of, meta);
|
|
46
|
+
}
|
|
47
|
+
|
|
41
48
|
const {
|
|
42
49
|
name
|
|
43
50
|
} = props;
|
|
@@ -53,8 +60,8 @@ const getStoryProps = ({
|
|
|
53
60
|
}, story) => {
|
|
54
61
|
const {
|
|
55
62
|
name: storyName,
|
|
56
|
-
parameters
|
|
57
|
-
} = story;
|
|
63
|
+
parameters = {}
|
|
64
|
+
} = story || {};
|
|
58
65
|
const {
|
|
59
66
|
docs = {}
|
|
60
67
|
} = parameters;
|
|
@@ -71,7 +78,7 @@ const getStoryProps = ({
|
|
|
71
78
|
const storyIsInline = typeof inline === 'boolean' ? inline : inlineStories;
|
|
72
79
|
return Object.assign({
|
|
73
80
|
inline: storyIsInline,
|
|
74
|
-
id: story
|
|
81
|
+
id: story?.id,
|
|
75
82
|
height: height || (storyIsInline ? undefined : iframeHeight),
|
|
76
83
|
title: storyName
|
|
77
84
|
}, storyIsInline && {
|
|
@@ -109,7 +116,9 @@ const Story = props => {
|
|
|
109
116
|
return null;
|
|
110
117
|
}
|
|
111
118
|
|
|
112
|
-
|
|
119
|
+
const inline = context.type === 'external' || storyProps.inline;
|
|
120
|
+
|
|
121
|
+
if (inline) {
|
|
113
122
|
// We do this so React doesn't complain when we replace the span in a secondary render
|
|
114
123
|
const htmlContents = `<span></span>`; // FIXME: height/style/etc. lifted from PureStory
|
|
115
124
|
|
|
@@ -120,7 +129,7 @@ const Story = props => {
|
|
|
120
129
|
id: storyBlockIdFromId(story.id)
|
|
121
130
|
}, /*#__PURE__*/_react.default.createElement(_react2.MDXProvider, {
|
|
122
131
|
components: _components.resetComponents
|
|
123
|
-
}, height ? /*#__PURE__*/_react.default.createElement("style", null, `#story--${story.id} { min-height: ${height}; transform: translateZ(0); overflow: auto }`) : null, showLoader && /*#__PURE__*/_react.default.createElement(_components.StorySkeleton, null), /*#__PURE__*/_react.default.createElement("div", {
|
|
132
|
+
}, height ? /*#__PURE__*/_react.default.createElement("style", null, `#story--${story.id} { min-height: ${height}px; transform: translateZ(0); overflow: auto }`) : null, showLoader && /*#__PURE__*/_react.default.createElement(_components.StorySkeleton, null), /*#__PURE__*/_react.default.createElement("div", {
|
|
124
133
|
ref: storyRef,
|
|
125
134
|
"data-name": story.name,
|
|
126
135
|
dangerouslySetInnerHTML: {
|
|
@@ -28,7 +28,7 @@ const Subtitle = ({
|
|
|
28
28
|
let text = children;
|
|
29
29
|
|
|
30
30
|
if (!text) {
|
|
31
|
-
text = parameters
|
|
31
|
+
text = parameters?.componentSubtitle;
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
return text ? /*#__PURE__*/_react.default.createElement(_components.Subtitle, {
|
|
@@ -60,8 +60,6 @@ const extract = (targetId, {
|
|
|
60
60
|
};
|
|
61
61
|
|
|
62
62
|
const enhanceSource = story => {
|
|
63
|
-
var _docs$source;
|
|
64
|
-
|
|
65
63
|
const {
|
|
66
64
|
id,
|
|
67
65
|
parameters
|
|
@@ -74,7 +72,7 @@ const enhanceSource = story => {
|
|
|
74
72
|
transformSource
|
|
75
73
|
} = docs; // no input or user has manually overridden the output
|
|
76
74
|
|
|
77
|
-
if (!
|
|
75
|
+
if (!storySource?.source || docs.source?.code) {
|
|
78
76
|
return null;
|
|
79
77
|
}
|
|
80
78
|
|
package/dist/cjs/blocks/index.js
CHANGED
|
@@ -141,6 +141,34 @@ Object.keys(_DocsContainer).forEach(function (key) {
|
|
|
141
141
|
});
|
|
142
142
|
});
|
|
143
143
|
|
|
144
|
+
var _DocsRenderer = require("./DocsRenderer");
|
|
145
|
+
|
|
146
|
+
Object.keys(_DocsRenderer).forEach(function (key) {
|
|
147
|
+
if (key === "default" || key === "__esModule") return;
|
|
148
|
+
if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
|
|
149
|
+
if (key in exports && exports[key] === _DocsRenderer[key]) return;
|
|
150
|
+
Object.defineProperty(exports, key, {
|
|
151
|
+
enumerable: true,
|
|
152
|
+
get: function () {
|
|
153
|
+
return _DocsRenderer[key];
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
var _ExternalDocsContainer = require("./ExternalDocsContainer");
|
|
159
|
+
|
|
160
|
+
Object.keys(_ExternalDocsContainer).forEach(function (key) {
|
|
161
|
+
if (key === "default" || key === "__esModule") return;
|
|
162
|
+
if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
|
|
163
|
+
if (key in exports && exports[key] === _ExternalDocsContainer[key]) return;
|
|
164
|
+
Object.defineProperty(exports, key, {
|
|
165
|
+
enumerable: true,
|
|
166
|
+
get: function () {
|
|
167
|
+
return _ExternalDocsContainer[key];
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
});
|
|
171
|
+
|
|
144
172
|
var _DocsStory = require("./DocsStory");
|
|
145
173
|
|
|
146
174
|
Object.keys(_DocsStory).forEach(function (key) {
|
|
@@ -14,11 +14,9 @@ function useStory(storyId, context) {
|
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
function useStories(storyIds, context) {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
}, {});
|
|
21
|
-
const [storiesById, setStories] = (0, _react.useState)(initialStoriesById);
|
|
17
|
+
// Legacy docs pages can reference any story by id. Those stories will need to be
|
|
18
|
+
// asyncronously loaded; we use the state for this
|
|
19
|
+
const [storiesById, setStories] = (0, _react.useState)({});
|
|
22
20
|
(0, _react.useEffect)(() => {
|
|
23
21
|
Promise.all(storyIds.map(async storyId => {
|
|
24
22
|
// loadStory will be called every single time useStory is called
|
|
@@ -33,5 +31,14 @@ function useStories(storyIds, context) {
|
|
|
33
31
|
}));
|
|
34
32
|
}));
|
|
35
33
|
});
|
|
36
|
-
return storyIds.map(storyId =>
|
|
34
|
+
return storyIds.map(storyId => {
|
|
35
|
+
if (storiesById[storyId]) return storiesById[storyId];
|
|
36
|
+
|
|
37
|
+
try {
|
|
38
|
+
// If we are allowed to load this story id synchonously, this will work
|
|
39
|
+
return context.storyById(storyId);
|
|
40
|
+
} catch (err) {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
});
|
|
37
44
|
}
|
package/dist/cjs/preset.js
CHANGED
|
@@ -29,7 +29,7 @@ function createBabelOptions({
|
|
|
29
29
|
mdxBabelOptions,
|
|
30
30
|
configureJSX
|
|
31
31
|
}) {
|
|
32
|
-
const babelPlugins =
|
|
32
|
+
const babelPlugins = mdxBabelOptions?.plugins || babelOptions?.plugins || [];
|
|
33
33
|
const jsxPlugin = [require.resolve('@babel/plugin-transform-react-jsx'), {
|
|
34
34
|
pragma: 'React.createElement',
|
|
35
35
|
pragmaFrag: 'React.Fragment'
|
|
@@ -45,8 +45,6 @@ function createBabelOptions({
|
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
async function webpack(webpackConfig = {}, options) {
|
|
48
|
-
var _global$FEATURES, _global$FEATURES2;
|
|
49
|
-
|
|
50
48
|
const resolvedBabelLoader = require.resolve('babel-loader');
|
|
51
49
|
|
|
52
50
|
const {
|
|
@@ -67,11 +65,11 @@ async function webpack(webpackConfig = {}, options) {
|
|
|
67
65
|
skipCsf: true,
|
|
68
66
|
remarkPlugins: [_remarkSlug.default, _remarkExternalLinks.default]
|
|
69
67
|
};
|
|
70
|
-
const mdxVersion =
|
|
68
|
+
const mdxVersion = _global.default.FEATURES?.previewMdx2 ? 'MDX2' : 'MDX1';
|
|
71
69
|
|
|
72
70
|
_nodeLogger.logger.info(`Addon-docs: using ${mdxVersion}`);
|
|
73
71
|
|
|
74
|
-
const mdxLoader =
|
|
72
|
+
const mdxLoader = _global.default.FEATURES?.previewMdx2 ? require.resolve('@storybook/mdx2-csf/loader') : require.resolve('@storybook/mdx1-csf/loader'); // set `sourceLoaderOptions` to `null` to disable for manual configuration
|
|
75
73
|
|
|
76
74
|
const sourceLoader = sourceLoaderOptions ? [{
|
|
77
75
|
test: /\.(stories|story)\.[tj]sx?$/,
|
|
@@ -84,11 +82,7 @@ async function webpack(webpackConfig = {}, options) {
|
|
|
84
82
|
let rules = module.rules || [];
|
|
85
83
|
|
|
86
84
|
if (transcludeMarkdown) {
|
|
87
|
-
rules = [...rules.filter(rule => {
|
|
88
|
-
var _rule$test;
|
|
89
|
-
|
|
90
|
-
return ((_rule$test = rule.test) === null || _rule$test === void 0 ? void 0 : _rule$test.toString()) !== '/\\.md$/';
|
|
91
|
-
}), {
|
|
85
|
+
rules = [...rules.filter(rule => rule.test?.toString() !== '/\\.md$/'), {
|
|
92
86
|
test: /\.md$/,
|
|
93
87
|
use: [{
|
|
94
88
|
loader: resolvedBabelLoader,
|
|
@@ -140,13 +134,11 @@ async function webpack(webpackConfig = {}, options) {
|
|
|
140
134
|
|
|
141
135
|
const storyIndexers = async indexers => {
|
|
142
136
|
const mdxIndexer = async (fileName, opts) => {
|
|
143
|
-
var _global$FEATURES3;
|
|
144
|
-
|
|
145
137
|
let code = (await _fsExtra.default.readFile(fileName, 'utf-8')).toString(); // @ts-ignore
|
|
146
138
|
|
|
147
139
|
const {
|
|
148
140
|
compile
|
|
149
|
-
} =
|
|
141
|
+
} = _global.default.FEATURES?.previewMdx2 ? await Promise.resolve().then(() => _interopRequireWildcard(require('@storybook/mdx2-csf'))) : await Promise.resolve().then(() => _interopRequireWildcard(require('@storybook/mdx1-csf')));
|
|
150
142
|
code = await compile(code, {});
|
|
151
143
|
return (0, _csfTools.loadCsf)(code, Object.assign({}, opts, {
|
|
152
144
|
fileName
|
package/dist/cjs/preview.js
CHANGED
|
@@ -11,8 +11,12 @@ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj &&
|
|
|
11
11
|
|
|
12
12
|
const parameters = {
|
|
13
13
|
docs: {
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
renderer: async () => {
|
|
15
|
+
const {
|
|
16
|
+
DocsRenderer
|
|
17
|
+
} = await Promise.resolve().then(() => _interopRequireWildcard(require('./blocks/DocsRenderer')));
|
|
18
|
+
return new DocsRenderer();
|
|
19
|
+
}
|
|
16
20
|
}
|
|
17
21
|
};
|
|
18
22
|
exports.parameters = parameters;
|
|
@@ -47,8 +47,18 @@ const getPreviewProps = (_ref, docsContext, sourceContext) => {
|
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
const childArray = Array.isArray(children) ? children : [children];
|
|
50
|
-
const storyChildren = childArray.filter(c => c.props && (c.props.id || c.props.name));
|
|
51
|
-
const targetIds = storyChildren.map(
|
|
50
|
+
const storyChildren = childArray.filter(c => c.props && (c.props.id || c.props.name || c.props.of));
|
|
51
|
+
const targetIds = storyChildren.map(({
|
|
52
|
+
props: {
|
|
53
|
+
id,
|
|
54
|
+
of,
|
|
55
|
+
name
|
|
56
|
+
}
|
|
57
|
+
}) => {
|
|
58
|
+
if (id) return id;
|
|
59
|
+
if (of) return docsContext.storyIdByModuleExport(of);
|
|
60
|
+
return toId(mdxComponentAnnotations.id || mdxComponentAnnotations.title, storyNameFromExport(mdxStoryNameToKey[name]));
|
|
61
|
+
});
|
|
52
62
|
const sourceProps = getSourceProps({
|
|
53
63
|
ids: targetIds
|
|
54
64
|
}, docsContext, sourceContext);
|
|
@@ -30,23 +30,30 @@ export const DocsContainer = ({
|
|
|
30
30
|
}) => {
|
|
31
31
|
const {
|
|
32
32
|
id: storyId,
|
|
33
|
+
type,
|
|
33
34
|
storyById
|
|
34
35
|
} = context;
|
|
35
|
-
const {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
36
|
+
const allComponents = Object.assign({}, defaultComponents);
|
|
37
|
+
let theme = ensureTheme(null);
|
|
38
|
+
|
|
39
|
+
if (type === 'legacy') {
|
|
40
|
+
const {
|
|
41
|
+
parameters: {
|
|
42
|
+
options = {},
|
|
43
|
+
docs = {}
|
|
44
|
+
}
|
|
45
|
+
} = storyById(storyId);
|
|
46
|
+
let themeVars = docs.theme;
|
|
47
|
+
|
|
48
|
+
if (!themeVars && options.theme) {
|
|
49
|
+
warnOptionsTheme();
|
|
50
|
+
themeVars = options.theme;
|
|
39
51
|
}
|
|
40
|
-
} = storyById(storyId);
|
|
41
|
-
let themeVars = docs.theme;
|
|
42
52
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
themeVars = options.theme;
|
|
53
|
+
theme = ensureTheme(themeVars);
|
|
54
|
+
Object.assign(allComponents, docs.components);
|
|
46
55
|
}
|
|
47
56
|
|
|
48
|
-
const theme = ensureTheme(themeVars);
|
|
49
|
-
const allComponents = Object.assign({}, defaultComponents, docs.components);
|
|
50
57
|
useEffect(() => {
|
|
51
58
|
let url;
|
|
52
59
|
|
|
@@ -9,8 +9,8 @@ import { window as globalWindow } from 'global';
|
|
|
9
9
|
|
|
10
10
|
/* eslint-disable no-underscore-dangle */
|
|
11
11
|
if (globalWindow && globalWindow.__DOCS_CONTEXT__ === undefined) {
|
|
12
|
-
globalWindow.__DOCS_CONTEXT__ = /*#__PURE__*/createContext(
|
|
12
|
+
globalWindow.__DOCS_CONTEXT__ = /*#__PURE__*/createContext(null);
|
|
13
13
|
globalWindow.__DOCS_CONTEXT__.displayName = 'DocsContext';
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
export const DocsContext = globalWindow ? globalWindow.__DOCS_CONTEXT__ : /*#__PURE__*/createContext(
|
|
16
|
+
export const DocsContext = globalWindow ? globalWindow.__DOCS_CONTEXT__ : /*#__PURE__*/createContext(null);
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import ReactDOM from 'react-dom';
|
|
3
|
+
import { DocsContainer } from './DocsContainer';
|
|
4
|
+
import { DocsPage } from './DocsPage';
|
|
5
|
+
export class DocsRenderer {
|
|
6
|
+
constructor() {
|
|
7
|
+
this.render = void 0;
|
|
8
|
+
this.unmount = void 0;
|
|
9
|
+
|
|
10
|
+
this.render = (docsContext, docsParameters, element, callback) => {
|
|
11
|
+
renderDocsAsync(docsContext, docsParameters, element).then(callback);
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
this.unmount = element => {
|
|
15
|
+
ReactDOM.unmountComponentAtNode(element);
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
async function renderDocsAsync(docsContext, docsParameters, element) {
|
|
22
|
+
const Container = docsParameters.container || (await docsParameters.getContainer?.()) || DocsContainer;
|
|
23
|
+
const Page = docsParameters.page || (await docsParameters.getPage?.()) || DocsPage; // Use `title` as a key so that we force a re-render every time we switch components
|
|
24
|
+
|
|
25
|
+
const docsElement = /*#__PURE__*/React.createElement(Container, {
|
|
26
|
+
key: docsContext.title,
|
|
27
|
+
context: docsContext
|
|
28
|
+
}, /*#__PURE__*/React.createElement(Page, null));
|
|
29
|
+
await new Promise(resolve => {
|
|
30
|
+
ReactDOM.render(docsElement, element, resolve);
|
|
31
|
+
});
|
|
32
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { ThemeProvider, themes, ensure } from '@storybook/theming';
|
|
3
|
+
import { DocsContext } from './DocsContext';
|
|
4
|
+
import { ExternalPreview } from './ExternalPreview';
|
|
5
|
+
let preview;
|
|
6
|
+
export const ExternalDocsContainer = ({
|
|
7
|
+
projectAnnotations,
|
|
8
|
+
children
|
|
9
|
+
}) => {
|
|
10
|
+
if (!preview) preview = new ExternalPreview(projectAnnotations);
|
|
11
|
+
let pageMeta;
|
|
12
|
+
|
|
13
|
+
const setMeta = m => {
|
|
14
|
+
pageMeta = m;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const docsContext = {
|
|
18
|
+
type: 'external',
|
|
19
|
+
id: 'external-docs',
|
|
20
|
+
title: 'External',
|
|
21
|
+
name: 'Docs',
|
|
22
|
+
storyIdByModuleExport: (storyExport, metaExport) => {
|
|
23
|
+
return preview.storyIdByModuleExport(storyExport, metaExport || pageMeta);
|
|
24
|
+
},
|
|
25
|
+
storyById: id => {
|
|
26
|
+
return preview.storyById(id);
|
|
27
|
+
},
|
|
28
|
+
getStoryContext: () => {
|
|
29
|
+
throw new Error('not implemented');
|
|
30
|
+
},
|
|
31
|
+
componentStories: () => {
|
|
32
|
+
// TODO: could implement in a very similar way to in DocsRender. (TODO: How to share code?)
|
|
33
|
+
throw new Error('not implemented');
|
|
34
|
+
},
|
|
35
|
+
loadStory: async id => {
|
|
36
|
+
return preview.storyById(id);
|
|
37
|
+
},
|
|
38
|
+
renderStoryToElement: (story, element) => {
|
|
39
|
+
return preview.renderStoryToElement(story, element);
|
|
40
|
+
},
|
|
41
|
+
setMeta
|
|
42
|
+
};
|
|
43
|
+
return /*#__PURE__*/React.createElement(DocsContext.Provider, {
|
|
44
|
+
value: docsContext
|
|
45
|
+
}, /*#__PURE__*/React.createElement(ThemeProvider, {
|
|
46
|
+
theme: ensure(themes.normal)
|
|
47
|
+
}, children));
|
|
48
|
+
};
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { Preview } from '@storybook/preview-web';
|
|
2
|
+
import { toId } from '@storybook/csf';
|
|
3
|
+
|
|
4
|
+
class ConstantMap {
|
|
5
|
+
// eslint-disable-next-line no-useless-constructor
|
|
6
|
+
constructor(prefix) {
|
|
7
|
+
this.prefix = prefix;
|
|
8
|
+
this.entries = new Map();
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
get(key) {
|
|
12
|
+
if (!this.entries.has(key)) {
|
|
13
|
+
this.entries.set(key, `${this.prefix}${this.entries.size}`);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
return this.entries.get(key);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export class ExternalPreview extends Preview {
|
|
22
|
+
constructor(projectAnnotations) {
|
|
23
|
+
super();
|
|
24
|
+
this.projectAnnotations = projectAnnotations;
|
|
25
|
+
this.initialized = false;
|
|
26
|
+
this.importPaths = new ConstantMap('./importPath/');
|
|
27
|
+
this.titles = new ConstantMap('title-');
|
|
28
|
+
this.storyIds = new Map();
|
|
29
|
+
this.storyIndex = {
|
|
30
|
+
v: 4,
|
|
31
|
+
entries: {}
|
|
32
|
+
};
|
|
33
|
+
this.moduleExportsByImportPath = {};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
storyIdByModuleExport(storyExport, meta) {
|
|
37
|
+
if (!this.storyIds.has(storyExport)) this.addStoryFromExports(storyExport, meta);
|
|
38
|
+
return this.storyIds.get(storyExport);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
addStoryFromExports(storyExport, meta) {
|
|
42
|
+
const importPath = this.importPaths.get(meta);
|
|
43
|
+
this.moduleExportsByImportPath[importPath] = meta;
|
|
44
|
+
const title = meta.default.title || this.titles.get(meta);
|
|
45
|
+
const exportEntry = Object.entries(meta).find(([_, moduleExport]) => moduleExport === storyExport);
|
|
46
|
+
if (!exportEntry) throw new Error(`Didn't find \`of\` used in Story block in the provided CSF exports`);
|
|
47
|
+
const storyId = toId(title, exportEntry[0]);
|
|
48
|
+
this.storyIds.set(storyExport, storyId);
|
|
49
|
+
this.storyIndex.entries[storyId] = {
|
|
50
|
+
id: storyId,
|
|
51
|
+
importPath,
|
|
52
|
+
title,
|
|
53
|
+
name: 'Name',
|
|
54
|
+
type: 'story'
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
if (!this.initialized) {
|
|
58
|
+
this.initialized = true;
|
|
59
|
+
return this.initialize({
|
|
60
|
+
getStoryIndex: () => this.storyIndex,
|
|
61
|
+
importFn: path => {
|
|
62
|
+
return Promise.resolve(this.moduleExportsByImportPath[path]);
|
|
63
|
+
},
|
|
64
|
+
getProjectAnnotations: () => this.projectAnnotations
|
|
65
|
+
});
|
|
66
|
+
} // else
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
return this.onStoriesChanged({
|
|
70
|
+
storyIndex: this.storyIndex
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
storyById(storyId) {
|
|
75
|
+
const entry = this.storyIndex.entries[storyId];
|
|
76
|
+
if (!entry) throw new Error(`Unknown storyId ${storyId}`);
|
|
77
|
+
const {
|
|
78
|
+
importPath,
|
|
79
|
+
title
|
|
80
|
+
} = entry;
|
|
81
|
+
const moduleExports = this.moduleExportsByImportPath[importPath];
|
|
82
|
+
const csfFile = this.storyStore.processCSFFileWithCache(moduleExports, importPath, title);
|
|
83
|
+
return this.storyStore.storyFromCSFFile({
|
|
84
|
+
storyId,
|
|
85
|
+
csfFile
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
}
|
package/dist/esm/blocks/Meta.js
CHANGED
|
@@ -13,6 +13,11 @@ function getFirstStoryId(docsContext) {
|
|
|
13
13
|
|
|
14
14
|
function renderAnchor() {
|
|
15
15
|
const context = useContext(DocsContext);
|
|
16
|
+
|
|
17
|
+
if (context.type !== 'legacy') {
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
|
|
16
21
|
const anchorId = getFirstStoryId(context) || context.id;
|
|
17
22
|
return /*#__PURE__*/React.createElement(Anchor, {
|
|
18
23
|
storyId: anchorId
|
|
@@ -24,8 +29,17 @@ function renderAnchor() {
|
|
|
24
29
|
*/
|
|
25
30
|
|
|
26
31
|
|
|
27
|
-
export const Meta = (
|
|
28
|
-
|
|
29
|
-
|
|
32
|
+
export const Meta = ({
|
|
33
|
+
of
|
|
34
|
+
}) => {
|
|
35
|
+
let isDocs = true;
|
|
36
|
+
|
|
37
|
+
if (document) {
|
|
38
|
+
const params = new URL(document.location).searchParams;
|
|
39
|
+
isDocs = params.get('viewMode') === 'docs';
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const context = useContext(DocsContext);
|
|
43
|
+
if (of) context.setMeta(of);
|
|
30
44
|
return isDocs ? renderAnchor() : null;
|
|
31
45
|
};
|
|
@@ -71,9 +71,15 @@ export const getSourceProps = (props, docsContext, sourceContext) => {
|
|
|
71
71
|
id: currentId,
|
|
72
72
|
storyById
|
|
73
73
|
} = docsContext;
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
74
|
+
let parameters = {};
|
|
75
|
+
|
|
76
|
+
try {
|
|
77
|
+
({
|
|
78
|
+
parameters
|
|
79
|
+
} = storyById(currentId));
|
|
80
|
+
} catch (err) {// TODO: in external mode, there is no "current"
|
|
81
|
+
}
|
|
82
|
+
|
|
77
83
|
const codeProps = props;
|
|
78
84
|
const singleProps = props;
|
|
79
85
|
const multiProps = props;
|
package/dist/esm/blocks/Story.js
CHANGED
|
@@ -12,8 +12,15 @@ export const lookupStoryId = (storyName, {
|
|
|
12
12
|
}) => toId(mdxComponentAnnotations.id || mdxComponentAnnotations.title, storyNameFromExport(mdxStoryNameToKey[storyName]));
|
|
13
13
|
export const getStoryId = (props, context) => {
|
|
14
14
|
const {
|
|
15
|
-
id
|
|
15
|
+
id,
|
|
16
|
+
of,
|
|
17
|
+
meta
|
|
16
18
|
} = props;
|
|
19
|
+
|
|
20
|
+
if (of) {
|
|
21
|
+
return context.storyIdByModuleExport(of, meta);
|
|
22
|
+
}
|
|
23
|
+
|
|
17
24
|
const {
|
|
18
25
|
name
|
|
19
26
|
} = props;
|
|
@@ -26,8 +33,8 @@ export const getStoryProps = ({
|
|
|
26
33
|
}, story) => {
|
|
27
34
|
const {
|
|
28
35
|
name: storyName,
|
|
29
|
-
parameters
|
|
30
|
-
} = story;
|
|
36
|
+
parameters = {}
|
|
37
|
+
} = story || {};
|
|
31
38
|
const {
|
|
32
39
|
docs = {}
|
|
33
40
|
} = parameters;
|
|
@@ -44,7 +51,7 @@ export const getStoryProps = ({
|
|
|
44
51
|
const storyIsInline = typeof inline === 'boolean' ? inline : inlineStories;
|
|
45
52
|
return Object.assign({
|
|
46
53
|
inline: storyIsInline,
|
|
47
|
-
id: story
|
|
54
|
+
id: story?.id,
|
|
48
55
|
height: height || (storyIsInline ? undefined : iframeHeight),
|
|
49
56
|
title: storyName
|
|
50
57
|
}, storyIsInline && {
|
|
@@ -80,7 +87,9 @@ const Story = props => {
|
|
|
80
87
|
return null;
|
|
81
88
|
}
|
|
82
89
|
|
|
83
|
-
|
|
90
|
+
const inline = context.type === 'external' || storyProps.inline;
|
|
91
|
+
|
|
92
|
+
if (inline) {
|
|
84
93
|
// We do this so React doesn't complain when we replace the span in a secondary render
|
|
85
94
|
const htmlContents = `<span></span>`; // FIXME: height/style/etc. lifted from PureStory
|
|
86
95
|
|
|
@@ -91,7 +100,7 @@ const Story = props => {
|
|
|
91
100
|
id: storyBlockIdFromId(story.id)
|
|
92
101
|
}, /*#__PURE__*/React.createElement(MDXProvider, {
|
|
93
102
|
components: resetComponents
|
|
94
|
-
}, height ? /*#__PURE__*/React.createElement("style", null, `#story--${story.id} { min-height: ${height}; transform: translateZ(0); overflow: auto }`) : null, showLoader && /*#__PURE__*/React.createElement(StorySkeleton, null), /*#__PURE__*/React.createElement("div", {
|
|
103
|
+
}, height ? /*#__PURE__*/React.createElement("style", null, `#story--${story.id} { min-height: ${height}px; transform: translateZ(0); overflow: auto }`) : null, showLoader && /*#__PURE__*/React.createElement(StorySkeleton, null), /*#__PURE__*/React.createElement("div", {
|
|
95
104
|
ref: storyRef,
|
|
96
105
|
"data-name": story.name,
|
|
97
106
|
dangerouslySetInnerHTML: {
|
package/dist/esm/blocks/index.js
CHANGED
|
@@ -6,6 +6,9 @@ export * from './Description';
|
|
|
6
6
|
export * from './DocsContext';
|
|
7
7
|
export * from './DocsPage';
|
|
8
8
|
export * from './DocsContainer';
|
|
9
|
+
export * from './DocsRenderer'; // For testing
|
|
10
|
+
|
|
11
|
+
export * from './ExternalDocsContainer';
|
|
9
12
|
export * from './DocsStory';
|
|
10
13
|
export * from './Heading';
|
|
11
14
|
export * from './Meta';
|
|
@@ -4,11 +4,9 @@ export function useStory(storyId, context) {
|
|
|
4
4
|
return stories && stories[0];
|
|
5
5
|
}
|
|
6
6
|
export function useStories(storyIds, context) {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
}, {});
|
|
11
|
-
const [storiesById, setStories] = useState(initialStoriesById);
|
|
7
|
+
// Legacy docs pages can reference any story by id. Those stories will need to be
|
|
8
|
+
// asyncronously loaded; we use the state for this
|
|
9
|
+
const [storiesById, setStories] = useState({});
|
|
12
10
|
useEffect(() => {
|
|
13
11
|
Promise.all(storyIds.map(async storyId => {
|
|
14
12
|
// loadStory will be called every single time useStory is called
|
|
@@ -23,5 +21,14 @@ export function useStories(storyIds, context) {
|
|
|
23
21
|
}));
|
|
24
22
|
}));
|
|
25
23
|
});
|
|
26
|
-
return storyIds.map(storyId =>
|
|
24
|
+
return storyIds.map(storyId => {
|
|
25
|
+
if (storiesById[storyId]) return storiesById[storyId];
|
|
26
|
+
|
|
27
|
+
try {
|
|
28
|
+
// If we are allowed to load this story id synchonously, this will work
|
|
29
|
+
return context.storyById(storyId);
|
|
30
|
+
} catch (err) {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
});
|
|
27
34
|
}
|
package/dist/esm/preview.js
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
export const parameters = {
|
|
2
2
|
docs: {
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
renderer: async () => {
|
|
4
|
+
const {
|
|
5
|
+
DocsRenderer
|
|
6
|
+
} = await import('./blocks/DocsRenderer');
|
|
7
|
+
return new DocsRenderer();
|
|
8
|
+
}
|
|
5
9
|
}
|
|
6
10
|
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { AnyFramework } from '@storybook/csf';
|
|
2
|
+
import { DocsRenderFunction } from '@storybook/preview-web';
|
|
3
|
+
export declare class DocsRenderer<TFramework extends AnyFramework> {
|
|
4
|
+
render: DocsRenderFunction<TFramework>;
|
|
5
|
+
unmount: (element: HTMLElement) => void;
|
|
6
|
+
constructor();
|
|
7
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Preview } from '@storybook/preview-web';
|
|
2
|
+
import { ModuleExports, ModuleExport } from '@storybook/store';
|
|
3
|
+
import { AnyFramework, StoryId, ProjectAnnotations } from '@storybook/csf';
|
|
4
|
+
declare type StoryExport = ModuleExport;
|
|
5
|
+
declare type MetaExport = ModuleExports;
|
|
6
|
+
export declare class ExternalPreview<TFramework extends AnyFramework> extends Preview<TFramework> {
|
|
7
|
+
projectAnnotations: ProjectAnnotations;
|
|
8
|
+
private initialized;
|
|
9
|
+
private importPaths;
|
|
10
|
+
private titles;
|
|
11
|
+
storyIds: Map<any, string>;
|
|
12
|
+
private storyIndex;
|
|
13
|
+
private moduleExportsByImportPath;
|
|
14
|
+
constructor(projectAnnotations: ProjectAnnotations);
|
|
15
|
+
storyIdByModuleExport(storyExport: StoryExport, meta: MetaExport): string;
|
|
16
|
+
addStoryFromExports(storyExport: StoryExport, meta: MetaExport): Promise<void>;
|
|
17
|
+
storyById(storyId: StoryId): import("@storybook/store").Story<TFramework>;
|
|
18
|
+
}
|
|
19
|
+
export {};
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { FC } from 'react';
|
|
2
2
|
import { BaseAnnotations } from '@storybook/csf';
|
|
3
|
-
|
|
3
|
+
import type { ModuleExports } from '@storybook/store';
|
|
4
|
+
declare type MetaProps = BaseAnnotations & {
|
|
5
|
+
of?: ModuleExports;
|
|
6
|
+
};
|
|
4
7
|
/**
|
|
5
8
|
* This component is used to declare component metadata in docs
|
|
6
9
|
* and gets transformed into a default export underneath the hood.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { FunctionComponent, ReactNode, ElementType, ComponentProps } from 'react';
|
|
2
2
|
import { Story as PureStory } from '@storybook/components';
|
|
3
3
|
import { StoryId, StoryAnnotations, AnyFramework } from '@storybook/csf';
|
|
4
|
-
import type { Story as StoryType } from '@storybook/store';
|
|
4
|
+
import type { ModuleExport, ModuleExports, Story as StoryType } from '@storybook/store';
|
|
5
5
|
import { DocsContextProps } from './DocsContext';
|
|
6
6
|
export declare const storyBlockIdFromId: (storyId: string) => string;
|
|
7
7
|
declare type PureStoryProps = ComponentProps<typeof PureStory>;
|
|
@@ -15,6 +15,8 @@ declare type StoryDefProps = {
|
|
|
15
15
|
};
|
|
16
16
|
declare type StoryRefProps = {
|
|
17
17
|
id?: string;
|
|
18
|
+
of?: ModuleExport;
|
|
19
|
+
meta?: ModuleExports;
|
|
18
20
|
};
|
|
19
21
|
declare type StoryImportProps = {
|
|
20
22
|
name: string;
|
|
@@ -6,6 +6,8 @@ export * from './Description';
|
|
|
6
6
|
export * from './DocsContext';
|
|
7
7
|
export * from './DocsPage';
|
|
8
8
|
export * from './DocsContainer';
|
|
9
|
+
export * from './DocsRenderer';
|
|
10
|
+
export * from './ExternalDocsContainer';
|
|
9
11
|
export * from './DocsStory';
|
|
10
12
|
export * from './Heading';
|
|
11
13
|
export * from './Meta';
|
package/dist/types/preview.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
export declare const parameters: {
|
|
2
2
|
docs: {
|
|
3
|
-
|
|
4
|
-
getPage: () => Promise<import("react").FC<{}>>;
|
|
3
|
+
renderer: () => Promise<import("./blocks/DocsRenderer").DocsRenderer<import("@storybook/csf").AnyFramework>>;
|
|
5
4
|
};
|
|
6
5
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@storybook/addon-docs",
|
|
3
|
-
"version": "7.0.0-alpha.
|
|
3
|
+
"version": "7.0.0-alpha.7",
|
|
4
4
|
"description": "Document component usage and properties in Markdown",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"addon",
|
|
@@ -52,21 +52,21 @@
|
|
|
52
52
|
"@babel/preset-env": "^7.12.11",
|
|
53
53
|
"@jest/transform": "^26.6.2",
|
|
54
54
|
"@mdx-js/react": "^1.6.22",
|
|
55
|
-
"@storybook/addons": "7.0.0-alpha.
|
|
56
|
-
"@storybook/api": "7.0.0-alpha.
|
|
57
|
-
"@storybook/components": "7.0.0-alpha.
|
|
58
|
-
"@storybook/core-common": "7.0.0-alpha.
|
|
59
|
-
"@storybook/core-events": "7.0.0-alpha.
|
|
55
|
+
"@storybook/addons": "7.0.0-alpha.7",
|
|
56
|
+
"@storybook/api": "7.0.0-alpha.7",
|
|
57
|
+
"@storybook/components": "7.0.0-alpha.7",
|
|
58
|
+
"@storybook/core-common": "7.0.0-alpha.7",
|
|
59
|
+
"@storybook/core-events": "7.0.0-alpha.7",
|
|
60
60
|
"@storybook/csf": "0.0.2--canary.4566f4d.1",
|
|
61
|
-
"@storybook/csf-tools": "7.0.0-alpha.
|
|
62
|
-
"@storybook/docs-tools": "7.0.0-alpha.
|
|
61
|
+
"@storybook/csf-tools": "7.0.0-alpha.7",
|
|
62
|
+
"@storybook/docs-tools": "7.0.0-alpha.7",
|
|
63
63
|
"@storybook/mdx1-csf": "^0.0.1",
|
|
64
|
-
"@storybook/node-logger": "7.0.0-alpha.
|
|
65
|
-
"@storybook/postinstall": "7.0.0-alpha.
|
|
66
|
-
"@storybook/preview-web": "7.0.0-alpha.
|
|
67
|
-
"@storybook/source-loader": "7.0.0-alpha.
|
|
68
|
-
"@storybook/store": "7.0.0-alpha.
|
|
69
|
-
"@storybook/theming": "7.0.0-alpha.
|
|
64
|
+
"@storybook/node-logger": "7.0.0-alpha.7",
|
|
65
|
+
"@storybook/postinstall": "7.0.0-alpha.7",
|
|
66
|
+
"@storybook/preview-web": "7.0.0-alpha.7",
|
|
67
|
+
"@storybook/source-loader": "7.0.0-alpha.7",
|
|
68
|
+
"@storybook/store": "7.0.0-alpha.7",
|
|
69
|
+
"@storybook/theming": "7.0.0-alpha.7",
|
|
70
70
|
"babel-loader": "^8.2.5",
|
|
71
71
|
"core-js": "^3.8.2",
|
|
72
72
|
"fast-deep-equal": "^3.1.3",
|
|
@@ -101,7 +101,7 @@
|
|
|
101
101
|
"publishConfig": {
|
|
102
102
|
"access": "public"
|
|
103
103
|
},
|
|
104
|
-
"gitHead": "
|
|
104
|
+
"gitHead": "d334cabd251cd0ed8b845a87707dc84f007d4074",
|
|
105
105
|
"storybook": {
|
|
106
106
|
"displayName": "Docs",
|
|
107
107
|
"icon": "https://user-images.githubusercontent.com/263385/101991672-48355c80-3c7c-11eb-82d9-95fa12438f64.png",
|