Skip to main content

guise/layout/
space.rs

1//! `Space` — a fixed spacing block on one axis, sized by the theme's
2//! spacing scale.
3//!
4//! ```ignore
5//! use guise::prelude::*;
6//!
7//! Stack::new()
8//!     .child(Title::new("Heading").order(3))
9//!     .child(Space::y(Size::Md))
10//!     .child(Text::new("Body copy."))
11//! ```
12
13use gpui::prelude::*;
14use gpui::{div, px, App, IntoElement, Window};
15
16use crate::theme::{theme, Size};
17
18/// The axis a [`Space`] occupies.
19#[derive(Debug, Clone, Copy, PartialEq, Eq)]
20enum SpaceAxis {
21    Horizontal,
22    Vertical,
23}
24
25/// A fixed gap between siblings. The Mantine `Space`.
26#[derive(IntoElement)]
27pub struct Space {
28    axis: SpaceAxis,
29    size: Size,
30}
31
32impl Space {
33    /// Horizontal space: a block `size` wide (for rows).
34    pub fn x(size: Size) -> Self {
35        Space {
36            axis: SpaceAxis::Horizontal,
37            size,
38        }
39    }
40
41    /// Vertical space: a block `size` tall (for columns).
42    pub fn y(size: Size) -> Self {
43        Space {
44            axis: SpaceAxis::Vertical,
45            size,
46        }
47    }
48}
49
50impl RenderOnce for Space {
51    fn render(self, _window: &mut Window, cx: &mut App) -> impl IntoElement {
52        let gap = theme(cx).spacing(self.size);
53        let el = div().flex_none();
54        match self.axis {
55            SpaceAxis::Horizontal => el.w(px(gap)),
56            SpaceAxis::Vertical => el.h(px(gap)),
57        }
58    }
59}