103 lines
2 KiB
Rust
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);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|