radix_leptos_core/utils/
events.rs1use web_sys::{Event, EventTarget, MouseEvent, KeyboardEvent, FocusEvent};
2use wasm_bindgen::{JsCast, JsValue};
3
4pub fn compose_event_handlers<E, F1, F2>(
8 handler1: Option<F1>,
9 handler2: Option<F2>,
10) -> impl Fn(E)
11where
12 E: Clone,
13 F1: Fn(E),
14 F2: Fn(E),
15{
16 move |event: E| {
17 if let Some(ref h1) = handler1 {
18 h1(event.clone());
19 }
20 if let Some(ref h2) = handler2 {
21 h2(event);
22 }
23 }
24}
25
26pub fn should_handle_key_event(event: &KeyboardEvent, key: &str, modifiers: Option<KeyModifiers>) -> bool {
28 if event.key() != key {
29 return false;
30 }
31
32 if let Some(mods) = modifiers {
33 return event.ctrl_key() == mods.ctrl &&
34 event.shift_key() == mods.shift &&
35 event.alt_key() == mods.alt &&
36 event.meta_key() == mods.meta;
37 }
38
39 true
40}
41
42#[derive(Debug, Clone, PartialEq)]
44pub struct KeyModifiers {
45 pub ctrl: bool,
46 pub shift: bool,
47 pub alt: bool,
48 pub meta: bool,
49}
50
51impl KeyModifiers {
52 pub fn none() -> Self {
53 Self {
54 ctrl: false,
55 shift: false,
56 alt: false,
57 meta: false,
58 }
59 }
60
61 pub fn ctrl() -> Self {
62 Self {
63 ctrl: true,
64 shift: false,
65 alt: false,
66 meta: false,
67 }
68 }
69
70 pub fn shift() -> Self {
71 Self {
72 ctrl: false,
73 shift: true,
74 alt: false,
75 meta: false,
76 }
77 }
78}
79
80pub fn prevent_default_and_stop_propagation(event: &Event) {
82 event.prevent_default();
83 event.stop_propagation();
84}
85
86pub fn get_event_target_element(event: &Event) -> Option<web_sys::Element> {
88 event
89 .target()?
90 .dyn_into()
91 .ok()
92}
93
94#[cfg(test)]
96pub fn create_keyboard_event(event_type: &str, key: &str, modifiers: Option<KeyModifiers>) -> KeyboardEvent {
97 use web_sys::KeyboardEventInit;
98
99 let mut init = KeyboardEventInit::new();
100 init.key(key);
101
102 if let Some(mods) = modifiers {
103 init.ctrl_key(mods.ctrl);
104 init.shift_key(mods.shift);
105 init.alt_key(mods.alt);
106 init.meta_key(mods.meta);
107 }
108
109 KeyboardEvent::new_with_keyboard_event_init_dict(event_type, &init)
110 .expect("Failed to create keyboard event")
111}
112
113#[cfg(test)]
115pub fn create_mouse_event(event_type: &str) -> MouseEvent {
116 MouseEvent::new(event_type).expect("Failed to create mouse event")
117}
118
119#[cfg(test)]
120mod tests {
121 use super::*;
122 use wasm_bindgen_test::*;
123
124 wasm_bindgen_test_configure!(run_in_browser);
125
126 #[test]
127 fn test_key_modifiers() {
128 let none = KeyModifiers::none();
129 assert!(!none.ctrl && !none.shift && !none.alt && !none.meta);
130
131 let ctrl = KeyModifiers::ctrl();
132 assert!(ctrl.ctrl && !ctrl.shift && !ctrl.alt && !ctrl.meta);
133
134 let shift = KeyModifiers::shift();
135 assert!(!shift.ctrl && shift.shift && !shift.alt && !shift.meta);
136 }
137
138 #[wasm_bindgen_test]
139 fn test_keyboard_event_creation() {
140 let event = create_keyboard_event("keydown", "Enter", Some(KeyModifiers::ctrl()));
141
142 assert_eq!(event.key(), "Enter");
143 assert!(event.ctrl_key());
144 assert!(!event.shift_key());
145 }
146
147 #[wasm_bindgen_test]
148 fn test_should_handle_key_event() {
149 let event = create_keyboard_event("keydown", "Escape", None);
150
151 assert!(should_handle_key_event(&event, "Escape", None));
152 assert!(!should_handle_key_event(&event, "Enter", None));
153
154 let event_with_ctrl = create_keyboard_event("keydown", "s", Some(KeyModifiers::ctrl()));
155 assert!(should_handle_key_event(&event_with_ctrl, "s", Some(KeyModifiers::ctrl())));
156 assert!(!should_handle_key_event(&event_with_ctrl, "s", None));
157 }
158}