Jelajahi Sumber

fix: allow prevent_default on svg

Jonathan Kelley 3 tahun lalu
induk
melakukan
a9ac0568e2
3 mengubah file dengan 116 tambahan dan 6 penghapusan
  1. 99 0
      examples/svg.rs
  2. 1 6
      packages/html/src/elements.rs
  3. 16 0
      packages/html/src/global_attributes.rs

+ 99 - 0
examples/svg.rs

@@ -0,0 +1,99 @@
+use dioxus::{events::MouseEvent, prelude::*};
+
+fn main() {
+    dioxus::desktop::launch(app);
+}
+
+fn app(cx: Scope) -> Element {
+    let (val, set_val) = use_state(&cx, || 5);
+
+    cx.render(rsx! {
+        div {
+            user_select: "none",
+            webkit_user_select: "none",
+            margin_left: "10%",
+            margin_right: "10%",
+            h1 { "Click die to generate a new value" }
+            div {
+                cursor: "pointer",
+                height: "80%",
+                width: "80%",
+                Die {
+                    value: *val,
+                    keep: true,
+                    onclick: move |_| {
+                        use rand::Rng;
+                        let mut rng = rand::thread_rng();
+                        set_val(rng.gen_range(1..6));
+                    }
+                }
+            }
+        }
+    })
+}
+
+#[derive(Props)]
+pub struct DieProps<'a> {
+    pub value: u64,
+    pub keep: bool,
+    pub onclick: EventHandler<'a, MouseEvent>,
+}
+
+const DOTS: [(i64, i64); 7] = [(-1, -1), (-1, -0), (-1, 1), (1, -1), (1, 0), (1, 1), (0, 0)];
+const DOTS_FOR_VALUE: [[bool; 7]; 6] = [
+    [false, false, false, false, false, false, true],
+    [false, false, true, true, false, false, false],
+    [false, false, true, true, false, false, true],
+    [true, false, true, true, false, true, false],
+    [true, false, true, true, false, true, true],
+    [true, true, true, true, true, true, false],
+];
+
+const OFFSET: i64 = 600;
+const DOT_RADIUS: &str = "200";
+const HELD_COLOR: &str = "#aaa";
+const UNHELD_COLOR: &str = "#ddd";
+
+// A six-sided die (D6) with dots.
+#[allow(non_snake_case)]
+pub fn Die<'a>(cx: Scope<'a, DieProps<'a>>) -> Element {
+    let &DieProps { value, keep, .. } = cx.props;
+
+    let active_dots = &DOTS_FOR_VALUE[(value - 1) as usize];
+    let fill = if keep { HELD_COLOR } else { UNHELD_COLOR };
+    let dots = DOTS
+        .iter()
+        .zip(active_dots.iter())
+        .filter(|(_, &active)| active)
+        .map(|((x, y), _)| {
+            let dcx = x * OFFSET;
+            let dcy = y * OFFSET;
+            rsx!(circle {
+                cx: "{dcx}",
+                cy: "{dcy}",
+                r: "{DOT_RADIUS}",
+                fill: "#333"
+            })
+        });
+
+    rsx!(cx,
+      svg {
+        onclick: move |e| cx.props.onclick.call(e),
+        prevent_default: "onclick",
+        "dioxus-prevent-default": "onclick",
+        class: "die",
+        view_box: "-1000 -1000 2000 2000",
+
+        rect {
+          x: "-1000",
+          y: "-1000",
+          width: "2000",
+          height: "2000",
+          rx: "{DOT_RADIUS}",
+          fill: "{fill}",
+        }
+
+        dots
+      }
+    )
+}

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

@@ -1047,7 +1047,7 @@ impl input {
     /// - `text`
     /// - `time`
     /// - `url`
-    /// - `week`    
+    /// - `week`
     pub fn r#type<'a>(&self, cx: NodeFactory<'a>, val: Arguments) -> Attribute<'a> {
         cx.attr("type", val, None, false)
     }
@@ -1100,11 +1100,6 @@ impl label {
         cx.attr("for", val, None, false)
     }
 }
-impl a {
-    pub fn prevent_default<'a>(&self, cx: NodeFactory<'a>, val: Arguments) -> Attribute<'a> {
-        cx.attr("dioxus-prevent-default", val, None, false)
-    }
-}
 
 builder_constructors! {
     // SVG components

+ 16 - 0
packages/html/src/global_attributes.rs

@@ -49,6 +49,10 @@ macro_rules! aria_trait_methods {
 }
 
 pub trait GlobalAttributes {
+    /// Prevent the default action for this element.
+    ///
+    /// For more information, see the MDN docs:
+    /// <https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault>
     fn prevent_default<'a>(&self, cx: NodeFactory<'a>, val: Arguments) -> Attribute<'a> {
         cx.attr("dioxus-prevent-default", val, None, false)
     }
@@ -603,6 +607,11 @@ pub trait GlobalAttributes {
         /// Specifies the speed curve of the transition effect.
         transition_timing_function: "transition-timing-function",
 
+        /// The user-select CSS property controls whether the user can select text.
+        /// This doesn't have any effect on content loaded as part of a browser's user interface (its chrome), except in textboxes.
+        user_select: "user-select",
+        webkit_user_select: "-webkit-user-select",
+
         /// Sets the vertical positioning of an element relative to the current text baseline.
         vertical_align: "vertical-align",
 
@@ -685,6 +694,13 @@ pub trait GlobalAttributes {
 }
 
 pub trait SvgAttributes {
+    /// Prevent the default action for this element.
+    ///
+    /// For more information, see the MDN docs:
+    /// <https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault>
+    fn prevent_default<'a>(&self, cx: NodeFactory<'a>, val: Arguments) -> Attribute<'a> {
+        cx.attr("dioxus-prevent-default", val, None, false)
+    }
     aria_trait_methods! {
         accent_height: "accent-height",
         accumulate: "accumulate",