use serde::Serialize;
use serde_json::{Map, Value};
use super::{
InputType, Node,
node::{
actions_methods, base_methods, children_methods, event_methods, kind_type, max_method, props,
title_method,
},
};
kind_type!(
El
);
impl<M> El<M> {
base_methods!();
title_method!();
max_method!();
actions_methods!();
event_methods!();
children_methods!();
props! {
tag(String) = "tag";
class(String) = "class";
text(String) = "text";
input_type(InputType) = "type";
name(String) = "name";
value(String) = "value";
checked(bool) = "checked";
disabled(bool) = "disabled";
}
pub fn attrs(mut self, attrs: Map<String, Value>) -> Self {
self.0.props.insert("attrs".into(), Value::Object(attrs));
self
}
pub fn attr(mut self, name: impl Into<String>, value: impl Serialize) -> Self {
let Ok(value) = serde_json::to_value(value) else {
return self;
};
if let Some(Value::Object(attrs)) = self.0.props.get_mut("attrs") {
attrs.insert(name.into(), value);
} else {
let mut attrs = Map::new();
attrs.insert(name.into(), value);
self.0.props.insert("attrs".into(), Value::Object(attrs));
}
self
}
}
pub fn el<M>(tag: impl Into<String>) -> El<M> {
El(Node::new("el")).tag(tag)
}
macro_rules! bare_tags {
($($(#[$m:meta])* $f:ident = $tag:literal;)*) => {
$($(#[$m])* pub fn $f<M>() -> El<M> {
el($tag)
})*
};
}
macro_rules! text_tags {
($($(#[$m:meta])* $f:ident = $tag:literal;)*) => {
$($(#[$m])* pub fn $f<M>(text: impl Into<String>) -> El<M> {
el($tag).text(text)
})*
};
}
bare_tags! {
div = "div";
section = "section";
header = "header";
footer = "footer";
nav = "nav";
aside = "aside";
main = "main";
article = "article";
figure = "figure";
blockquote = "blockquote";
ul = "ul";
ol = "ol";
dl = "dl";
hr = "hr";
table = "table";
thead = "thead";
tbody = "tbody";
tr = "tr";
label = "label";
form = "form";
}
text_tags! {
span = "span";
p = "p";
li = "li";
dt = "dt";
dd = "dd";
h1 = "h1";
h2 = "h2";
h3 = "h3";
h4 = "h4";
pre = "pre";
code = "code";
kbd = "kbd";
strong = "strong";
b = "b";
em = "em";
i = "i";
del = "del";
mark = "mark";
th = "th";
td = "td";
button = "button";
}
pub fn input<M>(kind: impl Into<InputType>) -> El<M> {
el("input").input_type(kind)
}
pub fn checkbox<M>(name: impl Into<String>, value: impl Into<String>) -> El<M> {
input(InputType::Checkbox).name(name).value(value)
}
pub fn radio<M>(name: impl Into<String>, value: impl Into<String>) -> El<M> {
input(InputType::Radio).name(name).value(value)
}