Skip to main content

whisker_css/data_type/
sizing.rs

1//! `<fit-content>` and `<max-content>` — track-sizing keywords used
2//! by `width`, `height`, `min-width`, `min-height`, `max-width`, and
3//! `max-height`.
4//!
5//! Lynx references:
6//! - <https://lynxjs.org/api/css/data-type/fit-content.html>
7//! - <https://lynxjs.org/api/css/data-type/max-content.html>
8
9use core::fmt;
10
11use crate::to_css::ToCss;
12
13use super::LengthPercentage;
14
15/// `<fit-content>` — sizes the box to the content with an optional
16/// upper bound.
17///
18/// `FitContent(None)` serializes to the bare `fit-content` keyword;
19/// `FitContent(Some(limit))` serializes to `fit-content(<limit>)`.
20#[derive(Clone, Debug, PartialEq)]
21pub struct FitContent(pub Option<LengthPercentage>);
22
23impl FitContent {
24    /// `fit-content` without an upper bound.
25    pub const fn keyword() -> Self {
26        Self(None)
27    }
28
29    /// `fit-content(<limit>)`.
30    pub fn with_limit(limit: impl Into<LengthPercentage>) -> Self {
31        Self(Some(limit.into()))
32    }
33}
34
35impl ToCss for FitContent {
36    fn to_css(&self, dest: &mut dyn fmt::Write) -> fmt::Result {
37        dest.write_str("fit-content")?;
38        if let Some(limit) = &self.0 {
39            dest.write_char('(')?;
40            limit.to_css(dest)?;
41            dest.write_char(')')?;
42        }
43        Ok(())
44    }
45}
46
47/// `<max-content>` — sizes the box to its maximum intrinsic content
48/// size.
49#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Default)]
50pub struct MaxContent;
51
52impl ToCss for MaxContent {
53    fn to_css(&self, dest: &mut dyn fmt::Write) -> fmt::Result {
54        dest.write_str("max-content")
55    }
56}
57
58#[cfg(test)]
59mod tests {
60    use super::*;
61    use crate::data_type::Length;
62
63    #[test]
64    fn fit_content_keyword() {
65        assert_eq!(FitContent::keyword().to_css_string(), "fit-content");
66    }
67
68    #[test]
69    fn fit_content_with_limit() {
70        let fc = FitContent::with_limit(Length::Px(200.0));
71        assert_eq!(fc.to_css_string(), "fit-content(200px)");
72    }
73
74    #[test]
75    fn max_content_keyword() {
76        assert_eq!(MaxContent.to_css_string(), "max-content");
77    }
78}