Skip to main content

maud_ui/primitives/
button_group.rs

1//! ButtonGroup component — groups multiple buttons with shared borders.
2use maud::{html, Markup};
3
4#[derive(Clone, Copy, Debug, PartialEq, Eq)]
5pub enum Orientation {
6    Horizontal,
7    Vertical,
8}
9
10impl Orientation {
11    fn class_name(self) -> &'static str {
12        match self {
13            Orientation::Horizontal => "mui-button-group--horizontal",
14            Orientation::Vertical => "mui-button-group--vertical",
15        }
16    }
17}
18
19#[derive(Clone, Debug)]
20pub struct Props {
21    pub children: Markup,
22    pub orientation: Orientation,
23    pub size: Option<String>,
24}
25
26impl Default for Props {
27    fn default() -> Self {
28        Self {
29            children: html! {},
30            orientation: Orientation::Horizontal,
31            size: None,
32        }
33    }
34}
35
36pub fn render(props: Props) -> Markup {
37    let mut class = "mui-button-group".to_string();
38    class.push(' ');
39    class.push_str(props.orientation.class_name());
40
41    if let Some(size) = props.size {
42        class.push(' ');
43        class.push_str(&size);
44    }
45
46    html! {
47        div class=(class) role="group" {
48            (props.children)
49        }
50    }
51}
52
53pub fn showcase() -> Markup {
54    // Text alignment — Left/Center/Right with glyph icons
55    let buttons_align = html! {
56        button type="button" class="mui-btn mui-btn--outline mui-btn--md" aria-pressed="true" aria-label="Align left" {
57            span aria-hidden="true" { "\u{2630}" }
58            " Left"
59        }
60        button type="button" class="mui-btn mui-btn--outline mui-btn--md" aria-label="Align center" {
61            span aria-hidden="true" { "\u{2261}" }
62            " Center"
63        }
64        button type="button" class="mui-btn mui-btn--outline mui-btn--md" aria-label="Align right" {
65            span aria-hidden="true" { "\u{268c}" }
66            " Right"
67        }
68    };
69
70    // Text formatting — Bold/Italic/Underline
71    let buttons_format = html! {
72        button type="button" class="mui-btn mui-btn--outline mui-btn--md" aria-pressed="true" aria-label="Bold" {
73            strong { "B" }
74        }
75        button type="button" class="mui-btn mui-btn--outline mui-btn--md" aria-label="Italic" {
76            em { "I" }
77        }
78        button type="button" class="mui-btn mui-btn--outline mui-btn--md" aria-label="Underline" {
79            span style="text-decoration:underline;" { "U" }
80        }
81    };
82
83    // View switcher — Grid/List/Board
84    let buttons_view = html! {
85        button type="button" class="mui-btn mui-btn--outline mui-btn--md" aria-pressed="true" {
86            span aria-hidden="true" { "\u{25a6}" }
87            " Grid"
88        }
89        button type="button" class="mui-btn mui-btn--outline mui-btn--md" {
90            span aria-hidden="true" { "\u{2630}" }
91            " List"
92        }
93        button type="button" class="mui-btn mui-btn--outline mui-btn--md" {
94            span aria-hidden="true" { "\u{25a7}" }
95            " Board"
96        }
97    };
98
99    html! {
100        div.mui-showcase__grid {
101            section {
102                h2 { "Text alignment toolbar" }
103                p.mui-showcase__caption { "Editor toolbar — exactly one alignment active at a time." }
104                div.mui-showcase__row {
105                    (render(Props {
106                        children: buttons_align,
107                        orientation: Orientation::Horizontal,
108                        size: None,
109                    }))
110                }
111            }
112            section {
113                h2 { "Text formatting" }
114                p.mui-showcase__caption { "Rich-text controls — each toggle independent (Bold currently on)." }
115                div.mui-showcase__row {
116                    (render(Props {
117                        children: buttons_format,
118                        orientation: Orientation::Horizontal,
119                        size: None,
120                    }))
121                }
122            }
123            section {
124                h2 { "View switcher" }
125                p.mui-showcase__caption { "Project listing view — Grid / List / Board (Grid active)." }
126                div.mui-showcase__row {
127                    (render(Props {
128                        children: buttons_view,
129                        orientation: Orientation::Horizontal,
130                        size: None,
131                    }))
132                }
133            }
134        }
135    }
136}