1use serde::Serialize;
25use serde_json::{Map, Value};
26
27use super::{
28 InputType, Node,
29 node::{
30 actions_methods, base_methods, children_methods, event_methods, kind_type, max_method,
31 min_method, props, title_method,
32 },
33};
34
35kind_type!(
36 El
39);
40
41impl<M> El<M> {
42 base_methods!();
43
44 min_method!();
45
46 title_method!();
47
48 max_method!();
49
50 actions_methods!();
51
52 event_methods!();
53
54 children_methods!();
55
56 props! {
57 tag(String) = "tag";
59 class(String) = "class";
61 text(String) = "text";
63 input_type(InputType) = "type";
65 name(String) = "name";
67 value(String) = "value";
69 checked(bool) = "checked";
71 disabled(bool) = "disabled";
73 }
74
75 pub fn attrs(mut self, attrs: Map<String, Value>) -> Self {
78 self.0.props.insert("attrs".into(), Value::Object(attrs));
79 self
80 }
81
82 pub fn attr(mut self, name: impl Into<String>, value: impl Serialize) -> Self {
84 let Ok(value) = serde_json::to_value(value) else {
85 return self;
86 };
87 if let Some(Value::Object(attrs)) = self.0.props.get_mut("attrs") {
88 attrs.insert(name.into(), value);
89 } else {
90 let mut attrs = Map::new();
91 attrs.insert(name.into(), value);
92 self.0.props.insert("attrs".into(), Value::Object(attrs));
93 }
94 self
95 }
96}
97
98pub fn el<M>(tag: impl Into<String>) -> El<M> {
100 El(Node::new("el")).tag(tag)
101}
102
103macro_rules! bare_tags {
105 ($($(#[$m:meta])* $f:ident = $tag:literal;)*) => {
106 $($(#[$m])* pub fn $f<M>() -> El<M> {
107 el($tag)
108 })*
109 };
110}
111
112macro_rules! text_tags {
114 ($($(#[$m:meta])* $f:ident = $tag:literal;)*) => {
115 $($(#[$m])* pub fn $f<M>(text: impl Into<String>) -> El<M> {
116 el($tag).text(text)
117 })*
118 };
119}
120
121bare_tags! {
122 div = "div";
124 section = "section";
126 header = "header";
128 footer = "footer";
130 nav = "nav";
132 aside = "aside";
134 main = "main";
136 article = "article";
138 figure = "figure";
140 blockquote = "blockquote";
142 ul = "ul";
144 ol = "ol";
146 dl = "dl";
148 hr = "hr";
150 table = "table";
152 thead = "thead";
154 tbody = "tbody";
156 tr = "tr";
158 label = "label";
160 form = "form";
162}
163
164text_tags! {
165 span = "span";
167 p = "p";
169 li = "li";
171 dt = "dt";
173 dd = "dd";
175 h1 = "h1";
177 h2 = "h2";
179 h3 = "h3";
181 h4 = "h4";
183 pre = "pre";
185 code = "code";
187 kbd = "kbd";
189 strong = "strong";
191 b = "b";
193 em = "em";
195 i = "i";
197 del = "del";
199 mark = "mark";
201 th = "th";
203 td = "td";
205 button = "button";
207}
208
209pub fn input<M>(kind: impl Into<InputType>) -> El<M> {
211 el("input").input_type(kind)
212}
213
214pub fn checkbox<M>(name: impl Into<String>, value: impl Into<String>) -> El<M> {
217 input(InputType::Checkbox).name(name).value(value)
218}
219
220pub fn radio<M>(name: impl Into<String>, value: impl Into<String>) -> El<M> {
222 input(InputType::Radio).name(name).value(value)
223}