1use gpui::prelude::*;
4use gpui::{div, px, AnyElement, App, IntoElement, Window};
5
6use super::{apply_align, apply_justify, Align, Justify};
7use crate::theme::{theme, Size};
8
9#[derive(IntoElement)]
11pub struct Group {
12 children: Vec<AnyElement>,
13 gap: Size,
14 align: Align,
15 justify: Justify,
16 wrap: bool,
17 grow: bool,
18}
19
20impl Group {
21 pub fn new() -> Self {
22 Group {
23 children: Vec::new(),
24 gap: Size::Md,
25 align: Align::Center,
26 justify: Justify::Start,
27 wrap: true,
28 grow: false,
29 }
30 }
31
32 pub fn gap(mut self, gap: Size) -> Self {
33 self.gap = gap;
34 self
35 }
36
37 pub fn align(mut self, align: Align) -> Self {
38 self.align = align;
39 self
40 }
41
42 pub fn justify(mut self, justify: Justify) -> Self {
43 self.justify = justify;
44 self
45 }
46
47 pub fn wrap(mut self, wrap: bool) -> Self {
49 self.wrap = wrap;
50 self
51 }
52
53 pub fn grow(mut self, grow: bool) -> Self {
55 self.grow = grow;
56 self
57 }
58}
59
60impl Default for Group {
61 fn default() -> Self {
62 Group::new()
63 }
64}
65
66impl ParentElement for Group {
67 fn extend(&mut self, elements: impl IntoIterator<Item = AnyElement>) {
68 self.children.extend(elements);
69 }
70}
71
72impl RenderOnce for Group {
73 fn render(self, _window: &mut Window, cx: &mut App) -> impl IntoElement {
74 let gap = theme(cx).spacing(self.gap);
75 let mut base = div().flex().flex_row().gap(px(gap));
76 if self.wrap {
77 base = base.flex_wrap();
78 }
79 let grow = self.grow;
80 apply_justify(apply_align(base, self.align), self.justify).children(
81 self.children.into_iter().map(move |c| {
82 if grow {
83 div().flex_1().child(c).into_any_element()
84 } else {
85 c
86 }
87 }),
88 )
89 }
90}