dioxus_document/elements/
link.rs1use super::*;
2use crate::document;
3use dioxus_core::{VNode, use_hook};
4
5#[non_exhaustive]
6#[derive(Clone, Props, PartialEq)]
7pub struct OtherLinkProps {
8 pub rel: String,
9 #[props(extends = link, extends = GlobalAttributes)]
10 pub additional_attributes: Vec<Attribute>,
11}
12
13#[non_exhaustive]
14#[derive(Clone, Props, PartialEq)]
15pub struct LinkProps {
16 pub rel: Option<String>,
17 pub media: Option<String>,
18 pub title: Option<String>,
19 pub disabled: Option<bool>,
20 pub r#as: Option<String>,
21 pub sizes: Option<String>,
22 pub href: Option<String>,
24 pub crossorigin: Option<String>,
25 pub referrerpolicy: Option<String>,
26 pub fetchpriority: Option<String>,
27 pub hreflang: Option<String>,
28 pub integrity: Option<String>,
29 pub r#type: Option<String>,
30 pub blocking: Option<String>,
31 #[props(extends = link, extends = GlobalAttributes)]
32 pub additional_attributes: Vec<Attribute>,
33 pub onload: Option<String>,
34}
35
36impl LinkProps {
37 pub fn stylesheet(href: impl Into<String>) -> Self {
39 Self {
40 rel: Some("stylesheet".to_string()),
41 media: None,
42 title: None,
43 disabled: None,
44 r#as: None,
45 sizes: None,
46 href: Some(href.into()),
47 crossorigin: None,
48 referrerpolicy: None,
49 fetchpriority: None,
50 hreflang: None,
51 integrity: None,
52 r#type: None,
53 blocking: None,
54 additional_attributes: Vec::new(),
55 onload: None,
56 }
57 }
58
59 pub fn attributes(&self) -> Vec<(&'static str, String)> {
61 let mut attributes = Vec::new();
62 extend_attributes(&mut attributes, &self.additional_attributes);
63 if let Some(rel) = &self.rel {
64 attributes.push(("rel", rel.clone()));
65 }
66 if let Some(media) = &self.media {
67 attributes.push(("media", media.clone()));
68 }
69 if let Some(title) = &self.title {
70 attributes.push(("title", title.clone()));
71 }
72 if let Some(disabled) = &self.disabled {
73 attributes.push(("disabled", disabled.to_string()));
74 }
75 if let Some(r#as) = &self.r#as {
76 attributes.push(("as", r#as.clone()));
77 }
78 if let Some(sizes) = &self.sizes {
79 attributes.push(("sizes", sizes.clone()));
80 }
81 if let Some(href) = &self.href {
82 attributes.push(("href", href.clone()));
83 }
84 if let Some(crossorigin) = &self.crossorigin {
85 attributes.push(("crossOrigin", crossorigin.clone()));
86 }
87 if let Some(referrerpolicy) = &self.referrerpolicy {
88 attributes.push(("referrerPolicy", referrerpolicy.clone()));
89 }
90 if let Some(fetchpriority) = &self.fetchpriority {
91 attributes.push(("fetchPriority", fetchpriority.clone()));
92 }
93 if let Some(hreflang) = &self.hreflang {
94 attributes.push(("hrefLang", hreflang.clone()));
95 }
96 if let Some(integrity) = &self.integrity {
97 attributes.push(("integrity", integrity.clone()));
98 }
99 if let Some(r#type) = &self.r#type {
100 attributes.push(("type", r#type.clone()));
101 }
102 if let Some(blocking) = &self.blocking {
103 attributes.push(("blocking", blocking.clone()));
104 }
105 if let Some(onload) = &self.onload {
106 attributes.push(("onload", onload.clone()));
107 }
108 attributes
109 }
110}
111
112#[doc(alias = "<link>")]
138#[component]
139pub fn Link(props: LinkProps) -> Element {
140 use_update_warning(&props, "Link {}");
141
142 use_hook(|| {
143 let document = document();
144 let mut insert_link = document.create_head_component();
145 if let Some(href) = &props.href
146 && !should_insert_link(href, props.rel.as_deref())
147 {
148 insert_link = false;
149 }
150
151 if !insert_link {
152 return;
153 }
154
155 document.create_link(props);
156 });
157
158 VNode::empty()
159}
160
161pub fn insert_stylesheet(href: &str) {
167 if !should_insert_link(href, Some("stylesheet")) {
170 return;
171 }
172
173 let document = document();
174 if !document.create_head_component() {
175 return;
176 }
177
178 document.create_link(LinkProps::stylesheet(href.to_string()));
179}
180
181#[derive(Default, Clone)]
182struct LinkContext(DeduplicationContext);
183
184fn should_insert_link(href: &str, rel: Option<&str>) -> bool {
185 let key = match rel {
188 Some(rel) => format!("{href}|{rel}"),
189 None => href.to_string(),
190 };
191 get_or_insert_root_context::<LinkContext>()
192 .0
193 .should_insert(&key)
194}