Skip to main content

gpui_base/
toggle_group.rs

1use gpui::{
2    AnyElement, App, Axis, Div, ElementId, InteractiveElement, Interactivity, IntoElement,
3    ParentElement, RenderOnce, Role, Stateful, StatefulInteractiveElement, StyleRefinement, Styled,
4    Window, accesskit, div,
5};
6use smallvec::SmallVec;
7
8use crate::StyledExt as _;
9
10/// An unstyled container for a set of toggle elements.
11#[derive(IntoElement)]
12pub struct ToggleGroup {
13    base: Stateful<Div>,
14    style: StyleRefinement,
15    axis: Axis,
16    children: SmallVec<[AnyElement; 4]>,
17}
18
19impl ToggleGroup {
20    pub fn new(id: impl Into<ElementId>) -> Self {
21        Self {
22            base: div().id(id.into()),
23            style: StyleRefinement::default(),
24            axis: Axis::Horizontal,
25            children: SmallVec::new(),
26        }
27    }
28
29    /// Sets the semantic axis of the group.
30    pub fn axis(mut self, axis: Axis) -> Self {
31        self.axis = axis;
32        self
33    }
34}
35
36impl Styled for ToggleGroup {
37    fn style(&mut self) -> &mut StyleRefinement {
38        &mut self.style
39    }
40}
41
42impl ParentElement for ToggleGroup {
43    fn extend(&mut self, elements: impl IntoIterator<Item = AnyElement>) {
44        self.children.extend(elements);
45    }
46}
47
48impl InteractiveElement for ToggleGroup {
49    fn interactivity(&mut self) -> &mut Interactivity {
50        self.base.interactivity()
51    }
52}
53
54impl StatefulInteractiveElement for ToggleGroup {}
55
56impl RenderOnce for ToggleGroup {
57    fn render(self, _: &mut Window, _: &mut App) -> impl IntoElement {
58        self.base
59            .role(Role::Toolbar)
60            .aria_orientation(match self.axis {
61                Axis::Horizontal => accesskit::Orientation::Horizontal,
62                Axis::Vertical => accesskit::Orientation::Vertical,
63            })
64            .children(self.children)
65            .refine_style(&self.style)
66    }
67}