forked from Foxy/foxy-elements
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathgetStory.ts
94 lines (85 loc) · 3.26 KB
/
getStory.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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
import { TemplateResult, html } from 'lit-html';
import { Args } from './Args';
import { Summary } from './Summary';
import { getStoryArgs } from './getStoryArgs';
import { getStoryCode } from './getStoryCode';
import { unsafeHTML } from 'lit-html/directives/unsafe-html';
type Story = ((args: Args) => TemplateResult) & { args: Args };
type Params = Summary & { code?: boolean };
type TemplateArgs = {
readonlyControls: string;
disabledControls: string;
hiddenControls: string;
storyArgs: Args;
readonly: boolean;
disabled: boolean;
hidden: boolean;
parent: string;
href: string;
base: string;
lang: string;
code: TemplateResult;
html: typeof html;
unsafeHTML: typeof unsafeHTML;
};
export function getStory(params: Params): Story {
const { sections = [], buttons = [], inputs = [] } = params.configurable ?? {};
const interactiveControls = [...buttons, ...inputs];
const allControls = [...sections, ...buttons, ...inputs];
const localName = params.localName;
const isNarrow = localName.endsWith('-form') || localName.endsWith('-card');
const getTemplate = new Function(
'args',
`return args.html\`
<div class="foxy-story ${isNarrow ? 'foxy-story--narrow' : ''}">
<${params.localName}
${interactiveControls.length > 0 ? 'disabledcontrols="${args.disabledControls}"' : ''}
${inputs.length > 0 ? 'readonlycontrols="${args.readonlyControls}"' : ''}
${allControls.length > 0 ? 'hiddencontrols="${args.hiddenControls}"' : ''}
${params.parent ? 'parent=${args.parent}' : ''}
${params.href ? 'href=${args.href}' : ''}
${params.base ? 'base=${args.base}' : ''}
${params.translatable ? 'lang=${args.lang}' : ''}
${allControls.length > 0 ? 'mode="development"' : ''}
?disabled=\${args.disabled}
?readonly=\${args.readonly}
?hidden=\${args.hidden}
class="foxy-story__preview"
>
${allControls
.reduce<string[]>((slots, name) => {
if (name.endsWith('default')) return [...slots, name];
return [...slots, `${name}:before`, `${name}:after`];
}, [])
.reduce<string>((innerHTML, slot) => {
const content = `args.storyArgs["${slot}"]`;
const template = `args.html\`<template slot="${slot}"><div>\${args.unsafeHTML(${content})}</div></template>\``;
return `${innerHTML}\${${content} ? ${template} : ''}`;
}, '')}
</${params.localName}>
${params.code ? '<pre>${args.code}</pre>' : ''}
</div>
\`
`
) as (args: TemplateArgs) => TemplateResult;
const Story = function (args: Args) {
return getTemplate({
readonlyControls: args.readonlyControls?.join(' ') ?? '',
disabledControls: args.disabledControls?.join(' ') ?? '',
hiddenControls: args.hiddenControls?.join(' ') ?? '',
storyArgs: args,
readonly: !!args.readonly,
disabled: !!args.disabled,
hidden: !!args.hidden,
parent: args.parent ?? '',
href: args.href ?? '',
base: args.base ?? '',
lang: args.lang ?? '',
code: params.code ? getStoryCode(params, args) : html``,
html,
unsafeHTML,
});
};
Story.args = getStoryArgs(params);
return Story;
}