forked from storybookjs/storybook
/
render.ts
52 lines (47 loc) 路 1.76 KB
/
render.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
import { document, Node } from 'global';
import dedent from 'ts-dedent';
import { render, TemplateResult } from 'lit-html';
import { simulatePageLoad, simulateDOMContentLoaded } from '@storybook/client-api';
import { RenderContext } from './types';
const rootElement = document.getElementById('root');
export default function renderMain({
storyFn,
kind,
name,
showMain,
showError,
forceRender,
}: RenderContext) {
const element = storyFn();
showMain();
if (element instanceof TemplateResult) {
// `render` stores the TemplateInstance in the Node and tries to update based on that.
// Since we reuse `rootElement` for all stories, remove the stored instance first.
// But forceRender means that it's the same story, so we want too keep the state in that case.
if (!forceRender || !rootElement.querySelector('[id="root-inner"]')) {
rootElement.innerHTML = '<div id="root-inner"></div>';
}
const renderTo = rootElement.querySelector('[id="root-inner"]');
render(element, renderTo);
simulatePageLoad(rootElement);
} else if (typeof element === 'string') {
rootElement.innerHTML = element;
simulatePageLoad(rootElement);
} else if (element instanceof Node) {
// Don't re-mount the element if it didn't change and neither did the story
if (rootElement.firstChild === element && forceRender === true) {
return;
}
rootElement.innerHTML = '';
rootElement.appendChild(element);
simulateDOMContentLoaded();
} else {
showError({
title: `Expecting an HTML snippet or DOM node from the story: "${name}" of "${kind}".`,
description: dedent`
Did you forget to return the HTML snippet from the story?
Use "() => <your snippet or node>" or when defining the story.
`,
});
}
}