PanelSet
One panel or many. CSS animates.
What is it?
It is a transition helper for panels that you want to show or hide.
The package exports three classes. Two main classes: Panel and PanelSet and one additional class PanelControl. Both main classes animate a size between values using an LMAU* cycle:
- Panel animates height or width
- PanelSet animates height of a whole set of panels, showing one at a time
- PanelControl is an addition to PanelSet that handles navigation for tabs
The two main classes use the same animation core and share most config options. Animation is CSS-only: JS just measures and sets pixel values, then lets your browser do the rest with CSS. For async content, you can pass a promise to let the panel wait until it resolves. A spinner kicks in if loading takes longer than what you set it to be. Both also handle focus management.
* LMAU: Lock-Measure-Animate-Unlock (I should trademark the term).
Panel
A single element that can be opened and closed. Use it for sidebars, show-more blocks, accordions, or any element that expands and collapses.
Triggers are any element with aria-controls pointing to the panel’s ID. Or a button with data-panel-trigger if it is a sibling of a panel, which sets up the id and ARIA for you.
You can add a close button that uses data-panel-close.
PanelSet
A container that switches between some panels. Use it for tabs, wizards, or multi-step interfaces. Only one panel is (fully) visible at a time. Height transitions as well.
Triggers are any element with aria-controls pointing to an internal panel’s ID.
It can also be opened and closed as a whole, just like a regular Panel.
Add PanelControl for activation, keyboard navigation, roving tabindex, and state reflection.
PanelSet example
Key Features
- This is our most important feature ever!
Pricing Plans
- Starter Plan: Whenever you don’t want to pay a lot.
- Professional Plan: Ideal for managers who like to spend money!
Support Options
- If you send us an email, we will probably ignore it.
- We don’t even have a community forum.
- Opening an issue on GitHub is your next best option. Or even better: PR’s! You do the work!
Features
CSS-driven animation
JS measures and sets a pixel value. After that, the browser animates. No JS animation loop.
Async content
Pass a promise to onBeforeOpen() and the panel waits. A spinner appears if loading takes longer than loadingDelay ms.
Interrupt-safe
Click again mid-animation and it reverses from exactly where it is. No jumping.
Accessible
aria-expanded, aria-controls, aria-selected (or aria-current) and inert are managed for you. Opt into autoFocus and returnFocus for focus handling.
Persist & deep-link
persist: true saves the active panel to localStorage so it survives reloads. deepLink: true reflects it in the ?panel= URL for shareable links. And a ?panel= link is always honoured on load.
Reduced motion
Respects prefers-reduced-motion. Users who prefer less motion get instant state changes instead.
Setup
Installing Panel, PanelSet and PanelControl
npm install panelset
Using Panel, PanelSet and PanelControl
Installing Panel, PanelSet and PanelControl
Download the ZIP from the releases page, unzip, and place the files somewhere your HTML can reach.
Using Panel, PanelSet and PanelControl
Installing Panel, PanelSet and PanelControl
No download needed. Files are served directly from jsDelivr.
https://cdn.jsdelivr.net/npm/panelset@latest/dist/
Using Panel, PanelSet and PanelControl
Support this project
PanelSet is free. If it saved you time, a coffee goes a long way.
Support my work on Ko-fi