yew_and_bulma/helpers/
spacing.rs

1use std::fmt::Display;
2
3/// Enum defining the possible direction values, as described in the
4/// [Bulma documentation][bd].
5///
6/// Defines the possible direction values, according to the
7/// [Bulma documentation][bd]. They _**must be combined**_ with the
8/// [`crate::helpers::spacing::Spacing`] values and either the
9/// [`crate::utils::constants::MARGIN_PREFIX`] or
10/// [`crate::utils::constants::PADDING_PREFIX`]. Since all of the Bulma classes
11/// use the `m-*`, `m*-*`, `p-*` or `p*-*` prefixes, both are needed to be
12/// included when formatting the display value. This can be simplified by using
13/// the [`crate::utils::class::ClassBuilder`] instead of manually handling
14/// creation of the class strings.
15///
16/// # Examples
17///
18/// ```rust
19/// use yew::prelude::*;
20/// use yew_and_bulma::{
21///     helpers::spacing::Direction,
22///     helpers::spacing::Spacing,
23///     utils::class::ClassBuilder,
24/// };
25///
26/// // Create a `<div>` HTML element that has the marign and padding set to 2.
27/// #[function_component(SpacedDiv)]
28/// fn spaced_div() -> Html {
29///     let class = ClassBuilder::default()
30///         .with_margin(Direction::All, Spacing::Two)
31///         .with_padding(Direction::All, Spacing::Two)
32///         .build();
33///     html!{
34///         <div class={class}>{ "Lorem ispum..." }</div>
35///     }
36/// }
37/// ```
38///
39/// It is also possible to use them wihtout the
40/// [`crate::utils::class::ClassBuilder`], instead formatting the class names
41/// manually, using the constants defined in [`crate::utils::constants`]:
42///
43/// ```rust
44/// use yew::prelude::*;
45/// use yew_and_bulma::{
46///     helpers::spacing::Direction,
47///     helpers::spacing::Spacing,
48///     utils::constants::MARGIN_PREFIX,
49///     utils::constants::PADDING_PREFIX,
50/// };
51///
52/// // Create a `<div>` HTML element that has the marign and padding set to 2.
53/// #[function_component(SpacedDiv)]
54/// fn spaced_div() -> Html {
55///     let class = classes![
56///         format!("{MARGIN_PREFIX}{}-{}", Direction::All, Spacing::Two),
57///         format!("{PADDING_PREFIX}{}-{}", Direction::All, Spacing::Two),
58///     ];
59///     html!{
60///         <div class={class}>{ "Lorem ispum..." }</div>
61///     }
62/// }
63/// ```
64///
65/// [bd]: https://bulma.io/documentation/helpers/spacing-helpers
66#[derive(Clone, Debug, PartialEq, Eq, Hash)]
67pub enum Direction {
68    All,
69    Top,
70    Right,
71    Bottom,
72    Left,
73    Horizontal,
74    Vertical,
75}
76
77impl Display for Direction {
78    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
79        let direction_name = match self {
80            Direction::All => "",
81            Direction::Top => "t",
82            Direction::Right => "r",
83            Direction::Bottom => "b",
84            Direction::Left => "l",
85            Direction::Horizontal => "x",
86            Direction::Vertical => "y",
87        };
88
89        write!(f, "{direction_name}")
90    }
91}
92
93/// Enum defining the possible spacing values, as described in the
94/// [Bulma documentation][bd].
95///
96/// Defines the possible spacing values, according to the
97/// [Bulma documentation][bd]. They _**must be combined**_ with the
98/// [`crate::helpers::spacing::Direction`] values and either the
99/// [`crate::utils::constants::MARGIN_PREFIX`] or
100/// [`crate::utils::constants::PADDING_PREFIX`]. Since all of the Bulma classes
101/// use the `m-*`, `m*-*`, `p-*` or `p*-*` prefixes, both are needed to be
102/// included when formatting the display value. This can be simplified by using
103/// the [`crate::utils::class::ClassBuilder`] instead of manually handling
104/// creation of the class strings.
105///
106/// # Examples
107///
108/// ```rust
109/// use yew::prelude::*;
110/// use yew_and_bulma::{
111///     helpers::spacing::Direction,
112///     helpers::spacing::Spacing,
113///     utils::class::ClassBuilder,
114/// };
115///
116/// // Create a `<div>` HTML element that has the margin and padding set to 2.
117/// #[function_component(SpacedDiv)]
118/// fn spaced_div() -> Html {
119///     let class = ClassBuilder::default()
120///         .with_margin(Direction::All, Spacing::Two)
121///         .with_padding(Direction::All, Spacing::Two)
122///         .build();
123///     html!{
124///         <div class={class}>{ "Lorem ispum..." }</div>
125///     }
126/// }
127/// ```
128///
129/// It is also possible to use them wihtout the
130/// [`crate::utils::class::ClassBuilder`], instead formatting the class names
131/// manually, using the constants defined in [`crate::utils::constants`]:
132///
133/// ```rust
134/// use yew::prelude::*;
135/// use yew_and_bulma::{
136///     helpers::spacing::Direction,
137///     helpers::spacing::Spacing,
138///     utils::constants::MARGIN_PREFIX,
139///     utils::constants::PADDING_PREFIX,
140/// };
141///
142/// // Create a `<div>` HTML element that has the margin and padding set to 2.
143/// #[function_component(SpacedDiv)]
144/// fn spaced_div() -> Html {
145///     let class = classes![
146///         format!("{MARGIN_PREFIX}{}-{}", Direction::All, Spacing::Two),
147///         format!("{PADDING_PREFIX}{}-{}", Direction::All, Spacing::Two),
148///     ];
149///     html!{
150///         <div class={class}>{ "Lorem ispum..." }</div>
151///     }
152/// }
153/// ```
154///
155/// [bd]: https://bulma.io/documentation/helpers/spacing-helpers
156#[derive(Clone, Debug, PartialEq, Eq, Hash)]
157pub enum Spacing {
158    Zero,
159    One,
160    Two,
161    Three,
162    Four,
163    Five,
164    Six,
165}
166
167impl Display for Spacing {
168    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
169        let spacing_value = match self {
170            Spacing::Zero => "0",
171            Spacing::One => "1",
172            Spacing::Two => "2",
173            Spacing::Three => "3",
174            Spacing::Four => "4",
175            Spacing::Five => "5",
176            Spacing::Six => "6",
177        };
178
179        write!(f, "{spacing_value}")
180    }
181}
182
183#[cfg(test)]
184mod tests {
185    use super::*;
186    use test_case::test_case;
187
188    #[test_case(Direction::All, "" ; "all converts to empty string")]
189    #[test_case(Direction::Top, "t" ; "top converts to t")]
190    #[test_case(Direction::Right, "r" ; "right converts to r")]
191    #[test_case(Direction::Bottom, "b" ; "bottom converts to b")]
192    #[test_case(Direction::Left, "l" ; "left converts to l")]
193    #[test_case(Direction::Horizontal, "x" ; "horizontal converts to x")]
194    #[test_case(Direction::Vertical, "y" ; "vertical converts to y")]
195    fn direction_values_to_string(direction: Direction, expected_direction: &str) {
196        let converted_direction = format!("{direction}");
197
198        assert_eq!(converted_direction, expected_direction);
199    }
200
201    #[test_case(Spacing::Zero, "0" ; "zero converts to 0")]
202    #[test_case(Spacing::One, "1" ; "one converts to 1")]
203    #[test_case(Spacing::Two, "2" ; "two converts to 2")]
204    #[test_case(Spacing::Three, "3" ; "three converts to 3")]
205    #[test_case(Spacing::Four, "4" ; "four converts to 4")]
206    #[test_case(Spacing::Five, "5" ; "five converts to 5")]
207    #[test_case(Spacing::Six, "6" ; "six converts to 6")]
208    fn spacing_values_to_string(spacing: Spacing, expected_spacing: &str) {
209        let converted_spacing = format!("{spacing}");
210
211        assert_eq!(converted_spacing, expected_spacing);
212    }
213}