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 {}