浏览代码

feat: better link

Jonathan Kelley 3 年之前
父节点
当前提交
8ca505b65b
共有 1 个文件被更改,包括 40 次插入8 次删除
  1. 40 8
      packages/router/src/components/link.rs

+ 40 - 8
packages/router/src/components/link.rs

@@ -34,6 +34,17 @@ pub struct LinkProps<'a> {
     #[props(default, strip_option)]
     title: Option<&'a str>,
 
+    #[props(default = true)]
+    autodetect: bool,
+
+    /// Is this link an external link?
+    #[props(default = false)]
+    external: bool,
+
+    /// New tab?
+    #[props(default = false)]
+    new_tab: bool,
+
     children: Element<'a>,
 
     #[props(default)]
@@ -41,17 +52,38 @@ pub struct LinkProps<'a> {
 }
 
 pub fn Link<'a>(cx: Scope<'a, LinkProps<'a>>) -> Element {
-    // log::trace!("render Link to {}", cx.props.to);
     if let Some(service) = cx.consume_context::<RouterService>() {
+        let LinkProps {
+            to,
+            href,
+            class,
+            id,
+            title,
+            autodetect,
+            external,
+            new_tab,
+            children,
+            ..
+        } = cx.props;
+
+        let is_http = to.starts_with("http") || to.starts_with("https");
+        let outerlink = (*autodetect && is_http) || *external;
+
+        let prevent_default = if outerlink { "" } else { "onclick" };
+
         return cx.render(rsx! {
             a {
-                href: "{cx.props.to}",
-                class: format_args!("{}", cx.props.class.unwrap_or("")),
-                id: format_args!("{}", cx.props.id.unwrap_or("")),
-                title: format_args!("{}", cx.props.title.unwrap_or("")),
-
-                prevent_default: "onclick",
-                onclick: move |_| service.push_route(cx.props.to),
+                href: "{to}",
+                class: format_args!("{}", class.unwrap_or("")),
+                id: format_args!("{}", id.unwrap_or("")),
+                title: format_args!("{}", title.unwrap_or("")),
+                prevent_default: "{prevent_default}",
+                target: format_args!("{}", if *new_tab { "_blank" } else { "" }),
+                onclick: move |_| {
+                    if !outerlink {
+                        service.push_route(to);
+                    }
+                },
 
                 &cx.props.children
             }