toggle_button.rs

  1use std::rc::Rc;
  2
  3use gpui::{AnyView, ClickEvent, relative};
  4
  5use crate::{ButtonLike, ButtonLikeRounding, ElevationIndex, TintColor, Tooltip, prelude::*};
  6
  7/// The position of a [`ToggleButton`] within a group of buttons.
  8#[derive(Debug, PartialEq, Eq, Clone, Copy)]
  9pub enum ToggleButtonPosition {
 10    /// The toggle button is first in the group.
 11    First,
 12
 13    /// The toggle button is in the middle of the group (i.e., it is not the first or last toggle button).
 14    Middle,
 15
 16    /// The toggle button is last in the group.
 17    Last,
 18}
 19
 20#[derive(IntoElement, RegisterComponent)]
 21pub struct ToggleButton {
 22    base: ButtonLike,
 23    position_in_group: Option<ToggleButtonPosition>,
 24    label: SharedString,
 25    label_color: Option<Color>,
 26}
 27
 28impl ToggleButton {
 29    pub fn new(id: impl Into<ElementId>, label: impl Into<SharedString>) -> Self {
 30        Self {
 31            base: ButtonLike::new(id),
 32            position_in_group: None,
 33            label: label.into(),
 34            label_color: None,
 35        }
 36    }
 37
 38    pub fn color(mut self, label_color: impl Into<Option<Color>>) -> Self {
 39        self.label_color = label_color.into();
 40        self
 41    }
 42
 43    pub fn position_in_group(mut self, position: ToggleButtonPosition) -> Self {
 44        self.position_in_group = Some(position);
 45        self
 46    }
 47
 48    pub fn first(self) -> Self {
 49        self.position_in_group(ToggleButtonPosition::First)
 50    }
 51
 52    pub fn middle(self) -> Self {
 53        self.position_in_group(ToggleButtonPosition::Middle)
 54    }
 55
 56    pub fn last(self) -> Self {
 57        self.position_in_group(ToggleButtonPosition::Last)
 58    }
 59}
 60
 61impl Toggleable for ToggleButton {
 62    fn toggle_state(mut self, selected: bool) -> Self {
 63        self.base = self.base.toggle_state(selected);
 64        self
 65    }
 66}
 67
 68impl SelectableButton for ToggleButton {
 69    fn selected_style(mut self, style: ButtonStyle) -> Self {
 70        self.base.selected_style = Some(style);
 71        self
 72    }
 73}
 74
 75impl FixedWidth for ToggleButton {
 76    fn width(mut self, width: impl Into<DefiniteLength>) -> Self {
 77        self.base.width = Some(width.into());
 78        self
 79    }
 80
 81    fn full_width(mut self) -> Self {
 82        self.base.width = Some(relative(1.));
 83        self
 84    }
 85}
 86
 87impl Disableable for ToggleButton {
 88    fn disabled(mut self, disabled: bool) -> Self {
 89        self.base = self.base.disabled(disabled);
 90        self
 91    }
 92}
 93
 94impl Clickable for ToggleButton {
 95    fn on_click(mut self, handler: impl Fn(&ClickEvent, &mut Window, &mut App) + 'static) -> Self {
 96        self.base = self.base.on_click(handler);
 97        self
 98    }
 99
100    fn cursor_style(mut self, cursor_style: gpui::CursorStyle) -> Self {
101        self.base = self.base.cursor_style(cursor_style);
102        self
103    }
104}
105
106impl ButtonCommon for ToggleButton {
107    fn id(&self) -> &ElementId {
108        self.base.id()
109    }
110
111    fn style(mut self, style: ButtonStyle) -> Self {
112        self.base = self.base.style(style);
113        self
114    }
115
116    fn size(mut self, size: ButtonSize) -> Self {
117        self.base = self.base.size(size);
118        self
119    }
120
121    fn tooltip(mut self, tooltip: impl Fn(&mut Window, &mut App) -> AnyView + 'static) -> Self {
122        self.base = self.base.tooltip(tooltip);
123        self
124    }
125
126    fn tab_index(mut self, tab_index: impl Into<isize>) -> Self {
127        self.base = self.base.tab_index(tab_index);
128        self
129    }
130
131    fn layer(mut self, elevation: ElevationIndex) -> Self {
132        self.base = self.base.layer(elevation);
133        self
134    }
135}
136
137impl RenderOnce for ToggleButton {
138    fn render(self, _window: &mut Window, _cx: &mut App) -> impl IntoElement {
139        let is_disabled = self.base.disabled;
140        let is_selected = self.base.selected;
141
142        let label_color = if is_disabled {
143            Color::Disabled
144        } else if is_selected {
145            Color::Selected
146        } else {
147            self.label_color.unwrap_or_default()
148        };
149
150        self.base
151            .when_some(self.position_in_group, |this, position| match position {
152                ToggleButtonPosition::First => this.rounding(ButtonLikeRounding::Left),
153                ToggleButtonPosition::Middle => this.rounding(None),
154                ToggleButtonPosition::Last => this.rounding(ButtonLikeRounding::Right),
155            })
156            .child(
157                Label::new(self.label)
158                    .color(label_color)
159                    .line_height_style(LineHeightStyle::UiLabel),
160            )
161    }
162}
163
164impl Component for ToggleButton {
165    fn scope() -> ComponentScope {
166        ComponentScope::Input
167    }
168
169    fn sort_name() -> &'static str {
170        "ButtonC"
171    }
172
173    fn preview(_window: &mut Window, _cx: &mut App) -> Option<AnyElement> {
174        Some(
175            v_flex()
176                .gap_6()
177                .children(vec![
178                    example_group_with_title(
179                        "Button Styles",
180                        vec![
181                            single_example(
182                                "Off",
183                                ToggleButton::new("off", "Off")
184                                    .layer(ElevationIndex::Background)
185                                    .style(ButtonStyle::Filled)
186                                    .into_any_element(),
187                            ),
188                            single_example(
189                                "On",
190                                ToggleButton::new("on", "On")
191                                    .layer(ElevationIndex::Background)
192                                    .toggle_state(true)
193                                    .style(ButtonStyle::Filled)
194                                    .into_any_element(),
195                            ),
196                            single_example(
197                                "Off – Disabled",
198                                ToggleButton::new("disabled_off", "Disabled Off")
199                                    .layer(ElevationIndex::Background)
200                                    .disabled(true)
201                                    .style(ButtonStyle::Filled)
202                                    .into_any_element(),
203                            ),
204                            single_example(
205                                "On – Disabled",
206                                ToggleButton::new("disabled_on", "Disabled On")
207                                    .layer(ElevationIndex::Background)
208                                    .disabled(true)
209                                    .toggle_state(true)
210                                    .style(ButtonStyle::Filled)
211                                    .into_any_element(),
212                            ),
213                        ],
214                    ),
215                    example_group_with_title(
216                        "Button Group",
217                        vec![
218                            single_example(
219                                "Three Buttons",
220                                h_flex()
221                                    .child(
222                                        ToggleButton::new("three_btn_first", "First")
223                                            .layer(ElevationIndex::Background)
224                                            .style(ButtonStyle::Filled)
225                                            .first()
226                                            .into_any_element(),
227                                    )
228                                    .child(
229                                        ToggleButton::new("three_btn_middle", "Middle")
230                                            .layer(ElevationIndex::Background)
231                                            .style(ButtonStyle::Filled)
232                                            .middle()
233                                            .toggle_state(true)
234                                            .into_any_element(),
235                                    )
236                                    .child(
237                                        ToggleButton::new("three_btn_last", "Last")
238                                            .layer(ElevationIndex::Background)
239                                            .style(ButtonStyle::Filled)
240                                            .last()
241                                            .into_any_element(),
242                                    )
243                                    .into_any_element(),
244                            ),
245                            single_example(
246                                "Two Buttons",
247                                h_flex()
248                                    .child(
249                                        ToggleButton::new("two_btn_first", "First")
250                                            .layer(ElevationIndex::Background)
251                                            .style(ButtonStyle::Filled)
252                                            .first()
253                                            .into_any_element(),
254                                    )
255                                    .child(
256                                        ToggleButton::new("two_btn_last", "Last")
257                                            .layer(ElevationIndex::Background)
258                                            .style(ButtonStyle::Filled)
259                                            .last()
260                                            .into_any_element(),
261                                    )
262                                    .into_any_element(),
263                            ),
264                        ],
265                    ),
266                    example_group_with_title(
267                        "Alternate Sizes",
268                        vec![
269                            single_example(
270                                "None",
271                                ToggleButton::new("none", "None")
272                                    .layer(ElevationIndex::Background)
273                                    .style(ButtonStyle::Filled)
274                                    .size(ButtonSize::None)
275                                    .into_any_element(),
276                            ),
277                            single_example(
278                                "Compact",
279                                ToggleButton::new("compact", "Compact")
280                                    .layer(ElevationIndex::Background)
281                                    .style(ButtonStyle::Filled)
282                                    .size(ButtonSize::Compact)
283                                    .into_any_element(),
284                            ),
285                            single_example(
286                                "Large",
287                                ToggleButton::new("large", "Large")
288                                    .layer(ElevationIndex::Background)
289                                    .style(ButtonStyle::Filled)
290                                    .size(ButtonSize::Large)
291                                    .into_any_element(),
292                            ),
293                        ],
294                    ),
295                ])
296                .into_any_element(),
297        )
298    }
299}
300
301pub struct ButtonConfiguration {
302    label: SharedString,
303    icon: Option<IconName>,
304    on_click: Box<dyn Fn(&ClickEvent, &mut Window, &mut App) + 'static>,
305    selected: bool,
306    tooltip: Option<Rc<dyn Fn(&mut Window, &mut App) -> AnyView>>,
307}
308
309mod private {
310    pub trait ToggleButtonStyle {}
311}
312
313pub trait ButtonBuilder: 'static + private::ToggleButtonStyle {
314    fn into_configuration(self) -> ButtonConfiguration;
315}
316
317pub struct ToggleButtonSimple {
318    label: SharedString,
319    on_click: Box<dyn Fn(&ClickEvent, &mut Window, &mut App) + 'static>,
320    selected: bool,
321    tooltip: Option<Rc<dyn Fn(&mut Window, &mut App) -> AnyView>>,
322}
323
324impl ToggleButtonSimple {
325    pub fn new(
326        label: impl Into<SharedString>,
327        on_click: impl Fn(&ClickEvent, &mut Window, &mut App) + 'static,
328    ) -> Self {
329        Self {
330            label: label.into(),
331            on_click: Box::new(on_click),
332            selected: false,
333            tooltip: None,
334        }
335    }
336
337    pub fn selected(mut self, selected: bool) -> Self {
338        self.selected = selected;
339        self
340    }
341
342    pub fn tooltip(mut self, tooltip: impl Fn(&mut Window, &mut App) -> AnyView + 'static) -> Self {
343        self.tooltip = Some(Rc::new(tooltip));
344        self
345    }
346}
347
348impl private::ToggleButtonStyle for ToggleButtonSimple {}
349
350impl ButtonBuilder for ToggleButtonSimple {
351    fn into_configuration(self) -> ButtonConfiguration {
352        ButtonConfiguration {
353            label: self.label,
354            icon: None,
355            on_click: self.on_click,
356            selected: self.selected,
357            tooltip: self.tooltip,
358        }
359    }
360}
361
362pub struct ToggleButtonWithIcon {
363    label: SharedString,
364    icon: IconName,
365    on_click: Box<dyn Fn(&ClickEvent, &mut Window, &mut App) + 'static>,
366    selected: bool,
367    tooltip: Option<Rc<dyn Fn(&mut Window, &mut App) -> AnyView>>,
368}
369
370impl ToggleButtonWithIcon {
371    pub fn new(
372        label: impl Into<SharedString>,
373        icon: IconName,
374        on_click: impl Fn(&ClickEvent, &mut Window, &mut App) + 'static,
375    ) -> Self {
376        Self {
377            label: label.into(),
378            icon,
379            on_click: Box::new(on_click),
380            selected: false,
381            tooltip: None,
382        }
383    }
384
385    pub fn selected(mut self, selected: bool) -> Self {
386        self.selected = selected;
387        self
388    }
389
390    pub fn tooltip(mut self, tooltip: impl Fn(&mut Window, &mut App) -> AnyView + 'static) -> Self {
391        self.tooltip = Some(Rc::new(tooltip));
392        self
393    }
394}
395
396impl private::ToggleButtonStyle for ToggleButtonWithIcon {}
397
398impl ButtonBuilder for ToggleButtonWithIcon {
399    fn into_configuration(self) -> ButtonConfiguration {
400        ButtonConfiguration {
401            label: self.label,
402            icon: Some(self.icon),
403            on_click: self.on_click,
404            selected: self.selected,
405            tooltip: self.tooltip,
406        }
407    }
408}
409
410#[derive(Clone, Copy, PartialEq)]
411pub enum ToggleButtonGroupStyle {
412    Transparent,
413    Filled,
414    Outlined,
415}
416
417#[derive(Clone, Copy, PartialEq)]
418pub enum ToggleButtonGroupSize {
419    Default,
420    Medium,
421}
422
423#[derive(IntoElement)]
424pub struct ToggleButtonGroup<T, const COLS: usize = 3, const ROWS: usize = 1>
425where
426    T: ButtonBuilder,
427{
428    group_name: &'static str,
429    rows: [[T; COLS]; ROWS],
430    style: ToggleButtonGroupStyle,
431    size: ToggleButtonGroupSize,
432    group_width: Option<DefiniteLength>,
433    selected_index: usize,
434    tab_index: Option<isize>,
435}
436
437impl<T: ButtonBuilder, const COLS: usize> ToggleButtonGroup<T, COLS> {
438    pub fn single_row(group_name: &'static str, buttons: [T; COLS]) -> Self {
439        Self {
440            group_name,
441            rows: [buttons],
442            style: ToggleButtonGroupStyle::Transparent,
443            size: ToggleButtonGroupSize::Default,
444            group_width: None,
445            selected_index: 0,
446            tab_index: None,
447        }
448    }
449}
450
451impl<T: ButtonBuilder, const COLS: usize> ToggleButtonGroup<T, COLS, 2> {
452    pub fn two_rows(group_name: &'static str, first_row: [T; COLS], second_row: [T; COLS]) -> Self {
453        Self {
454            group_name,
455            rows: [first_row, second_row],
456            style: ToggleButtonGroupStyle::Transparent,
457            size: ToggleButtonGroupSize::Default,
458            group_width: None,
459            selected_index: 0,
460            tab_index: None,
461        }
462    }
463}
464
465impl<T: ButtonBuilder, const COLS: usize, const ROWS: usize> ToggleButtonGroup<T, COLS, ROWS> {
466    pub fn style(mut self, style: ToggleButtonGroupStyle) -> Self {
467        self.style = style;
468        self
469    }
470
471    pub fn size(mut self, size: ToggleButtonGroupSize) -> Self {
472        self.size = size;
473        self
474    }
475
476    pub fn selected_index(mut self, index: usize) -> Self {
477        self.selected_index = index;
478        self
479    }
480
481    /// Sets the tab index for the toggle button group.
482    /// The tab index is set to the initial value provided, then the
483    /// value is incremented by the number of buttons in the group.
484    pub fn tab_index(mut self, tab_index: &mut isize) -> Self {
485        self.tab_index = Some(*tab_index);
486        *tab_index += (COLS * ROWS) as isize;
487        self
488    }
489
490    const fn button_width() -> DefiniteLength {
491        relative(1. / COLS as f32)
492    }
493}
494
495impl<T: ButtonBuilder, const COLS: usize, const ROWS: usize> FixedWidth
496    for ToggleButtonGroup<T, COLS, ROWS>
497{
498    fn width(mut self, width: impl Into<DefiniteLength>) -> Self {
499        self.group_width = Some(width.into());
500        self
501    }
502
503    fn full_width(mut self) -> Self {
504        self.group_width = Some(relative(1.));
505        self
506    }
507}
508
509impl<T: ButtonBuilder, const COLS: usize, const ROWS: usize> RenderOnce
510    for ToggleButtonGroup<T, COLS, ROWS>
511{
512    fn render(self, _window: &mut Window, cx: &mut App) -> impl IntoElement {
513        let entries =
514            self.rows.into_iter().enumerate().map(|(row_index, row)| {
515                row.into_iter().enumerate().map(move |(col_index, button)| {
516                    let ButtonConfiguration {
517                        label,
518                        icon,
519                        on_click,
520                        selected,
521                        tooltip,
522                    } = button.into_configuration();
523
524                    let entry_index = row_index * COLS + col_index;
525
526                    ButtonLike::new((self.group_name, entry_index))
527                        .full_width()
528                        .rounding(None)
529                        .when_some(self.tab_index, |this, tab_index| {
530                            this.tab_index(tab_index + entry_index as isize)
531                        })
532                        .when(entry_index == self.selected_index || selected, |this| {
533                            this.toggle_state(true)
534                                .selected_style(ButtonStyle::Tinted(TintColor::Accent))
535                        })
536                        .when(self.style == ToggleButtonGroupStyle::Filled, |button| {
537                            button.style(ButtonStyle::Filled)
538                        })
539                        .when(self.size == ToggleButtonGroupSize::Medium, |button| {
540                            button.size(ButtonSize::Medium)
541                        })
542                        .child(
543                            h_flex()
544                                .w_full()
545                                .gap_1p5()
546                                .px_3()
547                                .py_1()
548                                .justify_center()
549                                .when_some(icon, |this, icon| {
550                                    this.py_2()
551                                        .child(Icon::new(icon).size(IconSize::XSmall).map(|this| {
552                                            if entry_index == self.selected_index || selected {
553                                                this.color(Color::Accent)
554                                            } else {
555                                                this.color(Color::Muted)
556                                            }
557                                        }))
558                                })
559                                .child(Label::new(label).size(LabelSize::Small).when(
560                                    entry_index == self.selected_index || selected,
561                                    |this| this.color(Color::Accent),
562                                )),
563                        )
564                        .when_some(tooltip, |this, tooltip| {
565                            this.tooltip(move |window, cx| tooltip(window, cx))
566                        })
567                        .on_click(on_click)
568                        .into_any_element()
569                })
570            });
571
572        let border_color = cx.theme().colors().border.opacity(0.6);
573        let is_outlined_or_filled = self.style == ToggleButtonGroupStyle::Outlined
574            || self.style == ToggleButtonGroupStyle::Filled;
575        let is_transparent = self.style == ToggleButtonGroupStyle::Transparent;
576
577        v_flex()
578            .map(|this| {
579                if let Some(width) = self.group_width {
580                    this.w(width)
581                } else {
582                    this.w_full()
583                }
584            })
585            .rounded_md()
586            .overflow_hidden()
587            .map(|this| {
588                if is_transparent {
589                    this.gap_px()
590                } else {
591                    this.border_1().border_color(border_color)
592                }
593            })
594            .children(entries.enumerate().map(|(row_index, row)| {
595                let last_row = row_index == ROWS - 1;
596                h_flex()
597                    .when(!is_outlined_or_filled, |this| this.gap_px())
598                    .when(is_outlined_or_filled && !last_row, |this| {
599                        this.border_b_1().border_color(border_color)
600                    })
601                    .children(row.enumerate().map(|(item_index, item)| {
602                        let last_item = item_index == COLS - 1;
603                        div()
604                            .when(is_outlined_or_filled && !last_item, |this| {
605                                this.border_r_1().border_color(border_color)
606                            })
607                            .w(Self::button_width())
608                            .overflow_hidden()
609                            .child(item)
610                    }))
611            }))
612    }
613}
614
615fn register_toggle_button_group() {
616    component::register_component::<ToggleButtonGroup<ToggleButtonSimple>>();
617}
618
619component::__private::inventory::submit! {
620    component::ComponentFn::new(register_toggle_button_group)
621}
622
623impl<T: ButtonBuilder, const COLS: usize, const ROWS: usize> Component
624    for ToggleButtonGroup<T, COLS, ROWS>
625{
626    fn name() -> &'static str {
627        "ToggleButtonGroup"
628    }
629
630    fn scope() -> ComponentScope {
631        ComponentScope::Input
632    }
633
634    fn sort_name() -> &'static str {
635        "ButtonG"
636    }
637
638    fn preview(_window: &mut Window, _cx: &mut App) -> Option<AnyElement> {
639        Some(
640            v_flex()
641                .gap_6()
642                .children(vec![example_group_with_title(
643                    "Transparent Variant",
644                    vec![
645                        single_example(
646                            "Single Row Group",
647                            ToggleButtonGroup::single_row(
648                                "single_row_test",
649                                [
650                                    ToggleButtonSimple::new("First", |_, _, _| {}),
651                                    ToggleButtonSimple::new("Second", |_, _, _| {}),
652                                    ToggleButtonSimple::new("Third", |_, _, _| {}),
653                                ],
654                            )
655                            .selected_index(1)
656                            .into_any_element(),
657                        ),
658                        single_example(
659                            "Single Row Group with icons",
660                            ToggleButtonGroup::single_row(
661                                "single_row_test_icon",
662                                [
663                                    ToggleButtonWithIcon::new(
664                                        "First",
665                                        IconName::AiZed,
666                                        |_, _, _| {},
667                                    ),
668                                    ToggleButtonWithIcon::new(
669                                        "Second",
670                                        IconName::AiZed,
671                                        |_, _, _| {},
672                                    ),
673                                    ToggleButtonWithIcon::new(
674                                        "Third",
675                                        IconName::AiZed,
676                                        |_, _, _| {},
677                                    ),
678                                ],
679                            )
680                            .selected_index(1)
681                            .into_any_element(),
682                        ),
683                        single_example(
684                            "Multiple Row Group",
685                            ToggleButtonGroup::two_rows(
686                                "multiple_row_test",
687                                [
688                                    ToggleButtonSimple::new("First", |_, _, _| {}),
689                                    ToggleButtonSimple::new("Second", |_, _, _| {}),
690                                    ToggleButtonSimple::new("Third", |_, _, _| {}),
691                                ],
692                                [
693                                    ToggleButtonSimple::new("Fourth", |_, _, _| {}),
694                                    ToggleButtonSimple::new("Fifth", |_, _, _| {}),
695                                    ToggleButtonSimple::new("Sixth", |_, _, _| {}),
696                                ],
697                            )
698                            .selected_index(3)
699                            .into_any_element(),
700                        ),
701                        single_example(
702                            "Multiple Row Group with Icons",
703                            ToggleButtonGroup::two_rows(
704                                "multiple_row_test_icons",
705                                [
706                                    ToggleButtonWithIcon::new(
707                                        "First",
708                                        IconName::AiZed,
709                                        |_, _, _| {},
710                                    ),
711                                    ToggleButtonWithIcon::new(
712                                        "Second",
713                                        IconName::AiZed,
714                                        |_, _, _| {},
715                                    ),
716                                    ToggleButtonWithIcon::new(
717                                        "Third",
718                                        IconName::AiZed,
719                                        |_, _, _| {},
720                                    ),
721                                ],
722                                [
723                                    ToggleButtonWithIcon::new(
724                                        "Fourth",
725                                        IconName::AiZed,
726                                        |_, _, _| {},
727                                    ),
728                                    ToggleButtonWithIcon::new(
729                                        "Fifth",
730                                        IconName::AiZed,
731                                        |_, _, _| {},
732                                    ),
733                                    ToggleButtonWithIcon::new(
734                                        "Sixth",
735                                        IconName::AiZed,
736                                        |_, _, _| {},
737                                    ),
738                                ],
739                            )
740                            .selected_index(3)
741                            .into_any_element(),
742                        ),
743                    ],
744                )])
745                .children(vec![example_group_with_title(
746                    "Outlined Variant",
747                    vec![
748                        single_example(
749                            "Single Row Group",
750                            ToggleButtonGroup::single_row(
751                                "single_row_test_outline",
752                                [
753                                    ToggleButtonSimple::new("First", |_, _, _| {}),
754                                    ToggleButtonSimple::new("Second", |_, _, _| {}),
755                                    ToggleButtonSimple::new("Third", |_, _, _| {}),
756                                ],
757                            )
758                            .selected_index(1)
759                            .style(ToggleButtonGroupStyle::Outlined)
760                            .into_any_element(),
761                        ),
762                        single_example(
763                            "Single Row Group with icons",
764                            ToggleButtonGroup::single_row(
765                                "single_row_test_icon_outlined",
766                                [
767                                    ToggleButtonWithIcon::new(
768                                        "First",
769                                        IconName::AiZed,
770                                        |_, _, _| {},
771                                    ),
772                                    ToggleButtonWithIcon::new(
773                                        "Second",
774                                        IconName::AiZed,
775                                        |_, _, _| {},
776                                    ),
777                                    ToggleButtonWithIcon::new(
778                                        "Third",
779                                        IconName::AiZed,
780                                        |_, _, _| {},
781                                    ),
782                                ],
783                            )
784                            .selected_index(1)
785                            .style(ToggleButtonGroupStyle::Outlined)
786                            .into_any_element(),
787                        ),
788                        single_example(
789                            "Multiple Row Group",
790                            ToggleButtonGroup::two_rows(
791                                "multiple_row_test",
792                                [
793                                    ToggleButtonSimple::new("First", |_, _, _| {}),
794                                    ToggleButtonSimple::new("Second", |_, _, _| {}),
795                                    ToggleButtonSimple::new("Third", |_, _, _| {}),
796                                ],
797                                [
798                                    ToggleButtonSimple::new("Fourth", |_, _, _| {}),
799                                    ToggleButtonSimple::new("Fifth", |_, _, _| {}),
800                                    ToggleButtonSimple::new("Sixth", |_, _, _| {}),
801                                ],
802                            )
803                            .selected_index(3)
804                            .style(ToggleButtonGroupStyle::Outlined)
805                            .into_any_element(),
806                        ),
807                        single_example(
808                            "Multiple Row Group with Icons",
809                            ToggleButtonGroup::two_rows(
810                                "multiple_row_test",
811                                [
812                                    ToggleButtonWithIcon::new(
813                                        "First",
814                                        IconName::AiZed,
815                                        |_, _, _| {},
816                                    ),
817                                    ToggleButtonWithIcon::new(
818                                        "Second",
819                                        IconName::AiZed,
820                                        |_, _, _| {},
821                                    ),
822                                    ToggleButtonWithIcon::new(
823                                        "Third",
824                                        IconName::AiZed,
825                                        |_, _, _| {},
826                                    ),
827                                ],
828                                [
829                                    ToggleButtonWithIcon::new(
830                                        "Fourth",
831                                        IconName::AiZed,
832                                        |_, _, _| {},
833                                    ),
834                                    ToggleButtonWithIcon::new(
835                                        "Fifth",
836                                        IconName::AiZed,
837                                        |_, _, _| {},
838                                    ),
839                                    ToggleButtonWithIcon::new(
840                                        "Sixth",
841                                        IconName::AiZed,
842                                        |_, _, _| {},
843                                    ),
844                                ],
845                            )
846                            .selected_index(3)
847                            .style(ToggleButtonGroupStyle::Outlined)
848                            .into_any_element(),
849                        ),
850                    ],
851                )])
852                .children(vec![example_group_with_title(
853                    "Filled Variant",
854                    vec![
855                        single_example(
856                            "Single Row Group",
857                            ToggleButtonGroup::single_row(
858                                "single_row_test_outline",
859                                [
860                                    ToggleButtonSimple::new("First", |_, _, _| {}),
861                                    ToggleButtonSimple::new("Second", |_, _, _| {}),
862                                    ToggleButtonSimple::new("Third", |_, _, _| {}),
863                                ],
864                            )
865                            .selected_index(2)
866                            .style(ToggleButtonGroupStyle::Filled)
867                            .into_any_element(),
868                        ),
869                        single_example(
870                            "Single Row Group with icons",
871                            ToggleButtonGroup::single_row(
872                                "single_row_test_icon_outlined",
873                                [
874                                    ToggleButtonWithIcon::new(
875                                        "First",
876                                        IconName::AiZed,
877                                        |_, _, _| {},
878                                    ),
879                                    ToggleButtonWithIcon::new(
880                                        "Second",
881                                        IconName::AiZed,
882                                        |_, _, _| {},
883                                    ),
884                                    ToggleButtonWithIcon::new(
885                                        "Third",
886                                        IconName::AiZed,
887                                        |_, _, _| {},
888                                    ),
889                                ],
890                            )
891                            .selected_index(1)
892                            .style(ToggleButtonGroupStyle::Filled)
893                            .into_any_element(),
894                        ),
895                        single_example(
896                            "Multiple Row Group",
897                            ToggleButtonGroup::two_rows(
898                                "multiple_row_test",
899                                [
900                                    ToggleButtonSimple::new("First", |_, _, _| {}),
901                                    ToggleButtonSimple::new("Second", |_, _, _| {}),
902                                    ToggleButtonSimple::new("Third", |_, _, _| {}),
903                                ],
904                                [
905                                    ToggleButtonSimple::new("Fourth", |_, _, _| {}),
906                                    ToggleButtonSimple::new("Fifth", |_, _, _| {}),
907                                    ToggleButtonSimple::new("Sixth", |_, _, _| {}),
908                                ],
909                            )
910                            .selected_index(3)
911                            .width(rems_from_px(100.))
912                            .style(ToggleButtonGroupStyle::Filled)
913                            .into_any_element(),
914                        ),
915                        single_example(
916                            "Multiple Row Group with Icons",
917                            ToggleButtonGroup::two_rows(
918                                "multiple_row_test",
919                                [
920                                    ToggleButtonWithIcon::new(
921                                        "First",
922                                        IconName::AiZed,
923                                        |_, _, _| {},
924                                    ),
925                                    ToggleButtonWithIcon::new(
926                                        "Second",
927                                        IconName::AiZed,
928                                        |_, _, _| {},
929                                    ),
930                                    ToggleButtonWithIcon::new(
931                                        "Third",
932                                        IconName::AiZed,
933                                        |_, _, _| {},
934                                    ),
935                                ],
936                                [
937                                    ToggleButtonWithIcon::new(
938                                        "Fourth",
939                                        IconName::AiZed,
940                                        |_, _, _| {},
941                                    ),
942                                    ToggleButtonWithIcon::new(
943                                        "Fifth",
944                                        IconName::AiZed,
945                                        |_, _, _| {},
946                                    ),
947                                    ToggleButtonWithIcon::new(
948                                        "Sixth",
949                                        IconName::AiZed,
950                                        |_, _, _| {},
951                                    ),
952                                ],
953                            )
954                            .selected_index(3)
955                            .width(rems_from_px(100.))
956                            .style(ToggleButtonGroupStyle::Filled)
957                            .into_any_element(),
958                        ),
959                    ],
960                )])
961                .children(vec![single_example(
962                    "With Tooltips",
963                    ToggleButtonGroup::single_row(
964                        "with_tooltips",
965                        [
966                            ToggleButtonSimple::new("First", |_, _, _| {})
967                                .tooltip(Tooltip::text("This is a tooltip. Hello!")),
968                            ToggleButtonSimple::new("Second", |_, _, _| {})
969                                .tooltip(Tooltip::text("This is a tooltip. Hey?")),
970                            ToggleButtonSimple::new("Third", |_, _, _| {})
971                                .tooltip(Tooltip::text("This is a tooltip. Get out of here now!")),
972                        ],
973                    )
974                    .selected_index(1)
975                    .into_any_element(),
976                )])
977                .into_any_element(),
978        )
979    }
980}