Seven treefactory declarations, each naming its own tags over the
same EVGElement, painted by EVG's WebGL painter. Three of them
rebuild the whole tree on every control; the motion showcase, the table
and the dropdown keep theirs,
because a transition remembers where a value was and a rebuilt element
remembers nothing.
effects.css — live
Try evg-fx-density, -hue, -speed on .fx-sky, or -sweep-speed on .fx-glass. Change evg-surface-effect to plasma-wave, raindrop or ambient-light and paste a block from lib/evg/gl/effect-presets.css to see another one.
Drag a row onto another and the list reorders — and it is
rebuilt, not moved: the page holds an order and hands it over, and the
tree literal builds whatever it is given. Click a row and use Space, ↑
↓ and Escape for the same thing from the keyboard. The behaviour is the
one gallery/ui/src/SortableCtl.rgr is measured against, item for
item, with @dnd-kit/sortable as the reference.
The state is not this demo's. Sorting, page-scoped
selection and the paging arithmetic all live in
gallery/ui/src/TableCtl.rgr, which the conformance
harness measures against @tanstack/react-table — the
library ReUI's table is built on. This file is the other half: a
treefactory and a stylesheet, and nothing else. The
controller decides what is true; the tree literal decides what it
looks like.
The rows are siblings. There is no group per folder:
the visible rows are one flat list and the nesting is carried by
aria-level alone, because that is what
@headless-tree/core renders and therefore what ReUI's
tree renders. The indent is a spacer this demo adds; a reader never
sees it and does not need to. Open/closed, focus and every key are
gallery/ui/src/TreeCtl.rgr’s.
This demo owns no state at all. Open/closed, the
roving focus, the submenu stack, the 100 ms hover delay and
every key are gallery/ui/src/MenuCtl.rgr’s, which
five conformance specs measure against
@radix-ui/react-dropdown-menu. What is here is a
treefactory, a stylesheet, and which icon goes on which
row. Compare it with the menubar demo above, whose keyboard
is hand-written and matched against nothing.
Anything can go inside.WindowCtl owns a
frame and a title bar; bodyEl is an ordinary
EVGElement the caller fills, and build()
re-makes the chrome around it without touching it. Here one holds a
form and the other a small table, from two unrelated tree literals.
The older EVGWindow could hold neither: its vocabulary is
label, button, radio, checkbox, and one rectangle whose pixels the
owner paints by hand.
Hover the cards at the bottom. Nothing in
MotionDemo.rgr knows what a pointer is: the tree is boxes
with class names, and every hover, press and journey on this page is a
rule in motion.css. The page’s only job is to turn a
theme over every 1.7 seconds and to hand the engine the real elapsed
time each frame.
Cross the slow card quickly. Its transition is 900ms,
and leaving half way through does not take another 900ms to come
back — a reversal is shortened by how far the value actually
got, measured after the easing curve rather than off the clock. On
ease-in at the midpoint those differ by nearly a factor of
two.
Click it. The canvas answers the pointer through EVG’s own
hit testing: a press is resolved against the same laid-out tree that was
drawn, topmost first, so a click inside an open panel reaches the panel and
not the trigger it covers. Hovering Share opens the submenu; Escape
closes; ← and → walk the bar, ↑ and ↓ the rows. The sidebar is a second view
of the same state.
And read it. A canvas hands a screen reader one empty
graphic no matter what was drawn into it, so the page also publishes what
the frame means: EVGA11yFromTree walks the same
elements and emits roles, names, states and rectangles, and
evg-a11y.js mirrors those into transparent DOM over the canvas
— which is what a reader actually walks. Nothing is described twice: the
roles are on the treefactory tags beside the classes. A reader
activating a node is answered by pressing the app at that node’s
rectangle, so it takes the same path as the mouse.
The dropdowns float under their triggers because EVG has overlay
surfaces: Content is still the Menu’s child, and
layout takes it out of the parent’s flow, finds the anchor among its own
siblings and moves it and its subtree there. A submenu is a
Menu like any other — there is no submenu case in the demo.
A surface near an edge flips to the other side of its anchor and slides
along the edge to stay on the page. The toolbar’s italic and underlined
buttons are missing for an unrelated reason: EVG has no
font-style and no text-decoration.