polished_css/property/
mod.rs

1//! Characteristic _(like `color`)_ whose associated value defines one aspect of
2//! how the UI engine should display the element.
3//!
4//! ### Resources
5//!
6//! - [CSSWG specification](https://www.w3.org/TR/CSS/#properties)
7//! - [MDN documentation](https://developer.mozilla.org/en-US/docs/Glossary/Property/CSS)
8
9pub mod appearance;
10pub mod layout;
11pub mod misc;
12pub mod scroll;
13pub mod transform;
14pub mod transition;
15pub mod typography;
16
17pub use appearance::*;
18pub use layout::*;
19pub use misc::*;
20pub use scroll::*;
21pub use transform::*;
22pub use transition::*;
23pub use typography::*;
24
25pub trait PropertyName {
26    fn property_name<'a>(&self) -> &'a str;
27}
28
29/// Characteristic _(like `color`)_ whose associated value defines one aspect of
30/// how the UI engine should display the element.
31///
32/// ### Resources
33///
34/// - [CSSWG specification](https://www.w3.org/TR/CSS/#properties)
35/// - [MDN documentation](https://developer.mozilla.org/en-US/docs/Glossary/Property/CSS)
36pub trait Property: std::fmt::Debug + std::fmt::Display + PropertyName {
37    /// Returns the stringified property name with its value
38    /// as a **CSS declaration** to be used within a declaration block.
39    ///
40    /// ### Resources
41    ///
42    /// - [CSSWG specification](https://drafts.csswg.org/css2/#declaration)
43    /// - [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/CSS/Syntax#css_declarations)
44    fn declaration(&self) -> String {
45        format!("{}:{}", &self.property_name(), &self)
46    }
47}
48
49crate::create_property!(
50    All,
51    display = "",
52    atomic = "all",
53    custom = false,
54    data_type = "",
55    initial_value = Initial,
56    keywords = "",
57);
58
59#[cfg(test)]
60mod test {
61    use crate::prelude::*;
62
63    #[test]
64    fn name() {
65        assert_eq!(
66            crate::property::Opacity::initial().property_name(),
67            String::from("opacity")
68        );
69        assert_eq!(
70            crate::property::BackgroundColor::initial().property_name(),
71            String::from("background-color")
72        );
73    }
74
75    #[test]
76    fn rule() {
77        assert_eq!(
78            crate::property::Opacity::initial().declaration(),
79            String::from("opacity:initial")
80        );
81        assert_eq!(
82            crate::property::Opacity::percentage(0.0).declaration(),
83            String::from("opacity:0%")
84        );
85    }
86
87    #[test]
88    fn property_with_data_type_alpha() {
89        assert_eq!(
90            Opacity::number(1.0),
91            Opacity(OpacityValue::Alpha(Alpha::Number(Number(1.0)))),
92        );
93        assert_eq!(
94            Opacity::percentage(100.0),
95            Opacity(OpacityValue::Alpha(Alpha::Percentage(Percentage(100.0)))),
96        );
97    }
98
99    #[test]
100    fn property_with_data_type_angle() {
101        assert_eq!(
102            Rotate::deg(180.0),
103            Rotate(RotateValue::Angle(Angle::Degree(Deg(180.0)))),
104        );
105        assert_eq!(
106            Rotate::rad(100.0),
107            Rotate(RotateValue::Angle(Angle::Radiant(Rad(100.0)))),
108        );
109        assert_eq!(
110            Rotate::grad(120.0),
111            Rotate(RotateValue::Angle(Angle::Gradiant(Grad(120.0)))),
112        );
113        assert_eq!(
114            Rotate::turn(3.0),
115            Rotate(RotateValue::Angle(Angle::Turn(Turn(3.0)))),
116        );
117    }
118
119    // #[test]
120    // fn property_with_data_type_chroma() {
121    // TODO: Add est when property based on this data type is created
122    // }
123
124    #[test]
125    fn property_with_data_type_color() {
126        assert_eq!(
127            TextColor::current_color(),
128            TextColor(TextColorValue::CurrentColor),
129        );
130        assert_eq!(
131            TextColor::transparent(),
132            TextColor(TextColorValue::Color(Color::Absolute(
133                AbsoluteColor::Transparent
134            )))
135        );
136        assert_eq!(
137            TextColor::oklch(Oklch::from((
138                Lightness::percentage(10.0),
139                Chroma::number(0.3),
140                Hue::deg(225.0),
141                Alpha::visible(),
142            ))),
143            TextColor(TextColorValue::Color(Color::Absolute(
144                AbsoluteColor::Function(AbsoluteColorFunction::Oklch(Oklch {
145                    lightness: Lightness::Percentage(Percentage(10.0)),
146                    chroma: Chroma::Number(Number(0.3)),
147                    hue: Hue::Angle(Angle::Degree(Deg(225.0))),
148                    alpha: Some(Alpha::Number(Number(1.0))),
149                }))
150            )))
151        );
152    }
153
154    #[test]
155    fn property_with_data_type_custom_ident() {
156        assert_eq!(
157            TransitionProperty::custom_ident("color"),
158            TransitionProperty(TransitionPropertyValue::CustomIdent(CustomIdent::from(
159                "color"
160            ))),
161        );
162        assert_eq!(
163            Height::px(100),
164            Height::length(Length::Absolute(AbsoluteLength::Pixel(Px(100)))),
165        );
166    }
167
168    // #[test]
169    // fn property_with_data_type_custom_ident() {
170    //     // NOTE: Not applicable to properties (used with var)
171    // }
172
173    // #[test]
174    // fn property_with_data_type_dimention() {
175    //     // TODO: Add some test when property based on this data type is created
176    // }
177
178    // #[test]
179    // fn property_with_data_type_flex() {
180    //     // TODO: Add some test when property based on this data type is created
181    // }
182
183    // #[test]
184    // fn property_with_data_type_frequency() {
185    //     // TODO: Add some test when property based on this data type is created
186    // }
187
188    // #[test]
189    // fn property_with_data_type_frequency_percentage() {
190    //     // TODO: Add some test when property based on this data type is created
191    // }
192
193    // #[test]
194    // fn property_with_data_type_hue() {
195    //     // TODO: Add some test when property based on this data type is created
196    // }
197
198    #[test]
199    fn property_with_data_type_integer() {
200        assert_eq!(
201            ZIndex::integer(100),
202            ZIndex(ZIndexValue::Integer(Integer(100))),
203        );
204    }
205
206    #[test]
207    fn property_with_data_type_length() {
208        assert_eq!(
209            ScrollMarginBlockStart::px(100),
210            ScrollMarginBlockStart(ScrollMarginBlockStartValue::Length(Length::Absolute(
211                AbsoluteLength::Pixel(Px(100))
212            ))),
213        );
214        assert_eq!(
215            ScrollMarginBlockStart::cqmax(100.0),
216            ScrollMarginBlockStart(ScrollMarginBlockStartValue::Length(Length::Relative(
217                RelativeLength::Container(ContainerLength::QueryMax(Cqmax(100.0)))
218            ))),
219        );
220        assert_eq!(
221            ScrollMarginBlockStart::em(1.5),
222            ScrollMarginBlockStart(ScrollMarginBlockStartValue::Length(Length::Relative(
223                RelativeLength::Font(FontLength::Em(Em(1.5)))
224            ))),
225        );
226        assert_eq!(
227            ScrollMarginBlockStart::vh(75.0),
228            ScrollMarginBlockStart(ScrollMarginBlockStartValue::Length(Length::Relative(
229                RelativeLength::Viewport(ViewportLength::Height(Vh(75.0)))
230            ))),
231        );
232    }
233
234    #[test]
235    fn property_with_data_type_length_percentage() {
236        assert_eq!(
237            Height::px(100),
238            Height(HeightValue::LengthPercentage(LengthPercentage::Length(
239                Length::Absolute(AbsoluteLength::Pixel(Px(100)))
240            ))),
241        );
242        assert_eq!(
243            Height::cqmin(25.0),
244            Height(HeightValue::LengthPercentage(LengthPercentage::Length(
245                Length::Relative(RelativeLength::Container(ContainerLength::QueryMin(Cqmin(
246                    25.0
247                ))))
248            )))
249        );
250        assert_eq!(
251            Height::lh(1.0),
252            Height(HeightValue::LengthPercentage(LengthPercentage::Length(
253                Length::Relative(RelativeLength::Font(FontLength::LineHeight(Lh(1.0))))
254            ))),
255        );
256        assert_eq!(
257            Height::dvw(50.0),
258            Height(HeightValue::LengthPercentage(LengthPercentage::Length(
259                Length::Relative(RelativeLength::Viewport(ViewportLength::DynamicWidth(Dvw(
260                    50.0
261                ))))
262            ))),
263        );
264        assert_eq!(
265            Height::percentage(100.0),
266            Height(HeightValue::LengthPercentage(LengthPercentage::Percentage(
267                Percentage(100.0)
268            ))),
269        );
270    }
271
272    // #[test]
273    // fn property_with_data_type_lightness() {
274    //     // TODO: Add some test when property based on this data type is created
275    // }
276
277    #[test]
278    fn property_with_data_type_number() {
279        assert_eq!(
280            LineHeight::number(1.75),
281            LineHeight(LineHeightValue::Number(Number(1.75))),
282        );
283    }
284
285    #[test]
286    fn property_with_data_type_percentage() {
287        assert_eq!(
288            Scale::reset(),
289            Scale(ScaleValue::Percentage(Percentage(0.0))),
290        );
291    }
292
293    #[test]
294    fn property_with_data_type_ratio() {
295        assert_eq!(
296            AspectRatio::ratio(Ratio::from((4, 3))),
297            AspectRatio(AspectRatioValue::Ratio(Ratio {
298                a: 4.0,
299                b: Some(3.0)
300            })),
301        );
302    }
303
304    // #[test]
305    // fn property_with_data_type_resolution() {
306    //     // TODO: Add some test when property based on this data type is created
307    // }
308
309    #[test]
310    fn property_with_data_type_string() {
311        assert_eq!(
312            FontFamily::string("Arial"),
313            FontFamily(FontFamilyValue::String(DataTypeString::from("Arial"))),
314        );
315    }
316
317    #[test]
318    fn property_with_data_type_time() {
319        assert_eq!(
320            TransitionDuration::ms(1_000),
321            TransitionDuration(TransitionDurationValue::Time(Time::Millisecond(Ms(1_000)))),
322        );
323    }
324}