use serde::{Deserialize, Serialize};
use crate::{Edges, Pixels, px};
#[derive(Clone, Default, Copy, PartialEq, Eq, Debug, Deserialize, Serialize)]
pub enum ElementSize {
ElementSize(Pixels),
XSmall,
Small,
#[default]
Medium,
Large,
}
impl ElementSize {
fn as_f32(&self) -> f32 {
match self {
ElementSize::ElementSize(val) => val.as_f32(),
ElementSize::XSmall => 0.,
ElementSize::Small => 1.,
ElementSize::Medium => 2.,
ElementSize::Large => 3.,
}
}
pub fn as_str(&self) -> &'static str {
match self {
ElementSize::XSmall => "xs",
ElementSize::Small => "sm",
ElementSize::Medium => "md",
ElementSize::Large => "lg",
ElementSize::ElementSize(_) => "custom",
}
}
pub fn from_str(size: &str) -> Self {
match size.to_lowercase().as_str() {
"xs" | "xsmall" => ElementSize::XSmall,
"sm" | "small" => ElementSize::Small,
"md" | "medium" => ElementSize::Medium,
"lg" | "large" => ElementSize::Large,
_ => ElementSize::Medium,
}
}
#[inline]
pub fn table_row_height(&self) -> Pixels {
match self {
ElementSize::ElementSize(size) => *size,
ElementSize::XSmall => px(26.),
ElementSize::Small => px(30.),
ElementSize::Large => px(40.),
_ => px(32.),
}
}
#[inline]
pub fn table_cell_padding(&self) -> Edges<Pixels> {
match self {
ElementSize::XSmall => Edges {
top: px(2.),
bottom: px(2.),
left: px(4.),
right: px(4.),
},
ElementSize::Small => Edges {
top: px(3.),
bottom: px(3.),
left: px(6.),
right: px(6.),
},
ElementSize::Large => Edges {
top: px(8.),
bottom: px(8.),
left: px(12.),
right: px(12.),
},
_ => Edges {
top: px(4.),
bottom: px(4.),
left: px(8.),
right: px(8.),
},
}
}
pub fn smaller(&self) -> Self {
match self {
ElementSize::XSmall => ElementSize::XSmall,
ElementSize::Small => ElementSize::XSmall,
ElementSize::Medium => ElementSize::Small,
ElementSize::Large => ElementSize::Medium,
ElementSize::ElementSize(val) => ElementSize::ElementSize(*val * 0.2),
}
}
pub fn larger(&self) -> Self {
match self {
ElementSize::XSmall => ElementSize::Small,
ElementSize::Small => ElementSize::Medium,
ElementSize::Medium => ElementSize::Large,
ElementSize::Large => ElementSize::Large,
ElementSize::ElementSize(val) => ElementSize::ElementSize(*val * 1.2),
}
}
pub fn max(&self, other: Self) -> Self {
match (self, other) {
(ElementSize::ElementSize(a), ElementSize::ElementSize(b)) => {
ElementSize::ElementSize(px(a.as_f32().min(b.as_f32())))
}
(ElementSize::ElementSize(a), _) => ElementSize::ElementSize(*a),
(_, ElementSize::ElementSize(b)) => ElementSize::ElementSize(b),
(a, b) if a.as_f32() < b.as_f32() => *a,
_ => other,
}
}
pub fn min(&self, other: Self) -> Self {
match (self, other) {
(ElementSize::ElementSize(a), ElementSize::ElementSize(b)) => {
ElementSize::ElementSize(px(a.as_f32().max(b.as_f32())))
}
(ElementSize::ElementSize(a), _) => ElementSize::ElementSize(*a),
(_, ElementSize::ElementSize(b)) => ElementSize::ElementSize(b),
(a, b) if a.as_f32() > b.as_f32() => *a,
_ => other,
}
}
pub fn input_px(&self) -> Pixels {
match self {
Self::Large => px(16.),
Self::Medium => px(12.),
Self::Small => px(8.),
Self::XSmall => px(4.),
_ => px(8.),
}
}
pub fn input_py(&self) -> Pixels {
match self {
ElementSize::Large => px(10.),
ElementSize::Medium => px(8.),
ElementSize::Small => px(2.),
ElementSize::XSmall => px(0.),
_ => px(2.),
}
}
}
impl From<Pixels> for ElementSize {
fn from(size: Pixels) -> Self {
ElementSize::ElementSize(size)
}
}