| 155 |
155 |
|
//! the same magnitude with its sign off the depth. Both values are the measured
|
| 156 |
156 |
|
//! consensus rather than a new opinion.
|
| 157 |
157 |
|
//!
|
|
158 |
+ |
//! # 0.17.0: the depth classes stop being controls
|
|
159 |
+ |
//!
|
|
160 |
+ |
//! [`depth_rules`] gave `.raised` the whole interactive set. A depth is a
|
|
161 |
+ |
//! statement about shape, so that left the vocabulary with no raised surface
|
|
162 |
+ |
//! that is merely an object, and an app wanting one had two moves: write its
|
|
163 |
+ |
//! own class from tokens, or take a control class and cancel the control half.
|
|
164 |
+ |
//! goingson took the second, in three variants over sixteen elements
|
|
165 |
+ |
//! (`.card--static` at 14 call sites, `.card--muted` at 2, `.card--shell` at 1),
|
|
166 |
+ |
//! each re-asserting the resting fill and bevel on `:hover` and `:active`.
|
|
167 |
+ |
//!
|
|
168 |
+ |
//! Measured before changing it: `.raised` is emitted into goingson, Balanced
|
|
169 |
+ |
//! Breakfast and the MNW server, and none of the three has a single call site.
|
|
170 |
+ |
//! The states were unasked-for everywhere at once, and dropping them costs no
|
|
171 |
+ |
//! migration anywhere.
|
|
172 |
+ |
//!
|
|
173 |
+ |
//! `.card` and `.button` are unchanged. They are the same depth *and* controls,
|
|
174 |
+ |
//! and they take their states from [`surface_rules`], which is where a state
|
|
175 |
+ |
//! belongs: on the thing that claims to answer a pointer.
|
|
176 |
+ |
//!
|
| 158 |
177 |
|
//! # Substitution, three ways
|
| 159 |
178 |
|
//!
|
| 160 |
179 |
|
//! `Fill::Well` has no colour on makeover before 2.3.0, and each renderer
|
| 482 |
501 |
|
|
| 483 |
502 |
|
/// One rule per depth: its fill and its edge, together.
|
| 484 |
503 |
|
///
|
| 485 |
|
- |
/// A pressed rule rides along with the raised one, because the cascade can
|
| 486 |
|
- |
/// carry a state that an immediate-mode renderer has to resolve per call site.
|
| 487 |
|
- |
/// That is the one thing this renderer gets for free and the others do not.
|
|
504 |
+ |
/// A depth and nothing else. `.raised` says a surface sits on what is behind
|
|
505 |
+ |
/// it, which is a statement about the shape and not about what happens when a
|
|
506 |
+ |
/// pointer arrives, so it emits no hover, press, focus or disabled rule. The
|
|
507 |
+ |
/// named surfaces are where interaction lives: `.card` and `.button` are the
|
|
508 |
+ |
/// same depth *and* controls, and they get their states from
|
|
509 |
+ |
/// [`surface_rules`].
|
|
510 |
+ |
///
|
|
511 |
+ |
/// This class carried the interactive set until 0.17.0, which left the
|
|
512 |
+ |
/// vocabulary with no raised surface that is merely an object. Consumers that
|
|
513 |
+ |
/// needed one took a control class and cancelled half of it instead: sixteen
|
|
514 |
+ |
/// elements in goingson across three `.card--*` variants, each re-asserting the
|
|
515 |
+ |
/// resting fill and bevel on `:hover` and `:active`. Nothing anywhere used
|
|
516 |
+ |
/// `.raised` itself, so the states were unasked-for in every consumer at once.
|
| 488 |
517 |
|
#[must_use]
|
| 489 |
518 |
|
pub fn depth_rules(opts: &Emit) -> String {
|
| 490 |
519 |
|
let mut css = String::new();
|
| 494 |
523 |
|
};
|
| 495 |
524 |
|
css.push_str(&depth_rule(&class, depth));
|
| 496 |
525 |
|
}
|
| 497 |
|
- |
if let Some(raised) = depth_class(Depth::Raised, opts) {
|
| 498 |
|
- |
css.push_str(&interactive_rules(&raised, Depth::Raised, opts));
|
| 499 |
|
- |
}
|
| 500 |
526 |
|
css
|
| 501 |
527 |
|
}
|
| 502 |
528 |
|
|
| 832 |
858 |
|
|
| 833 |
859 |
|
#[test]
|
| 834 |
860 |
|
fn the_cascade_carries_the_pressed_state() {
|
| 835 |
|
- |
let css = depth_rules(&Emit::default());
|
|
861 |
+ |
let css = surface_rules(&Emit::default());
|
| 836 |
862 |
|
// The one thing this renderer gets free that the other two resolve by
|
| 837 |
|
- |
// hand, eighteen call sites deep in audiofiles' case.
|
| 838 |
|
- |
assert!(css.contains(".raised:active {"));
|
|
863 |
+ |
// hand, eighteen call sites deep in audiofiles' case. Asserted on a
|
|
864 |
+ |
// named surface: pressing belongs to the control, not to the depth.
|
|
865 |
+ |
assert!(css.contains(".card:active {"));
|
|
866 |
+ |
assert!(css.contains(".button:active {"));
|
|
867 |
+ |
}
|
|
868 |
+ |
|
|
869 |
+ |
#[test]
|
|
870 |
+ |
fn the_depth_class_is_a_surface_and_not_a_control() {
|
|
871 |
+ |
let css = depth_rules(&Emit::default());
|
|
872 |
+ |
// The static surface the vocabulary was missing. Sixteen goingson
|
|
873 |
+ |
// elements wore .card and cancelled its hover and press to get this,
|
|
874 |
+ |
// because a raised object that is not pressable had no other spelling.
|
|
875 |
+ |
for state in [":hover", ":active", ":focus-visible", ":disabled"] {
|
|
876 |
+ |
assert!(
|
|
877 |
+ |
!css.contains(&format!(".raised{state}")),
|
|
878 |
+ |
"the depth class claimed {state}: {css}"
|
|
879 |
+ |
);
|
|
880 |
+ |
}
|
|
881 |
+ |
assert!(css.contains("var(--bevel-raised)"), "still raised: {css}");
|
| 839 |
882 |
|
}
|
| 840 |
883 |
|
|
| 841 |
884 |
|
#[test]
|