1mod attribute;
2mod cache;
3mod loader;
4mod parse;
5mod selector;
6mod stylesheet;
7mod transition;
8
9pub use attribute::*;
10pub use cache::*;
11pub use loader::*;
12pub use selector::*;
13pub use stylesheet::*;
14pub use transition::*;
15
16use deref_derive::{Deref, DerefMut};
17
18use crate::{BoxConstraints, DrawContext, Event, EventContext, LayoutContext, View};
19
20#[derive(Clone, Debug, Default)]
21pub struct Style {
22 pub element: Option<&'static str>,
23 pub classes: StyleClasses,
24 pub attributes: StyleAttributes,
25}
26
27impl Style {
28 pub const fn new(element: &'static str) -> Self {
29 Self {
30 element: Some(element),
31 classes: StyleClasses::new(),
32 attributes: StyleAttributes::new(),
33 }
34 }
35
36 pub fn with_element(mut self, name: &'static str) -> Self {
37 self.element = Some(name);
38 self
39 }
40
41 pub fn with_class(mut self, class: &str) -> Self {
42 let classes = class.split_whitespace().map(StyleClass::from);
43 self.classes.extend(classes);
44 self
45 }
46
47 pub fn with_classes(
48 mut self,
49 classes: impl IntoIterator<Item = impl Into<StyleClass>>,
50 ) -> Self {
51 self.classes.extend(classes.into_iter().map(Into::into));
52 self
53 }
54
55 pub fn with_attr(mut self, key: &str, builder: impl StyleAttributeBuilder) -> Self {
56 let attr = builder.attribute(key);
57 self.attributes.add(attr);
58 self
59 }
60
61 pub fn with_attrs(mut self, attrs: impl IntoIterator<Item = StyleAttribute>) -> Self {
62 self.attributes.extend(attrs);
63 self
64 }
65}
66
67#[derive(Clone, Debug, Default, Deref, DerefMut)]
69pub struct Styled<T> {
70 #[deref]
71 pub value: T,
72 pub classes: StyleClasses,
73 pub attributes: StyleAttributes,
74}
75
76impl<T> Styled<T> {
77 pub const fn new(value: T) -> Self {
79 Self {
80 value,
81 classes: StyleClasses::new(),
82 attributes: StyleAttributes::new(),
83 }
84 }
85}
86
87impl<T: View> View for Styled<T> {
88 type State = T::State;
89
90 fn build(&self) -> Self::State {
91 self.value.build()
92 }
93
94 fn style(&self) -> Style {
95 self.value
96 .style()
97 .with_classes(self.classes.iter().cloned())
98 .with_attrs(self.attributes.iter().cloned())
99 }
100
101 fn event(&self, state: &mut Self::State, cx: &mut EventContext, event: &Event) {
102 self.value.event(state, cx, event)
103 }
104
105 fn layout(
106 &self,
107 state: &mut Self::State,
108 cx: &mut LayoutContext,
109 bc: BoxConstraints,
110 ) -> glam::Vec2 {
111 self.value.layout(state, cx, bc)
112 }
113
114 fn draw(&self, state: &mut Self::State, cx: &mut DrawContext) {
115 self.value.draw(state, cx)
116 }
117}
118
119pub trait Styleable<T> {
121 fn styled(self) -> Styled<T>;
123
124 fn class(self, class: impl AsRef<str>) -> Styled<T>;
126
127 fn attr(self, key: &str, builder: impl StyleAttributeBuilder) -> Styled<T>;
129
130 fn attr_trans(
132 self,
133 key: &str,
134 value: impl Into<StyleAttributeValue>,
135 transition: impl Into<StyleTransition>,
136 ) -> Styled<T>;
137}
138
139impl<T> Styleable<T> for Styled<T> {
140 fn styled(self) -> Styled<T> {
141 self
142 }
143
144 fn class(mut self, class: impl AsRef<str>) -> Styled<T> {
145 let classes = class.as_ref().split_whitespace().map(StyleClass::from);
146 self.classes.extend(classes);
147 self
148 }
149
150 fn attr(mut self, key: &str, builder: impl StyleAttributeBuilder) -> Styled<T> {
151 self.attributes.add(builder.attribute(key));
152 self
153 }
154
155 fn attr_trans(
156 mut self,
157 key: &str,
158 value: impl Into<StyleAttributeValue>,
159 transition: impl Into<StyleTransition>,
160 ) -> Styled<T> {
161 let attr = StyleAttribute::with_transition(key, value, transition);
162 self.attributes.add(attr);
163 self
164 }
165}
166
167impl<T> Styleable<T> for T {
168 fn styled(self) -> Styled<T> {
169 Styled::new(self)
170 }
171
172 fn class(self, class: impl AsRef<str>) -> Styled<T> {
173 Styled::new(self).class(class)
174 }
175
176 fn attr(self, key: &str, value: impl StyleAttributeBuilder) -> Styled<T> {
177 Styled::new(self).attr(key, value)
178 }
179
180 fn attr_trans(
181 self,
182 key: &str,
183 value: impl Into<StyleAttributeValue>,
184 transition: impl Into<StyleTransition>,
185 ) -> Styled<T> {
186 Styled::new(self).attr_trans(key, value, transition)
187 }
188}