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::devtools::Probed;
17use crate::theme::{theme, Size};
18
19/// The axis a [`Space`] occupies.
20#[derive(Debug, Clone, Copy, PartialEq, Eq)]
21enum SpaceAxis {
22  Horizontal,
23  Vertical,
24}
25
26/// A fixed gap between siblings.
27#[derive(IntoElement)]
28pub struct Space {
29  axis: SpaceAxis,
30  size: Size,
31}
32
33impl Space {
34  /// Horizontal space: a block `size` wide (for rows).
35  pub fn x(size: Size) -> Self {
36    Space {
37      axis: SpaceAxis::Horizontal,
38      size,
39    }
40  }
41
42  /// Vertical space: a block `size` tall (for columns).
43  pub fn y(size: Size) -> Self {
44    Space {
45      axis: SpaceAxis::Vertical,
46      size,
47    }
48  }
49}
50
51impl RenderOnce for Space {
52  fn render(self, _window: &mut Window, cx: &mut App) -> impl IntoElement {
53    let gap = theme(cx).spacing(self.size);
54    let el = div().flex_none();
55
56    let element = match self.axis {
57      SpaceAxis::Horizontal => el.w(px(gap)),
58      SpaceAxis::Vertical => el.h(px(gap)),
59    };
60
61    element.probe("Space")
62  }
63}