dioxus_gestures/
use_gestures.rs1use nanoid::nanoid;
2use paste;
3use std::{cell::RefCell, rc::Rc};
4
5use dioxus::{
6 core::{AttributeValue, Event, ListenerCallback},
7 html::PlatformEventData,
8 prelude::{use_hook, Attribute},
9};
10
11#[cfg(feature = "fullstack")]
12use dioxus::prelude::use_server_cached;
13
14use crate::state::{
15 events::PointerEventReceiver,
16 gestures::{drag::Drag, hover::Hover, pinch::Pinch},
17 options::UseGesturesOptions,
18};
19use crate::state::{external_handlers::ExternalHandlers, state::UseGesturesState};
20
21#[derive(Clone)]
22pub struct UseGestures {
23 state: Rc<RefCell<UseGesturesState>>,
24}
25
26impl UseGestures {
27 pub fn new(target_id: String, config: Gestures) -> Self {
28 let Gestures {
29 external_handlers,
30 hover,
31 drag,
32 pinch,
33 options,
34 } = config;
35 Self {
36 state: Rc::new(RefCell::new(UseGesturesState::new(
37 target_id,
38 external_handlers,
39 hover,
40 drag,
41 pinch,
42 options,
43 ))),
44 }
45 }
46
47 pub fn event_handlers(self) -> Vec<Attribute> {
48 macro_rules! pointer_event_handler {
49 ($attribute_name: ident, $function_name: ident) => {{
50 let pointer_ref = Rc::clone(&self.state);
51 Attribute::new(
52 paste::paste! { stringify!([<$attribute_name:camel:lower>])},
53 AttributeValue::Listener(
54 ListenerCallback::new(move |e: Event<PlatformEventData>| {
55 let _ = pointer_ref
56 .try_borrow_mut()
57 .map(|mut s| s.$function_name(e.map(|data| data.into())));
58 })
59 .erase(),
60 ),
61 None,
62 false,
63 )
64 }};
65 }
66
67 vec![
68 Attribute::new(
69 self.state.borrow().options.target_id_attribute_name,
70 AttributeValue::Text(self.state.borrow().target_id.clone()),
71 None,
72 false,
73 ),
74 pointer_event_handler!(on_pointer_over, pointer_over),
75 pointer_event_handler!(on_pointer_enter, pointer_enter),
76 pointer_event_handler!(on_pointer_down, pointer_down),
77 pointer_event_handler!(on_pointer_move, pointer_move),
78 pointer_event_handler!(on_pointer_up, pointer_up),
79 pointer_event_handler!(on_pointer_cancel, pointer_cancel),
80 pointer_event_handler!(on_pointer_out, pointer_out),
81 pointer_event_handler!(on_pointer_leave, pointer_leave),
82 ]
83 }
84}
85
86pub fn use_gestures(props: Gestures) -> UseGestures {
87 #[cfg(not(feature = "fullstack"))]
88 let target_id =
89 use_hook(|| props.options.target_id.clone().unwrap_or_else(|| nanoid!()));
90
91 #[cfg(feature = "fullstack")]
92 let target_id =
93 use_server_cached(|| props.options.target_id.clone().unwrap_or_else(|| nanoid!()));
94
95 use_hook(|| UseGestures::new(target_id, props))
96}
97
98#[derive(Default)]
99pub struct Gestures {
100 pub external_handlers: ExternalHandlers,
101 pub hover: Hover,
102 pub drag: Drag,
103 pub pinch: Pinch,
104 pub options: UseGesturesOptions,
105}
106
107impl Gestures {
108 pub fn external_handlers(mut self, external_handlers: ExternalHandlers) -> Self {
109 self.external_handlers = external_handlers;
110 self
111 }
112
113 pub fn hover(mut self, hover: Hover) -> Self {
114 self.hover = hover;
115 self
116 }
117
118 pub fn drag(mut self, drag: Drag) -> Self {
119 self.drag = drag;
120 self
121 }
122
123 pub fn pinch(mut self, pinch: Pinch) -> Self {
124 self.pinch = pinch;
125 self
126 }
127
128 pub fn options(mut self, options: UseGesturesOptions) -> Self {
129 self.options = options;
130 self
131 }
132}