1
0
Jonathan Kelley 2 жил өмнө
parent
commit
0dad91bc08

+ 2 - 2
docs/guide/examples/event_handler_prop.rs

@@ -1,6 +1,6 @@
 #![allow(non_snake_case)]
 
-use dioxus::events::MouseEvent;
+use dioxus::events::MouseData;
 use dioxus::prelude::*;
 
 fn main() {
@@ -20,7 +20,7 @@ fn App(cx: Scope) -> Element {
 // ANCHOR: component_with_handler
 #[derive(Props)]
 pub struct FancyButtonProps<'a> {
-    on_click: EventHandler<'a, MouseEvent>,
+    on_click: EventHandler<'a, MouseData>,
 }
 
 pub fn FancyButton<'a>(cx: Scope<'a, FancyButtonProps<'a>>) -> Element<'a> {

+ 2 - 2
docs/guide/examples/meme_editor.rs

@@ -1,7 +1,7 @@
 // ANCHOR: all
 #![allow(non_snake_case)]
 
-use dioxus::events::FormEvent;
+use dioxus::events::FormData;
 use dioxus::prelude::*;
 
 fn main() {
@@ -83,7 +83,7 @@ fn Meme<'a>(cx: Scope<'a>, caption: &'a str) -> Element<'a> {
 fn CaptionEditor<'a>(
     cx: Scope<'a>,
     caption: &'a str,
-    on_input: EventHandler<'a, FormEvent>,
+    on_input: EventHandler<'a, FormData>,
 ) -> Element<'a> {
     let input_style = r"
         border: none;

+ 2 - 2
docs/guide/examples/meme_editor_dark_mode.rs

@@ -1,7 +1,7 @@
 // ANCHOR: all
 #![allow(non_snake_case)]
 
-use dioxus::events::FormEvent;
+use dioxus::events::FormData;
 use dioxus::prelude::*;
 
 fn main() {
@@ -150,7 +150,7 @@ fn Meme<'a>(cx: Scope<'a>, caption: &'a str) -> Element<'a> {
 fn CaptionEditor<'a>(
     cx: Scope<'a>,
     caption: &'a str,
-    on_input: EventHandler<'a, FormEvent>,
+    on_input: EventHandler<'a, FormData>,
 ) -> Element<'a> {
     let is_dark_mode = use_is_dark_mode(&cx);
 

+ 1 - 1
examples/all_events.rs

@@ -1,4 +1,4 @@
-use dioxus::{events::*, prelude::*};
+use dioxus::{events::*, html::MouseEvent, prelude::*};
 
 fn main() {
     dioxus_desktop::launch(app);

+ 1 - 1
examples/hydration.rs

@@ -14,7 +14,7 @@ use dioxus_desktop::Config;
 
 fn main() {
     let vdom = VirtualDom::new(app);
-    let content = dioxus_ssr::render_vdom_cfg(&vdom, |f| f.pre_render(true));
+    let content = dioxus_ssr::pre_render(&vdom);
 
     dioxus_desktop::launch_cfg(app, Config::new().with_prerendered(content));
 }

+ 1 - 1
examples/inputs.rs

@@ -2,7 +2,7 @@
 //!
 //! There is some conversion happening when input types are checkbox/radio/select/textarea etc.
 
-use dioxus::events::FormEvent;
+use dioxus::events::FormData;
 use dioxus::prelude::*;
 
 fn main() {

+ 2 - 4
examples/login_form.rs

@@ -1,7 +1,6 @@
 //! This example demonstrates the following:
 //! Futures in a callback, Router, and Forms
 
-use dioxus::events::*;
 use dioxus::prelude::*;
 
 fn main() {
@@ -37,11 +36,10 @@ fn app(cx: Scope) -> Element {
         form {
             onsubmit: onsubmit,
             prevent_default: "onsubmit", // Prevent the default behavior of <form> to post
-
-            input { "type": "text", id: "username", name: "username" }
+            input { r#type: "text", id: "username", name: "username" }
             label { "Username" }
             br {}
-            input { "type": "password", id: "password", name: "password" }
+            input { r#type: "password", id: "password", name: "password" }
             label { "Password" }
             br {}
             button { "Login" }

+ 1 - 0
examples/pattern_model.rs

@@ -19,6 +19,7 @@
 
 use dioxus::events::*;
 use dioxus::html::input_data::keyboard_types::Key;
+use dioxus::html::MouseEvent;
 use dioxus::prelude::*;
 use dioxus_desktop::wry::application::dpi::LogicalSize;
 use dioxus_desktop::{Config, WindowBuilder};

+ 1 - 2
examples/svg.rs

@@ -1,6 +1,6 @@
 // Thanks to @japsu and their project https://github.com/japsu/jatsi for the example!
 
-use dioxus::{events::MouseEvent, prelude::*};
+use dioxus::{events::MouseData, html::MouseEvent, prelude::*};
 
 fn main() {
     dioxus_desktop::launch(app);
@@ -82,7 +82,6 @@ pub fn Die<'a>(cx: Scope<'a, DieProps<'a>>) -> Element {
       svg {
         onclick: move |e| cx.props.onclick.call(e),
         prevent_default: "onclick",
-        "dioxus-prevent-default": "onclick",
         class: "die",
         view_box: "-1000 -1000 2000 2000",
 

+ 34 - 1
packages/core/src/events.rs

@@ -1,5 +1,38 @@
 use bumpalo::boxed::Box as BumpBox;
-use std::{any::Any, cell::RefCell};
+use std::{
+    any::Any,
+    cell::{Cell, RefCell},
+    fmt::Debug,
+    rc::Rc,
+};
+
+pub struct UiEvent<T> {
+    bubble_state: Cell<bool>,
+    data: Rc<T>,
+}
+
+impl<T> UiEvent<T> {
+    pub fn cancel_bubble(&self) {
+        self.bubble_state.set(false);
+    }
+}
+
+impl<T> std::ops::Deref for UiEvent<T> {
+    type Target = Rc<T>;
+
+    fn deref(&self) -> &Self::Target {
+        &self.data
+    }
+}
+
+impl<T: Debug> std::fmt::Debug for UiEvent<T> {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        f.debug_struct("UiEvent")
+            .field("bubble_state", &self.bubble_state)
+            .field("data", &self.data)
+            .finish()
+    }
+}
 
 /// Priority of Event Triggers.
 ///

+ 13 - 2
packages/core/src/factory.rs

@@ -1,4 +1,7 @@
-use std::{cell::Cell, fmt::Arguments};
+use std::{
+    cell::{Cell, RefCell},
+    fmt::Arguments,
+};
 
 use bumpalo::boxed::Box as BumpBox;
 use bumpalo::Bump;
@@ -7,7 +10,7 @@ use std::future::Future;
 use crate::{
     any_props::{AnyProps, VComponentProps},
     arena::ElementId,
-    innerlude::DynamicNode,
+    innerlude::{DynamicNode, EventHandler},
     Attribute, AttributeValue, Element, LazyNodes, Properties, Scope, ScopeState, VNode,
 };
 
@@ -106,6 +109,14 @@ impl ScopeState {
             scope: Cell::new(None),
         }
     }
+
+    /// Create a new [`EventHandler`] from an [`FnMut`]
+    pub fn event_handler<'a, T>(&'a self, f: impl FnMut(T) + 'a) -> EventHandler<'a, T> {
+        let handler: &mut dyn FnMut(T) = self.bump().alloc(f);
+        let caller = unsafe { BumpBox::from_raw(handler as *mut dyn FnMut(T)) };
+        let callback = RefCell::new(Some(caller));
+        EventHandler { callback }
+    }
 }
 
 pub trait ComponentReturn<'a, A = ()> {

+ 2 - 1
packages/core/src/lib.rs

@@ -92,6 +92,7 @@ pub use crate::innerlude::{
     Template,
     TemplateAttribute,
     TemplateNode,
+    UiEvent,
     VNode,
     VirtualDom,
 };
@@ -103,7 +104,7 @@ pub mod prelude {
     pub use crate::innerlude::{
         fc_to_builder, Element, EventHandler, EventPriority, Fragment, LazyNodes, NodeFactory,
         Properties, Scope, ScopeId, ScopeState, Scoped, TaskId, Template, TemplateAttribute,
-        TemplateNode, VNode, VirtualDom,
+        TemplateNode, UiEvent, VNode, VirtualDom,
     };
 }
 

+ 2 - 2
packages/dioxus/src/lib.rs

@@ -7,7 +7,7 @@ pub use dioxus_hooks as hooks;
 
 pub mod events {
     #[cfg(feature = "html")]
-    pub use dioxus_html::{AnimationEvent, FormEvent, KeyCode, MouseEvent};
+    pub use dioxus_html::{AnimationEvent, FormData, FormEvent, KeyCode, KeyboardEvent, MouseData};
 }
 
 #[cfg(feature = "html")]
@@ -32,5 +32,5 @@ pub mod prelude {
     pub use dioxus_html as dioxus_elements;
 
     #[cfg(feature = "html")]
-    pub use dioxus_elements::{GlobalAttributes, SvgAttributes};
+    pub use dioxus_elements::{FormEvent, GlobalAttributes, SvgAttributes};
 }

+ 1 - 1
packages/html/src/elements.rs

@@ -27,7 +27,7 @@ macro_rules! builder_constructors {
                 pub const NAME_SPACE: Option<&'static str> = None;
 
                 $(
-                    pub const $fil: (&'static str, &'static str) = (stringify!($fil), stringify!($vil));
+                    pub const $fil: AttributeDiscription = (stringify!($fil), None, false);
                 )*
             }
 

+ 1 - 1
packages/html/src/events.rs

@@ -11,7 +11,7 @@ macro_rules! impl_event {
     ) => {
         $(
             $( #[$attr] )*
-            pub fn $name<'a>(_cx: &'a ::dioxus_core::ScopeState, _f: impl FnMut(&'a $data) + 'a) -> ::dioxus_core::Attribute<'a> {
+            pub fn $name<'a>(_cx: &'a ::dioxus_core::ScopeState, _f: impl FnMut(::dioxus_core::UiEvent<$data>) + 'a) -> ::dioxus_core::Attribute<'a> {
                 todo!()
             }
         )*

+ 23 - 0
packages/html/src/events/focus.rs

@@ -0,0 +1,23 @@
+use dioxus_core::UiEvent;
+
+pub type FocusEvent = UiEvent<FocusData>;
+
+#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
+#[derive(Debug, Clone)]
+pub struct FocusData {/* DOMEventInner:  Send + SyncTarget relatedTarget */}
+
+impl_event! [
+    FocusData;
+
+    /// onfocus
+    onfocus
+
+    // onfocusout
+    onfocusout
+
+    // onfocusin
+    onfocusin
+
+    /// onblur
+    onblur
+];

+ 16 - 3
packages/html/src/events/form.rs

@@ -1,9 +1,13 @@
-use std::{collections::HashMap, sync::Arc};
+use std::{collections::HashMap, fmt::Debug, sync::Arc};
+
+use dioxus_core::UiEvent;
+
+pub type FormEvent = UiEvent<FormData>;
 
 /* DOMEvent:  Send + SyncTarget relatedTarget */
 #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
 #[derive(Clone)]
-pub struct FormEvent {
+pub struct FormData {
     pub value: String,
 
     pub values: HashMap<String, String>,
@@ -12,6 +16,15 @@ pub struct FormEvent {
     pub files: Option<Arc<dyn FileEngine>>,
 }
 
+impl Debug for FormData {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        f.debug_struct("FormEvent")
+            .field("value", &self.value)
+            .field("values", &self.values)
+            .finish()
+    }
+}
+
 #[async_trait::async_trait(?Send)]
 pub trait FileEngine {
     // get a list of file names
@@ -25,7 +38,7 @@ pub trait FileEngine {
 }
 
 impl_event! {
-    FormEvent;
+    FormData;
 
     /// onchange
     onchange

+ 651 - 0
packages/html/src/events/keyboard.rs

@@ -0,0 +1,651 @@
+use crate::geometry::{
+    ClientPoint, Coordinates, ElementPoint, LinesVector, PagePoint, PagesVector, PixelsVector,
+    ScreenPoint, WheelDelta,
+};
+use crate::input_data::{
+    decode_key_location, decode_mouse_button_set, encode_key_location, encode_mouse_button_set,
+    MouseButton, MouseButtonSet,
+};
+use dioxus_core::{NodeFactory, UiEvent};
+use euclid::UnknownUnit;
+use keyboard_types::{Code, Key, Location, Modifiers};
+use std::collections::HashMap;
+use std::convert::TryInto;
+use std::fmt::{Debug, Formatter};
+use std::str::FromStr;
+
+pub type KeyboardEvent = UiEvent<KeyboardData>;
+#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
+#[derive(Clone)]
+pub struct KeyboardData {
+    #[deprecated(
+        since = "0.3.0",
+        note = "This may not work in all environments. Use key() instead."
+    )]
+    pub char_code: u32,
+
+    /// Identify which "key" was entered.
+    #[deprecated(since = "0.3.0", note = "use key() instead")]
+    pub key: String,
+
+    /// Get the key code as an enum Variant.
+    #[deprecated(
+        since = "0.3.0",
+        note = "This may not work in all environments. Use code() instead."
+    )]
+    pub key_code: KeyCode,
+
+    /// the physical key on the keyboard
+    code: Code,
+
+    /// Indicate if the `alt` modifier key was pressed during this keyboard event
+    #[deprecated(since = "0.3.0", note = "use modifiers() instead")]
+    pub alt_key: bool,
+
+    /// Indicate if the `ctrl` modifier key was pressed during this keyboard event
+    #[deprecated(since = "0.3.0", note = "use modifiers() instead")]
+    pub ctrl_key: bool,
+
+    /// Indicate if the `meta` modifier key was pressed during this keyboard event
+    #[deprecated(since = "0.3.0", note = "use modifiers() instead")]
+    pub meta_key: bool,
+
+    /// Indicate if the `shift` modifier key was pressed during this keyboard event
+    #[deprecated(since = "0.3.0", note = "use modifiers() instead")]
+    pub shift_key: bool,
+
+    #[deprecated(since = "0.3.0", note = "use location() instead")]
+    pub location: usize,
+
+    #[deprecated(since = "0.3.0", note = "use is_auto_repeating() instead")]
+    pub repeat: bool,
+
+    #[deprecated(since = "0.3.0", note = "use code() or key() instead")]
+    pub which: usize,
+}
+
+impl_event! {
+    KeyboardData;
+
+    /// onkeydown
+    onkeydown
+
+    /// onkeypress
+    onkeypress
+
+    /// onkeyup
+    onkeyup
+}
+
+impl KeyboardData {
+    pub fn new(
+        key: Key,
+        code: Code,
+        location: Location,
+        is_auto_repeating: bool,
+        modifiers: Modifiers,
+    ) -> Self {
+        #[allow(deprecated)]
+        KeyboardData {
+            char_code: key.legacy_charcode(),
+            key: key.to_string(),
+            key_code: KeyCode::from_raw_code(
+                key.legacy_keycode()
+                    .try_into()
+                    .expect("could not convert keycode to u8"),
+            ),
+            code,
+            alt_key: modifiers.contains(Modifiers::ALT),
+            ctrl_key: modifiers.contains(Modifiers::CONTROL),
+            meta_key: modifiers.contains(Modifiers::META),
+            shift_key: modifiers.contains(Modifiers::SHIFT),
+            location: encode_key_location(location),
+            repeat: is_auto_repeating,
+            which: key
+                .legacy_charcode()
+                .try_into()
+                .expect("could not convert charcode to usize"),
+        }
+    }
+
+    /// The value of the key pressed by the user, taking into consideration the state of modifier keys such as Shift as well as the keyboard locale and layout.
+    pub fn key(&self) -> Key {
+        #[allow(deprecated)]
+        FromStr::from_str(&self.key).expect("could not parse")
+    }
+
+    /// A physical key on the keyboard (as opposed to the character generated by pressing the key). In other words, this property returns a value that isn't altered by keyboard layout or the state of the modifier keys.
+    pub fn code(&self) -> Code {
+        self.code
+    }
+
+    /// The set of modifier keys which were pressed when the event occurred
+    pub fn modifiers(&self) -> Modifiers {
+        let mut modifiers = Modifiers::empty();
+
+        #[allow(deprecated)]
+        {
+            if self.alt_key {
+                modifiers.insert(Modifiers::ALT);
+            }
+            if self.ctrl_key {
+                modifiers.insert(Modifiers::CONTROL);
+            }
+            if self.meta_key {
+                modifiers.insert(Modifiers::META);
+            }
+            if self.shift_key {
+                modifiers.insert(Modifiers::SHIFT);
+            }
+        }
+
+        modifiers
+    }
+
+    /// The location of the key on the keyboard or other input device.
+    pub fn location(&self) -> Location {
+        #[allow(deprecated)]
+        decode_key_location(self.location)
+    }
+
+    /// `true` iff the key is being held down such that it is automatically repeating.
+    pub fn is_auto_repeating(&self) -> bool {
+        #[allow(deprecated)]
+        self.repeat
+    }
+}
+
+impl Debug for KeyboardData {
+    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
+        f.debug_struct("KeyboardData")
+            .field("key", &self.key())
+            .field("code", &self.code())
+            .field("modifiers", &self.modifiers())
+            .field("location", &self.location())
+            .field("is_auto_repeating", &self.is_auto_repeating())
+            .finish()
+    }
+}
+
+#[cfg_attr(
+    feature = "serialize",
+    derive(serde_repr::Serialize_repr, serde_repr::Deserialize_repr)
+)]
+#[derive(Clone, Copy, Debug, Eq, PartialEq)]
+#[repr(u8)]
+pub enum KeyCode {
+    // That key has no keycode, = 0
+    // break, = 3
+    // backspace / delete, = 8
+    // tab, = 9
+    // clear, = 12
+    // enter, = 13
+    // shift, = 16
+    // ctrl, = 17
+    // alt, = 18
+    // pause/break, = 19
+    // caps lock, = 20
+    // hangul, = 21
+    // hanja, = 25
+    // escape, = 27
+    // conversion, = 28
+    // non-conversion, = 29
+    // spacebar, = 32
+    // page up, = 33
+    // page down, = 34
+    // end, = 35
+    // home, = 36
+    // left arrow, = 37
+    // up arrow, = 38
+    // right arrow, = 39
+    // down arrow, = 40
+    // select, = 41
+    // print, = 42
+    // execute, = 43
+    // Print Screen, = 44
+    // insert, = 45
+    // delete, = 46
+    // help, = 47
+    // 0, = 48
+    // 1, = 49
+    // 2, = 50
+    // 3, = 51
+    // 4, = 52
+    // 5, = 53
+    // 6, = 54
+    // 7, = 55
+    // 8, = 56
+    // 9, = 57
+    // :, = 58
+    // semicolon (firefox), equals, = 59
+    // <, = 60
+    // equals (firefox), = 61
+    // ß, = 63
+    // @ (firefox), = 64
+    // a, = 65
+    // b, = 66
+    // c, = 67
+    // d, = 68
+    // e, = 69
+    // f, = 70
+    // g, = 71
+    // h, = 72
+    // i, = 73
+    // j, = 74
+    // k, = 75
+    // l, = 76
+    // m, = 77
+    // n, = 78
+    // o, = 79
+    // p, = 80
+    // q, = 81
+    // r, = 82
+    // s, = 83
+    // t, = 84
+    // u, = 85
+    // v, = 86
+    // w, = 87
+    // x, = 88
+    // y, = 89
+    // z, = 90
+    // Windows Key / Left ⌘ / Chromebook Search key, = 91
+    // right window key, = 92
+    // Windows Menu / Right ⌘, = 93
+    // sleep, = 95
+    // numpad 0, = 96
+    // numpad 1, = 97
+    // numpad 2, = 98
+    // numpad 3, = 99
+    // numpad 4, = 100
+    // numpad 5, = 101
+    // numpad 6, = 102
+    // numpad 7, = 103
+    // numpad 8, = 104
+    // numpad 9, = 105
+    // multiply, = 106
+    // add, = 107
+    // numpad period (firefox), = 108
+    // subtract, = 109
+    // decimal point, = 110
+    // divide, = 111
+    // f1, = 112
+    // f2, = 113
+    // f3, = 114
+    // f4, = 115
+    // f5, = 116
+    // f6, = 117
+    // f7, = 118
+    // f8, = 119
+    // f9, = 120
+    // f10, = 121
+    // f11, = 122
+    // f12, = 123
+    // f13, = 124
+    // f14, = 125
+    // f15, = 126
+    // f16, = 127
+    // f17, = 128
+    // f18, = 129
+    // f19, = 130
+    // f20, = 131
+    // f21, = 132
+    // f22, = 133
+    // f23, = 134
+    // f24, = 135
+    // f25, = 136
+    // f26, = 137
+    // f27, = 138
+    // f28, = 139
+    // f29, = 140
+    // f30, = 141
+    // f31, = 142
+    // f32, = 143
+    // num lock, = 144
+    // scroll lock, = 145
+    // airplane mode, = 151
+    // ^, = 160
+    // !, = 161
+    // ؛ (arabic semicolon), = 162
+    // #, = 163
+    // $, = 164
+    // ù, = 165
+    // page backward, = 166
+    // page forward, = 167
+    // refresh, = 168
+    // closing paren (AZERTY), = 169
+    // *, = 170
+    // ~ + * key, = 171
+    // home key, = 172
+    // minus (firefox), mute/unmute, = 173
+    // decrease volume level, = 174
+    // increase volume level, = 175
+    // next, = 176
+    // previous, = 177
+    // stop, = 178
+    // play/pause, = 179
+    // e-mail, = 180
+    // mute/unmute (firefox), = 181
+    // decrease volume level (firefox), = 182
+    // increase volume level (firefox), = 183
+    // semi-colon / ñ, = 186
+    // equal sign, = 187
+    // comma, = 188
+    // dash, = 189
+    // period, = 190
+    // forward slash / ç, = 191
+    // grave accent / ñ / æ / ö, = 192
+    // ?, / or °, = 193
+    // numpad period (chrome), = 194
+    // open bracket, = 219
+    // back slash, = 220
+    // close bracket / å, = 221
+    // single quote / ø / ä, = 222
+    // `, = 223
+    // left or right ⌘ key (firefox), = 224
+    // altgr, = 225
+    // < /git >, left back slash, = 226
+    // GNOME Compose Key, = 230
+    // ç, = 231
+    // XF86Forward, = 233
+    // XF86Back, = 234
+    // non-conversion, = 235
+    // alphanumeric, = 240
+    // hiragana/katakana, = 242
+    // half-width/full-width, = 243
+    // kanji, = 244
+    // unlock trackpad (Chrome/Edge), = 251
+    // toggle touchpad, = 255
+    NA = 0,
+    Break = 3,
+    Backspace = 8,
+    Tab = 9,
+    Clear = 12,
+    Enter = 13,
+    Shift = 16,
+    Ctrl = 17,
+    Alt = 18,
+    Pause = 19,
+    CapsLock = 20,
+    // hangul, = 21
+    // hanja, = 25
+    Escape = 27,
+    // conversion, = 28
+    // non-conversion, = 29
+    Space = 32,
+    PageUp = 33,
+    PageDown = 34,
+    End = 35,
+    Home = 36,
+    LeftArrow = 37,
+    UpArrow = 38,
+    RightArrow = 39,
+    DownArrow = 40,
+    // select, = 41
+    // print, = 42
+    // execute, = 43
+    // Print Screen, = 44
+    Insert = 45,
+    Delete = 46,
+    // help, = 47
+    Num0 = 48,
+    Num1 = 49,
+    Num2 = 50,
+    Num3 = 51,
+    Num4 = 52,
+    Num5 = 53,
+    Num6 = 54,
+    Num7 = 55,
+    Num8 = 56,
+    Num9 = 57,
+    // :, = 58
+    // semicolon (firefox), equals, = 59
+    // <, = 60
+    // equals (firefox), = 61
+    // ß, = 63
+    // @ (firefox), = 64
+    A = 65,
+    B = 66,
+    C = 67,
+    D = 68,
+    E = 69,
+    F = 70,
+    G = 71,
+    H = 72,
+    I = 73,
+    J = 74,
+    K = 75,
+    L = 76,
+    M = 77,
+    N = 78,
+    O = 79,
+    P = 80,
+    Q = 81,
+    R = 82,
+    S = 83,
+    T = 84,
+    U = 85,
+    V = 86,
+    W = 87,
+    X = 88,
+    Y = 89,
+    Z = 90,
+    LeftWindow = 91,
+    RightWindow = 92,
+    SelectKey = 93,
+    Numpad0 = 96,
+    Numpad1 = 97,
+    Numpad2 = 98,
+    Numpad3 = 99,
+    Numpad4 = 100,
+    Numpad5 = 101,
+    Numpad6 = 102,
+    Numpad7 = 103,
+    Numpad8 = 104,
+    Numpad9 = 105,
+    Multiply = 106,
+    Add = 107,
+    Subtract = 109,
+    DecimalPoint = 110,
+    Divide = 111,
+    F1 = 112,
+    F2 = 113,
+    F3 = 114,
+    F4 = 115,
+    F5 = 116,
+    F6 = 117,
+    F7 = 118,
+    F8 = 119,
+    F9 = 120,
+    F10 = 121,
+    F11 = 122,
+    F12 = 123,
+    // f13, = 124
+    // f14, = 125
+    // f15, = 126
+    // f16, = 127
+    // f17, = 128
+    // f18, = 129
+    // f19, = 130
+    // f20, = 131
+    // f21, = 132
+    // f22, = 133
+    // f23, = 134
+    // f24, = 135
+    // f25, = 136
+    // f26, = 137
+    // f27, = 138
+    // f28, = 139
+    // f29, = 140
+    // f30, = 141
+    // f31, = 142
+    // f32, = 143
+    NumLock = 144,
+    ScrollLock = 145,
+    // airplane mode, = 151
+    // ^, = 160
+    // !, = 161
+    // ؛ (arabic semicolon), = 162
+    // #, = 163
+    // $, = 164
+    // ù, = 165
+    // page backward, = 166
+    // page forward, = 167
+    // refresh, = 168
+    // closing paren (AZERTY), = 169
+    // *, = 170
+    // ~ + * key, = 171
+    // home key, = 172
+    // minus (firefox), mute/unmute, = 173
+    // decrease volume level, = 174
+    // increase volume level, = 175
+    // next, = 176
+    // previous, = 177
+    // stop, = 178
+    // play/pause, = 179
+    // e-mail, = 180
+    // mute/unmute (firefox), = 181
+    // decrease volume level (firefox), = 182
+    // increase volume level (firefox), = 183
+    Semicolon = 186,
+    EqualSign = 187,
+    Comma = 188,
+    Dash = 189,
+    Period = 190,
+    ForwardSlash = 191,
+    GraveAccent = 192,
+    // ?, / or °, = 193
+    // numpad period (chrome), = 194
+    OpenBracket = 219,
+    BackSlash = 220,
+    CloseBraket = 221,
+    SingleQuote = 222,
+    // `, = 223
+    // left or right ⌘ key (firefox), = 224
+    // altgr, = 225
+    // < /git >, left back slash, = 226
+    // GNOME Compose Key, = 230
+    // ç, = 231
+    // XF86Forward, = 233
+    // XF86Back, = 234
+    // non-conversion, = 235
+    // alphanumeric, = 240
+    // hiragana/katakana, = 242
+    // half-width/full-width, = 243
+    // kanji, = 244
+    // unlock trackpad (Chrome/Edge), = 251
+    // toggle touchpad, = 255
+    #[cfg_attr(feature = "serialize", serde(other))]
+    Unknown,
+}
+
+impl KeyCode {
+    pub fn from_raw_code(i: u8) -> Self {
+        use KeyCode::*;
+        match i {
+            8 => Backspace,
+            9 => Tab,
+            13 => Enter,
+            16 => Shift,
+            17 => Ctrl,
+            18 => Alt,
+            19 => Pause,
+            20 => CapsLock,
+            27 => Escape,
+            33 => PageUp,
+            34 => PageDown,
+            35 => End,
+            36 => Home,
+            37 => LeftArrow,
+            38 => UpArrow,
+            39 => RightArrow,
+            40 => DownArrow,
+            45 => Insert,
+            46 => Delete,
+            48 => Num0,
+            49 => Num1,
+            50 => Num2,
+            51 => Num3,
+            52 => Num4,
+            53 => Num5,
+            54 => Num6,
+            55 => Num7,
+            56 => Num8,
+            57 => Num9,
+            65 => A,
+            66 => B,
+            67 => C,
+            68 => D,
+            69 => E,
+            70 => F,
+            71 => G,
+            72 => H,
+            73 => I,
+            74 => J,
+            75 => K,
+            76 => L,
+            77 => M,
+            78 => N,
+            79 => O,
+            80 => P,
+            81 => Q,
+            82 => R,
+            83 => S,
+            84 => T,
+            85 => U,
+            86 => V,
+            87 => W,
+            88 => X,
+            89 => Y,
+            90 => Z,
+            91 => LeftWindow,
+            92 => RightWindow,
+            93 => SelectKey,
+            96 => Numpad0,
+            97 => Numpad1,
+            98 => Numpad2,
+            99 => Numpad3,
+            100 => Numpad4,
+            101 => Numpad5,
+            102 => Numpad6,
+            103 => Numpad7,
+            104 => Numpad8,
+            105 => Numpad9,
+            106 => Multiply,
+            107 => Add,
+            109 => Subtract,
+            110 => DecimalPoint,
+            111 => Divide,
+            112 => F1,
+            113 => F2,
+            114 => F3,
+            115 => F4,
+            116 => F5,
+            117 => F6,
+            118 => F7,
+            119 => F8,
+            120 => F9,
+            121 => F10,
+            122 => F11,
+            123 => F12,
+            144 => NumLock,
+            145 => ScrollLock,
+            186 => Semicolon,
+            187 => EqualSign,
+            188 => Comma,
+            189 => Dash,
+            190 => Period,
+            191 => ForwardSlash,
+            192 => GraveAccent,
+            219 => OpenBracket,
+            220 => BackSlash,
+            221 => CloseBraket,
+            222 => SingleQuote,
+            _ => Unknown,
+        }
+    }
+
+    // get the raw code
+    pub fn raw_code(&self) -> u32 {
+        *self as u32
+    }
+}

+ 7 - 5
packages/html/src/events/mouse.rs

@@ -2,17 +2,19 @@ use crate::geometry::{ClientPoint, Coordinates, ElementPoint, PagePoint, ScreenP
 use crate::input_data::{
     decode_mouse_button_set, encode_mouse_button_set, MouseButton, MouseButtonSet,
 };
-use dioxus_core::{Attribute, ScopeState};
+use dioxus_core::{Attribute, ScopeState, UiEvent};
 use keyboard_types::Modifiers;
 use std::fmt::{Debug, Formatter};
 
+pub type MouseEvent = UiEvent<MouseData>;
+
 /// A synthetic event that wraps a web-style [`MouseEvent`](https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent)
 #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
 #[derive(Clone)]
 /// Data associated with a mouse event
 ///
 /// Do not use the deprecated fields; they may change or become private in the future.
-pub struct MouseEvent {
+pub struct MouseData {
     /// True if the alt key was down when the mouse event was fired.
     #[deprecated(since = "0.3.0", note = "use modifiers() instead")]
     pub alt_key: bool,
@@ -86,7 +88,7 @@ pub struct MouseEvent {
     pub shift_key: bool,
 }
 
-impl MouseEvent {
+impl MouseData {
     /// Construct MouseData with the specified properties
     ///
     /// Note: the current implementation truncates coordinates. In the future, when we change the internal representation, it may also support a fractional part.
@@ -205,7 +207,7 @@ impl MouseEvent {
     }
 }
 
-impl Debug for MouseEvent {
+impl Debug for MouseData {
     fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
         f.debug_struct("MouseData")
             .field("coordinates", &self.coordinates())
@@ -217,7 +219,7 @@ impl Debug for MouseEvent {
 }
 
 impl_event! {
-    MouseEvent;
+    MouseData;
 
     /// Execute a callback when a button is clicked.
     ///

+ 10 - 0
packages/ssr/src/helpers.rs

@@ -1 +1,11 @@
+use std::fmt::Write;
 
+use dioxus_core::VirtualDom;
+
+pub fn pre_render(dom: &VirtualDom) -> String {
+    todo!()
+}
+
+pub fn pre_render_to(dom: &VirtualDom, write: impl Write) {
+    todo!()
+}