126 lines
2.8 KiB
Rust
126 lines
2.8 KiB
Rust
use std::collections::HashMap;
|
|
|
|
use maud::{Markup, PreEscaped, Render, html};
|
|
|
|
use crate::ui::{AttrExtendable, UIWidget, htmx::HTMXAttributes};
|
|
|
|
#[allow(non_snake_case)]
|
|
/// `<div>` element
|
|
///
|
|
/// Useful for grouping values together
|
|
#[must_use]
|
|
pub fn Div() -> DivWidget {
|
|
DivWidget(Vec::new(), false, HashMap::new())
|
|
}
|
|
|
|
pub struct DivWidget(Vec<Box<dyn UIWidget>>, bool, HashMap<String, String>);
|
|
|
|
impl AttrExtendable for DivWidget {
|
|
fn add_attr(mut self, key: &str, val: &str) -> Self {
|
|
self.2.insert(key.to_string(), val.replace('\'', "\\'"));
|
|
self
|
|
}
|
|
|
|
fn id(self, id: &str) -> Self {
|
|
self.add_attr("id", id)
|
|
}
|
|
}
|
|
|
|
impl DivWidget {
|
|
/// Add an element to the `<div>`
|
|
#[must_use]
|
|
pub fn push<T: UIWidget + 'static>(mut self, element: T) -> Self {
|
|
self.0.push(Box::new(element));
|
|
self
|
|
}
|
|
|
|
/// Add an optional element to the `<div>`
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```ignore
|
|
/// use based::ui::basic::*;
|
|
///
|
|
/// let div = Div().push(Some("hello"), |value| Text(value));
|
|
/// ```
|
|
#[must_use]
|
|
pub fn push_some<T: UIWidget + 'static, X, U: Fn(&X) -> T>(
|
|
mut self,
|
|
option: Option<&X>,
|
|
then: U,
|
|
) -> Self {
|
|
if let Some(val) = option {
|
|
self.0.push(Box::new(then(val)));
|
|
}
|
|
self
|
|
}
|
|
|
|
/// Extract the `<div>`s innerHTML
|
|
///
|
|
/// This will render `<content>` instead of `<div> <content> </div>`
|
|
#[must_use]
|
|
pub const fn vanish(mut self) -> Self {
|
|
self.1 = true;
|
|
self
|
|
}
|
|
}
|
|
|
|
impl Render for DivWidget {
|
|
fn render(&self) -> Markup {
|
|
self.render_with_class("")
|
|
}
|
|
}
|
|
|
|
impl DivWidget {
|
|
pub fn extended_class_(&self) -> Vec<String> {
|
|
let mut c = self.base_class();
|
|
for e in &self.0 {
|
|
c.extend_from_slice(&e.extended_class());
|
|
}
|
|
c
|
|
}
|
|
}
|
|
|
|
impl UIWidget for DivWidget {
|
|
fn can_inherit(&self) -> bool {
|
|
false
|
|
}
|
|
|
|
fn base_class(&self) -> Vec<String> {
|
|
vec![]
|
|
}
|
|
|
|
fn extended_class(&self) -> Vec<String> {
|
|
if self.1 {
|
|
self.extended_class_()
|
|
} else {
|
|
vec![]
|
|
}
|
|
}
|
|
|
|
fn render_with_class(&self, _: &str) -> Markup {
|
|
let inner = html! {
|
|
@for e in &self.0 {
|
|
(e.as_ref())
|
|
}
|
|
};
|
|
if self.1 {
|
|
inner
|
|
} else {
|
|
let attrs = self
|
|
.2
|
|
.iter()
|
|
.map(|(k, v)| format!("{k}='{v}'"))
|
|
.collect::<Vec<_>>()
|
|
.join(" ");
|
|
|
|
PreEscaped(format!(
|
|
"<div class='{}' {attrs}> {} </a>",
|
|
self.extended_class_().join(" "),
|
|
inner.0
|
|
))
|
|
}
|
|
}
|
|
}
|
|
|
|
impl HTMXAttributes for DivWidget {}
|