use std::collections::HashMap;
use maud::{Markup, PreEscaped, Render, html};
use crate::ui::{AttrExtendable, UIWidget, htmx::HTMXAttributes};
#[allow(non_snake_case)]
/// `
` element
///
/// Useful for grouping values together
#[must_use]
pub fn Div() -> DivWidget {
DivWidget(Vec::new(), false, HashMap::new())
}
pub struct DivWidget(Vec
>, bool, HashMap);
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 ``
#[must_use]
pub fn push
(mut self, element: T) -> Self {
self.0.push(Box::new(element));
self
}
/// Add an optional element to the ``
///
/// # Example
///
/// ```ignore
/// use based::ui::basic::*;
///
/// let div = Div().push(Some("hello"), |value| Text(value));
/// ```
#[must_use]
pub fn push_some
T>(
mut self,
option: Option<&X>,
then: U,
) -> Self {
if let Some(val) = option {
self.0.push(Box::new(then(val)));
}
self
}
/// Extract the ``s innerHTML
///
/// This will render `
` instead of `
`
#[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 {
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 {
vec![]
}
fn extended_class(&self) -> Vec {
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::>()
.join(" ");
PreEscaped(format!(
" {} ",
self.extended_class_().join(" "),
inner.0
))
}
}
}
impl HTMXAttributes for DivWidget {}