0.14.0: a renderer says how big a selection is, and will not commit an empty one
Two things every bulk bar does and no description can say. The ticks on a
screen are the host's until something submits them -- which is why `Act::over`
gathers them at press time rather than the handler being told up front -- so a
route answering from the store cannot know how many are set, and a commit
control over an empty selection was offered, pressed, and answered "0 rows
touched". A screen letting the reader find out by trying.
Each renderer says both with what it already holds. The terminal and egui hold
the set in their own `View`, so it is a count on the control's own label and a
`State::Disabled` when the count is zero, plus a refused press and a refused
key. The webview does not hold it -- the ticks are DOM state -- so this crate
now ships `SELECTION_JS`, twenty lines reading two hooks the emitter already
writes: `.row-select` on a tick and a new `data-over` on a control that commits
one. `Shell::selection_src` says where a host serves it, `without_selection`
drops it, and the fallback is safe rather than silent: a control stays enabled
and says no count, which is what every screen did yesterday. That is the
difference from `morph_src`, whose absence makes htmx swap destructively.
The count rides on the control's label rather than in a status line, because a
status line needs somewhere to go and nothing in the description says where. On
the control it is unambiguous besides: it is the number this press would act
on. Only a control that names a verb takes it -- a picker's words are a
question, and a question with a count after it reads as one more option.
Disabled rather than hidden. `bulk-actions.js` hides its bar and can afford to
because its rows keep their checkboxes; a bar that vanishes takes with it the
only evidence that bulk actions exist.
`Act::over`'s doc gains the other half: a handler still answers for an empty
set. A renderer's refusal is an affordance, not a guarantee about what arrives.
- Co-Authored-By
- Claude Opus 5 (1M context) <noreply@anthropic.com>
22 files changed,
+511 insertions,
-58 deletions
| 3092 |
3092 |
|
|
| 3093 |
3093 |
|
[[package]]
|
| 3094 |
3094 |
|
name = "quasi"
|
| 3095 |
|
- |
version = "0.13.0"
|
|
3095 |
+ |
version = "0.14.0"
|
| 3096 |
3096 |
|
|
| 3097 |
3097 |
|
[[package]]
|
| 3098 |
3098 |
|
name = "quasi-axum"
|
| 3099 |
|
- |
version = "0.13.0"
|
|
3099 |
+ |
version = "0.14.0"
|
| 3100 |
3100 |
|
dependencies = [
|
| 3101 |
3101 |
|
"axum",
|
| 3102 |
3102 |
|
"http",
|
| 3110 |
3110 |
|
|
| 3111 |
3111 |
|
[[package]]
|
| 3112 |
3112 |
|
name = "quasi-basics"
|
| 3113 |
|
- |
version = "0.13.0"
|
|
3113 |
+ |
version = "0.14.0"
|
| 3114 |
3114 |
|
dependencies = [
|
| 3115 |
3115 |
|
"makeover-layout",
|
| 3116 |
3116 |
|
"quasi-http",
|
| 3120 |
3120 |
|
|
| 3121 |
3121 |
|
[[package]]
|
| 3122 |
3122 |
|
name = "quasi-bench"
|
| 3123 |
|
- |
version = "0.13.0"
|
|
3123 |
+ |
version = "0.14.0"
|
| 3124 |
3124 |
|
dependencies = [
|
| 3125 |
3125 |
|
"dhat",
|
| 3126 |
3126 |
|
"makeover",
|
| 3135 |
3135 |
|
|
| 3136 |
3136 |
|
[[package]]
|
| 3137 |
3137 |
|
name = "quasi-http"
|
| 3138 |
|
- |
version = "0.13.0"
|
|
3138 |
+ |
version = "0.14.0"
|
| 3139 |
3139 |
|
dependencies = [
|
| 3140 |
3140 |
|
"form_urlencoded",
|
| 3141 |
3141 |
|
"http",
|
| 3144 |
3144 |
|
|
| 3145 |
3145 |
|
[[package]]
|
| 3146 |
3146 |
|
name = "quasi-immediate"
|
| 3147 |
|
- |
version = "0.13.0"
|
|
3147 |
+ |
version = "0.14.0"
|
| 3148 |
3148 |
|
dependencies = [
|
| 3149 |
3149 |
|
"docengine",
|
| 3150 |
3150 |
|
"egui",
|
| 3154 |
3154 |
|
|
| 3155 |
3155 |
|
[[package]]
|
| 3156 |
3156 |
|
name = "quasi-router"
|
| 3157 |
|
- |
version = "0.13.0"
|
|
3157 |
+ |
version = "0.14.0"
|
| 3158 |
3158 |
|
dependencies = [
|
| 3159 |
3159 |
|
"makeover-layout",
|
| 3160 |
3160 |
|
]
|
| 3171 |
3171 |
|
|
| 3172 |
3172 |
|
[[package]]
|
| 3173 |
3173 |
|
name = "quasi-tauri"
|
| 3174 |
|
- |
version = "0.13.0"
|
|
3174 |
+ |
version = "0.14.0"
|
| 3175 |
3175 |
|
dependencies = [
|
| 3176 |
3176 |
|
"http",
|
| 3177 |
3177 |
|
"quasi-http",
|
| 3182 |
3182 |
|
|
| 3183 |
3183 |
|
[[package]]
|
| 3184 |
3184 |
|
name = "quasi-tui"
|
| 3185 |
|
- |
version = "0.13.0"
|
|
3185 |
+ |
version = "0.14.0"
|
| 3186 |
3186 |
|
dependencies = [
|
| 3187 |
3187 |
|
"docengine",
|
| 3188 |
3188 |
|
"makeover",
|
| 3194 |
3194 |
|
|
| 3195 |
3195 |
|
[[package]]
|
| 3196 |
3196 |
|
name = "quasi-webview"
|
| 3197 |
|
- |
version = "0.13.0"
|
|
3197 |
+ |
version = "0.14.0"
|
| 3198 |
3198 |
|
dependencies = [
|
| 3199 |
3199 |
|
"docengine",
|
| 3200 |
3200 |
|
"makeover-layout",
|
| 5624 |
5624 |
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
| 5625 |
5625 |
|
checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b"
|
| 5626 |
5626 |
|
|
| 5627 |
|
- |
[[patch.unused]]
|
| 5628 |
|
- |
name = "synckit-client"
|
| 5629 |
|
- |
version = "0.8.0"
|
| 5630 |
|
- |
|
| 5631 |
|
- |
[[patch.unused]]
|
| 5632 |
|
- |
name = "synckit-config"
|
| 5633 |
|
- |
version = "0.2.0"
|
| 5634 |
|
- |
|
| 5635 |
5627 |
|
[[patch.unused]]
|
| 5636 |
5628 |
|
name = "kberg"
|
| 5637 |
5629 |
|
version = "0.1.0"
|
| 5647 |
5639 |
|
[[patch.unused]]
|
| 5648 |
5640 |
|
name = "tagtree"
|
| 5649 |
5641 |
|
version = "0.4.0"
|
|
5642 |
+ |
|
|
5643 |
+ |
[[patch.unused]]
|
|
5644 |
+ |
name = "synckit-client"
|
|
5645 |
+ |
version = "0.8.0"
|
|
5646 |
+ |
|
|
5647 |
+ |
[[patch.unused]]
|
|
5648 |
+ |
name = "synckit-config"
|
|
5649 |
+ |
version = "0.2.0"
|
| 1 |
1 |
|
[package]
|
| 2 |
2 |
|
name = "quasi-axum"
|
| 3 |
|
- |
version = "0.13.0"
|
|
3 |
+ |
version = "0.14.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.13.0" }
|
| 17 |
|
- |
quasi-http = { path = "../quasi-http", version = "0.13.0" }
|
|
16 |
+ |
quasi-router = { path = "../quasi-router", version = "0.14.0" }
|
|
17 |
+ |
quasi-http = { path = "../quasi-http", version = "0.14.0" }
|
| 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.13.0" }
|
|
23 |
+ |
quasi-webview = { path = "../quasi-webview", version = "0.14.0" }
|
| 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.13.0"
|
|
3 |
+ |
version = "0.14.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.13.0" }
|
|
16 |
+ |
quasi-router = { path = "../quasi-router", version = "0.14.0" }
|
| 17 |
17 |
|
makeover-layout = "0.27.0"
|
| 18 |
18 |
|
|
| 19 |
19 |
|
[dev-dependencies]
|
| 20 |
20 |
|
# A widget's guarantees are claims about what a renderer draws, so they are
|
| 21 |
21 |
|
# tested against a real one rather than by walking the tree the assembly just
|
| 22 |
22 |
|
# built. The webview is the renderer that recognises names today.
|
| 23 |
|
- |
quasi-webview = { path = "../quasi-webview", version = "0.13.0" }
|
| 24 |
|
- |
quasi-http = { path = "../quasi-http", version = "0.13.0" }
|
|
23 |
+ |
quasi-webview = { path = "../quasi-webview", version = "0.14.0" }
|
|
24 |
+ |
quasi-http = { path = "../quasi-http", version = "0.14.0" }
|
| 1 |
1 |
|
[package]
|
| 2 |
2 |
|
name = "quasi-bench"
|
| 3 |
|
- |
version = "0.13.0"
|
|
3 |
+ |
version = "0.14.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
|
| 22 |
22 |
|
count = ["dep:dhat"]
|
| 23 |
23 |
|
|
| 24 |
24 |
|
[dependencies]
|
| 25 |
|
- |
quasi-router = { path = "../quasi-router", version = "0.13.0" }
|
| 26 |
|
- |
quasi-webview = { path = "../quasi-webview", version = "0.13.0" }
|
| 27 |
|
- |
quasi-tui = { path = "../quasi-tui", version = "0.13.0" }
|
|
25 |
+ |
quasi-router = { path = "../quasi-router", version = "0.14.0" }
|
|
26 |
+ |
quasi-webview = { path = "../quasi-webview", version = "0.14.0" }
|
|
27 |
+ |
quasi-tui = { path = "../quasi-tui", version = "0.14.0" }
|
| 28 |
28 |
|
# `Serves` is the trait carrying `screen` and `fragment`, which is what the
|
| 29 |
29 |
|
# webview is measured through. Taken directly rather than through quasi-webview
|
| 30 |
30 |
|
# because a bench calling a trait method should name the trait it calls.
|
| 31 |
|
- |
quasi-http = { path = "../quasi-http", version = "0.13.0" }
|
|
31 |
+ |
quasi-http = { path = "../quasi-http", version = "0.14.0" }
|
| 32 |
32 |
|
makeover-layout = "0.27.0"
|
| 33 |
33 |
|
makeover-tui = { version = "0.25.0", features = ["theme"] }
|
| 34 |
34 |
|
# Only to load a bundled theme file. `makeover_tui::Theme` is `#[non_exhaustive]`,
|
| 1 |
1 |
|
[package]
|
| 2 |
2 |
|
name = "quasi-http"
|
| 3 |
|
- |
version = "0.13.0"
|
|
3 |
+ |
version = "0.14.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.13.0" }
|
|
16 |
+ |
quasi-router = { path = "../quasi-router", version = "0.14.0" }
|
| 17 |
17 |
|
http = "1.3.1"
|
| 18 |
18 |
|
form_urlencoded = "1.2.2"
|
| 1 |
1 |
|
[package]
|
| 2 |
2 |
|
name = "quasi-immediate"
|
| 3 |
|
- |
version = "0.13.0"
|
|
3 |
+ |
version = "0.14.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.13.0" }
|
|
15 |
+ |
quasi-router = { path = "../quasi-router", version = "0.14.0" }
|
| 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
|
| 1 |
1 |
|
[package]
|
| 2 |
2 |
|
name = "quasi-router"
|
| 3 |
|
- |
version = "0.13.0"
|
|
3 |
+ |
version = "0.14.0"
|
| 4 |
4 |
|
description = "Host-agnostic router: a request in, a renderer-agnostic description out"
|
| 5 |
5 |
|
edition.workspace = true
|
| 6 |
6 |
|
rust-version.workspace = true
|