use std::collections::HashMap; use maud::{Markup, PreEscaped, Render}; use crate::ui::{ AttrExtendable, UIWidget, htmx::{HTMXAttributes, Selector, SwapStrategy}, }; #[allow(non_snake_case)] /// A component for fixing an element's width to the current breakpoint. pub fn Link(reference: &str, inner: T) -> LinkWidget { LinkWidget(Box::new(inner), reference.to_owned(), HashMap::new()) } pub struct LinkWidget(Box, String, HashMap); impl AttrExtendable for LinkWidget { 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 HTMXAttributes for LinkWidget {} impl Render for LinkWidget { fn render(&self) -> Markup { self.render_with_class(&self.extended_class().join(" ")) } } impl UIWidget for LinkWidget { fn can_inherit(&self) -> bool { true } fn base_class(&self) -> Vec { vec![] } fn extended_class(&self) -> Vec { let mut c = self.base_class(); c.extend_from_slice(&self.0.extended_class()); c } fn render_with_class(&self, class: &str) -> Markup { let attrs = self .2 .iter() .map(|(k, v)| format!("{k}='{v}'")) .collect::>() .join(" "); PreEscaped(format!( " {} ", self.1, self.0.render().0 )) } } impl LinkWidget { /// Enable HTMX link capabilities #[must_use] pub fn use_htmx(self) -> Self { // todo : investigate htmx attrs let url = self.1.clone(); self.hx_get(&url) .hx_target(Selector::Query("#main_content".to_string())) .hx_push_url() .hx_swap(SwapStrategy::innerHTML) .hx_boost() .hx_disabled_elt(Selector::This) } }