-
Notifications
You must be signed in to change notification settings - Fork 123
/
Copy pathapi.11ty.cjs
132 lines (128 loc) · 3.14 KB
/
api.11ty.cjs
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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/**
* This page generates its content from the custom-element.json file as read by
* the _data/api.11tydata.js script.
*/
module.exports = class Docs {
data() {
return {
layout: 'page.11ty.cjs',
title: '<my-element> ⌲ Docs',
};
}
render(data) {
const manifest = data.api['11tydata'].customElements;
const elements = manifest.modules.reduce(
(els, module) =>
els.concat(
module.declarations?.filter((dec) => dec.customElement) ?? []
),
[]
);
return `
<h1>API</h1>
${elements
.map(
(element) => `
<h2><${element.tagName}></h2>
<div>
${element.description}
</div>
${renderTable(
'Attributes',
['name', 'description', 'type.text', 'default'],
element.attributes
)}
${renderTable(
'Properties',
['name', 'attribute', 'description', 'type.text', 'default'],
element.members.filter((m) => m.kind === 'field')
)}
${renderTable(
'Methods',
['name', 'parameters', 'description', 'return.type.text'],
element.members
.filter(
(m) =>
m.kind === 'method' &&
m.privacy !== 'private' &&
m.name[0] !== '_'
)
.map((m) => ({
...m,
parameters: renderTable(
'',
['name', 'description', 'type.text'],
m.parameters
),
}))
)}
${renderTable('Events', ['name', 'description'], element.events)}
${renderTable(
'Slots',
[['name', '(default)'], 'description'],
element.slots
)}
${renderTable(
'CSS Shadow Parts',
['name', 'description'],
element.cssParts
)}
${renderTable(
'CSS Custom Properties',
['name', 'description'],
element.cssProperties
)}
`
)
.join('')}
`;
}
};
/**
* Reads a (possibly deep) path off of an object.
*/
const get = (obj, path) => {
let fallback = '';
if (Array.isArray(path)) {
[path, fallback] = path;
}
const parts = path.split('.');
while (obj && parts.length) {
obj = obj[parts.shift()];
}
return obj == null || obj === '' ? fallback : obj;
};
/**
* Renders a table of data, plucking the given properties from each item in
* `data`.
*/
const renderTable = (name, properties, data) => {
if (data === undefined || data.length === 0) {
return '';
}
return `
${name ? `<h3>${name}</h3>` : ''}
<table>
<tr>
${properties
.map(
(p) =>
`<th>${capitalize(
(Array.isArray(p) ? p[0] : p).split('.')[0]
)}</th>`
)
.join('')}
</tr>
${data
.map(
(i) => `
<tr>
${properties.map((p) => `<td>${get(i, p)}</td>`).join('')}
</tr>
`
)
.join('')}
</table>
`;
};
const capitalize = (s) => s[0].toUpperCase() + s.substring(1);