update + text
This commit is contained in:
parent
340f014365
commit
bf72429ac5
6 changed files with 703 additions and 19 deletions
|
@ -12,6 +12,10 @@ pub mod ui;
|
|||
|
||||
// Postgres
|
||||
|
||||
// TODO : IDEA
|
||||
// more efficient table join using WHERE ANY instead of multiple SELECTs
|
||||
// map_tables(Vec<T>, Fn(&T) -> U) -> Vec<U>
|
||||
|
||||
pub static PG: OnceCell<sqlx::PgPool> = OnceCell::const_new();
|
||||
|
||||
/// A macro to retrieve or initialize the `PostgreSQL` connection pool.
|
||||
|
|
|
@ -39,7 +39,12 @@ pub mod prelude {
|
|||
pub use super::primitives::shadow::Shadow;
|
||||
pub use super::primitives::sized::Sized;
|
||||
pub use super::primitives::space::{ScreenValue, SpaceBetween};
|
||||
pub use super::primitives::text::{Paragraph, Span, Text};
|
||||
pub use super::primitives::text::{
|
||||
DecorationKind, DecorationStyle, DecorationThickness, LetterSpacing, LineClamp, LineHeight,
|
||||
ListStyle, NumberStyle, Paragraph, Span, Text, TextAlignment, TextContent, TextDecoration,
|
||||
TextHyphens, TextOverflow, TextTransform, TextWhitespace, TextWordBreak, TextWrap,
|
||||
UnderlineOffset, VerticalTextAlignment,
|
||||
};
|
||||
pub use super::primitives::visibility::Visibility;
|
||||
pub use super::primitives::width::{MaxWidth, MinWidth, Width};
|
||||
pub use super::primitives::zindex::ZIndex;
|
||||
|
|
|
@ -67,6 +67,7 @@ impl DivWidget {
|
|||
self
|
||||
}
|
||||
|
||||
// todo : Fix weird types
|
||||
#[must_use]
|
||||
pub fn push_for_each<
|
||||
T: UIWidget + 'static,
|
||||
|
|
|
@ -1,24 +1,36 @@
|
|||
use crate::ui::UIWidget;
|
||||
use maud::{Markup, Render, html};
|
||||
|
||||
use super::space::ScreenValue;
|
||||
use super::{
|
||||
flex::Either,
|
||||
space::{Fraction, ScreenValue},
|
||||
};
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
pub fn Height<T: UIWidget + 'static>(size: ScreenValue, inner: T) -> HeightWidget {
|
||||
pub fn Height<T: UIWidget + 'static>(
|
||||
size: Either<ScreenValue, Fraction>,
|
||||
inner: T,
|
||||
) -> HeightWidget {
|
||||
HeightWidget(Box::new(inner), size, 0)
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
pub fn MinHeight<T: UIWidget + 'static>(size: ScreenValue, inner: T) -> HeightWidget {
|
||||
pub fn MinHeight<T: UIWidget + 'static>(
|
||||
size: Either<ScreenValue, Fraction>,
|
||||
inner: T,
|
||||
) -> HeightWidget {
|
||||
HeightWidget(Box::new(inner), size, 1)
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
pub fn MaxHeight<T: UIWidget + 'static>(size: ScreenValue, inner: T) -> HeightWidget {
|
||||
pub fn MaxHeight<T: UIWidget + 'static>(
|
||||
size: Either<ScreenValue, Fraction>,
|
||||
inner: T,
|
||||
) -> HeightWidget {
|
||||
HeightWidget(Box::new(inner), size, 2)
|
||||
}
|
||||
|
||||
pub struct HeightWidget(Box<dyn UIWidget>, ScreenValue, u8);
|
||||
pub struct HeightWidget(Box<dyn UIWidget>, Either<ScreenValue, Fraction>, u8);
|
||||
|
||||
impl Render for HeightWidget {
|
||||
fn render(&self) -> Markup {
|
||||
|
@ -34,15 +46,27 @@ impl UIWidget for HeightWidget {
|
|||
fn base_class(&self) -> Vec<String> {
|
||||
match self.2 {
|
||||
1 => {
|
||||
return vec![format!("min-h-{}", self.1.to_value())];
|
||||
return vec![format!(
|
||||
"min-h-{}",
|
||||
self.1
|
||||
.map(|x| x.to_value().to_string(), |x| x.to_value().to_string())
|
||||
)];
|
||||
}
|
||||
2 => {
|
||||
return vec![format!("max-h-{}", self.1.to_value())];
|
||||
return vec![format!(
|
||||
"max-h-{}",
|
||||
self.1
|
||||
.map(|x| x.to_value().to_string(), |x| x.to_value().to_string())
|
||||
)];
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
vec![format!("h-{}", self.1.to_value())]
|
||||
vec![format!(
|
||||
"h-{}",
|
||||
self.1
|
||||
.map(|x| x.to_value().to_string(), |x| x.to_value().to_string())
|
||||
)]
|
||||
}
|
||||
|
||||
fn extended_class(&self) -> Vec<String> {
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
use crate::ui::{UIWidget, color::UIColor};
|
||||
use maud::{Markup, Render, html};
|
||||
|
||||
use super::{Nothing, space::ScreenValue};
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
/// Text UI Widget
|
||||
#[must_use]
|
||||
|
@ -13,6 +15,21 @@ pub fn Text(txt: &str) -> TextWidget {
|
|||
color: String::new(),
|
||||
style: Vec::new(),
|
||||
size: String::new(),
|
||||
line_height: None,
|
||||
overflow: None,
|
||||
wrap: None,
|
||||
indent: None,
|
||||
transform: None,
|
||||
decoration: None,
|
||||
whitespace: None,
|
||||
wordbreak: None,
|
||||
hyphens: None,
|
||||
spacing: None,
|
||||
clamp: None,
|
||||
pseudo: None,
|
||||
align: None,
|
||||
vert_align: None,
|
||||
list_style: None,
|
||||
span: false,
|
||||
}
|
||||
}
|
||||
|
@ -28,6 +45,21 @@ pub fn Paragraph<T: UIWidget + 'static>(inner: T) -> TextWidget {
|
|||
txt: String::new(),
|
||||
style: Vec::new(),
|
||||
size: String::new(),
|
||||
indent: None,
|
||||
overflow: None,
|
||||
decoration: None,
|
||||
whitespace: None,
|
||||
wordbreak: None,
|
||||
hyphens: None,
|
||||
wrap: None,
|
||||
spacing: None,
|
||||
transform: None,
|
||||
pseudo: None,
|
||||
vert_align: None,
|
||||
line_height: None,
|
||||
list_style: None,
|
||||
clamp: None,
|
||||
align: None,
|
||||
span: false,
|
||||
}
|
||||
}
|
||||
|
@ -43,7 +75,22 @@ pub fn Span(txt: &str) -> TextWidget {
|
|||
font: String::new(),
|
||||
style: Vec::new(),
|
||||
color: String::new(),
|
||||
list_style: None,
|
||||
size: String::new(),
|
||||
indent: None,
|
||||
overflow: None,
|
||||
whitespace: None,
|
||||
wordbreak: None,
|
||||
hyphens: None,
|
||||
decoration: None,
|
||||
transform: None,
|
||||
wrap: None,
|
||||
vert_align: None,
|
||||
spacing: None,
|
||||
line_height: None,
|
||||
clamp: None,
|
||||
align: None,
|
||||
pseudo: None,
|
||||
span: true,
|
||||
}
|
||||
}
|
||||
|
@ -55,11 +102,44 @@ pub struct TextWidget {
|
|||
style: Vec<String>,
|
||||
font: String,
|
||||
color: String,
|
||||
list_style: Option<ListStyle>,
|
||||
line_height: Option<LineHeight>,
|
||||
decoration: Option<DecorationWidget>,
|
||||
transform: Option<TextTransform>,
|
||||
vert_align: Option<VerticalTextAlignment>,
|
||||
overflow: Option<TextOverflow>,
|
||||
indent: Option<ScreenValue>,
|
||||
wrap: Option<TextWrap>,
|
||||
whitespace: Option<TextWhitespace>,
|
||||
wordbreak: Option<TextWordBreak>,
|
||||
hyphens: Option<TextHyphens>,
|
||||
size: String,
|
||||
span: bool,
|
||||
spacing: Option<LetterSpacing>,
|
||||
pseudo: Option<TextContent>,
|
||||
align: Option<TextAlignment>,
|
||||
clamp: Option<LineClamp>,
|
||||
}
|
||||
|
||||
impl TextWidget {
|
||||
#[must_use]
|
||||
pub fn whitespace(mut self, whitespace: TextWhitespace) -> Self {
|
||||
self.whitespace = Some(whitespace);
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn wordbreak(mut self, wordbreak: TextWordBreak) -> Self {
|
||||
self.wordbreak = Some(wordbreak);
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn hyphen(mut self, hyphen: TextHyphens) -> Self {
|
||||
self.hyphens = Some(hyphen);
|
||||
self
|
||||
}
|
||||
|
||||
// Weight
|
||||
|
||||
#[must_use]
|
||||
|
@ -137,12 +217,78 @@ impl TextWidget {
|
|||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn wrap(mut self, wrap: TextWrap) -> Self {
|
||||
self.wrap = Some(wrap);
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn indentation(mut self, indent: ScreenValue) -> Self {
|
||||
self.indent = Some(indent);
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn align(mut self, alignment: TextAlignment) -> Self {
|
||||
self.align = Some(alignment);
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn align_vertical(mut self, alignment: VerticalTextAlignment) -> Self {
|
||||
self.vert_align = Some(alignment);
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn transform(mut self, transform: TextTransform) -> Self {
|
||||
self.transform = Some(transform);
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn number_style(mut self, s: NumberStyle) -> Self {
|
||||
self.style.push(s.to_value().to_string());
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn overflow(mut self, overflow: TextOverflow) -> Self {
|
||||
self.overflow = Some(overflow);
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn max_lines(mut self, l: LineClamp) -> Self {
|
||||
self.clamp = Some(l);
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn decoration(mut self, decoration: DecorationWidget) -> Self {
|
||||
self.decoration = Some(decoration);
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn list_style(mut self, style: ListStyle) -> Self {
|
||||
self.list_style = Some(style);
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn content(mut self, content: TextContent) -> Self {
|
||||
self.pseudo = Some(content);
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn line_height(mut self, height: LineHeight) -> Self {
|
||||
self.line_height = Some(height);
|
||||
self
|
||||
}
|
||||
|
||||
// Sizes
|
||||
|
||||
#[must_use]
|
||||
|
@ -291,12 +437,48 @@ impl UIWidget for TextWidget {
|
|||
}
|
||||
|
||||
fn base_class(&self) -> Vec<String> {
|
||||
vec![
|
||||
let mut ret = vec![
|
||||
self.color.clone(),
|
||||
self.font.clone(),
|
||||
self.size.clone(),
|
||||
self.family.clone(),
|
||||
]
|
||||
];
|
||||
|
||||
macro_rules! add_option {
|
||||
($opt:ident, $ret:ident) => {
|
||||
if let Some($opt) = &self.$opt {
|
||||
$ret.push($opt.to_value().to_string());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
add_option!(spacing, ret);
|
||||
|
||||
if let Some(indent) = &self.indent {
|
||||
ret.push(format!("indent-{}", indent.to_value()));
|
||||
}
|
||||
|
||||
add_option!(clamp, ret);
|
||||
add_option!(align, ret);
|
||||
add_option!(vert_align, ret);
|
||||
add_option!(list_style, ret);
|
||||
add_option!(pseudo, ret);
|
||||
add_option!(line_height, ret);
|
||||
|
||||
if let Some(decoration) = &self.decoration {
|
||||
ret.extend_from_slice(&decoration.base_class());
|
||||
}
|
||||
|
||||
ret.extend_from_slice(&self.style);
|
||||
|
||||
add_option!(transform, ret);
|
||||
add_option!(overflow, ret);
|
||||
add_option!(wrap, ret);
|
||||
add_option!(whitespace, ret);
|
||||
add_option!(wordbreak, ret);
|
||||
add_option!(hyphens, ret);
|
||||
|
||||
ret
|
||||
}
|
||||
|
||||
fn extended_class(&self) -> Vec<String> {
|
||||
|
@ -357,3 +539,450 @@ impl NumberStyle {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub enum LetterSpacing {
|
||||
Tighter,
|
||||
Tight,
|
||||
Normal,
|
||||
Wide,
|
||||
Wider,
|
||||
Widest,
|
||||
}
|
||||
|
||||
impl LetterSpacing {
|
||||
pub const fn to_value(&self) -> &str {
|
||||
match self {
|
||||
LetterSpacing::Tighter => "tracking-tighter",
|
||||
LetterSpacing::Tight => "tracking-tight",
|
||||
LetterSpacing::Normal => "tracking-normal",
|
||||
LetterSpacing::Wide => "tracking-wide",
|
||||
LetterSpacing::Wider => "tracking-wider",
|
||||
LetterSpacing::Widest => "tracking-widest",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub enum LineClamp {
|
||||
None,
|
||||
_1,
|
||||
_2,
|
||||
_3,
|
||||
_4,
|
||||
_5,
|
||||
_6,
|
||||
}
|
||||
|
||||
impl LineClamp {
|
||||
pub fn to_value(&self) -> &str {
|
||||
match self {
|
||||
LineClamp::None => "line-clamp-none",
|
||||
LineClamp::_1 => "line-clamp-1",
|
||||
LineClamp::_2 => "line-clamp-2",
|
||||
LineClamp::_3 => "line-clamp-3",
|
||||
LineClamp::_4 => "line-clamp-4",
|
||||
LineClamp::_5 => "line-clamp-5",
|
||||
LineClamp::_6 => "line-clamp-6",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub enum TextAlignment {
|
||||
Left,
|
||||
Center,
|
||||
Right,
|
||||
Justify,
|
||||
Start,
|
||||
End,
|
||||
}
|
||||
|
||||
impl TextAlignment {
|
||||
pub const fn to_value(&self) -> &str {
|
||||
match self {
|
||||
TextAlignment::Left => "text-left",
|
||||
TextAlignment::Center => "text-center",
|
||||
TextAlignment::Right => "text-right",
|
||||
TextAlignment::Justify => "text-justify",
|
||||
TextAlignment::Start => "text-start",
|
||||
TextAlignment::End => "text-end",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub enum ListStyle {
|
||||
Url(String),
|
||||
None,
|
||||
Disc,
|
||||
Decimal,
|
||||
}
|
||||
|
||||
impl ListStyle {
|
||||
pub fn to_value(&self) -> String {
|
||||
match self {
|
||||
ListStyle::Url(url) => format!("list-image-[url({url})]"),
|
||||
ListStyle::None => "list-none".to_string(),
|
||||
ListStyle::Disc => "list-disc".to_string(),
|
||||
ListStyle::Decimal => "list-decimal".to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub enum TextContent {
|
||||
None,
|
||||
Before(String),
|
||||
After(String),
|
||||
}
|
||||
|
||||
impl TextContent {
|
||||
pub fn to_value(&self) -> String {
|
||||
match self {
|
||||
TextContent::None => "content-none".to_string(),
|
||||
TextContent::Before(c) => format!("before:content-['{c}']"),
|
||||
TextContent::After(c) => format!("after:content-['{c}']"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub enum LineHeight {
|
||||
_3,
|
||||
_4,
|
||||
_5,
|
||||
_6,
|
||||
_7,
|
||||
_8,
|
||||
_9,
|
||||
_10,
|
||||
None,
|
||||
Tight,
|
||||
Snug,
|
||||
Normal,
|
||||
Relaxed,
|
||||
Loose,
|
||||
}
|
||||
|
||||
impl LineHeight {
|
||||
pub const fn to_value(&self) -> &str {
|
||||
match self {
|
||||
LineHeight::_3 => "leading-3",
|
||||
LineHeight::_4 => "leading-4",
|
||||
LineHeight::_5 => "leading-5",
|
||||
LineHeight::_6 => "leading-6",
|
||||
LineHeight::_7 => "leading-7",
|
||||
LineHeight::_8 => "leading-8",
|
||||
LineHeight::_9 => "leading-9",
|
||||
LineHeight::_10 => "leading-10",
|
||||
LineHeight::None => "leading-none",
|
||||
LineHeight::Tight => "leading-tight",
|
||||
LineHeight::Snug => "leading-snug",
|
||||
LineHeight::Normal => "leading-normal",
|
||||
LineHeight::Relaxed => "leading-relaxed",
|
||||
LineHeight::Loose => "leading-loose",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Decoration
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
pub fn TextDecoration<T: UIWidget + 'static>(kind: DecorationKind) -> DecorationWidget {
|
||||
DecorationWidget {
|
||||
kind: kind.to_value().to_string(),
|
||||
color: None,
|
||||
style: None,
|
||||
underline_offset: None,
|
||||
thickness: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub struct DecorationWidget {
|
||||
kind: String,
|
||||
color: Option<String>,
|
||||
style: Option<DecorationStyle>,
|
||||
thickness: Option<DecorationThickness>,
|
||||
underline_offset: Option<UnderlineOffset>,
|
||||
}
|
||||
|
||||
impl DecorationWidget {
|
||||
#[must_use]
|
||||
pub fn thickness(mut self, thickness: DecorationThickness) -> Self {
|
||||
self.thickness = Some(thickness);
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn style(mut self, style: DecorationStyle) -> Self {
|
||||
self.style = Some(style);
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn color<C: UIColor>(mut self, color: C) -> Self {
|
||||
self.color = Some(format!("decoration-{}", color.color_class()));
|
||||
self
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn underline_offset(mut self, offset: UnderlineOffset) -> Self {
|
||||
self.underline_offset = Some(offset);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
pub enum DecorationKind {
|
||||
Underline,
|
||||
Overline,
|
||||
LineThrough,
|
||||
NoUnderline,
|
||||
}
|
||||
|
||||
impl DecorationKind {
|
||||
pub const fn to_value(&self) -> &str {
|
||||
match self {
|
||||
DecorationKind::Underline => "underline",
|
||||
DecorationKind::Overline => "overline",
|
||||
DecorationKind::LineThrough => "line-through",
|
||||
DecorationKind::NoUnderline => "no-underline",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub enum DecorationThickness {
|
||||
Auto,
|
||||
FromFont,
|
||||
_0,
|
||||
_1,
|
||||
_2,
|
||||
_4,
|
||||
_8,
|
||||
}
|
||||
|
||||
impl DecorationThickness {
|
||||
pub const fn to_value(&self) -> &str {
|
||||
match self {
|
||||
DecorationThickness::Auto => "decoration-auto",
|
||||
DecorationThickness::FromFont => "decoration-from-font",
|
||||
DecorationThickness::_0 => "decoration-0",
|
||||
DecorationThickness::_1 => "decoration-1",
|
||||
DecorationThickness::_2 => "decoration-2",
|
||||
DecorationThickness::_4 => "decoration-4",
|
||||
DecorationThickness::_8 => "decoration-8",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub enum DecorationStyle {
|
||||
Solid,
|
||||
Double,
|
||||
Dotted,
|
||||
Dashed,
|
||||
Wavy,
|
||||
}
|
||||
|
||||
impl DecorationStyle {
|
||||
pub const fn to_value(&self) -> &str {
|
||||
match self {
|
||||
DecorationStyle::Solid => "decoration-solid",
|
||||
DecorationStyle::Double => "decoration-double",
|
||||
DecorationStyle::Dotted => "decoration-dotted",
|
||||
DecorationStyle::Dashed => "decoration-dashed",
|
||||
DecorationStyle::Wavy => "decoration-wavy",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Render for DecorationWidget {
|
||||
fn render(&self) -> Markup {
|
||||
self.render_with_class("")
|
||||
}
|
||||
}
|
||||
|
||||
impl UIWidget for DecorationWidget {
|
||||
fn can_inherit(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn base_class(&self) -> Vec<String> {
|
||||
let mut ret = vec![self.kind.clone()];
|
||||
|
||||
if let Some(color) = &self.color {
|
||||
ret.push(color.clone());
|
||||
}
|
||||
|
||||
if let Some(style) = &self.style {
|
||||
ret.push(style.to_value().to_string());
|
||||
}
|
||||
|
||||
if let Some(thickness) = &self.thickness {
|
||||
ret.push(thickness.to_value().to_string());
|
||||
}
|
||||
|
||||
if let Some(offset) = &self.underline_offset {
|
||||
ret.push(offset.to_value().to_string());
|
||||
}
|
||||
|
||||
ret
|
||||
}
|
||||
|
||||
fn extended_class(&self) -> Vec<String> {
|
||||
self.base_class()
|
||||
}
|
||||
|
||||
fn render_with_class(&self, _: &str) -> Markup {
|
||||
Nothing()
|
||||
}
|
||||
}
|
||||
|
||||
pub enum UnderlineOffset {
|
||||
Auto,
|
||||
_0,
|
||||
_1,
|
||||
_2,
|
||||
_4,
|
||||
_8,
|
||||
}
|
||||
|
||||
impl UnderlineOffset {
|
||||
pub const fn to_value(&self) -> &str {
|
||||
match self {
|
||||
Self::Auto => "underline-offset-auto",
|
||||
Self::_0 => "underline-offset-0",
|
||||
Self::_1 => "underline-offset-1",
|
||||
Self::_2 => "underline-offset-2",
|
||||
Self::_4 => "underline-offset-4",
|
||||
Self::_8 => "underline-offset-8",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub enum VerticalTextAlignment {
|
||||
Baseline,
|
||||
Top,
|
||||
Middle,
|
||||
Bottom,
|
||||
TextTop,
|
||||
TextBottom,
|
||||
Sub,
|
||||
Super,
|
||||
}
|
||||
|
||||
impl VerticalTextAlignment {
|
||||
pub const fn to_value(&self) -> &str {
|
||||
match self {
|
||||
VerticalTextAlignment::Baseline => "align-baseline",
|
||||
VerticalTextAlignment::Top => "align-top",
|
||||
VerticalTextAlignment::Middle => "align-middle",
|
||||
VerticalTextAlignment::Bottom => "align-bottom",
|
||||
VerticalTextAlignment::TextTop => "align-text-top",
|
||||
VerticalTextAlignment::TextBottom => "align-text-bottom",
|
||||
VerticalTextAlignment::Sub => "align-sub",
|
||||
VerticalTextAlignment::Super => "align-super",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub enum TextTransform {
|
||||
Uppecase,
|
||||
Lowercase,
|
||||
Capitalize,
|
||||
None,
|
||||
}
|
||||
|
||||
impl TextTransform {
|
||||
pub const fn to_value(&self) -> &str {
|
||||
match self {
|
||||
TextTransform::Uppecase => "uppercase",
|
||||
TextTransform::Lowercase => "lowercase",
|
||||
TextTransform::Capitalize => "capitalize",
|
||||
TextTransform::None => "normal-case",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub enum TextOverflow {
|
||||
Truncate,
|
||||
Ellipsis,
|
||||
Clip,
|
||||
}
|
||||
|
||||
impl TextOverflow {
|
||||
pub const fn to_value(&self) -> &str {
|
||||
match self {
|
||||
TextOverflow::Truncate => "truncate",
|
||||
TextOverflow::Ellipsis => "text-ellipsis",
|
||||
TextOverflow::Clip => "text-clip",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub enum TextWrap {
|
||||
Wrap,
|
||||
NoWrap,
|
||||
Balance,
|
||||
Pretty,
|
||||
}
|
||||
|
||||
impl TextWrap {
|
||||
pub const fn to_value(&self) -> &str {
|
||||
match self {
|
||||
TextWrap::Wrap => "text-wrap",
|
||||
TextWrap::NoWrap => "text-nowrap",
|
||||
TextWrap::Balance => "text-balance",
|
||||
TextWrap::Pretty => "text-pretty",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub enum TextWhitespace {
|
||||
Normal,
|
||||
NoWrap,
|
||||
Pre,
|
||||
PreLine,
|
||||
PreWrap,
|
||||
BreakSpaces,
|
||||
}
|
||||
|
||||
impl TextWhitespace {
|
||||
pub const fn to_value(&self) -> &str {
|
||||
match self {
|
||||
TextWhitespace::Normal => "whitespace-normal",
|
||||
TextWhitespace::NoWrap => "whitespace-nowrap",
|
||||
TextWhitespace::Pre => "whitespace-pre",
|
||||
TextWhitespace::PreLine => "whitespace-pre-line",
|
||||
TextWhitespace::PreWrap => "whitespace-pre-wrap",
|
||||
TextWhitespace::BreakSpaces => "whitespace-break-spaces",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub enum TextWordBreak {
|
||||
Normal,
|
||||
Words,
|
||||
All,
|
||||
Keep,
|
||||
}
|
||||
|
||||
impl TextWordBreak {
|
||||
pub const fn to_value(&self) -> &str {
|
||||
match self {
|
||||
TextWordBreak::Normal => "break-normal",
|
||||
TextWordBreak::Words => "break-words",
|
||||
TextWordBreak::All => "break-all",
|
||||
TextWordBreak::Keep => "break-keep",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub enum TextHyphens {
|
||||
None,
|
||||
Manual,
|
||||
Auto,
|
||||
}
|
||||
|
||||
impl TextHyphens {
|
||||
pub const fn to_value(&self) -> &str {
|
||||
match self {
|
||||
TextHyphens::None => "hyphens-none",
|
||||
TextHyphens::Manual => "hyphens-manual",
|
||||
TextHyphens::Auto => "hyphens-auto",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,24 +1,33 @@
|
|||
use crate::ui::UIWidget;
|
||||
use maud::{Markup, Render, html};
|
||||
|
||||
use super::space::ScreenValue;
|
||||
use super::{
|
||||
flex::Either,
|
||||
space::{Fraction, ScreenValue},
|
||||
};
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
pub fn Width<T: UIWidget + 'static>(size: ScreenValue, inner: T) -> WidthWidget {
|
||||
pub fn Width<T: UIWidget + 'static>(size: Either<ScreenValue, Fraction>, inner: T) -> WidthWidget {
|
||||
WidthWidget(Box::new(inner), size, 0)
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
pub fn MinWidth<T: UIWidget + 'static>(size: ScreenValue, inner: T) -> WidthWidget {
|
||||
pub fn MinWidth<T: UIWidget + 'static>(
|
||||
size: Either<ScreenValue, Fraction>,
|
||||
inner: T,
|
||||
) -> WidthWidget {
|
||||
WidthWidget(Box::new(inner), size, 1)
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
pub fn MaxWidth<T: UIWidget + 'static>(size: ScreenValue, inner: T) -> WidthWidget {
|
||||
pub fn MaxWidth<T: UIWidget + 'static>(
|
||||
size: Either<ScreenValue, Fraction>,
|
||||
inner: T,
|
||||
) -> WidthWidget {
|
||||
WidthWidget(Box::new(inner), size, 2)
|
||||
}
|
||||
|
||||
pub struct WidthWidget(Box<dyn UIWidget>, ScreenValue, u8);
|
||||
pub struct WidthWidget(Box<dyn UIWidget>, Either<ScreenValue, Fraction>, u8);
|
||||
|
||||
impl Render for WidthWidget {
|
||||
fn render(&self) -> Markup {
|
||||
|
@ -34,15 +43,27 @@ impl UIWidget for WidthWidget {
|
|||
fn base_class(&self) -> Vec<String> {
|
||||
match self.2 {
|
||||
1 => {
|
||||
return vec![format!("min-w-{}", self.1.to_value())];
|
||||
return vec![format!(
|
||||
"min-w-{}",
|
||||
self.1
|
||||
.map(|x| x.to_value().to_string(), |x| x.to_value().to_string())
|
||||
)];
|
||||
}
|
||||
2 => {
|
||||
return vec![format!("max-w-{}", self.1.to_value())];
|
||||
return vec![format!(
|
||||
"max-w-{}",
|
||||
self.1
|
||||
.map(|x| x.to_value().to_string(), |x| x.to_value().to_string())
|
||||
)];
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
vec![format!("w-{}", self.1.to_value())]
|
||||
vec![format!(
|
||||
"w-{}",
|
||||
self.1
|
||||
.map(|x| x.to_value().to_string(), |x| x.to_value().to_string())
|
||||
)]
|
||||
}
|
||||
|
||||
fn extended_class(&self) -> Vec<String> {
|
||||
|
|
Loading…
Add table
Reference in a new issue