TL;DR;
- Do not unlearn HTML when you build Web Components.
- "Design Systems" add bloated code to create an Accordion.
- Use the default
<details>
and<summary>
elements to built a<details-accordion>
Custom Element.
If you have a hammer,
everything starts to look like a nail
Now we got this great technology Web Components, it is easy to get excited and use Custom Elements for everything in your Design System:
I won't name the Design Systems, and won't link to bloated JavaScript code.
Their HTML looks like this:
<ACME-accordion>
<ACME-accordion-item label="..." content="Content 1" expanded></ACME-accordion-item>
<ACME-accordion-item label="..." content="Content 2"></ACME-accordion-item>
</ACME-accordion>
or
<ACME-accordion>
<ACME-accordion-panel>
<div slot="summary">...</div>
<div>...</div>
</ACME-accordion-panel>
<ACME-accordion-panel>
<div slot="summary">...</div>
<div>...</div>
</ACME-accordion-panel>
</ACME-accordion>
or
<ACME-accordion>
<h3 slot="invoker"><button>...</button></h3>
<p slot="content">...</p>
<h3 slot="invoker"><button>...</button></h3>
<p slot="content">...</p>
</ACME-accordion>
Good, old, HTML
The Open/Close functionality is available in standard HTML with the <details>
and <summary>
elements.
Add a 7 line vanilla Web Component:
customElements.define('details-accordion', class extends HTMLElement {
connectedCallback() {
this.onclick = evt => [...this.children].map(detail => {
!evt.ctrlKey && detail.toggleAttribute("open", evt.target == detail);
});
}
});
To create an Accordion:
<details-accordion>
<details open>
<summary>...</summary>
...
</details>
<details>
<summary>...</summary>
...
</details>
<details>
<summary>...</summary>
...
</details>
</details-accordion>
hold down the Ctrl key to open multiple <details>
Notes:
- There is no shadowDOM, so easily apply any CSS styling you want
-
<details>
itself also has a click handler and will open/close! - For every click on
<details-accordion>
all children are toggled; - using
.map
instead of.forEach
saves 4 bytes
Top comments (0)