css-style 0.14.1

Typed CSS Style
Documentation
use crate::{calc::Calc, unit::*, Style, StyleUpdater};
use derive_rich::Rich;

/// ```
/// use css_style::{Style, unit::px};
///
/// Style::default()
///     .and_position(|conf| {
///         conf.absolute().top(px(28)).left(px(40))
///     });
/// ```
#[derive(Rich, Clone, Debug, PartialEq, Default)]
pub struct Position {
    #[rich(write(rename = position), write(option, rename = try_position), value_fns = {
        static_ = PositionType::Static,
        absolute = PositionType::Absolute,
        fixed = PositionType::Fixed,
        relative = PositionType::Relative,
        sticky = PositionType::Sticky,
        initial = PositionType::Initial,
        inherit = PositionType::Inherit,
    })]
    pub position: Option<PositionType>,
    #[rich(write, write(option))]
    pub left: Option<PostionLength>,
    #[rich(write, write(option))]
    pub top: Option<PostionLength>,
    #[rich(write, write(option))]
    pub right: Option<PostionLength>,
    #[rich(write, write(option))]
    pub bottom: Option<PostionLength>,
    #[rich(write, write(option))]
    pub z_index: Option<i32>,
    #[rich(write, write(option))]
    pub clip: Option<Clip>,
}

impl Position {
    pub fn move_top(self) -> Self {
        self.top(px(0))
    }

    pub fn move_right(self) -> Self {
        self.right(px(0))
    }

    pub fn move_bottom(self) -> Self {
        self.bottom(px(0))
    }

    pub fn move_left(self) -> Self {
        self.left(px(0))
    }

    pub fn move_top_stretch(self) -> Self {
        self.move_top().move_left().move_right()
    }

    pub fn move_right_stretch(self) -> Self {
        self.move_right().move_top().move_bottom()
    }

    pub fn move_bottom_stretch(self) -> Self {
        self.move_bottom().move_left().move_right()
    }

    pub fn move_left_stretch(self) -> Self {
        self.move_left().move_top().move_bottom()
    }

    pub fn move_top_right(self) -> Self {
        self.move_top().move_right()
    }

    pub fn move_top_left(self) -> Self {
        self.move_top().move_left()
    }

    pub fn move_bottom_right(self) -> Self {
        self.move_bottom().move_right()
    }

    pub fn move_bottom_left(self) -> Self {
        self.move_bottom().move_left()
    }

    pub fn cover(self) -> Self {
        self.move_top_right().move_bottom_left()
    }
}

impl StyleUpdater for Position {
    fn update_style(self, style: Style) -> Style {
        style
            .try_insert("position", self.position.as_ref())
            .try_insert("left", self.left.as_ref())
            .try_insert("top", self.top.as_ref())
            .try_insert("right", self.right.as_ref())
            .try_insert("bottom", self.bottom.as_ref())
            .try_insert("z-index", self.z_index.as_ref())
            .try_insert("clip", self.clip.as_ref())
    }
}

impl<T> From<T> for Position
where
    T: Into<PositionType>,
{
    fn from(source: T) -> Self {
        Self {
            position: Some(source.into()),
            ..Position::default()
        }
    }
}

#[derive(Clone, Debug, PartialEq, Display, From)]
pub enum PostionLength {
    #[display(fmt = "initial")]
    Initial,
    #[display(fmt = "inherit")]
    Inherit,
    #[display(fmt = "auto")]
    Auto,
    #[from]
    Length(Length),
    #[from(forward)]
    Percent(Percent),
}

impl From<Calc> for PostionLength {
    fn from(source: Calc) -> Self {
        PostionLength::Length(source.into())
    }
}

#[derive(Clone, Debug, PartialEq, Display, From)]
pub enum Clip {
    #[display(fmt = "auto")]
    Auto,
    #[display(fmt = "rect({}, {}, {}, {})", top, right, bottom, left)]
    ShapeRect {
        top: ClipRectLength,
        right: ClipRectLength,
        bottom: ClipRectLength,
        left: ClipRectLength,
    },
    #[display(fmt = "initial")]
    Initial,
    #[display(fmt = "inherit")]
    Inherit,
}

impl Clip {
    pub fn rect(
        top: impl Into<ClipRectLength>,
        right: impl Into<ClipRectLength>,
        bottom: impl Into<ClipRectLength>,
        left: impl Into<ClipRectLength>,
    ) -> Self {
        Self::ShapeRect {
            top: top.into(),
            right: right.into(),
            bottom: bottom.into(),
            left: left.into(),
        }
    }
}

#[derive(Clone, Debug, PartialEq, Display, From)]
pub enum ClipRectLength {
    #[display(fmt = "initial")]
    Initial,
    #[display(fmt = "inherit")]
    Inherit,
    #[display(fmt = "auto")]
    Auto,
    #[from]
    Length(Length),
    #[from(forward)]
    Percent(Percent),
}

impl From<Calc> for ClipRectLength {
    fn from(source: Calc) -> Self {
        ClipRectLength::Length(source.into())
    }
}

#[derive(Clone, Copy, Debug, PartialEq, Display, From)]
pub enum PositionType {
    #[display(fmt = "static")]
    Static,
    #[display(fmt = "absolute")]
    Absolute,
    #[display(fmt = "fixed")]
    Fixed,
    #[display(fmt = "relative")]
    Relative,
    #[display(fmt = "sticky")]
    Sticky,
    #[display(fmt = "initial")]
    Initial,
    #[display(fmt = "inherit")]
    Inherit,
}