mew_css/
values.rs

1//! # CSS Value Types
2//!
3//! This module provides strongly-typed representations of CSS values used throughout
4//! the Mew CSS library. Each CSS value type is represented as an enum or struct that
5//! implements the `Display` trait for conversion to CSS string representation.
6//!
7//! ## Design Philosophy
8//!
9//! The value types in this module are designed to:
10//!
11//! 1. Provide type safety by restricting values to valid CSS options
12//! 2. Enable IDE autocompletion for available values
13//! 3. Handle the correct string formatting for CSS output
14//! 4. Support CSS variables through the `Var` variant in each enum
15//!
16//! ## Common Value Types
17//!
18//! - `Color`: CSS color values (named colors, RGB, RGBA, HSL, HSLA, hex)
19//! - `Size`: CSS size values (px, %, em, rem, vw, vh, auto)
20//! - `Display`: CSS display property values
21//! - `Position`: CSS position property values
22//! - `FontWeight`: CSS font-weight property values
23//! - `BorderStyle`: CSS border-style property values
24//!
25//! ## Usage Example
26//!
27//! ```rust
28//! use mew_css::style;
29//! use mew_css::values::{Color, Size, Display};
30//!
31//! let css = style()
32//!     .color(Color::Blue)                      // Named color
33//!     .background_color(Color::Rgba(240, 240, 240, 0.5)) // RGBA color
34//!     .width(Size::Percent(100.0))             // Percentage
35//!     .height(Size::Px(200))                   // Pixels
36//!     .margin(Size::Auto)                      // Auto value
37//!     .display(Display::Flex)                  // Display type
38//!     .apply();
39//! ```
40
41use std::fmt;
42
43/// Represents CSS color values with various formats and named colors.
44///
45/// The `Color` enum provides a type-safe way to specify colors in CSS. It supports:
46/// - Standard named colors (e.g., `Blue`, `Red`, `White`)
47/// - RGB and RGBA values
48/// - Hexadecimal color codes
49/// - HSL and HSLA values
50/// - Special values like `Transparent` and `CurrentColor`
51/// - CSS variables through the `Var` variant
52///
53/// # Examples
54///
55/// ```rust
56/// use mew_css::style;
57/// use mew_css::values::Color;
58///
59/// // Using named colors
60/// let css1 = style().color(Color::Blue).apply();
61///
62/// // Using RGB values
63/// let css2 = style().color(Color::Rgb(0, 0, 255)).apply();
64///
65/// // Using RGBA with transparency
66/// let css3 = style().color(Color::Rgba(0, 0, 255, 0.5)).apply();
67///
68/// // Using hexadecimal
69/// let css4 = style().color(Color::Hex("#0000ff".to_string())).apply();
70///
71/// // Using HSL
72/// let css5 = style().color(Color::Hsl(240, 100, 50)).apply();
73/// ```
74#[derive(Debug, Clone, PartialEq)]
75pub enum Color {
76    /// Alice Blue (#F0F8FF)
77    AliceBlue,
78    /// Antique White (#FAEBD7)
79    AntiqueWhite,
80    /// Aqua (#00FFFF)
81    Aqua,
82    Aquamarine,
83    Azure,
84    Beige,
85    Bisque,
86    Black,
87    BlanchedAlmond,
88    Blue,
89    BlueViolet,
90    Brown,
91    BurlyWood,
92    CadetBlue,
93    Chartreuse,
94    Chocolate,
95    Coral,
96    CornflowerBlue,
97    Cornsilk,
98    Crimson,
99    Cyan,
100    DarkBlue,
101    DarkCyan,
102    DarkGoldenRod,
103    DarkGray,
104    DarkGrey,
105    DarkGreen,
106    DarkKhaki,
107    DarkMagenta,
108    DarkOliveGreen,
109    DarkOrange,
110    DarkOrchid,
111    DarkRed,
112    DarkSalmon,
113    DarkSeaGreen,
114    DarkSlateBlue,
115    DarkSlateGray,
116    DarkSlateGrey,
117    DarkTurquoise,
118    DarkViolet,
119    DeepPink,
120    DeepSkyBlue,
121    DimGray,
122    DimGrey,
123    DodgerBlue,
124    FireBrick,
125    FloralWhite,
126    ForestGreen,
127    Fuchsia,
128    Gainsboro,
129    GhostWhite,
130    Gold,
131    GoldenRod,
132    Gray,
133    Grey,
134    Green,
135    GreenYellow,
136    HoneyDew,
137    HotPink,
138    IndianRed,
139    Indigo,
140    Ivory,
141    Khaki,
142    Lavender,
143    LavenderBlush,
144    LawnGreen,
145    LemonChiffon,
146    LightBlue,
147    LightCoral,
148    LightCyan,
149    LightGoldenRodYellow,
150    LightGray,
151    LightGrey,
152    LightGreen,
153    LightPink,
154    LightSalmon,
155    LightSeaGreen,
156    LightSkyBlue,
157    LightSlateGray,
158    LightSlateGrey,
159    LightSteelBlue,
160    LightYellow,
161    Lime,
162    LimeGreen,
163    Linen,
164    Magenta,
165    Maroon,
166    MediumAquaMarine,
167    MediumBlue,
168    MediumOrchid,
169    MediumPurple,
170    MediumSeaGreen,
171    MediumSlateBlue,
172    MediumSpringGreen,
173    MediumTurquoise,
174    MediumVioletRed,
175    MidnightBlue,
176    MintCream,
177    MistyRose,
178    Moccasin,
179    NavajoWhite,
180    Navy,
181    OldLace,
182    Olive,
183    OliveDrab,
184    Orange,
185    OrangeRed,
186    Orchid,
187    PaleGoldenRod,
188    PaleGreen,
189    PaleTurquoise,
190    PaleVioletRed,
191    PapayaWhip,
192    PeachPuff,
193    Peru,
194    Pink,
195    Plum,
196    PowderBlue,
197    Purple,
198    RebeccaPurple,
199    Red,
200    RosyBrown,
201    RoyalBlue,
202    SaddleBrown,
203    Salmon,
204    SandyBrown,
205    SeaGreen,
206    SeaShell,
207    Sienna,
208    Silver,
209    SkyBlue,
210    SlateBlue,
211    SlateGray,
212    SlateGrey,
213    Snow,
214    SpringGreen,
215    SteelBlue,
216    Tan,
217    Teal,
218    Thistle,
219    Tomato,
220    Turquoise,
221    Violet,
222    Wheat,
223    White,
224    WhiteSmoke,
225    Yellow,
226    YellowGreen,
227
228    /// Special color values
229    Transparent,
230
231    /// RGB color with values from 0-255
232    Rgb(u8, u8, u8),
233
234    /// RGBA color with values from 0-255 and alpha from 0.0-1.0
235    Rgba(u8, u8, u8, f32),
236
237    /// Hex color code
238    Hex(String),
239
240    /// HSL color
241    Hsl(u16, u8, u8),
242
243    /// HSLA color
244    Hsla(u16, u8, u8, f32),
245
246    /// Current color
247    CurrentColor,
248
249    /// Inherit color
250    Inherit,
251
252    /// CSS variable
253    Var(crate::variable::CssVar),
254}
255
256impl fmt::Display for Color {
257    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
258        match self {
259            Color::AliceBlue => write!(f, "aliceblue"),
260            Color::AntiqueWhite => write!(f, "antiquewhite"),
261            Color::Aqua => write!(f, "aqua"),
262            Color::Aquamarine => write!(f, "aquamarine"),
263            Color::Azure => write!(f, "azure"),
264            Color::Beige => write!(f, "beige"),
265            Color::Bisque => write!(f, "bisque"),
266            Color::Black => write!(f, "black"),
267            Color::BlanchedAlmond => write!(f, "blanchedalmond"),
268            Color::Blue => write!(f, "blue"),
269            Color::BlueViolet => write!(f, "blueviolet"),
270            Color::Brown => write!(f, "brown"),
271            Color::BurlyWood => write!(f, "burlywood"),
272            Color::CadetBlue => write!(f, "cadetblue"),
273            Color::Chartreuse => write!(f, "chartreuse"),
274            Color::Chocolate => write!(f, "chocolate"),
275            Color::Coral => write!(f, "coral"),
276            Color::CornflowerBlue => write!(f, "cornflowerblue"),
277            Color::Cornsilk => write!(f, "cornsilk"),
278            Color::Crimson => write!(f, "crimson"),
279            Color::Cyan => write!(f, "cyan"),
280            Color::DarkBlue => write!(f, "darkblue"),
281            Color::DarkCyan => write!(f, "darkcyan"),
282            Color::DarkGoldenRod => write!(f, "darkgoldenrod"),
283            Color::DarkGray => write!(f, "darkgray"),
284            Color::DarkGrey => write!(f, "darkgrey"),
285            Color::DarkGreen => write!(f, "darkgreen"),
286            Color::DarkKhaki => write!(f, "darkkhaki"),
287            Color::DarkMagenta => write!(f, "darkmagenta"),
288            Color::DarkOliveGreen => write!(f, "darkolivegreen"),
289            Color::DarkOrange => write!(f, "darkorange"),
290            Color::DarkOrchid => write!(f, "darkorchid"),
291            Color::DarkRed => write!(f, "darkred"),
292            Color::DarkSalmon => write!(f, "darksalmon"),
293            Color::DarkSeaGreen => write!(f, "darkseagreen"),
294            Color::DarkSlateBlue => write!(f, "darkslateblue"),
295            Color::DarkSlateGray => write!(f, "darkslategray"),
296            Color::DarkSlateGrey => write!(f, "darkslategrey"),
297            Color::DarkTurquoise => write!(f, "darkturquoise"),
298            Color::DarkViolet => write!(f, "darkviolet"),
299            Color::DeepPink => write!(f, "deeppink"),
300            Color::DeepSkyBlue => write!(f, "deepskyblue"),
301            Color::DimGray => write!(f, "dimgray"),
302            Color::DimGrey => write!(f, "dimgrey"),
303            Color::DodgerBlue => write!(f, "dodgerblue"),
304            Color::FireBrick => write!(f, "firebrick"),
305            Color::FloralWhite => write!(f, "floralwhite"),
306            Color::ForestGreen => write!(f, "forestgreen"),
307            Color::Fuchsia => write!(f, "fuchsia"),
308            Color::Gainsboro => write!(f, "gainsboro"),
309            Color::GhostWhite => write!(f, "ghostwhite"),
310            Color::Gold => write!(f, "gold"),
311            Color::GoldenRod => write!(f, "goldenrod"),
312            Color::Gray => write!(f, "gray"),
313            Color::Grey => write!(f, "grey"),
314            Color::Green => write!(f, "green"),
315            Color::GreenYellow => write!(f, "greenyellow"),
316            Color::HoneyDew => write!(f, "honeydew"),
317            Color::HotPink => write!(f, "hotpink"),
318            Color::IndianRed => write!(f, "indianred"),
319            Color::Indigo => write!(f, "indigo"),
320            Color::Ivory => write!(f, "ivory"),
321            Color::Khaki => write!(f, "khaki"),
322            Color::Lavender => write!(f, "lavender"),
323            Color::LavenderBlush => write!(f, "lavenderblush"),
324            Color::LawnGreen => write!(f, "lawngreen"),
325            Color::LemonChiffon => write!(f, "lemonchiffon"),
326            Color::LightBlue => write!(f, "lightblue"),
327            Color::LightCoral => write!(f, "lightcoral"),
328            Color::LightCyan => write!(f, "lightcyan"),
329            Color::LightGoldenRodYellow => write!(f, "lightgoldenrodyellow"),
330            Color::LightGray => write!(f, "lightgray"),
331            Color::LightGrey => write!(f, "lightgrey"),
332            Color::LightGreen => write!(f, "lightgreen"),
333            Color::LightPink => write!(f, "lightpink"),
334            Color::LightSalmon => write!(f, "lightsalmon"),
335            Color::LightSeaGreen => write!(f, "lightseagreen"),
336            Color::LightSkyBlue => write!(f, "lightskyblue"),
337            Color::LightSlateGray => write!(f, "lightslategray"),
338            Color::LightSlateGrey => write!(f, "lightslategrey"),
339            Color::LightSteelBlue => write!(f, "lightsteelblue"),
340            Color::LightYellow => write!(f, "lightyellow"),
341            Color::Lime => write!(f, "lime"),
342            Color::LimeGreen => write!(f, "limegreen"),
343            Color::Linen => write!(f, "linen"),
344            Color::Magenta => write!(f, "magenta"),
345            Color::Maroon => write!(f, "maroon"),
346            Color::MediumAquaMarine => write!(f, "mediumaquamarine"),
347            Color::MediumBlue => write!(f, "mediumblue"),
348            Color::MediumOrchid => write!(f, "mediumorchid"),
349            Color::MediumPurple => write!(f, "mediumpurple"),
350            Color::MediumSeaGreen => write!(f, "mediumseagreen"),
351            Color::MediumSlateBlue => write!(f, "mediumslateblue"),
352            Color::MediumSpringGreen => write!(f, "mediumspringgreen"),
353            Color::MediumTurquoise => write!(f, "mediumturquoise"),
354            Color::MediumVioletRed => write!(f, "mediumvioletred"),
355            Color::MidnightBlue => write!(f, "midnightblue"),
356            Color::MintCream => write!(f, "mintcream"),
357            Color::MistyRose => write!(f, "mistyrose"),
358            Color::Moccasin => write!(f, "moccasin"),
359            Color::NavajoWhite => write!(f, "navajowhite"),
360            Color::Navy => write!(f, "navy"),
361            Color::OldLace => write!(f, "oldlace"),
362            Color::Olive => write!(f, "olive"),
363            Color::OliveDrab => write!(f, "olivedrab"),
364            Color::Orange => write!(f, "orange"),
365            Color::OrangeRed => write!(f, "orangered"),
366            Color::Orchid => write!(f, "orchid"),
367            Color::PaleGoldenRod => write!(f, "palegoldenrod"),
368            Color::PaleGreen => write!(f, "palegreen"),
369            Color::PaleTurquoise => write!(f, "paleturquoise"),
370            Color::PaleVioletRed => write!(f, "palevioletred"),
371            Color::PapayaWhip => write!(f, "papayawhip"),
372            Color::PeachPuff => write!(f, "peachpuff"),
373            Color::Peru => write!(f, "peru"),
374            Color::Pink => write!(f, "pink"),
375            Color::Plum => write!(f, "plum"),
376            Color::PowderBlue => write!(f, "powderblue"),
377            Color::Purple => write!(f, "purple"),
378            Color::RebeccaPurple => write!(f, "rebeccapurple"),
379            Color::Red => write!(f, "red"),
380            Color::RosyBrown => write!(f, "rosybrown"),
381            Color::RoyalBlue => write!(f, "royalblue"),
382            Color::SaddleBrown => write!(f, "saddlebrown"),
383            Color::Salmon => write!(f, "salmon"),
384            Color::SandyBrown => write!(f, "sandybrown"),
385            Color::SeaGreen => write!(f, "seagreen"),
386            Color::SeaShell => write!(f, "seashell"),
387            Color::Sienna => write!(f, "sienna"),
388            Color::Silver => write!(f, "silver"),
389            Color::SkyBlue => write!(f, "skyblue"),
390            Color::SlateBlue => write!(f, "slateblue"),
391            Color::SlateGray => write!(f, "slategray"),
392            Color::SlateGrey => write!(f, "slategrey"),
393            Color::Snow => write!(f, "snow"),
394            Color::SpringGreen => write!(f, "springgreen"),
395            Color::SteelBlue => write!(f, "steelblue"),
396            Color::Tan => write!(f, "tan"),
397            Color::Teal => write!(f, "teal"),
398            Color::Thistle => write!(f, "thistle"),
399            Color::Tomato => write!(f, "tomato"),
400            Color::Turquoise => write!(f, "turquoise"),
401            Color::Violet => write!(f, "violet"),
402            Color::Wheat => write!(f, "wheat"),
403            Color::White => write!(f, "white"),
404            Color::WhiteSmoke => write!(f, "whitesmoke"),
405            Color::Yellow => write!(f, "yellow"),
406            Color::YellowGreen => write!(f, "yellowgreen"),
407            Color::Transparent => write!(f, "transparent"),
408            Color::Rgb(r, g, b) => write!(f, "rgb({}, {}, {})", r, g, b),
409            Color::Rgba(r, g, b, a) => write!(f, "rgba({}, {}, {}, {})", r, g, b, a),
410            Color::Hex(hex) => {
411                let hex_str = if hex.starts_with('#') { hex.clone() } else { format!("#{}", hex) };
412                write!(f, "{}", hex_str)
413            },
414            Color::Hsl(h, s, l) => write!(f, "hsl({}, {}%, {}%)", h, s, l),
415            Color::Hsla(h, s, l, a) => write!(f, "hsla({}, {}%, {}%, {})", h, s, l, a),
416            Color::CurrentColor => write!(f, "currentColor"),
417            Color::Inherit => write!(f, "inherit"),
418            Color::Var(var) => write!(f, "{}", var),
419        }
420    }
421}
422
423/// Represents size and length values for CSS properties.
424///
425/// The `Size` enum provides a type-safe way to specify sizes in CSS. It supports
426/// various unit types including absolute units (like pixels), relative units
427/// (like percentages, em, rem), viewport-relative units, and special values like
428/// `Auto` and `Zero`.
429///
430/// This enum is used for properties like width, height, margin, padding, font-size,
431/// and any other CSS property that accepts a size or length value.
432///
433/// # Examples
434///
435/// ```rust
436/// use mew_css::style;
437/// use mew_css::values::Size;
438///
439/// // Using pixel values (absolute)
440/// let css1 = style().width(Size::Px(200)).apply();
441///
442/// // Using percentage values (relative to parent)
443/// let css2 = style().width(Size::Percent(50.0)).apply();
444///
445/// // Using em values (relative to element's font size)
446/// let css3 = style().margin(Size::Em(1.5)).apply();
447///
448/// // Using rem values (relative to root font size)
449/// let css4 = style().font_size(Size::Rem(1.2)).apply();
450///
451/// // Using viewport-relative units
452/// let css5 = style()
453///     .width(Size::Vw(100.0))  // 100% of viewport width
454///     .height(Size::Vh(50.0))  // 50% of viewport height
455///     .apply();
456///
457/// // Using special values
458/// let css6 = style()
459///     .margin(Size::Auto)  // Auto margins (useful for centering)
460///     .border_width(Size::Zero)  // Zero (equivalent to 0px)
461///     .apply();
462/// ```
463#[derive(Debug, Clone, PartialEq)]
464pub enum Size {
465    /// Zero value (equivalent to 0px)
466    Zero,
467
468    /// Pixel values - absolute length in pixels
469    Px(u32),
470    /// Percentage values - relative to parent element
471    Percent(f32),
472    /// Em values - relative to the element's font size
473    Em(f32),
474    /// Rem values - relative to the root element's font size
475    Rem(f32),
476    /// Viewport width percentage - relative to viewport width
477    Vw(f32),
478    /// Viewport height percentage - relative to viewport height
479    Vh(f32),
480    /// Auto value - browser determines the appropriate size
481    Auto,
482    /// CSS variable reference
483    Var(crate::variable::CssVar),
484}
485
486impl fmt::Display for Size {
487    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
488        match self {
489            Size::Zero => write!(f, "0"),
490            Size::Px(val) => write!(f, "{}px", val),
491            Size::Percent(val) => write!(f, "{}%", val),
492            Size::Em(val) => write!(f, "{}em", val),
493            Size::Rem(val) => write!(f, "{}rem", val),
494            Size::Vw(val) => write!(f, "{}vw", val),
495            Size::Vh(val) => write!(f, "{}vh", val),
496            Size::Auto => write!(f, "auto"),
497            Size::Var(var) => write!(f, "{}", var),
498        }
499    }
500}
501
502/// Represents CSS display property values that control how elements are rendered.
503///
504/// The `display` property is one of the most important CSS properties for controlling layout.
505/// It determines how an element is treated in the layout flow and how its children are laid out.
506///
507/// # Examples
508///
509/// ```rust
510/// use mew_css::style;
511/// use mew_css::values::Display;
512///
513/// // Hide an element
514/// let css1 = style().display(Display::None).apply();
515///
516/// // Block-level element (takes up full width)
517/// let css2 = style().display(Display::Block).apply();
518///
519/// // Inline element (flows with text)
520/// let css3 = style().display(Display::Inline).apply();
521///
522/// // Flexbox layout
523/// let css4 = style().display(Display::Flex).apply();
524///
525/// // Grid layout
526/// let css5 = style().display(Display::Grid).apply();
527/// ```
528#[derive(Debug, Clone, PartialEq)]
529pub enum Display {
530    /// Removes the element from the document flow (element is not displayed)
531    None,
532    /// Element generates a block-level box (takes up full width available)
533    Block,
534    /// Element generates an inline box (flows with text)
535    Inline,
536    /// Element generates a block-level box that flows with text
537    InlineBlock,
538    /// Element becomes a flex container (enables flexbox layout)
539    Flex,
540    /// Element becomes a grid container (enables grid layout)
541    Grid,
542    /// Element is displayed as a table
543    Table,
544    /// CSS variable reference
545    Var(crate::variable::CssVar),
546}
547
548impl fmt::Display for Display {
549    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
550        match self {
551            Display::None => write!(f, "none"),
552            Display::Block => write!(f, "block"),
553            Display::Inline => write!(f, "inline"),
554            Display::InlineBlock => write!(f, "inline-block"),
555            Display::Flex => write!(f, "flex"),
556            Display::Grid => write!(f, "grid"),
557            Display::Table => write!(f, "table"),
558            Display::Var(var) => write!(f, "{}", var),
559        }
560    }
561}
562
563/// Represents CSS position property values that control element positioning.
564///
565/// The `position` property specifies how an element is positioned in the document.
566/// It works together with the `top`, `right`, `bottom`, and `left` properties to
567/// determine the final position of the element.
568///
569/// # Examples
570///
571/// ```rust
572/// use mew_css::style;
573/// use mew_css::values::{Position, Size};
574///
575/// // Default positioning (in the normal document flow)
576/// let css1 = style().position(Position::Static).apply();
577///
578/// // Relative positioning (offset from normal position)
579/// let css2 = style()
580///     .position(Position::Relative)
581///     .top(Size::Px(10))
582///     .left(Size::Px(20))
583///     .apply();
584///
585/// // Absolute positioning (relative to nearest positioned ancestor)
586/// let css3 = style()
587///     .position(Position::Absolute)
588///     .top(Size::Px(0))
589///     .right(Size::Px(0))
590///     .apply();
591///
592/// // Fixed positioning (relative to viewport)
593/// let css4 = style()
594///     .position(Position::Fixed)
595///     .bottom(Size::Px(20))
596///     .right(Size::Px(20))
597///     .apply();
598/// ```
599#[derive(Debug, Clone, PartialEq)]
600pub enum Position {
601    /// Default positioning in the normal document flow
602    Static,
603    /// Positioned relative to its normal position
604    Relative,
605    /// Positioned relative to the nearest positioned ancestor
606    Absolute,
607    /// Positioned relative to the viewport
608    Fixed,
609    /// Positioned based on scroll position (hybrid of relative and fixed)
610    Sticky,
611    /// CSS variable reference
612    Var(crate::variable::CssVar),
613}
614
615impl fmt::Display for Position {
616    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
617        match self {
618            Position::Static => write!(f, "static"),
619            Position::Relative => write!(f, "relative"),
620            Position::Absolute => write!(f, "absolute"),
621            Position::Fixed => write!(f, "fixed"),
622            Position::Sticky => write!(f, "sticky"),
623            Position::Var(var) => write!(f, "{}", var),
624        }
625    }
626}
627
628/// Flex direction values
629#[derive(Debug, Clone, PartialEq)]
630pub enum FlexDirection {
631    Row,
632    RowReverse,
633    Column,
634    ColumnReverse,
635    /// CSS variable
636    Var(crate::variable::CssVar),
637}
638
639impl fmt::Display for FlexDirection {
640    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
641        match self {
642            FlexDirection::Row => write!(f, "row"),
643            FlexDirection::RowReverse => write!(f, "row-reverse"),
644            FlexDirection::Column => write!(f, "column"),
645            FlexDirection::ColumnReverse => write!(f, "column-reverse"),
646            FlexDirection::Var(var) => write!(f, "{}", var),
647        }
648    }
649}
650
651/// Justify content values
652#[derive(Debug, Clone, PartialEq)]
653pub enum JustifyContent {
654    FlexStart,
655    FlexEnd,
656    Center,
657    SpaceBetween,
658    SpaceAround,
659    SpaceEvenly,
660    /// CSS variable
661    Var(crate::variable::CssVar),
662}
663
664impl fmt::Display for JustifyContent {
665    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
666        match self {
667            JustifyContent::FlexStart => write!(f, "flex-start"),
668            JustifyContent::FlexEnd => write!(f, "flex-end"),
669            JustifyContent::Center => write!(f, "center"),
670            JustifyContent::SpaceBetween => write!(f, "space-between"),
671            JustifyContent::SpaceAround => write!(f, "space-around"),
672            JustifyContent::SpaceEvenly => write!(f, "space-evenly"),
673            JustifyContent::Var(var) => write!(f, "{}", var),
674        }
675    }
676}
677
678/// Align items values
679#[derive(Debug, Clone, PartialEq)]
680pub enum AlignItems {
681    FlexStart,
682    FlexEnd,
683    Center,
684    Baseline,
685    Stretch,
686    /// CSS variable
687    Var(crate::variable::CssVar),
688}
689
690impl fmt::Display for AlignItems {
691    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
692        match self {
693            AlignItems::FlexStart => write!(f, "flex-start"),
694            AlignItems::FlexEnd => write!(f, "flex-end"),
695            AlignItems::Center => write!(f, "center"),
696            AlignItems::Baseline => write!(f, "baseline"),
697            AlignItems::Stretch => write!(f, "stretch"),
698            AlignItems::Var(var) => write!(f, "{}", var),
699        }
700    }
701}
702
703/// Font weight values
704#[derive(Debug, Clone, PartialEq)]
705pub enum FontWeight {
706    Normal,
707    Bold,
708    Bolder,
709    Lighter,
710    /// Numeric weight (100-900)
711    Weight(u16),
712    /// CSS variable
713    Var(crate::variable::CssVar),
714}
715
716impl fmt::Display for FontWeight {
717    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
718        match self {
719            FontWeight::Normal => write!(f, "normal"),
720            FontWeight::Bold => write!(f, "bold"),
721            FontWeight::Bolder => write!(f, "bolder"),
722            FontWeight::Lighter => write!(f, "lighter"),
723            FontWeight::Weight(w) => {
724                // Validate weight is between 100-900 and a multiple of 100
725                if *w >= 100 && *w <= 900 && w % 100 == 0 {
726                    write!(f, "{}", w)
727                } else {
728                    write!(f, "400") // Default to normal if invalid
729                }
730            },
731            FontWeight::Var(var) => write!(f, "{}", var),
732        }
733    }
734}
735
736/// Text align values
737#[derive(Debug, Clone, PartialEq)]
738pub enum TextAlign {
739    Left,
740    Right,
741    Center,
742    Justify,
743    Start,
744    End,
745    /// CSS variable
746    Var(crate::variable::CssVar),
747}
748
749impl fmt::Display for TextAlign {
750    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
751        match self {
752            TextAlign::Left => write!(f, "left"),
753            TextAlign::Right => write!(f, "right"),
754            TextAlign::Center => write!(f, "center"),
755            TextAlign::Justify => write!(f, "justify"),
756            TextAlign::Start => write!(f, "start"),
757            TextAlign::End => write!(f, "end"),
758            TextAlign::Var(var) => write!(f, "{}", var),
759        }
760    }
761}
762
763/// Text decoration values
764#[derive(Debug, Clone, PartialEq)]
765pub enum TextDecoration {
766    None,
767    Underline,
768    Overline,
769    LineThrough,
770    /// CSS variable
771    Var(crate::variable::CssVar),
772}
773
774impl fmt::Display for TextDecoration {
775    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
776        match self {
777            TextDecoration::None => write!(f, "none"),
778            TextDecoration::Underline => write!(f, "underline"),
779            TextDecoration::Overline => write!(f, "overline"),
780            TextDecoration::LineThrough => write!(f, "line-through"),
781            TextDecoration::Var(var) => write!(f, "{}", var),
782        }
783    }
784}
785
786/// Overflow values
787#[derive(Debug, Clone, PartialEq)]
788pub enum Overflow {
789    Visible,
790    Hidden,
791    Scroll,
792    Auto,
793    Clip,
794    /// CSS variable
795    Var(crate::variable::CssVar),
796}
797
798impl fmt::Display for Overflow {
799    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
800        match self {
801            Overflow::Visible => write!(f, "visible"),
802            Overflow::Hidden => write!(f, "hidden"),
803            Overflow::Scroll => write!(f, "scroll"),
804            Overflow::Auto => write!(f, "auto"),
805            Overflow::Clip => write!(f, "clip"),
806            Overflow::Var(var) => write!(f, "{}", var),
807        }
808    }
809}
810
811/// Cursor values
812#[derive(Debug, Clone, PartialEq)]
813pub enum Cursor {
814    Default,
815    Pointer,
816    Text,
817    NotAllowed,
818    Wait,
819    Move,
820    Grab,
821    ZoomIn,
822    ZoomOut,
823    /// CSS variable
824    Var(crate::variable::CssVar),
825}
826
827impl fmt::Display for Cursor {
828    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
829        match self {
830            Cursor::Default => write!(f, "default"),
831            Cursor::Pointer => write!(f, "pointer"),
832            Cursor::Text => write!(f, "text"),
833            Cursor::NotAllowed => write!(f, "not-allowed"),
834            Cursor::Wait => write!(f, "wait"),
835            Cursor::Move => write!(f, "move"),
836            Cursor::Grab => write!(f, "grab"),
837            Cursor::ZoomIn => write!(f, "zoom-in"),
838            Cursor::ZoomOut => write!(f, "zoom-out"),
839            Cursor::Var(var) => write!(f, "{}", var),
840        }
841    }
842}
843
844/// Visibility values
845#[derive(Debug, Clone, PartialEq)]
846pub enum Visibility {
847    Visible,
848    Hidden,
849    Collapse,
850    /// CSS variable
851    Var(crate::variable::CssVar),
852}
853
854impl fmt::Display for Visibility {
855    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
856        match self {
857            Visibility::Visible => write!(f, "visible"),
858            Visibility::Hidden => write!(f, "hidden"),
859            Visibility::Collapse => write!(f, "collapse"),
860            Visibility::Var(var) => write!(f, "{}", var),
861        }
862    }
863}
864
865/// Border style values
866#[derive(Debug, Clone, PartialEq)]
867pub enum BorderStyle {
868    None,
869    Solid,
870    Dashed,
871    Dotted,
872    Double,
873    Groove,
874    Ridge,
875    Inset,
876    Outset,
877    /// CSS variable
878    Var(crate::variable::CssVar),
879}
880
881impl fmt::Display for BorderStyle {
882    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
883        match self {
884            BorderStyle::None => write!(f, "none"),
885            BorderStyle::Solid => write!(f, "solid"),
886            BorderStyle::Dashed => write!(f, "dashed"),
887            BorderStyle::Dotted => write!(f, "dotted"),
888            BorderStyle::Double => write!(f, "double"),
889            BorderStyle::Groove => write!(f, "groove"),
890            BorderStyle::Ridge => write!(f, "ridge"),
891            BorderStyle::Inset => write!(f, "inset"),
892            BorderStyle::Outset => write!(f, "outset"),
893            BorderStyle::Var(var) => write!(f, "{}", var),
894        }
895    }
896}
897
898/// Font size values
899#[derive(Debug, Clone, PartialEq)]
900pub enum FontSize {
901    /// Pixel values
902    Px(u32),
903    /// Percentage values
904    Percent(f32),
905    /// Em values (relative to font size)
906    Em(f32),
907    /// Rem values (relative to root font size)
908    Rem(f32),
909    /// Smaller than parent
910    Smaller,
911    /// Larger than parent
912    Larger,
913    /// Absolute size keywords
914    XxSmall,
915    XSmall,
916    Small,
917    Medium,
918    Large,
919    XLarge,
920    XxLarge,
921    /// Calculated value
922    Calc(String),
923    /// CSS variable
924    Var(crate::variable::CssVar),
925}
926
927impl fmt::Display for FontSize {
928    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
929        match self {
930            FontSize::Px(val) => write!(f, "{}px", val),
931            FontSize::Percent(val) => write!(f, "{}%", val),
932            FontSize::Em(val) => write!(f, "{}em", val),
933            FontSize::Rem(val) => write!(f, "{}rem", val),
934            FontSize::Smaller => write!(f, "smaller"),
935            FontSize::Larger => write!(f, "larger"),
936            FontSize::XxSmall => write!(f, "xx-small"),
937            FontSize::XSmall => write!(f, "x-small"),
938            FontSize::Small => write!(f, "small"),
939            FontSize::Medium => write!(f, "medium"),
940            FontSize::Large => write!(f, "large"),
941            FontSize::XLarge => write!(f, "x-large"),
942            FontSize::XxLarge => write!(f, "xx-large"),
943            FontSize::Calc(expr) => write!(f, "calc({})", expr),
944            FontSize::Var(var) => write!(f, "{}", var),
945        }
946    }
947}
948
949/// Line height values
950#[derive(Debug, Clone, PartialEq)]
951pub enum LineHeight {
952    /// Normal line height
953    Normal,
954    /// Number (unitless) value
955    Number(f32),
956    /// Length value
957    Length(Size),
958    /// Percentage value
959    Percent(f32),
960    /// Calculated value
961    Calc(String),
962    /// CSS variable
963    Var(crate::variable::CssVar),
964}
965
966impl fmt::Display for LineHeight {
967    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
968        match self {
969            LineHeight::Normal => write!(f, "normal"),
970            LineHeight::Number(val) => write!(f, "{}", val),
971            LineHeight::Length(size) => write!(f, "{}", size),
972            LineHeight::Percent(val) => write!(f, "{}%", val),
973            LineHeight::Calc(expr) => write!(f, "calc({})", expr),
974            LineHeight::Var(var) => write!(f, "{}", var),
975        }
976    }
977}
978
979/// Box shadow values
980#[derive(Debug, Clone, PartialEq)]
981pub struct BoxShadow {
982    pub h_offset: Size,
983    pub v_offset: Size,
984    pub blur: Option<Size>,
985    pub spread: Option<Size>,
986    pub color: Option<Color>,
987    pub inset: bool,
988}
989
990impl fmt::Display for BoxShadow {
991    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
992        if self.inset {
993            write!(f, "inset ")?;
994        }
995
996        write!(f, "{} {}", self.h_offset, self.v_offset)?;
997
998        if let Some(blur) = &self.blur {
999            write!(f, " {}", blur)?;
1000        }
1001
1002        if let Some(spread) = &self.spread {
1003            write!(f, " {}", spread)?;
1004        }
1005
1006        if let Some(color) = &self.color {
1007            write!(f, " {}", color)?;
1008        }
1009
1010        Ok(())
1011    }
1012}
1013
1014/// Transition values
1015#[derive(Debug, Clone, PartialEq)]
1016pub struct Transition {
1017    pub property: String,
1018    pub duration: f32,
1019    pub timing_function: Option<String>,
1020    pub delay: Option<f32>,
1021}
1022
1023impl fmt::Display for Transition {
1024    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1025        write!(f, "{} {}s", self.property, self.duration)?;
1026
1027        if let Some(timing) = &self.timing_function {
1028            write!(f, " {}", timing)?;
1029        }
1030
1031        if let Some(delay) = self.delay {
1032            write!(f, " {}s", delay)?;
1033        }
1034
1035        Ok(())
1036    }
1037}
1038
1039/// Z-index values
1040#[derive(Debug, Clone, PartialEq)]
1041pub enum ZIndex {
1042    Auto,
1043    Index(i32),
1044    /// CSS variable
1045    Var(crate::variable::CssVar),
1046}
1047
1048impl fmt::Display for ZIndex {
1049    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1050        match self {
1051            ZIndex::Auto => write!(f, "auto"),
1052            ZIndex::Index(val) => write!(f, "{}", val),
1053            ZIndex::Var(var) => write!(f, "{}", var),
1054        }
1055    }
1056}
1057
1058// Implement From<CssVar> for Color to allow automatic conversion
1059impl From<crate::variable::CssVar> for Color {
1060    fn from(var: crate::variable::CssVar) -> Self {
1061        Color::Var(var)
1062    }
1063}
1064
1065// Implement From<CssVar> for Size to allow automatic conversion
1066impl From<crate::variable::CssVar> for Size {
1067    fn from(var: crate::variable::CssVar) -> Self {
1068        Size::Var(var)
1069    }
1070}
1071
1072// Implement From<CssVar> for Display to allow automatic conversion
1073impl From<crate::variable::CssVar> for Display {
1074    fn from(var: crate::variable::CssVar) -> Self {
1075        Display::Var(var)
1076    }
1077}
1078
1079// Implement From<CssVar> for Position to allow automatic conversion
1080impl From<crate::variable::CssVar> for Position {
1081    fn from(var: crate::variable::CssVar) -> Self {
1082        Position::Var(var)
1083    }
1084}
1085
1086// Implement From<CssVar> for FlexDirection to allow automatic conversion
1087impl From<crate::variable::CssVar> for FlexDirection {
1088    fn from(var: crate::variable::CssVar) -> Self {
1089        FlexDirection::Var(var)
1090    }
1091}
1092
1093// Implement From<CssVar> for JustifyContent to allow automatic conversion
1094impl From<crate::variable::CssVar> for JustifyContent {
1095    fn from(var: crate::variable::CssVar) -> Self {
1096        JustifyContent::Var(var)
1097    }
1098}
1099
1100// Implement From<CssVar> for AlignItems to allow automatic conversion
1101impl From<crate::variable::CssVar> for AlignItems {
1102    fn from(var: crate::variable::CssVar) -> Self {
1103        AlignItems::Var(var)
1104    }
1105}
1106
1107// Implement From<CssVar> for FontWeight to allow automatic conversion
1108impl From<crate::variable::CssVar> for FontWeight {
1109    fn from(var: crate::variable::CssVar) -> Self {
1110        FontWeight::Var(var)
1111    }
1112}
1113
1114// Implement From<CssVar> for TextAlign to allow automatic conversion
1115impl From<crate::variable::CssVar> for TextAlign {
1116    fn from(var: crate::variable::CssVar) -> Self {
1117        TextAlign::Var(var)
1118    }
1119}
1120
1121// Implement From<CssVar> for TextDecoration to allow automatic conversion
1122impl From<crate::variable::CssVar> for TextDecoration {
1123    fn from(var: crate::variable::CssVar) -> Self {
1124        TextDecoration::Var(var)
1125    }
1126}
1127
1128// Implement From<CssVar> for Overflow to allow automatic conversion
1129impl From<crate::variable::CssVar> for Overflow {
1130    fn from(var: crate::variable::CssVar) -> Self {
1131        Overflow::Var(var)
1132    }
1133}
1134
1135// Implement From<CssVar> for Cursor to allow automatic conversion
1136impl From<crate::variable::CssVar> for Cursor {
1137    fn from(var: crate::variable::CssVar) -> Self {
1138        Cursor::Var(var)
1139    }
1140}
1141
1142// Implement From<CssVar> for Visibility to allow automatic conversion
1143impl From<crate::variable::CssVar> for Visibility {
1144    fn from(var: crate::variable::CssVar) -> Self {
1145        Visibility::Var(var)
1146    }
1147}
1148
1149// Implement From<CssVar> for BorderStyle to allow automatic conversion
1150impl From<crate::variable::CssVar> for BorderStyle {
1151    fn from(var: crate::variable::CssVar) -> Self {
1152        BorderStyle::Var(var)
1153    }
1154}
1155
1156// Implement From<CssVar> for ZIndex to allow automatic conversion
1157impl From<crate::variable::CssVar> for ZIndex {
1158    fn from(var: crate::variable::CssVar) -> Self {
1159        ZIndex::Var(var)
1160    }
1161}
1162
1163// Implement From<CssVar> for FontSize to allow automatic conversion
1164impl From<crate::variable::CssVar> for FontSize {
1165    fn from(var: crate::variable::CssVar) -> Self {
1166        FontSize::Var(var)
1167    }
1168}
1169
1170// Implement From<CssVar> for LineHeight to allow automatic conversion
1171impl From<crate::variable::CssVar> for LineHeight {
1172    fn from(var: crate::variable::CssVar) -> Self {
1173        LineHeight::Var(var)
1174    }
1175}