feat(ui): build LayoutSplitter and CustomScrollbar for real
Quality / quality (ubuntu-latest) (push) Failing after 6m8s
Quality / quality (windows-latest) (push) Canceled after 0s

Both advertised behaviour they did not have. LayoutSplitter declared
resizeStart, resize and resizeEnd with no pointer handling whatsoever, so a
caller wired up @resize and received nothing, for ever, with no error, and its
props were columns, gap and maxWidth copied from a grid scaffold.
CustomScrollbar was the same shape with a scroll output.

The splitter now resizes. Dragging lives in the reactive runtime behind
data-wrn-splitter, because a pointermove fires far too often to route through
a client function and a state write made in that callback is dropped; the
resolved size is held on the container as a --wrn-split custom property and
the component grids from it. The handle is a real separator: arrow keys step
it, Home and End go to the bounds rather than to nothing, and it carries
aria-valuenow, aria-valuemin and aria-valuemax. minSize fixes both bounds so
neither pane can be dragged away and left unrecoverable.

CustomScrollbar is CSS rather than script -- scrollbar-width and
scrollbar-color with webkit rules for the engines that still need them -- and
its fake scroll output is removed rather than left unimplemented, since a
caller can listen for a plain scroll event.

The test harness needed a fix too: mount did not bind the window CustomEvent,
so the runtime built events from the host global and happy-dom listeners never
matched them, which made anything dispatched look silently lost.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-08 11:22:45 +05:30
co-authored by Claude Opus 5
parent b3a4d80df3
commit b56cb8cba5
15 changed files with 794 additions and 184 deletions
@@ -2960,3 +2960,31 @@ body {
font-size: 0.86rem;
line-height: 1.6;
}
/*
* CustomScrollbar demo content. A scrolling region shows nothing at all unless
* its content overflows, so the demo has to supply enough of it.
*/
.showcase-scroll-demo {
display: grid;
gap: 0.5rem;
padding: 0.25rem;
}
.showcase-scroll-demo p {
margin: 0;
color: var(--wire-color-text-muted);
font-size: 0.85rem;
}
.showcase-scroll-demo--wide {
grid-auto-flow: column;
grid-auto-columns: 9rem;
}
.showcase-scroll-demo--wide span {
padding: 0.75rem;
border: 1px solid var(--wire-color-border);
border-radius: var(--wire-radius-sm);
font-size: 0.85rem;
}