allui/layout/
vstack.rs

1//! VStack - Vertical stack layout.
2
3use gpui::{div, px, App, IntoElement, ParentElement, RenderOnce, Styled, Window};
4
5use crate::alignment::HorizontalAlignment;
6use crate::modifier::Modifier;
7
8/// A view that arranges its children in a vertical line.
9///
10/// By default, VStack centers its children horizontally (matching SwiftUI).
11///
12/// # Example
13///
14/// ```rust,ignore
15/// VStack::new()
16///     .spacing(12.0)
17///     .alignment(HorizontalAlignment::Leading)
18///     .child(Text::new("Title"))
19///     .child(Text::new("Subtitle"))
20/// ```
21#[derive(IntoElement)]
22pub struct VStack {
23    spacing: f32,
24    alignment: HorizontalAlignment,
25    children: Vec<gpui::AnyElement>,
26}
27
28impl VStack {
29    /// Create a new vertical stack.
30    pub fn new() -> Self {
31        Self {
32            spacing: 8.0,
33            alignment: HorizontalAlignment::Center, // SwiftUI default
34            children: Vec::new(),
35        }
36    }
37
38    /// Set the spacing between children.
39    pub fn spacing(mut self, spacing: f32) -> Self {
40        self.spacing = spacing;
41        self
42    }
43
44    /// Set the horizontal alignment of children.
45    pub fn alignment(mut self, alignment: HorizontalAlignment) -> Self {
46        self.alignment = alignment;
47        self
48    }
49
50    impl_child_methods!();
51}
52
53impl Default for VStack {
54    fn default() -> Self {
55        Self::new()
56    }
57}
58
59impl Modifier for VStack {}
60
61impl RenderOnce for VStack {
62    fn render(self, _window: &mut Window, _cx: &mut App) -> impl IntoElement {
63        let container = div().flex().flex_col().gap(px(self.spacing));
64        self.alignment
65            .apply_as_items(container)
66            .children(self.children)
67    }
68}