| 987 |
987 |
|
css,
|
| 988 |
988 |
|
".{heading}[data-sortable] {{\n cursor: pointer;\n}}"
|
| 989 |
989 |
|
);
|
|
990 |
+ |
// The caret carries its own leading space, the way `makeover-tui` and
|
|
991 |
+ |
// `makeover-immediate` both write `" \u{25B2}"`. It used to be emitted bare,
|
|
992 |
+ |
// and both apps that adopted the vocabulary had to put the gap back in their
|
|
993 |
+ |
// own stylesheets on the same afternoon -- each having to work out first that
|
|
994 |
+ |
// app CSS outranks this crate's cascade layer, so adding the space the
|
|
995 |
+ |
// obvious way, as `content`, silently wins over the glyph and leaves the
|
|
996 |
+ |
// heading with no caret at all. A consumer should not have to know that, and
|
|
997 |
+ |
// with the space emitted here there is nothing left for one to add.
|
|
998 |
+ |
//
|
|
999 |
+ |
// The unsorted arm reserves the same box with the glyph hidden, so pressing
|
|
1000 |
+ |
// a heading does not reflow the row it sits in. Hidden rather than sized:
|
|
1001 |
+ |
// the reservation is the caret's own width, so it names no magnitude and
|
|
1002 |
+ |
// stays out of `makeover-geometry`'s territory.
|
|
1003 |
+ |
let _ = writeln!(
|
|
1004 |
+ |
css,
|
|
1005 |
+ |
".{heading}[data-sortable]::after \
|
|
1006 |
+ |
{{\n content: \" \\2191\";\n visibility: hidden;\n}}"
|
|
1007 |
+ |
);
|
| 990 |
1008 |
|
for (direction, caret) in [("ascending", "\\2191"), ("descending", "\\2193")] {
|
| 991 |
1009 |
|
let _ = writeln!(
|
| 992 |
1010 |
|
css,
|
| 993 |
|
- |
".{heading}[aria-sort=\"{direction}\"]::after {{\n content: \"{caret}\";\n}}"
|
|
1011 |
+ |
".{heading}[aria-sort=\"{direction}\"]::after \
|
|
1012 |
+ |
{{\n content: \" {caret}\";\n visibility: visible;\n}}"
|
| 994 |
1013 |
|
);
|
| 995 |
1014 |
|
}
|
| 996 |
1015 |
|
css
|
| 1780 |
1799 |
|
assert_eq!(option_class(Selector::Tabs), "tab");
|
| 1781 |
1800 |
|
}
|
| 1782 |
1801 |
|
|
|
1802 |
+ |
#[test]
|
|
1803 |
+ |
fn the_caret_brings_its_own_gap_and_its_own_reserved_box() {
|
|
1804 |
+ |
let css = stylesheet(&Emit::default());
|
|
1805 |
+ |
|
|
1806 |
+ |
// The space is inside the glyph, which is what the other two renderers
|
|
1807 |
+ |
// write. Emitted bare, every consumer has to add it back, and the
|
|
1808 |
+ |
// obvious way to add it -- `content` in an app stylesheet, which is
|
|
1809 |
+ |
// unlayered and so outranks this sheet -- deletes the caret instead.
|
|
1810 |
+ |
assert!(css.contains("content: \" \\2191\";"), "{css}");
|
|
1811 |
+ |
assert!(css.contains("content: \" \\2193\";"), "{css}");
|
|
1812 |
+ |
assert!(!css.contains("content: \"\\2"), "{css}");
|
|
1813 |
+ |
|
|
1814 |
+ |
// The unsorted arm holds the box open so pressing a heading does not
|
|
1815 |
+ |
// move the row, and the sorted arms have to turn the glyph back on
|
|
1816 |
+ |
// after it: same specificity, so order is what decides.
|
|
1817 |
+ |
let reserve = css
|
|
1818 |
+ |
.find(".table-heading[data-sortable]::after")
|
|
1819 |
+ |
.expect("the reserved box is emitted");
|
|
1820 |
+ |
let sorted = css
|
|
1821 |
+ |
.find(".table-heading[aria-sort=\"ascending\"]::after")
|
|
1822 |
+ |
.expect("the ascending caret is emitted");
|
|
1823 |
+ |
assert!(reserve < sorted, "{css}");
|
|
1824 |
+ |
assert!(css[reserve..sorted].contains("visibility: hidden;"), "{css}");
|
|
1825 |
+ |
assert!(css[sorted..].contains("visibility: visible;"), "{css}");
|
|
1826 |
+ |
}
|
|
1827 |
+ |
|
| 1783 |
1828 |
|
#[test]
|
| 1784 |
1829 |
|
fn a_destructive_button_has_somewhere_for_its_tone_to_land() {
|
| 1785 |
1830 |
|
let css = component_rules(&Emit::default());
|
| 1907 |
1952 |
|
// with the pointer, and the caret is this renderer's own
|
| 1908 |
1953 |
|
// expression of `aria-sort`. Neither is a colour, which is
|
| 1909 |
1954 |
|
// what this test is actually about, and neither is a size,
|
| 1910 |
|
- |
// which is the other thing this crate must not name.
|
| 1911 |
|
- |
|| value.starts_with("\"\\2")
|
|
1955 |
+ |
// which is the other thing this crate must not name. The
|
|
1956 |
+ |
// leading space inside the glyph is the same thing the other
|
|
1957 |
+ |
// two renderers write into theirs, so it is part of the
|
|
1958 |
+ |
// caret rather than spacing this crate decided on.
|
|
1959 |
+ |
|| value
|
|
1960 |
+ |
.trim_start_matches('"')
|
|
1961 |
+ |
.trim_start()
|
|
1962 |
+ |
.starts_with("\\2")
|
| 1912 |
1963 |
|
|| matches!(
|
| 1913 |
1964 |
|
value.trim_end_matches(';'),
|
| 1914 |
1965 |
|
"0" | "1"
|
| 1916 |
1967 |
|
| "auto"
|
| 1917 |
1968 |
|
| "not-allowed"
|
| 1918 |
1969 |
|
| "pointer"
|
|
1970 |
+ |
// The caret's reserved box. Visibility is presence,
|
|
1971 |
+ |
// not magnitude and not colour.
|
|
1972 |
+ |
| "hidden"
|
|
1973 |
+ |
| "visible"
|
| 1919 |
1974 |
|
// The table frame. `display` is structure and not a
|
| 1920 |
1975 |
|
// size; `nowrap` is what makes a content column
|
| 1921 |
1976 |
|
// content. The two widths are the awkward pair and
|