widget-box

The seam between the two SVG UI systems, so they compose instead of competing.

widgetBox puts the first inside the second. A Widget3d becomes a BoxChild, so an existing panel's rows can be dropped into a floating panel — or a popup, or a scrolling region — without rewriting them, and without box having to grow its own slider.

import { surface, widgetBox, slider3d, toggle3d } from 'tosijs-3d'

const s = surface({ width: 320, height: 240 })
s.openPanel({ x: 20, y: 20 }, widgetBox({ width: 200 }, [
  slider3d({ label: 'time', value: 12, min: 0, max: 24 }),
  toggle3d({ label: 'fog', value: true }),
]), { title: 'Scene', draggable: true })

Why an adapter rather than a port

Porting the controls to box would mean rewriting slider3d and friends and the 94 slider3d uses across this library's doc pages — a lot of churn to end up with the same widgets. The two protocols were already 90% aligned; the missing 10% was that BoxChild only had semantic activation (onActivate), which can't express a drag. BoxChild.handlePointer (raw, capturing) closes that gap, and this file is the translation.

The gap it closes is real: a slider needs down → move* → up with capture, so the drag survives the pointer slipping off the track. box now gives a raw child the whole gesture and keeps routing to it until up.