dioxus_html/events/generated.rs
1use super::*;
2
3#[doc(hidden)]
4#[macro_export]
5macro_rules! with_html_event_groups {
6 ($macro:ident) => {
7 $macro! {
8 enum Event {
9 #[convert = convert_animation_data]
10 #[events = [
11 onanimationstart => animationstart,
12 onanimationend => animationend,
13 onanimationiteration => animationiteration,
14 ]]
15 Animation(AnimationData),
16
17 #[convert = convert_cancel_data]
18 #[events = [
19 oncancel => cancel,
20 ]]
21 Cancel(CancelData),
22
23 #[convert = convert_clipboard_data]
24 #[events = [
25 oncopy => copy,
26 oncut => cut,
27 onpaste => paste,
28 ]]
29 Clipboard(ClipboardData),
30
31 #[convert = convert_composition_data]
32 #[events = [
33 oncompositionstart => compositionstart,
34 oncompositionend => compositionend,
35 oncompositionupdate => compositionupdate,
36 ]]
37 Composition(CompositionData),
38
39 #[convert = convert_drag_data]
40 #[events = [
41 ondrag => drag,
42 ondragend => dragend,
43 ondragenter => dragenter,
44 ondragexit => dragexit,
45 ondragleave => dragleave,
46 ondragover => dragover,
47 ondragstart => dragstart,
48 ondrop => drop,
49 ]]
50 Drag(DragData),
51
52 #[convert = convert_focus_data]
53 #[events = [
54 onfocus => focus,
55 onfocusout => focusout,
56 onfocusin => focusin,
57 onblur => blur,
58 ]]
59 Focus(FocusData),
60
61 #[convert = convert_form_data]
62 #[events = [
63 onchange => change,
64 /// The `oninput` event is fired when the value of a `<input>`, `<select>`, or `<textarea>` element is changed.
65 ///
66 /// There are two main approaches to updating your input element:
67 /// 1) Controlled inputs directly update the value of the input element as the user interacts with the element
68 ///
69 /// ```rust
70 /// use dioxus::prelude::*;
71 ///
72 /// fn App() -> Element {
73 /// let mut value = use_signal(|| "hello world".to_string());
74 ///
75 /// rsx! {
76 /// input {
77 /// value: "{value}",
78 /// oninput: move |event| value.set(event.value())
79 /// }
80 /// button {
81 /// onclick: move |_| value.write().clear(),
82 /// "Clear"
83 /// }
84 /// }
85 /// }
86 /// ```
87 ///
88 /// 2) Uncontrolled inputs just read the value of the input element as it changes
89 ///
90 /// ```rust
91 /// use dioxus::prelude::*;
92 ///
93 /// fn App() -> Element {
94 /// rsx! {
95 /// input {
96 /// oninput: move |event| println!("{}", event.value()),
97 /// }
98 /// }
99 /// }
100 /// ```
101 oninput => input,
102 oninvalid => invalid,
103 onreset => reset,
104 onsubmit => submit,
105 ]]
106 Form(FormData),
107
108 #[convert = convert_image_data]
109 #[events = [
110 onerror => error,
111 onload => load,
112 ]]
113 Image(ImageData),
114
115 #[convert = convert_keyboard_data]
116 #[events = [
117 onkeydown => keydown,
118 onkeypress => keypress,
119 onkeyup => keyup,
120 ]]
121 Keyboard(KeyboardData),
122
123 #[convert = convert_media_data]
124 #[events = [
125 onabort => abort,
126 oncanplay => canplay,
127 oncanplaythrough => canplaythrough,
128 ondurationchange => durationchange,
129 onemptied => emptied,
130 onencrypted => encrypted,
131 onended => ended,
132 onloadeddata => loadeddata,
133 onloadedmetadata => loadedmetadata,
134 onloadstart => loadstart,
135 onpause => pause,
136 onplay => play,
137 onplaying => playing,
138 onprogress => progress,
139 onratechange => ratechange,
140 onseeked => seeked,
141 onseeking => seeking,
142 onstalled => stalled,
143 onsuspend => suspend,
144 ontimeupdate => timeupdate,
145 onvolumechange => volumechange,
146 onwaiting => waiting,
147 ]]
148 #[raw = [interruptbegin, interruptend, loadend, timeout]]
149 Media(MediaData),
150
151 #[convert = convert_mounted_data]
152 #[events = [
153 #[doc(alias = "ref")]
154 #[doc(alias = "createRef")]
155 #[doc(alias = "useRef")]
156 /// The onmounted event is fired when the element is first added to the DOM. This event gives you a [`MountedData`] object and lets you interact with the raw DOM element.
157 ///
158 /// This event is fired once per element. If you need to access the element multiple times, you can store the [`MountedData`] object in a [`use_signal`](https://docs.rs/dioxus-hooks/latest/dioxus_hooks/fn.use_signal.html) hook and use it as needed.
159 ///
160 /// # Examples
161 ///
162 /// ```rust, no_run
163 /// # use dioxus::prelude::*;
164 /// fn App() -> Element {
165 /// let mut header_element = use_signal(|| None);
166 ///
167 /// rsx! {
168 /// div {
169 /// h1 {
170 /// // The onmounted event will run the first time the h1 element is mounted
171 /// onmounted: move |element| header_element.set(Some(element.data())),
172 /// "Scroll to top example"
173 /// }
174 ///
175 /// for i in 0..100 {
176 /// div { "Item {i}" }
177 /// }
178 ///
179 /// button {
180 /// // When you click the button, if the header element has been mounted, we scroll to that element
181 /// onclick: move |_| async move {
182 /// if let Some(header) = header_element.cloned() {
183 /// let _ = header.scroll_to(ScrollBehavior::Smooth).await;
184 /// }
185 /// },
186 /// "Scroll to top"
187 /// }
188 /// }
189 /// }
190 /// }
191 /// ```
192 ///
193 /// The `MountedData` struct contains cross platform APIs that work on the desktop, mobile, liveview and web platforms. For the web platform, you can also downcast the `MountedData` event to the `web-sys::Element` type for more web specific APIs:
194 ///
195 /// ```rust, ignore
196 /// use dioxus::prelude::*;
197 /// use dioxus_web::WebEventExt; // provides [`as_web_event()`] method
198 ///
199 /// fn App() -> Element {
200 /// rsx! {
201 /// div {
202 /// id: "some-id",
203 /// onmounted: move |element| {
204 /// // You can use the web_event trait to downcast the element to a web specific event. For the mounted event, this will be a web_sys::Element
205 /// let web_sys_element = element.as_web_event();
206 /// assert_eq!(web_sys_element.id(), "some-id");
207 /// }
208 /// }
209 /// }
210 /// }
211 /// ```
212 onmounted => mounted,
213 ]]
214 Mounted(MountedData),
215
216 #[convert = convert_mouse_data]
217 #[events = [
218 /// Execute a callback when a button is clicked.
219 ///
220 /// ## Description
221 ///
222 /// An element receives a click event when a pointing device button (such as a mouse's primary mouse button)
223 /// is both pressed and released while the pointer is located inside the element.
224 ///
225 /// - Bubbles: Yes
226 /// - Cancelable: Yes
227 /// - Interface(InteData): [`MouseEvent`]
228 ///
229 /// If the button is pressed on one element and the pointer is moved outside the element before the button
230 /// is released, the event is fired on the most specific ancestor element that contained both elements.
231 /// `click` fires after both the `mousedown` and `mouseup` events have fired, in that order.
232 ///
233 /// ## Example
234 /// ```rust, ignore
235 /// rsx!( button { onclick: move |_| tracing::info!("Clicked!"), "click me" } )
236 /// ```
237 ///
238 /// ## Reference
239 /// - <https://www.w3schools.com/tags/ev_onclick.asp>
240 /// - <https://developer.mozilla.org/en-US/docs/Web/API/Element/click_event>
241 onclick => click,
242 oncontextmenu => contextmenu,
243 #[deprecated(since = "0.5.0", note = "use ondoubleclick instead")]
244 ondblclick => dblclick,
245 #[doc(alias = "ondblclick")]
246 ondoubleclick => dblclick,
247 onmousedown => mousedown,
248 onmouseenter => mouseenter,
249 onmouseleave => mouseleave,
250 onmousemove => mousemove,
251 onmouseout => mouseout,
252 /// Triggered when the users's mouse hovers over an element.
253 onmouseover => mouseover,
254 onmouseup => mouseup,
255 ]]
256 #[raw = [doubleclick]]
257 Mouse(MouseData),
258
259 #[convert = convert_pointer_data]
260 #[events = [
261 onpointerdown => pointerdown,
262 onpointermove => pointermove,
263 onpointerup => pointerup,
264 onpointercancel => pointercancel,
265 ongotpointercapture => gotpointercapture,
266 onlostpointercapture => lostpointercapture,
267 onpointerenter => pointerenter,
268 onpointerleave => pointerleave,
269 onpointerover => pointerover,
270 onpointerout => pointerout,
271 onauxclick => auxclick,
272 ]]
273 #[raw = [pointerlockchange, pointerlockerror]]
274 Pointer(PointerData),
275
276 #[convert = convert_resize_data]
277 #[events = [
278 onresize => resize,
279 ]]
280 Resize(ResizeData),
281
282 #[convert = convert_scroll_data]
283 #[events = [
284 onscroll => scroll,
285 onscrollend => scrollend,
286 ]]
287 Scroll(ScrollData),
288
289 #[convert = convert_selection_data]
290 #[events = [
291 onselect => select,
292 onselectstart => selectstart,
293 onselectionchange => selectionchange,
294 ]]
295 Selection(SelectionData),
296
297 #[convert = convert_toggle_data]
298 #[events = [
299 ontoggle => toggle,
300 onbeforetoggle => beforetoggle,
301 ]]
302 Toggle(ToggleData),
303
304 #[convert = convert_touch_data]
305 #[events = [
306 ontouchstart => touchstart,
307 ontouchmove => touchmove,
308 ontouchend => touchend,
309 ontouchcancel => touchcancel,
310 ]]
311 Touch(TouchData),
312
313 #[convert = convert_transition_data]
314 #[events = [
315 ontransitionend => transitionend,
316 ]]
317 Transition(TransitionData),
318
319 #[convert = convert_visible_data]
320 #[events = [
321 onvisible => visible,
322 ]]
323 Visible(VisibleData),
324
325 #[convert = convert_wheel_data]
326 #[events = [
327 /// Called when the mouse wheel is rotated over an element.
328 onwheel => wheel,
329 ]]
330 Wheel(WheelData),
331 }
332 }
333 };
334}
335
336macro_rules! expand_html_event_converter {
337 (
338 enum Event {
339 $(
340 #[convert = $converter:ident]
341 #[events = [
342 $(
343 $( #[$attr:meta] )*
344 $name:ident => $raw:ident,
345 )*
346 ]]
347 $(#[raw = [$($raw_only:ident),* $(,)?]])?
348 $group:ident($data:ident),
349 )*
350 }
351 ) => {
352 /// A converter between a platform specific event and a general event. All code in a renderer that has a large binary size should be placed in this trait. Each of these functions should be snipped in high levels of optimization.
353 pub trait HtmlEventConverter: Send + Sync {
354 $(
355 fn $converter(&self, event: &PlatformEventData) -> $data;
356 )*
357 }
358
359 $(
360 impl From<&PlatformEventData> for $data {
361 fn from(val: &PlatformEventData) -> Self {
362 with_event_converter(|c| c.$converter(val))
363 }
364 }
365 )*
366 };
367}
368
369#[cfg(feature = "serialize")]
370macro_rules! expand_html_event_deserialize {
371 (
372 enum Event {
373 $(
374 #[convert = $converter:ident]
375 #[events = [
376 $(
377 $( #[$attr:meta] )*
378 $name:ident => $raw:ident,
379 )*
380 ]]
381 $(#[raw = [$($raw_only:ident),* $(,)?]])?
382 $group:ident($data:ident),
383 )*
384 }
385 ) => {
386 pub(crate) fn deserialize_raw_event(
387 name: &str,
388 data: &serde_json::Value,
389 ) -> Result<Option<crate::transit::EventData>, serde_json::Error> {
390 #[inline]
391 fn de<'de, F>(f: &'de serde_json::Value) -> Result<F, serde_json::Error>
392 where
393 F: serde::Deserialize<'de>,
394 {
395 F::deserialize(f)
396 }
397
398 Ok(match name {
399 $(
400 $( stringify!($raw) )|* $($(| stringify!($raw_only))*)? => {
401 Some(expand_html_event_deserialize!(@deserialize $group, data))
402 }
403 )*
404 _ => None,
405 })
406 }
407 };
408 (@deserialize Mounted, $data:ident) => {
409 crate::transit::EventData::Mounted
410 };
411 (@deserialize $group:ident, $data:ident) => {
412 crate::transit::EventData::$group(de($data)?)
413 };
414}
415
416macro_rules! expand_html_event_listeners {
417 (
418 enum Event {
419 $(
420 #[convert = $converter:ident]
421 #[events = [
422 $(
423 $( #[$attr:meta] )*
424 $name:ident => $raw:ident,
425 )*
426 ]]
427 $(#[raw = [$($raw_only:ident),* $(,)?]])?
428 $group:ident($data:ident),
429 )*
430 }
431 ) => {
432 $(
433 impl_event! {
434 $data;
435 $(
436 #[doc = concat!(stringify!($name))]
437 $( #[$attr] )*
438 $name: concat!("on", stringify!($raw));
439 )*
440 }
441 )*
442 };
443}
444
445with_html_event_groups!(expand_html_event_converter);
446#[cfg(feature = "serialize")]
447with_html_event_groups!(expand_html_event_deserialize);
448with_html_event_groups!(expand_html_event_listeners);