From b752d77815a4ac44343e2c12aa1553164b81d0e9 Mon Sep 17 00:00:00 2001 From: JMARyA Date: Mon, 20 Jan 2025 23:09:36 +0100 Subject: [PATCH] add position --- src/ui/mod.rs | 1 + src/ui/primitives/mod.rs | 4 +- src/ui/primitives/position.rs | 210 ++++++++++++++++++++++++++++++++++ 3 files changed, 213 insertions(+), 2 deletions(-) create mode 100644 src/ui/primitives/position.rs diff --git a/src/ui/mod.rs b/src/ui/mod.rs index bb8a803..3e37b3b 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -41,6 +41,7 @@ pub mod prelude { pub use super::primitives::link::Link; pub use super::primitives::margin::Margin; pub use super::primitives::padding::Padding; + pub use super::primitives::position::{Position, PositionKind}; pub use super::primitives::rounded::Rounded; pub use super::primitives::script; pub use super::primitives::shadow::Shadow; diff --git a/src/ui/primitives/mod.rs b/src/ui/primitives/mod.rs index 1ddc144..d0acf64 100644 --- a/src/ui/primitives/mod.rs +++ b/src/ui/primitives/mod.rs @@ -1,6 +1,5 @@ -use maud::{PreEscaped, html}; - use super::UIWidget; +use maud::{PreEscaped, html}; pub mod animation; pub mod aspect; @@ -18,6 +17,7 @@ pub mod input; pub mod link; pub mod margin; pub mod padding; +pub mod position; pub mod rounded; pub mod shadow; pub mod sized; diff --git a/src/ui/primitives/position.rs b/src/ui/primitives/position.rs new file mode 100644 index 0000000..75531ce --- /dev/null +++ b/src/ui/primitives/position.rs @@ -0,0 +1,210 @@ +use maud::{Markup, Render, html}; + +use crate::ui::UIWidget; + +#[allow(non_snake_case)] +pub fn Position(kind: PositionKind, inner: T) -> Positioned { + Positioned { + inner: Box::new(inner), + kind, + inset: None, + inset_x: None, + inset_y: None, + start: None, + end: None, + top: None, + right: None, + bottom: None, + left: None, + } +} + +pub struct Positioned { + inner: Box, + kind: PositionKind, + inset: Option, + inset_x: Option, + inset_y: Option, + start: Option, + end: Option, + top: Option, + right: Option, + bottom: Option, + left: Option, +} + +impl Positioned { + pub fn inset(mut self, value: i64) -> Self { + self.inset = Some(value); + self + } + pub fn inset_x(mut self, value: i64) -> Self { + self.inset_x = Some(value); + self + } + + pub fn inset_y(mut self, value: i64) -> Self { + self.inset_y = Some(value); + self + } + + pub fn start(mut self, value: i64) -> Self { + self.start = Some(value); + self + } + + pub fn end(mut self, value: i64) -> Self { + self.end = Some(value); + self + } + + pub fn top(mut self, value: i64) -> Self { + self.top = Some(value); + self + } + + pub fn right(mut self, value: i64) -> Self { + self.right = Some(value); + self + } + + pub fn bottom(mut self, value: i64) -> Self { + self.bottom = Some(value); + self + } + + pub fn left(mut self, value: i64) -> Self { + self.left = Some(value); + self + } +} + +impl Render for Positioned { + fn render(&self) -> Markup { + self.render_with_class("") + } +} + +impl UIWidget for Positioned { + fn can_inherit(&self) -> bool { + true + } + + fn base_class(&self) -> Vec { + let mut ret = vec![self.kind.to_value().to_string()]; + + if let Some(inset) = &self.inset { + if inset.is_negative() { + ret.push(format!("-inset-[{inset}px]")); + } else { + ret.push(format!("inset-[{inset}px]")); + } + } + + if let Some(inset) = &self.inset_x { + if inset.is_negative() { + ret.push(format!("-inset-x-[{inset}px]")); + } else { + ret.push(format!("inset-x-[{inset}px]")); + } + } + + if let Some(inset) = &self.inset_y { + if inset.is_negative() { + ret.push(format!("-inset-y-[{inset}px]")); + } else { + ret.push(format!("inset-y-[{inset}px]")); + } + } + + if let Some(start) = &self.start { + if start.is_negative() { + ret.push(format!("-start-[{start}px]")); + } else { + ret.push(format!("start-[{start}px]")); + } + } + + if let Some(end) = &self.end { + if end.is_negative() { + ret.push(format!("-end-[{end}px]")); + } else { + ret.push(format!("end-[{end}px]")); + } + } + + if let Some(value) = &self.top { + if value.is_negative() { + ret.push(format!("-top-[{value}px]")); + } else { + ret.push(format!("top-[{value}px]")); + } + } + + if let Some(value) = &self.right { + if value.is_negative() { + ret.push(format!("-right-[{value}px]")); + } else { + ret.push(format!("right-[{value}px]")); + } + } + + if let Some(value) = &self.bottom { + if value.is_negative() { + ret.push(format!("-bottom-[{value}px]")); + } else { + ret.push(format!("bottom-[{value}px]")); + } + } + + if let Some(value) = &self.left { + if value.is_negative() { + ret.push(format!("-left-[{value}px]")); + } else { + ret.push(format!("left-[{value}px]")); + } + } + + ret + } + + fn extended_class(&self) -> Vec { + let mut c = self.base_class(); + c.extend_from_slice(&self.inner.extended_class()); + c + } + + fn render_with_class(&self, class: &str) -> Markup { + if self.inner.as_ref().can_inherit() { + self.inner + .as_ref() + .render_with_class(&format!("{} {class}", self.base_class().join(" "))) + } else { + html! { + div class=(format!("{} {class}", self.base_class().join(" "))) { + (self.inner.as_ref()) + } + } + } + } +} + +pub enum PositionKind { + Static, + Fixed, + Absolute, + Relative, + Sticky, +} + +impl PositionKind { + pub const fn to_value(&self) -> &str { + match self { + PositionKind::Static => "static", + PositionKind::Fixed => "fixed", + PositionKind::Absolute => "absolute", + PositionKind::Relative => "relative", + PositionKind::Sticky => "sticky", + } + } +}