makeover-layout 0.52.1

The renderer-agnostic half of the make-family design system: what a thing IS, named as intents and relationships and never as values. Colour defers to makeover, spacing to makeover-geometry; what is left is composition, plus which affordances exist at a given input class and window size.
Documentation
/// How a picture sits in the box it is given.
///
/// An intent rather than a value, so a renderer picks the expression it has:
/// `object-fit` in a webview, a texture's UV rect in egui, and in a terminal a
/// choice about how many cells the blit gets. Named because MNW already makes
/// the distinction deliberately at 17 sites and makes it three different ways,
/// which is a policy the app decided rather than one a shared crate would be
/// picking by accident.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
#[non_exhaustive]
pub enum Fit {
    /// The picture's own proportions, and the box takes the height they imply.
    ///
    /// The default because it is the only one that shows the whole picture at
    /// its own shape, so a renderer that ignores this enum entirely is still
    /// right about the common case. A screenshot wants this; the shipped MNW
    /// carousel sets no `object-fit` at all, which is this.
    #[default]
    Natural,
    /// Fill the box and crop whatever does not fit.
    ///
    /// For a picture in a slot whose shape the layout fixed: a thumbnail, an
    /// avatar, cover art. 15 of MNW's 17 sites.
    Cover,
    /// Fit inside the box whole, leaving space on two sides.
    ///
    /// The letterbox. For when the whole picture matters more than filling the
    /// space, and the space is not the picture's shape.
    Contain,
}

/// A picture's own pixel dimensions.
///
/// Deliberately not [`makeover_geometry`]'s business. Geometry answers *how
/// much space a thing should get*, which is a scale question with the same
/// answer on every screen. This is the intrinsic size of one asset, which is a
/// fact about that asset and varies per picture.
///
/// [`makeover_geometry`]: https://docs.rs/makeover-geometry
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub struct Extent {
    /// Width in the picture's own pixels.
    pub width: u32,
    /// Height in the picture's own pixels.
    pub height: u32,
}

impl Extent {
    /// A picture's dimensions.
    #[must_use]
    pub const fn new(width: u32, height: u32) -> Self {
        Self { width, height }
    }

    /// Width over height, or `None` if either side is zero.
    ///
    /// The form a renderer actually reserves space with: a box that knows its
    /// proportion holds the right height at any width, which is what a
    /// responsive picture needs and what a fixed pixel height cannot give.
    #[must_use]
    pub fn ratio(self) -> Option<f32> {
        (self.width > 0 && self.height > 0).then(|| self.width as f32 / self.height as f32)
    }
}