Skip to content

Commit 24ada26

Browse files
authored
refactor: use vanilla custom elements for tabs (#136)
1 parent a4c4969 commit 24ada26

File tree

10 files changed

+245
-273
lines changed

10 files changed

+245
-273
lines changed

.changeset/fifty-toes-confess.md

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
'@api-viewer/common': patch
3+
'@api-viewer/demo': patch
4+
'@api-viewer/docs': patch
5+
'@api-viewer/tabs': patch
6+
'api-viewer-element': patch
7+
---
8+
9+
Use vanilla custom elements for tabs

.eslintrc.json

+3-1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
"import/no-unresolved": "off",
2525
"import/prefer-default-export": "off",
2626
"lit/no-template-map": "off",
27+
"lit/prefer-static-styles": "off",
2728
"class-methods-use-this": [
2829
"error",
2930
{
@@ -33,7 +34,8 @@
3334
"no-console": ["error", { "allow": ["error"] }],
3435
"no-param-reassign": "off",
3536
"no-plusplus": "off",
36-
"no-underscore-dangle": "off"
37+
"no-underscore-dangle": "off",
38+
"prefer-destructuring": "off"
3739
},
3840
"overrides": [
3941
{

packages/api-common/src/utils.ts

+9
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,12 @@ export const unquote = (value?: string): string | undefined =>
22
typeof value === 'string' && value.startsWith("'") && value.endsWith("'")
33
? value.slice(1, value.length - 1)
44
: value;
5+
6+
export function html(strings: TemplateStringsArray, ...values: string[]) {
7+
const template = document.createElement('template');
8+
template.innerHTML = values.reduce(
9+
(acc, v, idx) => acc + v + strings[idx + 1],
10+
strings[0]
11+
);
12+
return template;
13+
}

packages/api-demo/src/layout.ts

+16-21
Original file line numberDiff line numberDiff line change
@@ -102,13 +102,14 @@ class ApiDemoLayout extends LitElement {
102102
const slots = this.slotsController?.data || [];
103103
const cssProps = this.stylesController?.data || [];
104104
const hideSlots = noSlots || hasTemplate(id, tag, TemplateTypes.SLOT);
105+
const hideKnobs = noProps && noCustomKnobs;
105106

106107
return html`
107108
<div part="demo-output" @rendered=${this.onRendered}>
108109
${renderer({ id, tag, knobs: this.knobs })}
109110
</div>
110111
<api-viewer-tabs part="demo-tabs">
111-
<api-viewer-tab heading="Source" slot="tab" part="tab"></api-viewer-tab>
112+
<api-viewer-tab slot="tab" part="tab">Source</api-viewer-tab>
112113
<api-viewer-panel slot="panel" part="tab-panel">
113114
<button @click=${this._onCopyClick} part="button">
114115
${this.copyBtnText}
@@ -117,15 +118,16 @@ class ApiDemoLayout extends LitElement {
117118
${renderSnippet(id, tag, this.knobs, slots, cssProps)}
118119
</div>
119120
</api-viewer-panel>
120-
<api-viewer-tab
121-
heading="Knobs"
122-
slot="tab"
123-
part="tab"
124-
?hidden=${noProps && noCustomKnobs && hideSlots}
125-
></api-viewer-tab>
121+
<api-viewer-tab slot="tab" part="tab" ?hidden=${hideKnobs && hideSlots}>
122+
Knobs
123+
</api-viewer-tab>
126124
<api-viewer-panel slot="panel" part="tab-panel">
127125
<div part="knobs">
128-
<section part="knobs-column" @change=${this._onPropChanged}>
126+
<section
127+
?hidden=${hideKnobs}
128+
part="knobs-column"
129+
@change=${this._onPropChanged}
130+
>
129131
${renderKnobs(this.propKnobs, 'Properties', 'prop', propRenderer)}
130132
${renderKnobs(
131133
this.customKnobs,
@@ -143,12 +145,9 @@ class ApiDemoLayout extends LitElement {
143145
</section>
144146
</div>
145147
</api-viewer-panel>
146-
<api-viewer-tab
147-
heading="Styles"
148-
slot="tab"
149-
part="tab"
150-
?hidden=${noCss}
151-
></api-viewer-tab>
148+
<api-viewer-tab slot="tab" part="tab" ?hidden=${noCss}>
149+
Styles
150+
</api-viewer-tab>
152151
<api-viewer-panel slot="panel" part="tab-panel">
153152
<div part="knobs" ?hidden=${noCss}>
154153
<section part="knobs-column" @change=${this._onCssChanged}>
@@ -161,13 +160,9 @@ class ApiDemoLayout extends LitElement {
161160
</section>
162161
</div>
163162
</api-viewer-panel>
164-
<api-viewer-tab
165-
id="events"
166-
heading="Events"
167-
slot="tab"
168-
part="tab"
169-
?hidden=${noEvents}
170-
></api-viewer-tab>
163+
<api-viewer-tab id="events" slot="tab" part="tab" ?hidden=${noEvents}>
164+
Events
165+
</api-viewer-tab>
171166
<api-viewer-panel slot="panel" part="tab-panel">
172167
<div part="event-log" ?hidden=${noEvents}>
173168
<button

packages/api-docs/src/layout.ts

+3-6
Original file line numberDiff line numberDiff line change
@@ -65,12 +65,9 @@ const renderTab = (
6565
): TemplateResult => {
6666
const hidden = array.length === 0;
6767
return html`
68-
<api-viewer-tab
69-
heading=${heading}
70-
slot="tab"
71-
part="tab"
72-
?hidden=${hidden}
73-
></api-viewer-tab>
68+
<api-viewer-tab slot="tab" part="tab" ?hidden=${hidden}>
69+
${heading}
70+
</api-viewer-tab>
7471
<api-viewer-panel slot="panel" part="tab-panel" ?hidden=${hidden}>
7572
${content}
7673
</api-viewer-panel>

packages/api-tabs/package.json

+1-2
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,7 @@
2727
"web-components"
2828
],
2929
"dependencies": {
30-
"lit": "^2.0.0",
31-
"tslib": "^2.3.1"
30+
"@api-viewer/common": "^1.0.0-pre.2"
3231
},
3332
"contributors": [
3433
{

packages/api-tabs/src/api-viewer-panel.ts

+23-19
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,32 @@
1-
import { LitElement, html, css, TemplateResult } from 'lit';
1+
import { html } from '@api-viewer/common/lib/utils.js';
22

33
let panelIdCounter = 0;
44

5-
export class ApiViewerPanel extends LitElement {
6-
static get styles() {
7-
return css`
8-
:host {
9-
display: block;
10-
box-sizing: border-box;
11-
width: 100%;
12-
overflow: hidden;
13-
}
14-
15-
:host([hidden]) {
16-
display: none !important;
17-
}
18-
`;
19-
}
5+
const tpl = html`
6+
<style>
7+
:host {
8+
display: block;
9+
box-sizing: border-box;
10+
width: 100%;
11+
overflow: hidden;
12+
}
13+
14+
:host([hidden]) {
15+
display: none !important;
16+
}
17+
</style>
18+
<slot></slot>
19+
`;
20+
21+
export class ApiViewerPanel extends HTMLElement {
22+
constructor() {
23+
super();
2024

21-
protected render(): TemplateResult {
22-
return html`<slot></slot>`;
25+
const root = this.attachShadow({ mode: 'open' });
26+
root.appendChild(tpl.content.cloneNode(true));
2327
}
2428

25-
protected firstUpdated(): void {
29+
connectedCallback(): void {
2630
this.setAttribute('role', 'tabpanel');
2731

2832
if (!this.id) {

0 commit comments

Comments
 (0)