Skip to main content

dioxus_elements/
events.rs

1//! ArkUI event handlers usable inside `rsx!`.
2//!
3//! `rsx!` emits references to `dioxus_elements::events::<name>` (and
4//! `dioxus_elements::events::<name>::call_with_explicit_closure` for inline
5//! closures). Each event is a callable returning a `dioxus_core::Attribute`.
6//!
7//! The listener wraps the user callback and converts the platform
8//! [`ArkEventData`](crate::event::ArkEventData) into the typed event data.
9
10use crate::event::{
11    AccessibilityActionData, AreaData, ArkEventKind, AxisData, ChangeData, ClickData, FocusData,
12    HoverData, KeyData, MouseData, PointerData, ReachEndData, RefreshData, ScrollData, SubmitData,
13    SwiperChangeData,
14};
15
16/// Define every RSX listener, its payload type, and its semantic identity.
17///
18/// The declaration is the single source of truth: it generates the listener
19/// functions, their `call_with_explicit_closure` companions *and*
20/// [`EVENT_KINDS`], which [`crate::event::classify_event_name`] consults.
21/// Adding an event in one place cannot leave the classifier behind.
22macro_rules! impl_events {
23    ($(
24        $data:ty;
25        $($name:ident => $kind:ident),* $(,)?;
26    )*) => {
27        $($(
28            #[inline]
29            pub fn $name<__Marker>(mut _f: impl ::dioxus_core::SuperInto<::dioxus_core::ListenerCallback<$data>, __Marker>) -> ::dioxus_core::Attribute {
30                let event_handler = _f.super_into();
31                ::dioxus_core::Attribute::new(
32                    stringify!($name),
33                    ::dioxus_core::AttributeValue::listener(move |e: ::dioxus_core::Event<$crate::event::ArkEventData>| {
34                        let event: ::dioxus_core::Event<$data> = e.map(|d| d.into());
35                        event_handler.call(event.into_any());
36                    }),
37                    None,
38                    false,
39                )
40            }
41
42            #[doc(hidden)]
43            pub mod $name {
44                use super::*;
45
46                #[allow(deprecated)]
47                pub fn call_with_explicit_closure<__Marker, Return: ::dioxus_core::SpawnIfAsync<__Marker> + 'static>(
48                    event_handler: impl FnMut(::dioxus_core::Event<$data>) -> Return + 'static,
49                ) -> ::dioxus_core::Attribute {
50                    super::$name(event_handler)
51                }
52            }
53        )*)*
54
55        /// Every listener name declared in this file, paired with its
56        /// semantic identity.
57        ///
58        /// Names are stored in their RSX spelling (`onclick`);
59        /// [`crate::event::classify_event_name`] also accepts the compact
60        /// spelling Dioxus hands to renderers (`click`).
61        pub(crate) const EVENT_KINDS: &[(&str, ArkEventKind)] = &[
62            $($(
63                (stringify!($name), ArkEventKind::$kind),
64            )*)*
65        ];
66    };
67}
68
69impl_events! {
70    AccessibilityActionData;
71    onaccessibilityaction => AccessibilityAction;
72    ClickData;
73    onclick => Click, onlongpress => LongPress;
74    ChangeData;
75    onchange => Change, oninput => Change, ontoggle => Change;
76    SubmitData;
77    onsubmit => Submit;
78    ScrollData;
79    onscroll => Scroll;
80    ReachEndData;
81    onreachend => ReachEnd;
82    SwiperChangeData;
83    onswiperchange => SwiperChange;
84    RefreshData;
85    onrefresh => Refresh;
86    AreaData;
87    onarea => AreaChange;
88    HoverData;
89    onhover => Hover;
90    FocusData;
91    onfocus => Focus, onblur => Blur, onfocusin => FocusIn, onfocusout => FocusOut;
92    PointerData;
93    onhovermove => HoverMove, ondragstart => DragStart, ondragmove => DragMove,
94    ondragend => DragEnd, ondragleave => DragLeave, ondragenter => DragEnter, ontouch => Touch;
95    KeyData;
96    onkey => Key, onkeypreime => KeyPreIme;
97    MouseData;
98    onmouse => Mouse;
99    AxisData;
100    onaxis => Axis;
101}