1use crate::{
2 html::{
3 attribute::Attribute,
4 element::{ElementType, ElementWithChildren, HtmlElement},
5 },
6 view::Render,
7};
8use std::fmt::Debug;
9
10macro_rules! svg_elements {
11 ($($tag:ident [$($attr:ty),*]),* $(,)?) => {
12 paste::paste! {
13 $(
14 #[allow(non_snake_case)]
17 #[track_caller]
18 pub fn $tag() -> HtmlElement<[<$tag:camel>], (), ()>
19 where
20 {
21 HtmlElement {
22 #[cfg(any(debug_assertions, leptos_debuginfo))]
23 defined_at: std::panic::Location::caller(),
24 tag: [<$tag:camel>],
25 attributes: (),
26 children: (),
27 }
28 }
29
30 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
32 pub struct [<$tag:camel>];
33
34 impl<At, Ch> HtmlElement<[<$tag:camel>], At, Ch>
35 where
36 At: Attribute,
37 Ch: Render,
38
39 {
40 $(
41 pub fn $attr<V>(self, value: V) -> HtmlElement <
42 [<$tag:camel>],
43 <At as $crate::html::attribute::NextAttribute<Attr<$crate::html::attribute::[<$attr:camel>], V>>>::Output,
44 Ch
45 >
46 where
47 V: AttributeValue,
48 At: $crate::html::attribute::NextAttribute<Attr<$crate::html::attribute::[<$attr:camel>], V>>,
49 <At as $crate::html::attribute::NextAttribute<Attr<$crate::html::attribute::[<$attr:camel>], V>>>::Output: Attribute,
50 {
51 let HtmlElement { tag, children, attributes,
52 #[cfg(any(debug_assertions, leptos_debuginfo))]
53 defined_at
54 } = self;
55 HtmlElement {
56 tag,
57
58 children,
59 attributes: attributes.add_any_attr($crate::html::attribute::$attr(value)),
60 #[cfg(any(debug_assertions, leptos_debuginfo))]
61 defined_at
62 }
63 }
64 )*
65 }
66
67 impl ElementType for [<$tag:camel>] {
68 type Output = web_sys::SvgElement;
69
70 const TAG: &'static str = stringify!($tag);
71 const SELF_CLOSING: bool = false;
72 const ESCAPE_CHILDREN: bool = true;
73 const NAMESPACE: Option<&'static str> = Some("http://www.w3.org/2000/svg");
74
75 #[inline(always)]
76 fn tag(&self) -> &str {
77 Self::TAG
78 }
79 }
80
81 impl ElementWithChildren for [<$tag:camel>] {}
82 )*
83 }
84 }
85}
86
87svg_elements![
88 a [],
89 animate [],
90 animateMotion [],
91 animateTransform [],
92 circle [],
93 clipPath [],
94 defs [],
95 desc [],
96 discard [],
97 ellipse [],
98 feBlend [],
99 feColorMatrix [],
100 feComponentTransfer [],
101 feComposite [],
102 feConvolveMatrix [],
103 feDiffuseLighting [],
104 feDisplacementMap [],
105 feDistantLight [],
106 feDropShadow [],
107 feFlood [],
108 feFuncA [],
109 feFuncB [],
110 feFuncG [],
111 feFuncR [],
112 feGaussianBlur [],
113 feImage [],
114 feMerge [],
115 feMergeNode [],
116 feMorphology [],
117 feOffset [],
118 fePointLight [],
119 feSpecularLighting [],
120 feSpotLight [],
121 feTile [],
122 feTurbulence [],
123 filter [],
124 foreignObject [],
125 g [],
126 hatch [],
127 hatchpath [],
128 image [],
129 line [],
130 linearGradient [],
131 marker [],
132 mask [],
133 metadata [],
134 mpath [],
135 path [],
136 pattern [],
137 polygon [],
138 polyline [],
139 radialGradient [],
140 rect [],
141 script [],
142 set [],
143 stop [],
144 style [],
145 svg [],
146 switch [],
147 symbol [],
148 text [],
149 textPath [],
150 title [],
151 tspan [],
152 view [],
153];
154
155#[allow(non_snake_case)]
157#[track_caller]
158pub fn r#use() -> HtmlElement<Use, (), ()>
159where {
160 HtmlElement {
161 #[cfg(any(debug_assertions, leptos_debuginfo))]
162 defined_at: std::panic::Location::caller(),
163 tag: Use,
164 attributes: (),
165 children: (),
166 }
167}
168
169#[derive(Debug, Copy, Clone, PartialEq, Eq)]
171pub struct Use;
172
173impl ElementType for Use {
174 type Output = web_sys::SvgElement;
175
176 const TAG: &'static str = "use";
177 const SELF_CLOSING: bool = false;
178 const ESCAPE_CHILDREN: bool = true;
179 const NAMESPACE: Option<&'static str> = Some("http://www.w3.org/2000/svg");
180
181 #[inline(always)]
182 fn tag(&self) -> &str {
183 Self::TAG
184 }
185}
186
187impl ElementWithChildren for Use {}