| 383 |
383 |
|
// Hidden rather than absent: the row must not change height when
|
| 384 |
384 |
|
// the pointer arrives. `focus-within` carries the keyboard, which
|
| 385 |
385 |
|
// hover on its own would lock out.
|
| 386 |
|
- |
let _ = writeln!(css, ".{c} {{\n visibility: hidden;\n}}");
|
|
386 |
+ |
//
|
|
387 |
+ |
// Transparent rather than `visibility: hidden`, which was the first
|
|
388 |
+ |
// form and defeated the very escape above: a `visibility: hidden`
|
|
389 |
+ |
// element is out of the focus order and out of the accessibility
|
|
390 |
+ |
// tree, so tabbing could never reach an action and could never
|
|
391 |
+ |
// trigger the row's `focus-within`. goingson had reached the same
|
|
392 |
+ |
// opacity form independently, on its own comment "always in the DOM
|
|
393 |
+ |
// for keyboard and screen readers".
|
|
394 |
+ |
//
|
|
395 |
+ |
// `pointer-events` rides along because opacity leaves the hit area
|
|
396 |
+ |
// behind: without it a renderer with no hover carries an invisible
|
|
397 |
+ |
// tappable control. Keyboard focus is unaffected by it.
|
| 387 |
398 |
|
let _ = writeln!(
|
| 388 |
399 |
|
css,
|
| 389 |
|
- |
".{row}:hover .{c},\n.{row}:focus-within .{c} {{\n visibility: visible;\n}}"
|
|
400 |
+ |
".{c} {{\n opacity: 0;\n pointer-events: none;\n}}"
|
|
401 |
+ |
);
|
|
402 |
+ |
let _ = writeln!(
|
|
403 |
+ |
css,
|
|
404 |
+ |
".{row}:hover .{c},\n.{row}:focus-within .{c} {{\n opacity: 1;\n pointer-events: auto;\n}}"
|
| 390 |
405 |
|
);
|
| 391 |
406 |
|
}
|
| 392 |
407 |
|
}
|
| 672 |
687 |
|
#[test]
|
| 673 |
688 |
|
fn row_actions_are_revealed_without_moving_the_row() {
|
| 674 |
689 |
|
let css = row_rules(&Emit::default());
|
| 675 |
|
- |
assert!(css.contains(".row-actions {\n visibility: hidden;"));
|
|
690 |
+ |
assert!(css.contains(".row-actions {\n opacity: 0;"));
|
| 676 |
691 |
|
// Not display:none, which would reflow the row under the pointer.
|
| 677 |
692 |
|
assert!(!css.contains("display: none"));
|
| 678 |
693 |
|
// Hover alone would lock the keyboard out.
|
| 680 |
695 |
|
assert!(RowPart::Actions.revealed_on_hover());
|
| 681 |
696 |
|
}
|
| 682 |
697 |
|
|
|
698 |
+ |
#[test]
|
|
699 |
+ |
fn a_hidden_row_action_is_still_focusable_and_not_tappable() {
|
|
700 |
+ |
let css = row_rules(&Emit::default());
|
|
701 |
+ |
// `visibility: hidden` takes the actions out of the focus order, so the
|
|
702 |
+ |
// `focus-within` reveal above could never fire from an action itself.
|
|
703 |
+ |
assert!(!css.contains("visibility:"));
|
|
704 |
+ |
// Opacity leaves the hit area behind; the row must not carry an
|
|
705 |
+ |
// invisible tappable control where there is no hover to reveal it.
|
|
706 |
+ |
assert!(css.contains(".row-actions {\n opacity: 0;\n pointer-events: none;\n}"));
|
|
707 |
+ |
assert!(css.contains("opacity: 1;\n pointer-events: auto;"));
|
|
708 |
+ |
}
|
|
709 |
+ |
|
| 683 |
710 |
|
#[test]
|
| 684 |
711 |
|
fn the_three_text_parts_take_their_intents_and_actions_inherits() {
|
| 685 |
712 |
|
let css = row_rules(&Emit::default());
|
| 826 |
853 |
|
if value.contains("var(--") {
|
| 827 |
854 |
|
continue;
|
| 828 |
855 |
|
}
|
| 829 |
|
- |
// Everything left has to be a keyword or a caller-supplied length,
|
| 830 |
|
- |
// never a colour.
|
|
856 |
+ |
// Everything left has to be a keyword, a number or a
|
|
857 |
+ |
// caller-supplied length, never a colour.
|
| 831 |
858 |
|
assert!(
|
| 832 |
|
- |
value.contains("hidden")
|
| 833 |
|
- |
|| value.contains("visible")
|
| 834 |
|
- |
|| value.contains("inset"),
|
|
859 |
+ |
value.contains("inset")
|
|
860 |
+ |
|| matches!(value.trim_end_matches(';'), "0" | "1" | "none" | "auto"),
|
| 835 |
861 |
|
"unrecognised literal value: {line}"
|
| 836 |
862 |
|
);
|
| 837 |
863 |
|
}
|