taffy/style/
flex.rs

1//! Style types for Flexbox layout
2
3use crate::geometry::AbsoluteAxis;
4
5/// Controls whether flex items are forced onto one line or can wrap onto multiple lines.
6///
7/// Defaults to [`FlexWrap::NoWrap`]
8///
9/// [Specification](https://www.w3.org/TR/css-flexbox-1/#flex-wrap-property)
10#[derive(Copy, Clone, PartialEq, Eq, Debug)]
11#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
12pub enum FlexWrap {
13    /// Items will not wrap and stay on a single line
14    NoWrap,
15    /// Items will wrap according to this item's [`FlexDirection`]
16    Wrap,
17    /// Items will wrap in the opposite direction to this item's [`FlexDirection`]
18    WrapReverse,
19}
20
21impl Default for FlexWrap {
22    fn default() -> Self {
23        Self::NoWrap
24    }
25}
26
27/// The direction of the flexbox layout main axis.
28///
29/// There are always two perpendicular layout axes: main (or primary) and cross (or secondary).
30/// Adding items will cause them to be positioned adjacent to each other along the main axis.
31/// By varying this value throughout your tree, you can create complex axis-aligned layouts.
32///
33/// Items are always aligned relative to the cross axis, and justified relative to the main axis.
34///
35/// The default behavior is [`FlexDirection::Row`].
36///
37/// [Specification](https://www.w3.org/TR/css-flexbox-1/#flex-direction-property)
38#[derive(Copy, Clone, PartialEq, Eq, Debug)]
39#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
40pub enum FlexDirection {
41    /// Defines +x as the main axis
42    ///
43    /// Items will be added from left to right in a row.
44    Row,
45    /// Defines +y as the main axis
46    ///
47    /// Items will be added from top to bottom in a column.
48    Column,
49    /// Defines -x as the main axis
50    ///
51    /// Items will be added from right to left in a row.
52    RowReverse,
53    /// Defines -y as the main axis
54    ///
55    /// Items will be added from bottom to top in a column.
56    ColumnReverse,
57}
58
59impl Default for FlexDirection {
60    fn default() -> Self {
61        Self::Row
62    }
63}
64
65impl FlexDirection {
66    #[inline]
67    /// Is the direction [`FlexDirection::Row`] or [`FlexDirection::RowReverse`]?
68    pub(crate) fn is_row(self) -> bool {
69        matches!(self, Self::Row | Self::RowReverse)
70    }
71
72    #[inline]
73    /// Is the direction [`FlexDirection::Column`] or [`FlexDirection::ColumnReverse`]?
74    pub(crate) fn is_column(self) -> bool {
75        matches!(self, Self::Column | Self::ColumnReverse)
76    }
77
78    #[inline]
79    /// Is the direction [`FlexDirection::RowReverse`] or [`FlexDirection::ColumnReverse`]?
80    pub(crate) fn is_reverse(self) -> bool {
81        matches!(self, Self::RowReverse | Self::ColumnReverse)
82    }
83
84    #[inline]
85    /// The `AbsoluteAxis` that corresponds to the main axis
86    pub(crate) fn main_axis(self) -> AbsoluteAxis {
87        match self {
88            Self::Row | Self::RowReverse => AbsoluteAxis::Horizontal,
89            Self::Column | Self::ColumnReverse => AbsoluteAxis::Vertical,
90        }
91    }
92
93    #[inline]
94    /// The `AbsoluteAxis` that corresponds to the cross axis
95    pub(crate) fn cross_axis(self) -> AbsoluteAxis {
96        match self {
97            Self::Row | Self::RowReverse => AbsoluteAxis::Vertical,
98            Self::Column | Self::ColumnReverse => AbsoluteAxis::Horizontal,
99        }
100    }
101}
102
103#[cfg(test)]
104mod tests {
105    mod test_flex_direction {
106        use crate::style::*;
107
108        #[test]
109        fn flex_direction_is_row() {
110            assert_eq!(FlexDirection::Row.is_row(), true);
111            assert_eq!(FlexDirection::RowReverse.is_row(), true);
112            assert_eq!(FlexDirection::Column.is_row(), false);
113            assert_eq!(FlexDirection::ColumnReverse.is_row(), false);
114        }
115
116        #[test]
117        fn flex_direction_is_column() {
118            assert_eq!(FlexDirection::Row.is_column(), false);
119            assert_eq!(FlexDirection::RowReverse.is_column(), false);
120            assert_eq!(FlexDirection::Column.is_column(), true);
121            assert_eq!(FlexDirection::ColumnReverse.is_column(), true);
122        }
123
124        #[test]
125        fn flex_direction_is_reverse() {
126            assert_eq!(FlexDirection::Row.is_reverse(), false);
127            assert_eq!(FlexDirection::RowReverse.is_reverse(), true);
128            assert_eq!(FlexDirection::Column.is_reverse(), false);
129            assert_eq!(FlexDirection::ColumnReverse.is_reverse(), true);
130        }
131    }
132}