feat(ui): a scrollbar held where it was taken, a popover that keeps the mouse, easing that lands

- the scrollbar is .ui-scrollbar with a .ui-thumb, styled by the default sheet or a theme; a press
  on the thumb holds it at the point it was taken and the pointer moves it in proportion, a press on
  the track jumps the thumb's middle there and holds it, and neither presses what is under the bar
  (it used to centre the thumb on the pointer and press the row beneath as well);
- while a popover is up only scroll boxes inside it take the pointer, and a press outside it that
  closes it forgets any press in progress;
- a transition ends exactly on its value (it stopped a rounding error short, at every frame rate).

Tests: ui_popover_mouse, ui_scrollbar, ui_ease (60/120/180/240 Hz).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Orkun ÇAKILKAYA 2026-09-24 21:39:28 +03:00
parent 9f59000f5b
commit a4c7a756f0
19 changed files with 299 additions and 29 deletions

View file

@ -444,6 +444,9 @@ applies to both:
it is let go.
- A scroll box (`overflow: auto` or `<scroll>`) takes the wheel, has a scrollbar that can be
dragged (`scrollbar-color`), clips what it holds and pulls the focused control into view.
- The scrollbar is `.ui-scrollbar` with a `.ui-thumb`, styled like a control's parts. A press on
the thumb holds it where it was taken and the pointer moves it in proportion; a press on the
track jumps the thumb's middle there and holds it. A press on the bar presses nothing under it.
- `:focus`, `:focus-visible` and `:focus-within` style the focus, and `outline` (which follows
`border-radius`) draws the ring.
- A test drives all of it with `ui_input(i)`.
@ -474,6 +477,8 @@ applies to both:
- **Popovers, tooltips and bars.**
- `<div popover on-close="...">` sits absolutely in its parent and draws on the top layer. While
it is up, the pointer and Tab stay inside it, and a press outside it or Esc closes it.
A press on it goes to its own controls, never to what lies under it at the same pixels, and a
press outside it only closes it.
- `anchor="cell"` puts a popover beside the element with that id (the nearest, looking out from
the popover), and a bare `anchor` beside the element before it. `placement` is `right` (the
default), `left`, `bottom` or `top`, its margin on that side is the gap, and where it would
@ -511,7 +516,8 @@ applies to both:
`color` around it, as text does. An `<img>` with a `color` of its own is tinted by it.
- Motion: `opacity` fades the element and everything inside it. `@keyframes` with `animation:
name 0.25s [infinite] [alternate]` animate numeric properties from when the element first
appeared, and `transition: opacity 0.2s` eases a changed opacity.
appeared, and `transition: opacity 0.2s` eases a changed opacity. Both run on the clock, in
float, and land exactly on their end values whatever the frame rate.
- **Mixed content.** Text beside elements keeps its place: `<button><img src="icon:arrow"/>Resume
</button>`, `<p>Hi <b>there</b></p>`. A boolean attribute present with no value is true, as in
HTML (`<button autofocus>`).