use super::*;
use crate::document;
use dioxus_core::{use_hook, VNode};
use dioxus_html as dioxus_elements;
#[non_exhaustive]
#[derive(Clone, Props, PartialEq)]
pub struct StyleProps {
pub href: Option<String>,
pub media: Option<String>,
pub nonce: Option<String>,
pub title: Option<String>,
pub children: Element,
#[props(extends = style, extends = GlobalAttributes)]
pub additional_attributes: Vec<Attribute>,
}
impl StyleProps {
pub fn attributes(&self) -> Vec<(&'static str, String)> {
let mut attributes = Vec::new();
extend_attributes(&mut attributes, &self.additional_attributes);
if let Some(href) = &self.href {
attributes.push(("href", href.clone()));
}
if let Some(media) = &self.media {
attributes.push(("media", media.clone()));
}
if let Some(nonce) = &self.nonce {
attributes.push(("nonce", nonce.clone()));
}
if let Some(title) = &self.title {
attributes.push(("title", title.clone()));
}
attributes
}
pub fn style_contents(&self) -> Result<String, ExtractSingleTextNodeError<'_>> {
extract_single_text_node(&self.children)
}
}
#[component]
pub fn Style(props: StyleProps) -> Element {
use_update_warning(&props, "Style {}");
use_hook(|| {
let document = document();
let mut insert_style = document.create_head_component();
if let Some(href) = &props.href {
if !should_insert_style(href) {
insert_style = false;
}
}
if !insert_style {
return;
}
let mut attributes = props.attributes();
match (&props.href, props.style_contents()) {
(_, Ok(_)) => document.create_style(props),
(Some(_), _) => {
attributes.push(("type", "text/css".into()));
attributes.push(("rel", "stylesheet".into()));
document.create_link(LinkProps {
media: props.media,
title: props.title,
r#type: Some("text/css".to_string()),
additional_attributes: props.additional_attributes,
href: props.href,
rel: Some("stylesheet".to_string()),
disabled: None,
r#as: None,
sizes: None,
crossorigin: None,
referrerpolicy: None,
fetchpriority: None,
hreflang: None,
integrity: None,
blocking: None,
onload: None,
});
}
(None, Err(err)) => err.log("Style"),
};
});
VNode::empty()
}
#[derive(Default, Clone)]
struct StyleContext(DeduplicationContext);
fn should_insert_style(href: &str) -> bool {
get_or_insert_root_context::<StyleContext>()
.0
.should_insert(href)
}