ailloli_ui_core/style/
flex_style.rs

1//! Flex-container direction, spacing, alignment, and distribution.
2
3/// Main axis of a flex container (`Row` or `Column`).
4///
5/// # Examples
6///
7/// ```
8/// use ailloli_ui_core::style::FlexDirection;
9/// assert_eq!(FlexDirection::default(), FlexDirection::Row);
10/// ```
11#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
12pub enum FlexDirection {
13    /// Children progress left-to-right on the horizontal axis; this is default.
14    #[default]
15    Row,
16    /// Children progress top-to-bottom on the vertical axis.
17    Column,
18}
19
20/// Cross-axis alignment of flex children.
21///
22/// # Examples
23///
24/// ```
25/// use ailloli_ui_core::style::AlignItems;
26/// assert_eq!(AlignItems::default(), AlignItems::Start);
27/// ```
28#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
29pub enum AlignItems {
30    /// Align children at the cross-axis origin; this is default.
31    #[default]
32    Start,
33    /// Center children on the cross axis.
34    Center,
35    /// Align children at the far cross-axis edge.
36    End,
37    /// Expand eligible children to the container's cross-axis extent.
38    Stretch,
39}
40
41/// Main-axis distribution of flex children.
42///
43/// # Examples
44///
45/// ```
46/// use ailloli_ui_core::style::JustifyContent;
47/// assert_eq!(JustifyContent::default(), JustifyContent::Start);
48/// ```
49#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
50pub enum JustifyContent {
51    /// Pack children at the main-axis origin; this is default.
52    #[default]
53    Start,
54    /// Pack children as a centered group.
55    Center,
56    /// Pack children against the far main-axis edge.
57    End,
58    /// Distribute free space only between adjacent children.
59    SpaceBetween,
60    /// Distribute equal space around each child, yielding half-size outer gaps.
61    SpaceAround,
62    /// Distribute equal free space between children and both outer edges.
63    SpaceEvenly,
64}
65
66/// Flex container style: direction, gap, and alignment.
67///
68/// # Examples
69///
70/// ```
71/// use ailloli_ui_core::style::{AlignItems, FlexStyle};
72/// let style = FlexStyle::row().gap(8.0).align_items(AlignItems::Center);
73/// assert_eq!(style.gap, 8.0);
74/// ```
75#[derive(Debug, Clone, Copy, PartialEq)]
76pub struct FlexStyle {
77    /// Main-axis orientation.
78    pub direction: FlexDirection,
79    /// Non-negative separation between adjacent children in logical pixels.
80    pub gap: f32,
81    /// Default cross-axis alignment for children.
82    pub align_items: AlignItems,
83    /// Main-axis packing/distribution policy.
84    pub justify_content: JustifyContent,
85}
86
87impl FlexStyle {
88    /// Creates a horizontal container with zero gap and start alignment.
89    ///
90    /// # Examples
91    ///
92    /// ```
93    /// use ailloli_ui_core::style::{FlexDirection, FlexStyle};
94    /// assert_eq!(FlexStyle::row().direction, FlexDirection::Row);
95    /// ```
96    pub fn row() -> Self {
97        Self {
98            direction: FlexDirection::Row,
99            gap: 0.0,
100            align_items: AlignItems::Start,
101            justify_content: JustifyContent::Start,
102        }
103    }
104
105    /// Creates a vertical container with zero gap and start alignment.
106    ///
107    /// # Examples
108    ///
109    /// ```
110    /// use ailloli_ui_core::style::{FlexDirection, FlexStyle};
111    /// assert_eq!(FlexStyle::column().direction, FlexDirection::Column);
112    /// ```
113    pub fn column() -> Self {
114        Self {
115            direction: FlexDirection::Column,
116            gap: 0.0,
117            align_items: AlignItems::Start,
118            justify_content: JustifyContent::Start,
119        }
120    }
121
122    /// Sets adjacent-child gap, clamped to at least zero logical pixels.
123    ///
124    /// NaN and negative infinity become zero through floating-point `max`
125    /// semantics; positive infinity remains infinite.
126    ///
127    /// # Examples
128    ///
129    /// ```
130    /// use ailloli_ui_core::style::FlexStyle;
131    /// assert_eq!(FlexStyle::row().gap(-2.0).gap, 0.0);
132    /// ```
133    pub fn gap(mut self, value: f32) -> Self {
134        self.gap = value.max(0.0);
135        self
136    }
137
138    /// Replaces the default cross-axis alignment.
139    ///
140    /// # Examples
141    ///
142    /// ```
143    /// use ailloli_ui_core::style::{AlignItems, FlexStyle};
144    /// assert_eq!(FlexStyle::row().align_items(AlignItems::Stretch).align_items, AlignItems::Stretch);
145    /// ```
146    pub fn align_items(mut self, value: AlignItems) -> Self {
147        self.align_items = value;
148        self
149    }
150
151    /// Replaces the main-axis distribution policy.
152    ///
153    /// # Examples
154    ///
155    /// ```
156    /// use ailloli_ui_core::style::{FlexStyle, JustifyContent};
157    /// assert_eq!(FlexStyle::row().justify_content(JustifyContent::SpaceBetween).justify_content, JustifyContent::SpaceBetween);
158    /// ```
159    pub fn justify_content(mut self, value: JustifyContent) -> Self {
160        self.justify_content = value;
161        self
162    }
163}
164
165impl Default for FlexStyle {
166    fn default() -> Self {
167        Self::row()
168    }
169}