@agencecinq/windowsplitter
v2.0.0
Published
Accessible WAI-ARIA window splitter as a lightweight Web Component.
Downloads
534
Readme
@agencecinq/windowsplitter
Accessible WAI-ARIA window splitter as a lightweight Web Component.
A window splitter lets users resize a primary pane with a focusable separator.
<cinq-windowsplitter> is the layout wrapper (bounds + CSS custom
properties). A nested [role="separator"] (or slider) is the interactive
control — you deliver clean markup; the component wires pointer / keyboard
resizing and mirrors layout onto the primary pane.
Implementation follows the
WAI-ARIA Authoring Practices window splitter pattern.
Inspired by @19h47/windowsplitter.
Installation
pnpm add @agencecinq/windowsplitterUsage
import "@agencecinq/windowsplitter";<cinq-windowsplitter class="panes">
<div id="toc" class="pane pane--primary" style="width: 30%">
<strong id="toc-label">Table of Contents</strong>
</div>
<div
role="separator"
tabindex="0"
aria-orientation="vertical"
aria-valuemin="0"
aria-valuemax="100"
aria-valuenow="30"
aria-controls="toc"
aria-labelledby="toc-label"
></div>
<div class="pane pane--secondary">Content</div>
</cinq-windowsplitter>HTML is the source of truth. ARIA values, orientation, labelling, and
aria-controlslive on the separator. The component will not invent missing markup — use an a11y linter (axe-core, Lighthouse) to catch invalid markup.
The primary pane is resolved live via
ariaControlsElements
on the separator.
Required markup
| Selector / attribute | Required | Role |
| -------------------- | -------- | ---- |
| <cinq-windowsplitter> | Yes | Layout wrapper / bounds container. |
| Nested [role="separator"] or [role="slider"] | Yes | Focusable control ($separator). |
| tabindex="0" | Yes | On the separator. |
| aria-orientation | Yes | On the separator: vertical or horizontal. |
| aria-valuemin / aria-valuemax / aria-valuenow | Yes | On the separator. |
| aria-controls | Yes (for resize / clip) | On the separator: id of the primary pane. |
| aria-label / aria-labelledby | Yes | On the separator. |
Options
| Attribute / property | Description |
| -------------------- | ----------- |
| data-windowsplitter-mode | resize (default) | clip | none |
| data-windowsplitter-step | Arrow key step (default 1) |
| data-windowsplitter-page | Page / Shift+Arrow step (default 10) |
| data-windowsplitter-fixed | Enter / pointer toggle only |
| disabled / aria-disabled | Disable interaction (host and/or separator) |
| formatSize | FormatSize — CSS size for the primary pane in resize mode |
| formatValue | FormatValue — aria-valuetext formatter |
API
| Method | Description |
| ------ | ----------- |
| setValue(value, trigger?) | Set aria-valuenow on the separator and update layout. |
| collapse(trigger?) / restore(trigger?) / toggle(trigger?) | Collapse helpers (history only from collapse / Enter). |
| sync() | Re-read ARIA and re-apply layout. |
| destroy() | Removes listeners and observers. Called automatically from disconnectedCallback. |
| Property | Description |
| -------- | ----------- |
| $separator | Focusable separator control. |
| $primary | Primary pane from ariaControlsElements (live). |
| value / min / max / ratio / orientation | Read from separator ARIA (HTML source of truth). |
| collapsed / disabled | Derived state. |
| mode / step / page / fixed | Options (also via data attributes). |
| formatSize / formatValue | Formatters. |
Events
Dispatched on the host <cinq-windowsplitter> (bubble). Prefer constants
from @agencecinq/utils:
| Event | Constant | Detail | When |
| ----- | -------- | ------ | ---- |
| windowsplitter:change | WINDOWSPLITTER_CHANGE | { value, min, max, ratio, collapsed } | After a user-driven (or trigger: true) value change |
import { EVENTS } from "@agencecinq/utils";
const host = document.querySelector("cinq-windowsplitter");
host.addEventListener(EVENTS.WINDOWSPLITTER_CHANGE, ({ detail }) => {
console.log(detail.value, detail.collapsed);
});Styling hooks
| Hook | When |
| ---- | ---- |
| [collapsed] | Primary pane at aria-valuemin (on the host) |
| [dragging] | Pointer drag in progress (on the host) |
| [disabled] / [aria-disabled="true"] | Interaction disabled |
| :focus-visible on [role="separator"] | Keyboard focus on the separator |
| --windowsplitter-value / --windowsplitter-ratio / --windowsplitter-offset | On the host |
Keyboard
| Key | Function |
| --- | -------- |
| ← / → | Move a vertical splitter |
| ↑ / ↓ | Move a horizontal splitter |
| Enter | Collapse / restore |
| Home / End | Jump to min / max |
| PageUp / PageDown | Step by page |
| Shift + Arrow | Step by page |
A fixed splitter (data-windowsplitter-fixed) omits arrow keys and only
implements Enter (and pointer toggle).
Build setup
pnpm -C packages/windowsplitter buildAcknowledgments
- Window Splitter Pattern (WAI-ARIA Practices)
@19h47/windowsplitter— original implementation
See the interactive docs for live examples.
