dioxus_document/elements/
style.rs1use super::*;
2use crate::document;
3use dioxus_html as dioxus_elements;
4
5#[non_exhaustive]
6#[derive(Clone, Props, PartialEq)]
7pub struct StyleProps {
8 pub href: Option<String>,
10 pub media: Option<String>,
11 pub nonce: Option<String>,
12 pub title: Option<String>,
13 pub children: Element,
15 #[props(extends = style, extends = GlobalAttributes)]
16 pub additional_attributes: Vec<Attribute>,
17}
18
19impl StyleProps {
20 pub fn attributes(&self) -> Vec<(&'static str, String)> {
22 let mut attributes = Vec::new();
23 extend_attributes(&mut attributes, &self.additional_attributes);
24 if let Some(href) = &self.href {
25 attributes.push(("href", href.clone()));
26 }
27 if let Some(media) = &self.media {
28 attributes.push(("media", media.clone()));
29 }
30 if let Some(nonce) = &self.nonce {
31 attributes.push(("nonce", nonce.clone()));
32 }
33 if let Some(title) = &self.title {
34 attributes.push(("title", title.clone()));
35 }
36 attributes
37 }
38
39 pub fn style_contents(&self) -> Result<String, ExtractSingleTextNodeError<'_>> {
40 extract_single_text_node(&self.children)
41 }
42}
43
44#[component]
76pub fn Style(props: StyleProps) -> Element {
77 use_update_warning(&props, "Style {}");
78
79 use_hook(|| {
80 let document = document();
81 let mut insert_style = document.create_head_component();
82 if let Some(href) = &props.href {
83 if !should_insert_style(href) {
84 insert_style = false;
85 }
86 }
87 if !insert_style {
88 return;
89 }
90 let mut attributes = props.attributes();
91 match (&props.href, props.style_contents()) {
92 (_, Ok(_)) => document.create_style(props),
94 (Some(_), _) => {
96 attributes.push(("type", "text/css".into()));
97 attributes.push(("rel", "stylesheet".into()));
98 document.create_link(LinkProps {
99 media: props.media,
100 title: props.title,
101 r#type: Some("text/css".to_string()),
102 additional_attributes: props.additional_attributes,
103 href: props.href,
104 rel: Some("stylesheet".to_string()),
105 disabled: None,
106 r#as: None,
107 sizes: None,
108 crossorigin: None,
109 referrerpolicy: None,
110 fetchpriority: None,
111 hreflang: None,
112 integrity: None,
113 blocking: None,
114 });
115 }
116 (None, Err(err)) => err.log("Style"),
118 };
119 });
120
121 VNode::empty()
122}
123
124#[derive(Default, Clone)]
125struct StyleContext(DeduplicationContext);
126
127fn should_insert_style(href: &str) -> bool {
128 get_or_insert_root_context::<StyleContext>()
129 .0
130 .should_insert(href)
131}