based/src/ui/primitives/list.rs
2025-01-21 13:40:56 +01:00

103 lines
2 KiB
Rust

use crate::ui::UIWidget;
use maud::{Markup, Render, html};
#[allow(non_snake_case)]
#[must_use]
pub fn OrderedList() -> ListWidget {
ListWidget(Vec::new(), true)
}
#[allow(non_snake_case)]
#[must_use]
pub fn UnorderedList() -> ListWidget {
ListWidget(Vec::new(), false)
}
pub struct ListWidget(Vec<Box<dyn UIWidget>>, bool);
impl ListWidget {
#[must_use]
pub fn push<T: UIWidget + 'static>(mut self, element: T) -> Self {
self.0.push(Box::new(element));
self
}
#[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
}
#[must_use]
pub fn push_if<T: UIWidget + 'static, U: Fn() -> T>(
mut self,
condition: bool,
then: U,
) -> Self {
if condition {
self.0.push(Box::new(then()));
}
self
}
#[must_use]
pub fn push_for_each<T, X, F>(mut self, items: &[X], mut action: F) -> Self
where
T: UIWidget + 'static,
F: FnMut(&X) -> T,
{
for item in items {
self.0.push(Box::new(action(item)));
}
self
}
}
impl Render for ListWidget {
fn render(&self) -> Markup {
self.render_with_class("")
}
}
impl UIWidget for ListWidget {
fn can_inherit(&self) -> bool {
true
}
fn base_class(&self) -> Vec<String> {
vec![]
}
fn extended_class(&self) -> Vec<String> {
vec![]
}
fn render_with_class(&self, class: &str) -> Markup {
let inner = html! {
@for e in &self.0 {
li { (e.as_ref()) };
}
};
if self.1 {
html! {
ol class=(class) {
(inner);
}
}
} else {
html! {
ul class=(class) {
(inner);
}
}
}
}
}