use autumn_web::{Markup, html};
use super::{Behavior, marker};
use crate::markup::{Attributes, common};
#[derive(Debug, Clone, Default, PartialEq, Eq)]
#[must_use]
pub struct Count {
output: Option<String>,
mode: CountMode,
extra: Attributes,
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum CountMode {
#[default]
Used,
Remaining,
}
impl CountMode {
#[must_use]
pub const fn name(self) -> &'static str {
match self {
Self::Used => "used",
Self::Remaining => "remaining",
}
}
}
impl Count {
pub const fn new() -> Self {
Self {
output: None,
mode: CountMode::Used,
extra: Vec::new(),
}
}
pub fn output(mut self, selector: impl Into<String>) -> Self {
let selector = selector.into();
self.output = (!selector.trim().is_empty()).then_some(selector);
self
}
pub const fn mode(mut self, mode: CountMode) -> Self {
self.mode = mode;
self
}
#[must_use]
pub fn attributes(&self) -> Attributes {
let mut attributes = vec![marker(Behavior::Count)];
if let Some(output) = &self.output {
attributes.push(("data-vanilla-count", output.clone()));
}
if self.mode != CountMode::Used {
attributes.push(("data-vanilla-count-mode", self.mode.name().to_owned()));
}
attributes.extend(self.extra.iter().cloned());
attributes
}
pub const fn output_slot() -> OutputSlot {
OutputSlot { extra: Vec::new() }
}
}
common!(Count, wrap);
#[derive(Debug, Clone, Default, PartialEq, Eq)]
#[must_use]
pub struct OutputSlot {
extra: Attributes,
}
impl OutputSlot {
#[must_use]
pub fn attributes(&self) -> Attributes {
let mut attributes = vec![
("data-vanilla-count-output", String::new()),
("aria-live", "off".to_owned()),
];
attributes.extend(self.extra.iter().cloned());
attributes
}
#[must_use]
pub fn render(&self) -> Markup {
crate::markup::element("output", &self.attributes(), html! {})
}
}
common!(OutputSlot);
impl maud::Render for OutputSlot {
fn render(&self) -> Markup {
Self::render(self)
}
}