use maud::{html, Markup};
#[derive(Debug, Clone)]
pub struct Props {
pub name: String,
pub value: f64,
pub min: Option<f64>,
pub max: Option<f64>,
pub step: f64,
pub disabled: bool,
pub label: String,
pub id: String,
}
impl Default for Props {
fn default() -> Self {
Self {
name: String::new(),
value: 0.0,
min: None,
max: None,
step: 1.0,
disabled: false,
label: String::new(),
id: String::new(),
}
}
}
pub fn render(props: Props) -> Markup {
html! {
div class="mui-number-field" role="group" aria-label=(props.label) aria-disabled[props.disabled] {
button type="button" class="mui-number-field__btn mui-number-field__btn--decrement" tabindex="-1" aria-label="Decrement" data-mui="number-field-dec" disabled[props.disabled] { "−" }
input type="number" class="mui-number-field__input" name=(props.name) id=(props.id) value=(props.value)
step=(props.step) min=[props.min] max=[props.max] disabled[props.disabled];
button type="button" class="mui-number-field__btn mui-number-field__btn--increment" tabindex="-1" aria-label="Increment" data-mui="number-field-inc" disabled[props.disabled] { "+" }
}
}
}
pub fn showcase() -> Markup {
html! {
div.mui-showcase__grid {
div {
p.mui-showcase__caption { "Cart \u{2014} Wireless Headphones" }
div style="display:flex;flex-direction:column;gap:0.5rem;max-width:20rem;" {
div style="display:flex;justify-content:space-between;align-items:center;" {
div {
p style="font-size:0.875rem;font-weight:500;margin:0;" { "Aurora Wireless Headphones" }
p style="font-size:0.75rem;color:var(--mui-text-muted);margin:0.125rem 0 0;" { "$149 each" }
}
span style="font-size:0.875rem;font-weight:600;" { "$298" }
}
label for="cart-qty" style="font-size:0.75rem;color:var(--mui-text-muted);" { "Quantity" }
(render(Props {
name: "cart_quantity".into(),
value: 2.0,
min: Some(1.0),
max: Some(10.0),
step: 1.0,
id: "cart-qty".into(),
label: "Cart quantity".into(),
..Default::default()
}))
p style="font-size:0.75rem;color:var(--mui-text-muted);margin:0;" { "Max 10 per order" }
}
}
div {
p.mui-showcase__caption { "Account \u{2014} Age verification" }
div style="display:flex;flex-direction:column;gap:0.5rem;max-width:20rem;" {
label for="signup-age" style="font-size:0.875rem;font-weight:500;" { "Age" }
(render(Props {
name: "age".into(),
value: 24.0,
min: Some(13.0),
max: Some(120.0),
step: 1.0,
id: "signup-age".into(),
label: "Age".into(),
..Default::default()
}))
p style="font-size:0.75rem;color:var(--mui-text-muted);margin:0;" {
"You must be at least 13 to create an account."
}
}
}
div {
p.mui-showcase__caption { "Recipe \u{2014} Tomato Basil Risotto" }
div style="display:flex;flex-direction:column;gap:0.5rem;max-width:20rem;" {
label for="recipe-servings" style="font-size:0.875rem;font-weight:500;" { "Servings" }
(render(Props {
name: "servings".into(),
value: 4.0,
min: Some(1.0),
max: Some(12.0),
step: 1.0,
id: "recipe-servings".into(),
label: "Servings".into(),
..Default::default()
}))
p style="font-size:0.75rem;color:var(--mui-text-muted);margin:0;" {
"Adjust to scale ingredients (1\u{2013}12 people)."
}
}
}
div {
p.mui-showcase__caption { "Backordered \u{2014} quantity locked" }
div style="display:flex;flex-direction:column;gap:0.5rem;max-width:20rem;" {
label for="backorder-qty" style="font-size:0.875rem;font-weight:500;color:var(--mui-text-muted);" {
"Quantity (reserved)"
}
(render(Props {
name: "backorder".into(),
value: 1.0,
min: Some(1.0),
max: Some(1.0),
step: 1.0,
disabled: true,
id: "backorder-qty".into(),
label: "Backordered quantity".into(),
..Default::default()
}))
p style="font-size:0.75rem;color:var(--mui-text-muted);margin:0;" {
"Ships when restocked on April 28."
}
}
}
}
}
}