@zywave/customelement-manifest-element 1.0.2 → 1.2.0

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/README.md ADDED
@@ -0,0 +1,23 @@
1
+ @zywave/customelement-manifest-element
2
+
3
+ The `<customelement-manifest-element>` custom element is built to render a standards-compliant [custom element manifest](https://github.com/webcomponents/custom-elements-manifest/) in a user friendly way. This element is used in https://zui.zywave.com to render our own web component documentation.
4
+
5
+ ## Example
6
+
7
+ ```html
8
+ <customelement-manifest-element src="./custom-elements.json"></customelement-manifest-element>
9
+ ```
10
+
11
+ ## API
12
+ Read the [api docs](./docs/api.md) for more information.
13
+
14
+ ## Experimental
15
+
16
+ This component uses some experimental features that are only in the latest versions of Chrome or Firefox.
17
+
18
+ To use this in other browsers that support native ES modules, you can use [es-module-shims](https://github.com/guybedford/es-module-shims).
19
+
20
+ We use:
21
+
22
+ - [import assertions](https://github.com/tc39/proposal-import-assertions) to load CSS
23
+ - [CSS Houdini Properties and Values API](https://developer.mozilla.org/en-US/docs/Web/API/CSS_Properties_and_Values_API)
@@ -21,7 +21,7 @@
21
21
  }
22
22
 
23
23
  section + section {
24
- margin-top: 40px;
24
+ margin-top: 2.5rem;
25
25
  }
26
26
 
27
27
  h1 {
@@ -48,7 +48,7 @@ table span {
48
48
  }
49
49
  table thead th,
50
50
  table tbody td {
51
- padding: 15px;
51
+ padding: 0.9375rem;
52
52
  }
53
53
  table thead th:first-child,
54
54
  table tbody td:first-child {
@@ -68,7 +68,8 @@ table tbody tr:last-child > td {
68
68
  border-bottom: 0;
69
69
  }
70
70
  table tbody td {
71
- padding: 15px;
71
+ vertical-align: top;
72
+ padding: 0.9375rem;
72
73
  border-bottom: 1px solid hsla(var(--schema-primary-color-h), var(--schema-primary-color-s), var(--schema-primary-color-l), 0.1);
73
74
  }
74
75
  table tbody td:first-child {
@@ -81,13 +82,25 @@ table tbody td.name, table tbody td.type, table tbody td.default {
81
82
  width: 16.667%;
82
83
  }
83
84
  table tbody td.name span, table tbody td.type span, table tbody td.default span {
84
- padding: 5px 10px;
85
+ padding: 0.3125rem 0.625rem;
85
86
  }
86
- table tbody td.name span, table tbody td.type span {
87
+ table tbody td.name span, table tbody td.type span, table tbody td.signature span {
87
88
  font-family: monospace;
88
89
  background-color: hsla(var(--schema-primary-color-h), var(--schema-primary-color-s), var(--schema-primary-color-l), 0.1);
89
90
  color: var(--schema-primary-color);
90
91
  }
92
+ table tbody td.signature span {
93
+ padding: 0.3125rem 0.625rem;
94
+ }
95
+ table tbody td.signature .expanded-details {
96
+ margin-left: 1.5625rem;
97
+ }
98
+ table tbody td.signature .param-container {
99
+ margin-top: 0.3125rem;
100
+ }
101
+ table tbody td.signature .param-description {
102
+ margin-left: 0.9375rem;
103
+ }
91
104
  table tbody td.summary {
92
105
  width: 50%;
93
106
  }
@@ -111,7 +124,7 @@ a:hover {
111
124
  }
112
125
  a:focus {
113
126
  outline: 1px solid var(--schema-accent-color);
114
- outline-offset: 4px;
127
+ outline-offset: 0.25rem;
115
128
  text-decoration: none;
116
129
  }
117
130
  a:active {
@@ -126,11 +139,11 @@ code {
126
139
 
127
140
  select {
128
141
  display: inline-block;
129
- height: 36px;
142
+ height: 2.25rem;
130
143
  padding: 0 1em;
131
- padding-right: 35px;
144
+ padding-right: 2.1875rem;
132
145
  border: 1px solid #cbcbd2;
133
- border-radius: 4px;
146
+ border-radius: 0.25rem;
134
147
  outline: none;
135
148
  font: inherit;
136
149
  cursor: pointer;
@@ -33,7 +33,7 @@ export declare class CustomElementManifestElement extends LitElement {
33
33
  */
34
34
  get initialHeaderLevel(): 1 | 2 | 3;
35
35
  set initialHeaderLevel(value: 1 | 2 | 3);
36
- static get styles(): any[];
36
+ static get styles(): CSSStyleSheet[];
37
37
  constructor();
38
38
  firstUpdated(changedProps: PropertyValues): void;
39
39
  update(changedProps: PropertyValues): void;
@@ -3,9 +3,9 @@ import { __decorate } from "tslib";
3
3
  /* eslint-disable lit/binding-positions */
4
4
  import { LitElement, nothing } from "lit";
5
5
  import { customElement, property } from "lit/decorators.js";
6
- // @ts-ignore
7
- import css from "./customelement-manifest-element.css" assert { type: 'css' };
6
+ import css from "./customelement-manifest-element.css" assert { type: 'css' }; // eslint-disable-line
8
7
  import { html, unsafeStatic } from "lit/static-html.js";
8
+ import { findDefinition, getElementNames } from "./manifest-helpers";
9
9
  function publicMembersFilter(classMember) {
10
10
  return ((!classMember.privacy || classMember.privacy === "public") &&
11
11
  !classMember.name.startsWith("_") &&
@@ -33,7 +33,7 @@ function buildTable(items, columns) {
33
33
  <tbody> ${rows} </tbody>
34
34
  </table>`;
35
35
  }
36
- function renderDescripton(str) {
36
+ function renderDescription(str) {
37
37
  if (!str) {
38
38
  return str;
39
39
  }
@@ -47,6 +47,37 @@ function renderDescripton(str) {
47
47
  }
48
48
  return result;
49
49
  }
50
+ function renderMethodSignature(obj) {
51
+ const methodReturn = () => {
52
+ const returnType = obj.return?.type?.text;
53
+ if (returnType?.length === 0) {
54
+ return 'void';
55
+ }
56
+ return returnType ?? 'unknown';
57
+ };
58
+ if (obj.parameters) {
59
+ const methodSignatureSummary = obj.parameters?.map(param => param.name + (param.optional ? '?' : '')).join(', ');
60
+ const methodParametersDetailed = obj.parameters?.map(param => {
61
+ const argumentType = `: ${param?.type?.text}${param.default ? ` = ${param.default}` : ''}`;
62
+ const argumentHtml = param.name + (param.optional ? '?' : '') + argumentType;
63
+ return html `
64
+ <div class="param-container">
65
+ <div class="param">${argumentHtml}</div>
66
+ ${param.description
67
+ ? html `<div class="param-description">${renderDescription(param.description)}</div>`
68
+ : nothing}
69
+ </div>
70
+ `;
71
+ });
72
+ return html `<details>
73
+ <summary>${obj.name}(${methodSignatureSummary}): ${methodReturn()}</summary>
74
+ <div class="expanded-details">${methodParametersDetailed}</div>
75
+ </details>`;
76
+ }
77
+ else {
78
+ return html `${obj.name}(): ${methodReturn()}`;
79
+ }
80
+ }
50
81
  function prettify(str) {
51
82
  let regexMatch;
52
83
  const linkRegex = /^https?:\/\//;
@@ -114,34 +145,25 @@ let CustomElementManifestElement = class CustomElementManifestElement extends Li
114
145
  #failedLoad;
115
146
  // eslint-disable-next-line no-undef
116
147
  #internals;
117
- get #customElementDefinitions() {
118
- if (this.#schema) {
119
- const customElementExports = (this.#schema.modules
120
- .flatMap((x) => x.exports)
121
- .filter((x) => x?.kind === "custom-element-definition") ?? []);
122
- const arr = [];
123
- for (const ce of customElementExports) {
124
- if (this.elementNames && !this.elementNames.includes(ce.name)) {
125
- continue;
126
- }
127
- const containingModule = this.#schema.modules.find((x) => x.path === ce.declaration.module);
128
- if (containingModule) {
129
- const classDef = containingModule.declarations?.find((x) => x.kind === "class");
130
- if (classDef) {
131
- arr.push({
132
- name: ce.name,
133
- declaration: classDef,
134
- });
135
- }
136
- }
137
- }
138
- return arr.sort((a, b) => a.name.localeCompare(b.name));
148
+ get #elementNames() {
149
+ if (!this.#schema) {
150
+ return [];
139
151
  }
140
- return [];
152
+ let elementNames = getElementNames(this.#schema);
153
+ if (this.elementNames) {
154
+ elementNames = elementNames.filter((x) => this.elementNames.includes(x));
155
+ }
156
+ return elementNames.sort((a, b) => a.localeCompare(b));
141
157
  }
142
158
  get #activeElement() {
143
- return (this.#customElementDefinitions.find((x) => x.name === this.#activeElementName) ??
144
- this.#customElementDefinitions[0]);
159
+ if (!this.#schema) {
160
+ return undefined;
161
+ }
162
+ this.#activeElementName ??= this.#elementNames[0];
163
+ if (!this.#activeElementName) {
164
+ return undefined;
165
+ }
166
+ return findDefinition(this.#schema, this.#activeElementName);
145
167
  }
146
168
  constructor() {
147
169
  super();
@@ -170,20 +192,20 @@ let CustomElementManifestElement = class CustomElementManifestElement extends Li
170
192
  }
171
193
  return this.#activeElement
172
194
  ? html `<article>
173
- <div class="header-row"><${getHeaderTag(this.initialHeaderLevel)}>${this.#activeElement.name}</${getHeaderTag(this.initialHeaderLevel)}>${this.#renderElementChooser()}</div>
174
- <div>${renderDescripton(this.#activeElement.declaration.description)}</div>
195
+ <div class="header-row"><${getHeaderTag(this.initialHeaderLevel)}>${this.#activeElementName}</${getHeaderTag(this.initialHeaderLevel)}>${this.#renderElementChooser()}</div>
196
+ <div>${renderDescription(this.#activeElement.description)}</div>
175
197
  ${this.#renderAttributes()} ${this.#renderProperties()} ${this.#renderCssProperties()}
176
198
  ${this.#renderCssShadowParts()} ${this.#renderEvents()} ${this.#renderMethods()} ${this.#renderSlots()} </article
177
199
  >`
178
200
  : nothing;
179
201
  }
180
202
  #renderElementChooser() {
181
- if (this.#customElementDefinitions.length > 1) {
182
- let selectedElement = this.#customElementDefinitions.find((x) => x.name === this.#activeElementName)?.name;
203
+ if (this.#elementNames.length > 1) {
204
+ let selectedElement = this.#elementNames.find((x) => x === this.#activeElementName);
183
205
  if (!selectedElement) {
184
- selectedElement = this.#customElementDefinitions[0]?.name;
206
+ selectedElement = this.#elementNames[0];
185
207
  }
186
- const options = this.#customElementDefinitions.map((x) => html `<option ?selected="${x.name === selectedElement}" value="${x.name}">${x.name}</option>`);
208
+ const options = this.#elementNames.map((x) => html `<option ?selected="${x === selectedElement}" value="${x}">${x}</option>`);
187
209
  return html `<select part="chooser" @change="${this.#onElementChange}"
188
210
  >${options}</select
189
211
  >`;
@@ -191,7 +213,7 @@ let CustomElementManifestElement = class CustomElementManifestElement extends Li
191
213
  return nothing;
192
214
  }
193
215
  #renderAttributes() {
194
- const attributes = this.#activeElement?.declaration.attributes;
216
+ const attributes = this.#activeElement?.attributes;
195
217
  if (attributes?.length) {
196
218
  const table = buildTable(attributes, [
197
219
  {
@@ -205,7 +227,7 @@ let CustomElementManifestElement = class CustomElementManifestElement extends Li
205
227
  header: "Description",
206
228
  type: "summary",
207
229
  valueAccessor(item) {
208
- return renderDescripton(item.description);
230
+ return renderDescription(item.description);
209
231
  },
210
232
  },
211
233
  {
@@ -235,7 +257,7 @@ let CustomElementManifestElement = class CustomElementManifestElement extends Li
235
257
  }
236
258
  }
237
259
  #renderProperties() {
238
- const props = this.#activeElement?.declaration.members?.filter((x) => x.kind === "field" && publicMembersFilter(x));
260
+ const props = this.#activeElement?.members?.filter((x) => x.kind === "field" && publicMembersFilter(x));
239
261
  if (props?.length) {
240
262
  const table = buildTable(props, [
241
263
  {
@@ -248,7 +270,7 @@ let CustomElementManifestElement = class CustomElementManifestElement extends Li
248
270
  {
249
271
  header: "Description",
250
272
  valueAccessor(item) {
251
- return renderDescripton(item.description);
273
+ return renderDescription(item.description);
252
274
  },
253
275
  type: "summary",
254
276
  },
@@ -277,7 +299,7 @@ let CustomElementManifestElement = class CustomElementManifestElement extends Li
277
299
  return nothing;
278
300
  }
279
301
  #renderCssProperties() {
280
- const cssProps = this.#activeElement?.declaration.cssProperties;
302
+ const cssProps = this.#activeElement?.cssProperties;
281
303
  if (cssProps?.length) {
282
304
  const table = buildTable(cssProps, [
283
305
  {
@@ -290,7 +312,7 @@ let CustomElementManifestElement = class CustomElementManifestElement extends Li
290
312
  {
291
313
  header: "Description",
292
314
  valueAccessor(item) {
293
- return renderDescripton(item.description);
315
+ return renderDescription(item.description);
294
316
  },
295
317
  type: "summary",
296
318
  },
@@ -312,7 +334,7 @@ let CustomElementManifestElement = class CustomElementManifestElement extends Li
312
334
  return nothing;
313
335
  }
314
336
  #renderCssShadowParts() {
315
- const cssParts = this.#activeElement?.declaration.cssParts;
337
+ const cssParts = this.#activeElement?.cssParts;
316
338
  if (cssParts?.length) {
317
339
  const table = buildTable(cssParts, [
318
340
  {
@@ -325,7 +347,7 @@ let CustomElementManifestElement = class CustomElementManifestElement extends Li
325
347
  {
326
348
  header: "Description",
327
349
  valueAccessor(item) {
328
- return renderDescripton(item.description);
350
+ return renderDescription(item.description);
329
351
  },
330
352
  type: "summary",
331
353
  },
@@ -340,7 +362,7 @@ let CustomElementManifestElement = class CustomElementManifestElement extends Li
340
362
  return nothing;
341
363
  }
342
364
  #renderEvents() {
343
- const events = this.#activeElement?.declaration.events;
365
+ const events = this.#activeElement?.events;
344
366
  if (events?.length) {
345
367
  const table = buildTable(events, [
346
368
  {
@@ -353,14 +375,14 @@ let CustomElementManifestElement = class CustomElementManifestElement extends Li
353
375
  {
354
376
  header: "Description",
355
377
  valueAccessor(item) {
356
- return renderDescripton(item.description);
378
+ return renderDescription(item.description);
357
379
  },
358
380
  type: "summary",
359
381
  },
360
382
  {
361
383
  header: "Type",
362
384
  valueAccessor(item) {
363
- return item.type.text;
385
+ return item.type?.text;
364
386
  },
365
387
  type: "type",
366
388
  },
@@ -375,7 +397,7 @@ let CustomElementManifestElement = class CustomElementManifestElement extends Li
375
397
  return nothing;
376
398
  }
377
399
  #renderMethods() {
378
- const methods = this.#activeElement?.declaration.members?.filter((x) => x.kind === "method" && publicMembersFilter(x));
400
+ const methods = this.#activeElement?.members?.filter((x) => x.kind === "method" && publicMembersFilter(x));
379
401
  if (methods?.length) {
380
402
  const table = buildTable(methods, [
381
403
  {
@@ -388,10 +410,17 @@ let CustomElementManifestElement = class CustomElementManifestElement extends Li
388
410
  {
389
411
  header: "Description",
390
412
  valueAccessor(item) {
391
- return renderDescripton(item.description);
413
+ return renderDescription(item.description);
392
414
  },
393
415
  type: "summary",
394
416
  },
417
+ {
418
+ header: "Signature",
419
+ valueAccessor(item) {
420
+ return renderMethodSignature(item);
421
+ },
422
+ type: "signature",
423
+ },
395
424
  ]);
396
425
  return html `
397
426
  <section part="methods">
@@ -403,7 +432,7 @@ let CustomElementManifestElement = class CustomElementManifestElement extends Li
403
432
  return nothing;
404
433
  }
405
434
  #renderSlots() {
406
- const slots = this.#activeElement?.declaration.slots;
435
+ const slots = this.#activeElement?.slots;
407
436
  if (slots?.length) {
408
437
  const table = buildTable(slots, [
409
438
  {
@@ -420,7 +449,7 @@ let CustomElementManifestElement = class CustomElementManifestElement extends Li
420
449
  {
421
450
  header: "Description",
422
451
  valueAccessor(item) {
423
- return renderDescripton(item.description);
452
+ return renderDescription(item.description);
424
453
  },
425
454
  type: "summary",
426
455
  },
@@ -446,7 +475,12 @@ let CustomElementManifestElement = class CustomElementManifestElement extends Li
446
475
  if (response.ok) {
447
476
  const data = await response.json();
448
477
  this.#schema = data;
449
- this.#activeElementName = this.initialElementName ?? this.#customElementDefinitions[0]?.name;
478
+ if (this.initialElementName && this.#elementNames.includes(this.initialElementName)) {
479
+ this.#activeElementName = this.initialElementName;
480
+ }
481
+ else {
482
+ this.#activeElementName = this.#elementNames[0];
483
+ }
450
484
  this.requestUpdate();
451
485
  }
452
486
  else {
@@ -0,0 +1,4 @@
1
+ import type { Package, CustomElementDeclaration, CustomElement } from "custom-elements-manifest/schema";
2
+ export declare function getElementNames(schema: Package): string[];
3
+ export declare function findDefinition(schema: Package, tagName: string): (CustomElementDeclaration & CustomElement) | undefined;
4
+ //# sourceMappingURL=manifest-helpers.d.ts.map
@@ -0,0 +1,20 @@
1
+ function getElementExports(schema) {
2
+ return schema.modules.flatMap((x) => x.exports).filter((x) => x?.kind === "custom-element-definition");
3
+ }
4
+ export function getElementNames(schema) {
5
+ return getElementExports(schema)
6
+ .map((x) => x?.name)
7
+ .filter((x) => x);
8
+ }
9
+ export function findDefinition(schema, tagName) {
10
+ const elementExport = getElementExports(schema).find((x) => x?.name === tagName);
11
+ if (!elementExport) {
12
+ return undefined;
13
+ }
14
+ const definingModule = schema.modules.find((x) => x.path === elementExport.declaration.module);
15
+ if (!definingModule) {
16
+ return undefined;
17
+ }
18
+ const definition = definingModule.declarations?.find((x) => x.kind === "class" && x.name === elementExport.declaration.name);
19
+ return definition;
20
+ }
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@zywave/customelement-manifest-element",
3
- "version": "1.0.2",
3
+ "version": "1.2.0",
4
4
  "main": "index.js",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",
7
7
  "dependencies": {
8
- "lit": "^2.0.0-rc.2"
8
+ "lit": "^2.1.0"
9
9
  },
10
10
  "publishConfig": {
11
11
  "access": "public"
@@ -13,39 +13,47 @@
13
13
  "files": [
14
14
  "*.js",
15
15
  "*.css",
16
- "*.d.ts"
16
+ "*.d.ts",
17
+ "README.md",
18
+ "custom-elements.json"
17
19
  ],
20
+ "resolutions": {
21
+ "typescript": "4.5.0-beta"
22
+ },
18
23
  "devDependencies": {
19
- "@custom-elements-manifest/analyzer": "^0.3.2",
24
+ "@custom-elements-manifest/analyzer": "^0.5.5",
25
+ "@custom-elements-manifest/to-markdown": "^0.0.13",
20
26
  "@esm-bundle/chai": "^4.3.4",
21
27
  "@semantic-release/gitlab": "^6.2.1",
22
28
  "@semantic-release/gitlab-config": "^8.0.0",
23
- "@typescript-eslint/eslint-plugin": "^4.28.0",
24
- "@typescript-eslint/parser": "^4.28.0",
25
- "@web/test-runner": "^0.13.12",
26
- "@web/test-runner-junit-reporter": "^0.4.4",
29
+ "@typescript-eslint/eslint-plugin": "^4.33.0",
30
+ "@typescript-eslint/parser": "^4.33.0",
31
+ "@web/test-runner": "^0.13.18",
32
+ "@web/test-runner-junit-reporter": "^0.4.7",
27
33
  "@web/test-runner-playwright": "^0.8.6",
34
+ "@zywave/zui-sass-scripts": "^4.0.14",
28
35
  "custom-elements-manifest": "^1.0.0",
29
36
  "es-dev-server": "^2.1.0",
30
- "eslint": "^7.29.0",
37
+ "eslint": "^7.30.0",
31
38
  "eslint-config-prettier": "^8.3.0",
32
- "eslint-plugin-lit": "^1.5.1",
33
- "eslint-plugin-prettier": "^3.4.0",
34
- "mocha": "^9.0.1",
35
- "playwright": "^1.12.2",
36
- "prettier": "^2.3.1",
37
- "sass": "^1.35.1",
38
- "semantic-release": "^17.4.4",
39
+ "eslint-plugin-lit": "^1.6.0",
40
+ "eslint-plugin-prettier": "^4.0.0",
41
+ "mocha": "^9.1.2",
42
+ "playwright": "^1.15.2",
43
+ "prettier": "^2.4.1",
44
+ "sass": "^1.42.1",
45
+ "semantic-release": "^18.0.0",
39
46
  "sinon": "^11.1.1",
40
- "typescript": "^4.3.4"
47
+ "typescript": "^4.5.0-beta"
41
48
  },
42
49
  "scripts": {
43
50
  "analyze": "cem analyze --globs \"src/customelement-manifest-element.ts\" --litelement",
44
- "build": "yarn run build:ts && yarn run build:scss",
45
- "build:ts": "tsc -p tsconfig.json && node scripts/assertion-postprocessor.js",
51
+ "build": "yarn run build:scss && yarn run build:ts",
52
+ "build:ts": "tsc -p tsconfig.json",
46
53
  "build:scss": "sass src/customelement-manifest-element.scss customelement-manifest-element.css",
47
54
  "clean": "git clean -dfX",
48
55
  "demo": "es-dev-server --app-index demo/index.html --node-resolve --watch --open",
56
+ "docs": "yarn run analyze && node scripts/docs.js",
49
57
  "lint": "eslint \"{src,test}/**/*.ts\"",
50
58
  "test": "yarn run test:build && yarn run test:run",
51
59
  "test:build": "tsc --build tsconfig.test.json && cd test/schemas && cem analyze --globs \"element.js\" && cd ../..",