Skip to main content

whisker_css/keyword/
flex.rs

1//! Flexbox keyword enums.
2//!
3//! References:
4//! - <https://lynxjs.org/api/css/properties/flex-direction>
5//! - <https://lynxjs.org/api/css/properties/flex-wrap>
6//! - <https://lynxjs.org/api/css/properties/justify-content>
7//! - <https://lynxjs.org/api/css/properties/align-items>
8//! - <https://lynxjs.org/api/css/properties/align-self>
9//! - <https://lynxjs.org/api/css/properties/align-content>
10
11use core::fmt;
12
13use crate::to_css::ToCss;
14
15/// The `flex-direction` keyword. Lynx accepts the four standard
16/// values; the deprecated `vertical` and `horizontal` aliases are
17/// **not** included.
18#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
19pub enum FlexDirection {
20    /// `row` — main axis runs left-to-right. Default.
21    Row,
22    /// `row-reverse` — main axis runs right-to-left.
23    RowReverse,
24    /// `column` — main axis runs top-to-bottom.
25    Column,
26    /// `column-reverse` — main axis runs bottom-to-top.
27    ColumnReverse,
28}
29
30impl ToCss for FlexDirection {
31    fn to_css(&self, dest: &mut dyn fmt::Write) -> fmt::Result {
32        dest.write_str(match self {
33            FlexDirection::Row => "row",
34            FlexDirection::RowReverse => "row-reverse",
35            FlexDirection::Column => "column",
36            FlexDirection::ColumnReverse => "column-reverse",
37        })
38    }
39}
40
41/// The `flex-wrap` keyword.
42#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
43pub enum FlexWrap {
44    /// `nowrap` — single line, no wrapping. Default.
45    Nowrap,
46    /// `wrap` — multi-line, wrap forward.
47    Wrap,
48    /// `wrap-reverse` — multi-line, wrap reverse.
49    WrapReverse,
50}
51
52impl ToCss for FlexWrap {
53    fn to_css(&self, dest: &mut dyn fmt::Write) -> fmt::Result {
54        dest.write_str(match self {
55            FlexWrap::Nowrap => "nowrap",
56            FlexWrap::Wrap => "wrap",
57            FlexWrap::WrapReverse => "wrap-reverse",
58        })
59    }
60}
61
62/// The `justify-content` keyword. **Lynx does not support `normal`,
63/// `left`, `right`, or the `baseline*` family.**
64#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
65pub enum JustifyContent {
66    /// `stretch` — distribute remaining space to flexible items.
67    Stretch,
68    /// `flex-start` — pack at the start of the main axis. Default.
69    FlexStart,
70    /// `flex-end` — pack at the end of the main axis.
71    FlexEnd,
72    /// `center` — pack around the center of the main axis.
73    Center,
74    /// `space-between` — equal space between items.
75    SpaceBetween,
76    /// `space-around` — equal space around items.
77    SpaceAround,
78    /// `space-evenly` — equal space between and around items.
79    SpaceEvenly,
80    /// `start` — pack at the logical start (writing-mode aware).
81    Start,
82    /// `end` — pack at the logical end.
83    End,
84}
85
86impl ToCss for JustifyContent {
87    fn to_css(&self, dest: &mut dyn fmt::Write) -> fmt::Result {
88        dest.write_str(match self {
89            JustifyContent::Stretch => "stretch",
90            JustifyContent::FlexStart => "flex-start",
91            JustifyContent::FlexEnd => "flex-end",
92            JustifyContent::Center => "center",
93            JustifyContent::SpaceBetween => "space-between",
94            JustifyContent::SpaceAround => "space-around",
95            JustifyContent::SpaceEvenly => "space-evenly",
96            JustifyContent::Start => "start",
97            JustifyContent::End => "end",
98        })
99    }
100}
101
102/// The `align-items` keyword.
103#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
104pub enum AlignItems {
105    /// `stretch` — stretch items to fill the cross axis. Default.
106    Stretch,
107    /// `flex-start` — pack at the start of the cross axis.
108    FlexStart,
109    /// `flex-end` — pack at the end of the cross axis.
110    FlexEnd,
111    /// `center` — pack around the center of the cross axis.
112    Center,
113    /// `baseline` — align baselines of items.
114    Baseline,
115    /// `start` — pack at the logical start.
116    Start,
117    /// `end` — pack at the logical end.
118    End,
119}
120
121impl ToCss for AlignItems {
122    fn to_css(&self, dest: &mut dyn fmt::Write) -> fmt::Result {
123        dest.write_str(match self {
124            AlignItems::Stretch => "stretch",
125            AlignItems::FlexStart => "flex-start",
126            AlignItems::FlexEnd => "flex-end",
127            AlignItems::Center => "center",
128            AlignItems::Baseline => "baseline",
129            AlignItems::Start => "start",
130            AlignItems::End => "end",
131        })
132    }
133}
134
135/// The `align-self` keyword. Adds `auto` (defer to the container's
136/// `align-items`) to the [`AlignItems`] set.
137#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
138pub enum AlignSelf {
139    /// `auto` — inherit `align-items` from the parent. Default.
140    Auto,
141    /// `stretch` — stretch this item across the cross axis.
142    Stretch,
143    /// `flex-start` — pack at the start of the cross axis.
144    FlexStart,
145    /// `flex-end` — pack at the end of the cross axis.
146    FlexEnd,
147    /// `center` — pack around the center of the cross axis.
148    Center,
149    /// `baseline` — align baseline with sibling items.
150    Baseline,
151    /// `start` — pack at the logical start.
152    Start,
153    /// `end` — pack at the logical end.
154    End,
155}
156
157impl ToCss for AlignSelf {
158    fn to_css(&self, dest: &mut dyn fmt::Write) -> fmt::Result {
159        dest.write_str(match self {
160            AlignSelf::Auto => "auto",
161            AlignSelf::Stretch => "stretch",
162            AlignSelf::FlexStart => "flex-start",
163            AlignSelf::FlexEnd => "flex-end",
164            AlignSelf::Center => "center",
165            AlignSelf::Baseline => "baseline",
166            AlignSelf::Start => "start",
167            AlignSelf::End => "end",
168        })
169    }
170}
171
172/// The `align-content` keyword. Used to distribute extra cross-axis
173/// space when items wrap onto multiple lines.
174#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
175pub enum AlignContent {
176    /// `stretch` — stretch lines to fill remaining space. Default.
177    Stretch,
178    /// `flex-start` — pack lines at the start.
179    FlexStart,
180    /// `flex-end` — pack lines at the end.
181    FlexEnd,
182    /// `center` — center the lines.
183    Center,
184    /// `space-between` — equal space between lines.
185    SpaceBetween,
186    /// `space-around` — equal space around each line.
187    SpaceAround,
188    /// `space-evenly` — equal space between and around lines.
189    SpaceEvenly,
190}
191
192impl ToCss for AlignContent {
193    fn to_css(&self, dest: &mut dyn fmt::Write) -> fmt::Result {
194        dest.write_str(match self {
195            AlignContent::Stretch => "stretch",
196            AlignContent::FlexStart => "flex-start",
197            AlignContent::FlexEnd => "flex-end",
198            AlignContent::Center => "center",
199            AlignContent::SpaceBetween => "space-between",
200            AlignContent::SpaceAround => "space-around",
201            AlignContent::SpaceEvenly => "space-evenly",
202        })
203    }
204}
205
206#[cfg(test)]
207mod tests {
208    use super::*;
209
210    #[test]
211    fn flex_direction_all() {
212        let cases = [
213            (FlexDirection::Row, "row"),
214            (FlexDirection::RowReverse, "row-reverse"),
215            (FlexDirection::Column, "column"),
216            (FlexDirection::ColumnReverse, "column-reverse"),
217        ];
218        for (k, expected) in cases {
219            assert_eq!(k.to_css_string(), expected);
220        }
221    }
222
223    #[test]
224    fn flex_wrap_all() {
225        let cases = [
226            (FlexWrap::Nowrap, "nowrap"),
227            (FlexWrap::Wrap, "wrap"),
228            (FlexWrap::WrapReverse, "wrap-reverse"),
229        ];
230        for (k, expected) in cases {
231            assert_eq!(k.to_css_string(), expected);
232        }
233    }
234
235    #[test]
236    fn justify_content_all() {
237        let cases = [
238            (JustifyContent::Stretch, "stretch"),
239            (JustifyContent::FlexStart, "flex-start"),
240            (JustifyContent::FlexEnd, "flex-end"),
241            (JustifyContent::Center, "center"),
242            (JustifyContent::SpaceBetween, "space-between"),
243            (JustifyContent::SpaceAround, "space-around"),
244            (JustifyContent::SpaceEvenly, "space-evenly"),
245            (JustifyContent::Start, "start"),
246            (JustifyContent::End, "end"),
247        ];
248        for (k, expected) in cases {
249            assert_eq!(k.to_css_string(), expected);
250        }
251    }
252
253    #[test]
254    fn align_items_all() {
255        let cases = [
256            (AlignItems::Stretch, "stretch"),
257            (AlignItems::FlexStart, "flex-start"),
258            (AlignItems::FlexEnd, "flex-end"),
259            (AlignItems::Center, "center"),
260            (AlignItems::Baseline, "baseline"),
261            (AlignItems::Start, "start"),
262            (AlignItems::End, "end"),
263        ];
264        for (k, expected) in cases {
265            assert_eq!(k.to_css_string(), expected);
266        }
267    }
268
269    #[test]
270    fn align_self_all() {
271        let cases = [
272            (AlignSelf::Auto, "auto"),
273            (AlignSelf::Stretch, "stretch"),
274            (AlignSelf::FlexStart, "flex-start"),
275            (AlignSelf::FlexEnd, "flex-end"),
276            (AlignSelf::Center, "center"),
277            (AlignSelf::Baseline, "baseline"),
278            (AlignSelf::Start, "start"),
279            (AlignSelf::End, "end"),
280        ];
281        for (k, expected) in cases {
282            assert_eq!(k.to_css_string(), expected);
283        }
284    }
285
286    #[test]
287    fn align_content_all() {
288        let cases = [
289            (AlignContent::Stretch, "stretch"),
290            (AlignContent::FlexStart, "flex-start"),
291            (AlignContent::FlexEnd, "flex-end"),
292            (AlignContent::Center, "center"),
293            (AlignContent::SpaceBetween, "space-between"),
294            (AlignContent::SpaceAround, "space-around"),
295            (AlignContent::SpaceEvenly, "space-evenly"),
296        ];
297        for (k, expected) in cases {
298            assert_eq!(k.to_css_string(), expected);
299        }
300    }
301}