-
Notifications
You must be signed in to change notification settings - Fork 52
/
Copy pathrender-slots.ts
48 lines (40 loc) · 1.68 KB
/
render-slots.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
import { Args } from '@storybook/web-components';
import { nothing, TemplateResult } from 'lit';
import { unsafeHTML } from 'lit/directives/unsafe-html.js';
/**
* Render a list of slots, filtering out any null or undefined slots to prevent empty lines.
* Accepts an array of TemplateResults or an Args object. If an Args object is provided, it will render any properties that end with 'slot'.
*/
// TODO: add a way to control the new lines. Eg exclude newlines: before, after, between as an array
function renderSlots(args: Args): TemplateResult[] | typeof nothing;
function renderSlots(param: TemplateResult[] | Args) {
let slots: TemplateResult[] = [];
// if param is array, set slots to param
// if param is object, set slots to values of properties that end with 'slot'
if (Array.isArray(param)) {
slots = param;
} else {
const slotKeys = Object.keys(param).filter(
key => key === 'slot' || key.endsWith(' slot'),
);
slots = slotKeys.map(key => param[key]);
}
// Filter out any null or undefined slots to avoid rendering empty content
const validSlots = slots.filter(Boolean);
// If there are no valid slots, return an empty html result
if (validSlots.length === 0) {
return nothing;
}
// Join slots with consistent formatting; no extra line breaks between them
const spacing = ' ';
const stringSlots = validSlots.map(slot =>
typeof slot === 'string' ? slot : slot.strings?.[0] ?? '',
);
const stringSlotsJoined = stringSlots.join('\n');
const stringSlotsJoinedWithSpacing = stringSlotsJoined
.split('\n')
.map(line => spacing + line)
.join('\n');
return unsafeHTML(stringSlotsJoinedWithSpacing);
}
export { renderSlots };