stylist/yew/mod.rs
1//! This module contains yew specific features.
2//!
3//! ## Usage in function components
4//!
5//! You can create a style and use it like this:
6//!
7//! ```rust
8//! use stylist::yew::use_style;
9//! use yew::prelude::*;
10//!
11//! #[function_component]
12//! fn MyStyledComponent() -> Html {
13//! let style = use_style!("color: red;");
14//! html! {<div class={style}>{"Hello World!"}</div>}
15//! }
16//! ```
17
18use yew::html::{Classes, IntoPropValue};
19
20/// A procedural macro to style a function component.
21///
22/// Specifically this introduces a specialized [`css!`](crate::css) macro
23/// that is aware of the contextual style manager.
24///
25/// For detailed arguments and usage see also the underlying
26/// [`function_component`](::yew::function_component) attribute in Yew.
27///
28/// # Example:
29///
30/// ```rust
31/// use std::borrow::Cow;
32///
33/// use stylist::yew::styled_component;
34/// use yew::prelude::*;
35///
36/// #[styled_component]
37/// fn MyStyledComponent() -> Html {
38/// html! {<div class={css!("color: red;")}>{"Hello World!"}</div>}
39/// }
40/// ```
41///
42/// # Note:
43///
44/// You don't need to import [`css!`](crate::css) inside of a `styled_component`.
45#[cfg(feature = "macros")]
46pub use stylist_macros::styled_component;
47
48/// A procedural macro to use a specialized, contextual [`css!`](crate::css) macro.
49///
50/// [`styled_component`] is implemented in terms of this, prefer that if possible.
51/// If you need to use [`function_component`](::yew::function_component) directly
52/// but still inject the contextual `css!` macro, use this.
53///
54/// You can also use the attribute on functions that have access to [Hooks] to enable
55/// the usage of a contextual `css!` in their body.
56///
57/// # Example:
58///
59/// ```rust
60/// use stylist::yew::styled_component_impl;
61/// use yew::prelude::*;
62///
63/// // Equivalent to #[styled_component(MyStyledComponent)]
64/// // This usage is discouraged, prefer `styled_component`
65/// #[styled_component_impl]
66/// #[function_component(MyStyledComponent)]
67/// fn my_styled_component() -> Html {
68/// html! {<div class={css!("color: red;")}>{"Hello World!"}</div>}
69/// }
70/// ```
71///
72/// [Hooks]: https://yew.rs/next/concepts/function-components#hooks
73#[cfg(feature = "macros")]
74pub use stylist_macros::styled_component_impl;
75
76/// A procedural macro hook that parses a string literal or an inline stylesheet to create auto
77/// updating [`Style`]s.
78///
79/// Please consult the documentation of the [`macros`](crate::macros) module for the supported
80/// syntax of this macro.
81///
82/// # Example
83///
84/// ```
85/// use stylist::yew::use_style;
86/// use yew::prelude::*;
87///
88/// #[function_component(Comp)]
89/// fn comp() -> Html {
90/// // Returns a Style instance.
91/// let style = use_style!("color: red;");
92/// html! {<div class={style}>{"Hello world!"}</div>}
93/// }
94/// ```
95#[cfg(feature = "yew_use_style")]
96pub use stylist_macros::use_style;
97
98use crate::ast::Sheet;
99use crate::manager::StyleManager;
100use crate::{Style, StyleSource};
101
102use yew::html::ImplicitClone;
103
104impl ImplicitClone for StyleManager {}
105
106mod global;
107mod hooks;
108mod provider;
109
110pub use global::{Global, GlobalProps};
111pub use provider::{ManagerProvider, ManagerProviderProps};
112
113pub use hooks::*;
114
115impl From<Style> for Classes {
116 fn from(style: Style) -> Self {
117 let mut classes = Self::new();
118 classes.push(style.get_class_name().to_string());
119 classes
120 }
121}
122
123impl From<StyleSource> for Classes {
124 fn from(style_src: StyleSource) -> Self {
125 let mut classes = Self::new();
126 #[cfg(all(debug_assertions, feature = "debug_style_locations"))]
127 let location = style_src.location.clone();
128 let style = style_src.into_style();
129 classes.push(style.get_class_name().to_string());
130 #[cfg(all(debug_assertions, feature = "debug_style_locations"))]
131 classes.push(location);
132 classes
133 }
134}
135
136impl IntoPropValue<Classes> for Style {
137 fn into_prop_value(self) -> Classes {
138 self.into()
139 }
140}
141
142impl IntoPropValue<Classes> for StyleSource {
143 fn into_prop_value(self) -> Classes {
144 self.into()
145 }
146}
147
148impl IntoPropValue<StyleSource> for Sheet {
149 fn into_prop_value(self) -> StyleSource {
150 self.into()
151 }
152}
153
154#[cfg_attr(documenting, doc(cfg(feature = "parser")))]
155#[cfg(feature = "parser")]
156mod feat_parser {
157 use std::borrow::Cow;
158
159 use super::*;
160 use stylist_core::ResultDisplay;
161
162 impl IntoPropValue<StyleSource> for String {
163 fn into_prop_value(self) -> StyleSource {
164 self.try_into()
165 .expect_display("couldn't parse style string")
166 }
167 }
168
169 impl<'a> IntoPropValue<StyleSource> for &'a str {
170 fn into_prop_value(self) -> StyleSource {
171 self.try_into()
172 .expect_display("couldn't parse style string")
173 }
174 }
175
176 impl<'a> IntoPropValue<StyleSource> for Cow<'a, str> {
177 fn into_prop_value(self) -> StyleSource {
178 self.try_into()
179 .expect_display("couldn't parse style string")
180 }
181 }
182}