add screen wrapper
This commit is contained in:
parent
15e70da512
commit
302daacc82
4 changed files with 123 additions and 69 deletions
|
@ -14,6 +14,12 @@ pub async fn index_page(ctx: RequestContext) -> StringResponse {
|
|||
let content = html!(
|
||||
h1 { "Hello World!" };
|
||||
|
||||
(
|
||||
Screen::medium(Hover(Background(Red::_700, Nothing()))).on(
|
||||
Background(Blue::_700, Text("HELLO!"))
|
||||
)
|
||||
)
|
||||
|
||||
(Hover(
|
||||
Cursor::NorthEastResize.on(
|
||||
Padding(Text("").color(&Gray::_400)).x(ScreenValue::_10)
|
||||
|
|
|
@ -48,7 +48,9 @@ pub mod prelude {
|
|||
pub use super::primitives::visibility::Visibility;
|
||||
pub use super::primitives::width::{MaxWidth, MinWidth, Width};
|
||||
pub use super::primitives::zindex::ZIndex;
|
||||
pub use super::wrapper::Hover;
|
||||
pub use super::wrapper::{
|
||||
_2XLScreen, Hover, LargeScreen, MediumScreen, Screen, SmallScreen, XLScreen,
|
||||
};
|
||||
}
|
||||
|
||||
use crate::request::{RequestContext, StringResponse};
|
||||
|
|
|
@ -1,66 +0,0 @@
|
|||
use maud::{Markup, Render, html};
|
||||
|
||||
use crate::ui::UIWidget;
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
pub fn Hover<I: UIWidget + 'static>(inherit: I) -> HoverWrapper {
|
||||
HoverWrapper(None, Box::new(inherit))
|
||||
}
|
||||
|
||||
pub struct HoverWrapper(Option<Box<dyn UIWidget>>, Box<dyn UIWidget>);
|
||||
|
||||
impl HoverWrapper {
|
||||
fn hovered_class(&self) -> Vec<String> {
|
||||
self.1
|
||||
.extended_class()
|
||||
.into_iter()
|
||||
.filter(|x| !x.is_empty())
|
||||
.map(|x| format!("hover:{x}"))
|
||||
.collect::<Vec<_>>()
|
||||
}
|
||||
|
||||
pub fn on<T: UIWidget + 'static>(mut self, inner: T) -> Self {
|
||||
self.0 = Some(Box::new(inner));
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl Render for HoverWrapper {
|
||||
fn render(&self) -> Markup {
|
||||
self.render_with_class("")
|
||||
}
|
||||
}
|
||||
|
||||
impl UIWidget for HoverWrapper {
|
||||
fn can_inherit(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn base_class(&self) -> Vec<String> {
|
||||
self.hovered_class()
|
||||
}
|
||||
|
||||
fn extended_class(&self) -> Vec<String> {
|
||||
let mut ret = self.base_class();
|
||||
if let Some(inner) = &self.0 {
|
||||
ret.extend_from_slice(&inner.extended_class());
|
||||
}
|
||||
|
||||
ret
|
||||
}
|
||||
|
||||
fn render_with_class(&self, class: &str) -> Markup {
|
||||
if self.0.as_ref().unwrap().can_inherit() {
|
||||
self.0
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.render_with_class(&format!("{} {class}", self.hovered_class().join(" ")))
|
||||
} else {
|
||||
html! {
|
||||
div class=(format!("{} {class}", self.hovered_class().join(" "))) {
|
||||
(self.0.as_ref().unwrap())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,116 @@
|
|||
pub mod hover;
|
||||
pub use hover::Hover;
|
||||
use crate::ui::UIWidget;
|
||||
use maud::{Markup, Render, html};
|
||||
|
||||
macro_rules! wrapper {
|
||||
($constr:ident, $widgetname:ident, $class:literal) => {
|
||||
#[allow(non_snake_case)]
|
||||
pub fn $constr<I: UIWidget + 'static>(inherit: I) -> $widgetname {
|
||||
$widgetname(None, Box::new(inherit))
|
||||
}
|
||||
|
||||
pub struct $widgetname(Option<Box<dyn UIWidget>>, Box<dyn UIWidget>);
|
||||
|
||||
impl $widgetname {
|
||||
fn wrapped_class(&self) -> Vec<String> {
|
||||
self.1
|
||||
.extended_class()
|
||||
.into_iter()
|
||||
.filter(|x| !x.is_empty())
|
||||
.map(|x| {
|
||||
let mut s = $class.to_string();
|
||||
s.push_str(":");
|
||||
s.push_str(&x);
|
||||
s
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
}
|
||||
|
||||
pub fn on<T: UIWidget + 'static>(mut self, inner: T) -> Self {
|
||||
self.0 = Some(Box::new(inner));
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl Render for $widgetname {
|
||||
fn render(&self) -> Markup {
|
||||
self.render_with_class("")
|
||||
}
|
||||
}
|
||||
|
||||
impl UIWidget for $widgetname {
|
||||
fn can_inherit(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn base_class(&self) -> Vec<String> {
|
||||
self.wrapped_class()
|
||||
}
|
||||
|
||||
fn extended_class(&self) -> Vec<String> {
|
||||
let mut ret = self.base_class();
|
||||
if let Some(inner) = &self.0 {
|
||||
ret.extend_from_slice(&inner.extended_class());
|
||||
}
|
||||
|
||||
ret
|
||||
}
|
||||
|
||||
fn render_with_class(&self, class: &str) -> Markup {
|
||||
if self.0.as_ref().unwrap().can_inherit() {
|
||||
self.0
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.render_with_class(&format!("{} {class}", self.wrapped_class().join(" ")))
|
||||
} else {
|
||||
html! {
|
||||
div class=(format!("{} {class}", self.wrapped_class().join(" "))) {
|
||||
(self.0.as_ref().unwrap())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
wrapper!(Hover, HoverWrapper, "hover");
|
||||
|
||||
wrapper!(SmallScreen, SmallScreenWrapper, "sm");
|
||||
wrapper!(MediumScreen, MediumScreenWrapper, "md");
|
||||
wrapper!(LargeScreen, LargeScreenWrapper, "lg");
|
||||
wrapper!(XLScreen, XLScreenWrapper, "xl");
|
||||
wrapper!(_2XLScreen, _2XLScreenWrapper, "2xl");
|
||||
|
||||
// TODO : responsive media
|
||||
|
||||
// TODO : arbitrary values "min-[320px]:text-center max-[600px]:bg-sky-300"
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
pub mod Screen {
|
||||
use crate::ui::UIWidget;
|
||||
|
||||
use super::{
|
||||
_2XLScreen, _2XLScreenWrapper, LargeScreen, LargeScreenWrapper, MediumScreen,
|
||||
MediumScreenWrapper, SmallScreen, SmallScreenWrapper, XLScreen, XLScreenWrapper,
|
||||
};
|
||||
|
||||
pub fn small<I: UIWidget + 'static>(inherit: I) -> SmallScreenWrapper {
|
||||
SmallScreen(inherit)
|
||||
}
|
||||
|
||||
pub fn medium<I: UIWidget + 'static>(inherit: I) -> MediumScreenWrapper {
|
||||
MediumScreen(inherit)
|
||||
}
|
||||
|
||||
pub fn large<I: UIWidget + 'static>(inherit: I) -> LargeScreenWrapper {
|
||||
LargeScreen(inherit)
|
||||
}
|
||||
|
||||
pub fn xl<I: UIWidget + 'static>(inherit: I) -> XLScreenWrapper {
|
||||
XLScreen(inherit)
|
||||
}
|
||||
|
||||
pub fn _2xl<I: UIWidget + 'static>(inherit: I) -> _2XLScreenWrapper {
|
||||
_2XLScreen(inherit)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue