pub const SIZES_FULL_BLEED: &str = "100vw";
pub const SIZES_WIDE: &str = "(min-width: 48rem) min(63rem, 100vw), 100vw";
pub const SIZES_PAGE: &str = "(min-width: 48rem) min(1200px, 100vw), 100vw";
pub const SIZES_BODY: &str = "(min-width: 48rem) 47.25rem, 100vw";
pub const SIZES_CARD: &str = "(min-width: 48rem) 24rem, 100vw";
pub const SIZES_GALLERY: &str = "(min-width: 48rem) 33vw, 100vw";
pub fn sizes_for_data_width(width: &str) -> Option<&'static str> {
match width {
"wide" => Some(SIZES_WIDE),
"page" => Some(SIZES_PAGE),
"screen" | "full" => Some(SIZES_FULL_BLEED),
_ => None,
}
}
pub fn sizes_for_grid_cell(columns: u32, data_width: Option<&str>) -> String {
let band: &str = match data_width {
Some("wide") => "min(63rem, 100vw)",
Some("page") => "min(1200px, 100vw)",
Some("screen") | Some("full") => "100vw",
_ => "min(47.25rem, 100vw)",
};
let cols = columns.max(1);
if cols == 1 {
format!("(min-width: 48rem) {band}, 100vw")
} else {
format!("(min-width: 48rem) calc({band} / {cols}), 100vw")
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn sizes_strings_are_wellformed() {
let grid_samples: Vec<String> = (1..=4)
.flat_map(|n| {
[None, Some("wide"), Some("page"), Some("screen")]
.into_iter()
.map(move |w| sizes_for_grid_cell(n, w))
})
.collect();
for s in [SIZES_FULL_BLEED, SIZES_BODY, SIZES_CARD, SIZES_GALLERY, SIZES_WIDE, SIZES_PAGE]
.into_iter()
.chain(grid_samples.iter().map(String::as_str))
{
assert!(!s.is_empty());
assert!(!s.contains('"'));
let last = s.rsplit(',').next().unwrap();
assert!(
!last.contains('('),
"last sizes entry must be an unconditional length: {s}"
);
let mut depth: i32 = 0;
for c in s.chars() {
match c {
'(' => depth += 1,
')' => {
depth -= 1;
assert!(depth >= 0, "unbalanced parentheses: {s}");
}
_ => {}
}
}
assert_eq!(depth, 0, "unbalanced parentheses: {s}");
}
}
#[test]
fn data_width_mapping() {
assert_eq!(sizes_for_data_width("wide"), Some(SIZES_WIDE));
assert_eq!(sizes_for_data_width("page"), Some(SIZES_PAGE));
assert_eq!(sizes_for_data_width("screen"), Some(SIZES_FULL_BLEED));
assert_eq!(sizes_for_data_width("full"), Some(SIZES_FULL_BLEED));
assert_eq!(sizes_for_data_width("body"), None);
assert_eq!(sizes_for_data_width("55%"), None);
}
#[test]
fn grid_cell_declares_cell_not_column() {
assert_eq!(
sizes_for_grid_cell(3, None),
"(min-width: 48rem) calc(min(47.25rem, 100vw) / 3), 100vw"
);
assert_eq!(
sizes_for_grid_cell(3, Some("page")),
"(min-width: 48rem) calc(min(1200px, 100vw) / 3), 100vw"
);
assert_eq!(
sizes_for_grid_cell(1, Some("screen")),
"(min-width: 48rem) 100vw, 100vw"
);
assert_eq!(
sizes_for_grid_cell(0, None),
"(min-width: 48rem) min(47.25rem, 100vw), 100vw"
);
}
}