Give a region's label to the thing that draws it
A label is the name of the control that reveals a member: a tab's text, a
disclosure's summary. Only a region that discloses or steps through its
members draws one, and until now any region could carry one. Max ruled
that a label nothing will draw should not be representable.
It cannot be a check. A member is built before it is placed, so nothing
about the member knows whether its label will be drawn, and the parent
that decides may be in another declare! entirely. That is how MNW's
/use-cases lost the titles of nine cards for weeks with a green suite.
So Slot has no label. A selective region's body is its own arm carrying
frames, each with the name of the control that reveals it, and body,
showing and shown collapse into it. That retires the neighbouring trap in
the same move: shown was meaningless under Showing::All and ignored
there. Picks is the two selective variants only, so a selective body
cannot say it shows everything.
Slot::frame(label, node) is the only thing that takes a name, and it
places the member in the same call. layout::Showing is untouched: it
carries no data, so it stays the vocabulary's word and is derived.
The declare! syntax is unchanged where it can be. `label` stays written
inside the child, which is where it reads, and the macro hoists it onto
the placement. A `framed <label> <emission>` modifier covers what a hoist
cannot reach: a shape in another invocation answers a Slot, which now
carries no label, so goingson's summary_body is placed by its parent as
`framed "Time tracked" include summary_body(panel)`.
Found and fixed while landing it: three test fixtures labelling
screen-level slots, and MNW's shortcuts modal, whose label had never
reached markup. A dialog does want an accessible name, so that one became
`named`, which is the field that writes one.
Span placement is a repair again rather than a re-placement, and the
walk is a stack. Choosing every span afresh moved spans that were already
right -- a loop nested inside a branch has a range reaching back past the
branch that holds it -- which broke quasi-bench under the previous
commit. Comparing neighbours is not enough either: the two spans in a
straddle are often not adjacent once sorted, since a third can nest
inside the first and sort between them, which is /fan-plus.
Breaking, so every pin moves in the same pass: the family to 0.104, and
quasi-declare to 0.1.13 for `framed`.
- Co-Authored-By
- Claude Opus 5 (1M context) <noreply@anthropic.com>
- Claude-Session
- https://claude.ai/code/session_01P8ostB2UmZJGj5WjSHRSot
30 files changed,
+803 insertions,
-334 deletions
| 1 |
1 |
|
[package]
|
| 2 |
2 |
|
name = "quasi-axum"
|
| 3 |
|
- |
version = "0.103.0"
|
|
3 |
+ |
version = "0.104.0"
|
| 4 |
4 |
|
description = "The axum host adapter for quasi-router: an HTTP request in, a rendered description out"
|
| 5 |
5 |
|
edition.workspace = true
|
| 6 |
6 |
|
rust-version.workspace = true
|
| 13 |
13 |
|
workspace = true
|
| 14 |
14 |
|
|
| 15 |
15 |
|
[dependencies]
|
| 16 |
|
- |
quasi-router = { path = "../quasi-router", version = "0.103" }
|
| 17 |
|
- |
quasi-http = { path = "../quasi-http", version = "0.103" }
|
|
16 |
+ |
quasi-router = { path = "../quasi-router", version = "0.104" }
|
|
17 |
+ |
quasi-http = { path = "../quasi-http", version = "0.104" }
|
| 18 |
18 |
|
axum = "0.8.8"
|
| 19 |
19 |
|
http = "1.3.1"
|
| 20 |
20 |
|
tokio = { version = "1.50.0", features = ["rt"] }
|
| 21 |
21 |
|
|
| 22 |
22 |
|
[dev-dependencies]
|
| 23 |
|
- |
quasi-webview = { path = "../quasi-webview", version = "0.103" }
|
|
23 |
+ |
quasi-webview = { path = "../quasi-webview", version = "0.104" }
|
| 24 |
24 |
|
tokio = { version = "1.50.0", features = ["macros", "rt-multi-thread"] }
|
| 25 |
25 |
|
tower = { version = "0.5.3", features = ["util"] }
|
| 26 |
26 |
|
http-body-util = "0.1.3"
|
| 1 |
1 |
|
[package]
|
| 2 |
2 |
|
name = "quasi-basics"
|
| 3 |
|
- |
version = "0.103.0"
|
|
3 |
+ |
version = "0.104.0"
|
| 4 |
4 |
|
description = "The first-party widget set: named assemblies of primitives, shared across our apps"
|
| 5 |
5 |
|
edition.workspace = true
|
| 6 |
6 |
|
rust-version.workspace = true
|
| 13 |
13 |
|
workspace = true
|
| 14 |
14 |
|
|
| 15 |
15 |
|
[dependencies]
|
| 16 |
|
- |
quasi-router = { path = "../quasi-router", version = "0.103" }
|
|
16 |
+ |
quasi-router = { path = "../quasi-router", version = "0.104" }
|
| 17 |
17 |
|
quasi-declare = { path = "../quasi-declare", version = "0.1" }
|
| 18 |
18 |
|
makeover-layout = "0.44"
|
| 19 |
19 |
|
|
| 21 |
21 |
|
# A widget's guarantees are claims about what a renderer draws, so they are
|
| 22 |
22 |
|
# tested against a real one rather than by walking the tree the assembly just
|
| 23 |
23 |
|
# built. The webview is the renderer that recognises names today.
|
| 24 |
|
- |
quasi-webview = { path = "../quasi-webview", version = "0.103" }
|
| 25 |
|
- |
quasi-http = { path = "../quasi-http", version = "0.103" }
|
|
24 |
+ |
quasi-webview = { path = "../quasi-webview", version = "0.104" }
|
|
25 |
+ |
quasi-http = { path = "../quasi-http", version = "0.104" }
|
| 1 |
1 |
|
[package]
|
| 2 |
2 |
|
name = "quasi-bench"
|
| 3 |
|
- |
version = "0.103.0"
|
|
3 |
+ |
version = "0.104.0"
|
| 4 |
4 |
|
description = "What a described screen costs to render, in time and in allocations"
|
| 5 |
5 |
|
edition.workspace = true
|
| 6 |
6 |
|
rust-version.workspace = true
|
| 26 |
26 |
|
askama = ["dep:askama"]
|
| 27 |
27 |
|
|
| 28 |
28 |
|
[dependencies]
|
| 29 |
|
- |
quasi-router = { path = "../quasi-router", version = "0.103" }
|
| 30 |
|
- |
quasi-webview = { path = "../quasi-webview", version = "0.103" }
|
| 31 |
|
- |
quasi-tui = { path = "../quasi-tui", version = "0.103" }
|
| 32 |
|
- |
quasi-immediate = { path = "../quasi-immediate", version = "0.103" }
|
|
29 |
+ |
quasi-router = { path = "../quasi-router", version = "0.104" }
|
|
30 |
+ |
quasi-webview = { path = "../quasi-webview", version = "0.104" }
|
|
31 |
+ |
quasi-tui = { path = "../quasi-tui", version = "0.104" }
|
|
32 |
+ |
quasi-immediate = { path = "../quasi-immediate", version = "0.104" }
|
| 33 |
33 |
|
# `Serves` is the trait carrying `screen` and `fragment`, which is what the
|
| 34 |
34 |
|
# webview is measured through. Taken directly rather than through quasi-webview
|
| 35 |
35 |
|
# because a bench calling a trait method should name the trait it calls.
|
| 36 |
|
- |
quasi-http = { path = "../quasi-http", version = "0.103" }
|
|
36 |
+ |
quasi-http = { path = "../quasi-http", version = "0.104" }
|
| 37 |
37 |
|
# The macro under measurement. The bench holds the declared copy of the same
|
| 38 |
38 |
|
# screen `staging.rs` writes by hand, so the staged column measures what the
|
| 39 |
39 |
|
# server actually serves rather than a shape written for a benchmark.
|
| 1 |
1 |
|
[package]
|
| 2 |
2 |
|
name = "quasi-declare"
|
| 3 |
|
- |
version = "0.1.12"
|
|
3 |
+ |
version = "0.1.13"
|
| 4 |
4 |
|
description = "The declare! form: a screen description compiled to Rust at build time."
|
| 5 |
5 |
|
edition.workspace = true
|
| 6 |
6 |
|
rust-version.workspace = true
|
| 31 |
31 |
|
trybuild = "1"
|
| 32 |
32 |
|
# The generated code names the vocabulary, so a case that is meant to COMPILE
|
| 33 |
33 |
|
# needs it. A proc-macro crate cannot depend on it outside dev.
|
| 34 |
|
- |
quasi-router = { path = "../quasi-router", version = "0.103" }
|
|
34 |
+ |
quasi-router = { path = "../quasi-router", version = "0.104" }
|
| 1 |
1 |
|
[package]
|
| 2 |
2 |
|
name = "quasi-http"
|
| 3 |
|
- |
version = "0.103.0"
|
|
3 |
+ |
version = "0.104.0"
|
| 4 |
4 |
|
description = "The http-shaped seam quasi's webview host adapters share: decoding in, a rendered description out"
|
| 5 |
5 |
|
edition.workspace = true
|
| 6 |
6 |
|
rust-version.workspace = true
|
| 13 |
13 |
|
workspace = true
|
| 14 |
14 |
|
|
| 15 |
15 |
|
[dependencies]
|
| 16 |
|
- |
quasi-router = { path = "../quasi-router", version = "0.103" }
|
|
16 |
+ |
quasi-router = { path = "../quasi-router", version = "0.104" }
|
| 17 |
17 |
|
http = "1.3.1"
|
| 18 |
18 |
|
form_urlencoded = "1.2.2"
|
| 1 |
1 |
|
[package]
|
| 2 |
2 |
|
name = "quasi-immediate"
|
| 3 |
|
- |
version = "0.103.0"
|
|
3 |
+ |
version = "0.104.0"
|
| 4 |
4 |
|
edition = "2024"
|
| 5 |
5 |
|
description = "The immediate-mode renderer for quasi-router: a described screen in, an egui frame out. Immediate mode is the constraint that matters, not the library."
|
| 6 |
6 |
|
license = "MIT"
|
| 12 |
12 |
|
categories = ["gui"]
|
| 13 |
13 |
|
|
| 14 |
14 |
|
[dependencies]
|
| 15 |
|
- |
quasi-router = { path = "../quasi-router", version = "0.103" }
|
|
15 |
+ |
quasi-router = { path = "../quasi-router", version = "0.104" }
|
| 16 |
16 |
|
# The node drawing, which is the makeover layer's and not this crate's. Every
|
| 17 |
17 |
|
# widget here that is not a container comes from it: a screen walk that painted
|
| 18 |
18 |
|
# its own meter would be the divergence the suite exists to end, one copy per
|