based/src/ui/primitives/space.rs
2025-02-18 18:29:13 +01:00

232 lines
5 KiB
Rust

use crate::ui::UIWidget;
use maud::{Markup, Render, html};
#[allow(non_snake_case)]
/// Controlling the space between child elements.
pub fn SpaceBetween<T: UIWidget + 'static>(inner: T) -> SpaceBetweenWidget {
SpaceBetweenWidget(Box::new(inner), None, None)
}
pub struct SpaceBetweenWidget(Box<dyn UIWidget>, Option<ScreenValue>, Option<ScreenValue>);
impl Render for SpaceBetweenWidget {
fn render(&self) -> Markup {
self.render_with_class("")
}
}
impl SpaceBetweenWidget {
#[must_use]
pub const fn x(mut self, x: ScreenValue) -> Self {
self.1 = Some(x);
self
}
#[must_use]
pub const fn y(mut self, y: ScreenValue) -> Self {
self.2 = Some(y);
self
}
}
impl UIWidget for SpaceBetweenWidget {
fn can_inherit(&self) -> bool {
true
}
fn base_class(&self) -> Vec<String> {
let mut ret = Vec::new();
if let Some(x) = &self.1 {
ret.push(format!("space-x-{}", x.to_value()));
}
if let Some(y) = &self.2 {
ret.push(format!("space-y-{}", y.to_value()));
}
ret
}
fn extended_class(&self) -> Vec<String> {
let mut c = self.base_class();
c.extend_from_slice(&self.0.extended_class());
c
}
fn render_with_class(&self, class: &str) -> Markup {
if self.0.as_ref().can_inherit() {
self.0
.as_ref()
.render_with_class(&format!("{} {class}", self.base_class().join(" ")))
} else {
html! {
div class=(format!("{} {class}", self.base_class().join(" "))) {
(self.0.as_ref())
}
}
}
}
}
#[allow(non_camel_case_types)]
#[derive(Debug, Clone, Copy)]
pub enum ScreenValue {
_0,
_0p5,
_1,
_1p5,
_2,
_2p5,
_3,
_3p5,
_4,
_5,
_6,
_7,
_8,
_9,
_10,
_11,
_12,
_14,
_16,
_20,
_24,
_28,
_32,
_36,
_40,
_44,
_48,
_52,
_56,
_60,
_64,
_72,
_80,
_90,
px,
reverse,
min,
max,
fit,
fill,
screen,
full,
auto,
}
impl ScreenValue {
#[must_use]
pub const fn to_value(&self) -> &str {
match self {
Self::_0 => "0",
Self::_0p5 => "0.5",
Self::_1 => "1",
Self::_1p5 => "1.5",
Self::_2 => "2",
Self::_2p5 => "2.5",
Self::_3 => "3",
Self::_3p5 => "3.5",
Self::_4 => "4",
Self::_5 => "5",
Self::_6 => "6",
Self::_7 => "7",
Self::_8 => "8",
Self::_9 => "9",
Self::_10 => "10",
Self::_11 => "11",
Self::_12 => "12",
Self::_14 => "14",
Self::_16 => "16",
Self::_20 => "20",
Self::_24 => "24",
Self::_28 => "28",
Self::_32 => "32",
Self::_36 => "36",
Self::_40 => "40",
Self::_44 => "44",
Self::_48 => "48",
Self::_52 => "52",
Self::_56 => "56",
Self::_60 => "60",
Self::_64 => "64",
Self::_72 => "72",
Self::_80 => "80",
Self::_90 => "90",
Self::px => "px",
Self::reverse => "reverse",
Self::min => "min",
Self::max => "max",
Self::fit => "fit",
Self::fill => "fill",
Self::screen => "screen",
Self::full => "full",
Self::auto => "auto",
}
}
}
#[derive(Debug, Clone, Copy)]
pub enum Fraction {
_1on2,
_1on3,
_2on3,
_1on4,
_2on4,
_3on4,
_1on5,
_2on5,
_3on5,
_4on5,
_1on6,
_2on6,
_3on6,
_4on6,
_5on6,
_1on12,
_2on12,
_3on12,
_4on12,
_5on12,
_6on12,
_7on12,
_8on12,
_9on12,
_10on12,
_11on12,
}
impl Fraction {
pub const fn to_value(&self) -> &str {
match self {
Fraction::_1on2 => "1/2",
Fraction::_1on3 => "1/3",
Fraction::_2on3 => "2/3",
Fraction::_1on4 => "1/4",
Fraction::_2on4 => "2/4",
Fraction::_3on4 => "3/4",
Fraction::_1on5 => "1/5",
Fraction::_2on5 => "2/5",
Fraction::_3on5 => "3/5",
Fraction::_4on5 => "4/5",
Fraction::_1on6 => "1/6",
Fraction::_2on6 => "2/6",
Fraction::_3on6 => "3/6",
Fraction::_4on6 => "4/6",
Fraction::_5on6 => "5/6",
Fraction::_1on12 => "1/12",
Fraction::_2on12 => "2/12",
Fraction::_3on12 => "3/12",
Fraction::_4on12 => "4/12",
Fraction::_5on12 => "5/12",
Fraction::_6on12 => "6/12",
Fraction::_7on12 => "7/12",
Fraction::_8on12 => "8/12",
Fraction::_9on12 => "9/12",
Fraction::_10on12 => "10/12",
Fraction::_11on12 => "11/12",
}
}
}