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: SharedString,
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: impl Into<SharedString>, buttons: [T; COLS]) -> Self {
439        Self {
440            group_name: group_name.into(),
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(
453        group_name: impl Into<SharedString>,
454        first_row: [T; COLS],
455        second_row: [T; COLS],
456    ) -> Self {
457        Self {
458            group_name: group_name.into(),
459            rows: [first_row, second_row],
460            style: ToggleButtonGroupStyle::Transparent,
461            size: ToggleButtonGroupSize::Default,
462            group_width: None,
463            selected_index: 0,
464            tab_index: None,
465        }
466    }
467}
468
469impl<T: ButtonBuilder, const COLS: usize, const ROWS: usize> ToggleButtonGroup<T, COLS, ROWS> {
470    pub fn style(mut self, style: ToggleButtonGroupStyle) -> Self {
471        self.style = style;
472        self
473    }
474
475    pub fn size(mut self, size: ToggleButtonGroupSize) -> Self {
476        self.size = size;
477        self
478    }
479
480    pub fn selected_index(mut self, index: usize) -> Self {
481        self.selected_index = index;
482        self
483    }
484
485    /// Sets the tab index for the toggle button group.
486    /// The tab index is set to the initial value provided, then the
487    /// value is incremented by the number of buttons in the group.
488    pub fn tab_index(mut self, tab_index: &mut isize) -> Self {
489        self.tab_index = Some(*tab_index);
490        *tab_index += (COLS * ROWS) as isize;
491        self
492    }
493
494    const fn button_width() -> DefiniteLength {
495        relative(1. / COLS as f32)
496    }
497}
498
499impl<T: ButtonBuilder, const COLS: usize, const ROWS: usize> FixedWidth
500    for ToggleButtonGroup<T, COLS, ROWS>
501{
502    fn width(mut self, width: impl Into<DefiniteLength>) -> Self {
503        self.group_width = Some(width.into());
504        self
505    }
506
507    fn full_width(mut self) -> Self {
508        self.group_width = Some(relative(1.));
509        self
510    }
511}
512
513impl<T: ButtonBuilder, const COLS: usize, const ROWS: usize> RenderOnce
514    for ToggleButtonGroup<T, COLS, ROWS>
515{
516    fn render(self, _window: &mut Window, cx: &mut App) -> impl IntoElement {
517        let entries =
518            self.rows.into_iter().enumerate().map(|(row_index, row)| {
519                let group_name = self.group_name.clone();
520                row.into_iter().enumerate().map(move |(col_index, button)| {
521                    let ButtonConfiguration {
522                        label,
523                        icon,
524                        on_click,
525                        selected,
526                        tooltip,
527                    } = button.into_configuration();
528
529                    let entry_index = row_index * COLS + col_index;
530
531                    ButtonLike::new((group_name.clone(), entry_index))
532                        .full_width()
533                        .rounding(None)
534                        .when_some(self.tab_index, |this, tab_index| {
535                            this.tab_index(tab_index + entry_index as isize)
536                        })
537                        .when(entry_index == self.selected_index || selected, |this| {
538                            this.toggle_state(true)
539                                .selected_style(ButtonStyle::Tinted(TintColor::Accent))
540                        })
541                        .when(self.style == ToggleButtonGroupStyle::Filled, |button| {
542                            button.style(ButtonStyle::Filled)
543                        })
544                        .when(self.size == ToggleButtonGroupSize::Medium, |button| {
545                            button.size(ButtonSize::Medium)
546                        })
547                        .child(
548                            h_flex()
549                                .w_full()
550                                .gap_1p5()
551                                .px_3()
552                                .py_1()
553                                .justify_center()
554                                .when_some(icon, |this, icon| {
555                                    this.py_2()
556                                        .child(Icon::new(icon).size(IconSize::XSmall).map(|this| {
557                                            if entry_index == self.selected_index || selected {
558                                                this.color(Color::Accent)
559                                            } else {
560                                                this.color(Color::Muted)
561                                            }
562                                        }))
563                                })
564                                .child(Label::new(label).size(LabelSize::Small).when(
565                                    entry_index == self.selected_index || selected,
566                                    |this| this.color(Color::Accent),
567                                )),
568                        )
569                        .when_some(tooltip, |this, tooltip| {
570                            this.tooltip(move |window, cx| tooltip(window, cx))
571                        })
572                        .on_click(on_click)
573                        .into_any_element()
574                })
575            });
576
577        let border_color = cx.theme().colors().border.opacity(0.6);
578        let is_outlined_or_filled = self.style == ToggleButtonGroupStyle::Outlined
579            || self.style == ToggleButtonGroupStyle::Filled;
580        let is_transparent = self.style == ToggleButtonGroupStyle::Transparent;
581
582        v_flex()
583            .map(|this| {
584                if let Some(width) = self.group_width {
585                    this.w(width)
586                } else {
587                    this.w_full()
588                }
589            })
590            .rounded_md()
591            .overflow_hidden()
592            .map(|this| {
593                if is_transparent {
594                    this.gap_px()
595                } else {
596                    this.border_1().border_color(border_color)
597                }
598            })
599            .children(entries.enumerate().map(|(row_index, row)| {
600                let last_row = row_index == ROWS - 1;
601                h_flex()
602                    .when(!is_outlined_or_filled, |this| this.gap_px())
603                    .when(is_outlined_or_filled && !last_row, |this| {
604                        this.border_b_1().border_color(border_color)
605                    })
606                    .children(row.enumerate().map(|(item_index, item)| {
607                        let last_item = item_index == COLS - 1;
608                        div()
609                            .when(is_outlined_or_filled && !last_item, |this| {
610                                this.border_r_1().border_color(border_color)
611                            })
612                            .w(Self::button_width())
613                            .overflow_hidden()
614                            .child(item)
615                    }))
616            }))
617    }
618}
619
620fn register_toggle_button_group() {
621    component::register_component::<ToggleButtonGroup<ToggleButtonSimple>>();
622}
623
624component::__private::inventory::submit! {
625    component::ComponentFn::new(register_toggle_button_group)
626}
627
628impl<T: ButtonBuilder, const COLS: usize, const ROWS: usize> Component
629    for ToggleButtonGroup<T, COLS, ROWS>
630{
631    fn name() -> &'static str {
632        "ToggleButtonGroup"
633    }
634
635    fn scope() -> ComponentScope {
636        ComponentScope::Input
637    }
638
639    fn sort_name() -> &'static str {
640        "ButtonG"
641    }
642
643    fn preview(_window: &mut Window, _cx: &mut App) -> Option<AnyElement> {
644        Some(
645            v_flex()
646                .gap_6()
647                .children(vec![example_group_with_title(
648                    "Transparent Variant",
649                    vec![
650                        single_example(
651                            "Single Row Group",
652                            ToggleButtonGroup::single_row(
653                                "single_row_test",
654                                [
655                                    ToggleButtonSimple::new("First", |_, _, _| {}),
656                                    ToggleButtonSimple::new("Second", |_, _, _| {}),
657                                    ToggleButtonSimple::new("Third", |_, _, _| {}),
658                                ],
659                            )
660                            .selected_index(1)
661                            .into_any_element(),
662                        ),
663                        single_example(
664                            "Single Row Group with icons",
665                            ToggleButtonGroup::single_row(
666                                "single_row_test_icon",
667                                [
668                                    ToggleButtonWithIcon::new(
669                                        "First",
670                                        IconName::AiZed,
671                                        |_, _, _| {},
672                                    ),
673                                    ToggleButtonWithIcon::new(
674                                        "Second",
675                                        IconName::AiZed,
676                                        |_, _, _| {},
677                                    ),
678                                    ToggleButtonWithIcon::new(
679                                        "Third",
680                                        IconName::AiZed,
681                                        |_, _, _| {},
682                                    ),
683                                ],
684                            )
685                            .selected_index(1)
686                            .into_any_element(),
687                        ),
688                        single_example(
689                            "Multiple Row Group",
690                            ToggleButtonGroup::two_rows(
691                                "multiple_row_test",
692                                [
693                                    ToggleButtonSimple::new("First", |_, _, _| {}),
694                                    ToggleButtonSimple::new("Second", |_, _, _| {}),
695                                    ToggleButtonSimple::new("Third", |_, _, _| {}),
696                                ],
697                                [
698                                    ToggleButtonSimple::new("Fourth", |_, _, _| {}),
699                                    ToggleButtonSimple::new("Fifth", |_, _, _| {}),
700                                    ToggleButtonSimple::new("Sixth", |_, _, _| {}),
701                                ],
702                            )
703                            .selected_index(3)
704                            .into_any_element(),
705                        ),
706                        single_example(
707                            "Multiple Row Group with Icons",
708                            ToggleButtonGroup::two_rows(
709                                "multiple_row_test_icons",
710                                [
711                                    ToggleButtonWithIcon::new(
712                                        "First",
713                                        IconName::AiZed,
714                                        |_, _, _| {},
715                                    ),
716                                    ToggleButtonWithIcon::new(
717                                        "Second",
718                                        IconName::AiZed,
719                                        |_, _, _| {},
720                                    ),
721                                    ToggleButtonWithIcon::new(
722                                        "Third",
723                                        IconName::AiZed,
724                                        |_, _, _| {},
725                                    ),
726                                ],
727                                [
728                                    ToggleButtonWithIcon::new(
729                                        "Fourth",
730                                        IconName::AiZed,
731                                        |_, _, _| {},
732                                    ),
733                                    ToggleButtonWithIcon::new(
734                                        "Fifth",
735                                        IconName::AiZed,
736                                        |_, _, _| {},
737                                    ),
738                                    ToggleButtonWithIcon::new(
739                                        "Sixth",
740                                        IconName::AiZed,
741                                        |_, _, _| {},
742                                    ),
743                                ],
744                            )
745                            .selected_index(3)
746                            .into_any_element(),
747                        ),
748                    ],
749                )])
750                .children(vec![example_group_with_title(
751                    "Outlined Variant",
752                    vec![
753                        single_example(
754                            "Single Row Group",
755                            ToggleButtonGroup::single_row(
756                                "single_row_test_outline",
757                                [
758                                    ToggleButtonSimple::new("First", |_, _, _| {}),
759                                    ToggleButtonSimple::new("Second", |_, _, _| {}),
760                                    ToggleButtonSimple::new("Third", |_, _, _| {}),
761                                ],
762                            )
763                            .selected_index(1)
764                            .style(ToggleButtonGroupStyle::Outlined)
765                            .into_any_element(),
766                        ),
767                        single_example(
768                            "Single Row Group with icons",
769                            ToggleButtonGroup::single_row(
770                                "single_row_test_icon_outlined",
771                                [
772                                    ToggleButtonWithIcon::new(
773                                        "First",
774                                        IconName::AiZed,
775                                        |_, _, _| {},
776                                    ),
777                                    ToggleButtonWithIcon::new(
778                                        "Second",
779                                        IconName::AiZed,
780                                        |_, _, _| {},
781                                    ),
782                                    ToggleButtonWithIcon::new(
783                                        "Third",
784                                        IconName::AiZed,
785                                        |_, _, _| {},
786                                    ),
787                                ],
788                            )
789                            .selected_index(1)
790                            .style(ToggleButtonGroupStyle::Outlined)
791                            .into_any_element(),
792                        ),
793                        single_example(
794                            "Multiple Row Group",
795                            ToggleButtonGroup::two_rows(
796                                "multiple_row_test",
797                                [
798                                    ToggleButtonSimple::new("First", |_, _, _| {}),
799                                    ToggleButtonSimple::new("Second", |_, _, _| {}),
800                                    ToggleButtonSimple::new("Third", |_, _, _| {}),
801                                ],
802                                [
803                                    ToggleButtonSimple::new("Fourth", |_, _, _| {}),
804                                    ToggleButtonSimple::new("Fifth", |_, _, _| {}),
805                                    ToggleButtonSimple::new("Sixth", |_, _, _| {}),
806                                ],
807                            )
808                            .selected_index(3)
809                            .style(ToggleButtonGroupStyle::Outlined)
810                            .into_any_element(),
811                        ),
812                        single_example(
813                            "Multiple Row Group with Icons",
814                            ToggleButtonGroup::two_rows(
815                                "multiple_row_test",
816                                [
817                                    ToggleButtonWithIcon::new(
818                                        "First",
819                                        IconName::AiZed,
820                                        |_, _, _| {},
821                                    ),
822                                    ToggleButtonWithIcon::new(
823                                        "Second",
824                                        IconName::AiZed,
825                                        |_, _, _| {},
826                                    ),
827                                    ToggleButtonWithIcon::new(
828                                        "Third",
829                                        IconName::AiZed,
830                                        |_, _, _| {},
831                                    ),
832                                ],
833                                [
834                                    ToggleButtonWithIcon::new(
835                                        "Fourth",
836                                        IconName::AiZed,
837                                        |_, _, _| {},
838                                    ),
839                                    ToggleButtonWithIcon::new(
840                                        "Fifth",
841                                        IconName::AiZed,
842                                        |_, _, _| {},
843                                    ),
844                                    ToggleButtonWithIcon::new(
845                                        "Sixth",
846                                        IconName::AiZed,
847                                        |_, _, _| {},
848                                    ),
849                                ],
850                            )
851                            .selected_index(3)
852                            .style(ToggleButtonGroupStyle::Outlined)
853                            .into_any_element(),
854                        ),
855                    ],
856                )])
857                .children(vec![example_group_with_title(
858                    "Filled Variant",
859                    vec![
860                        single_example(
861                            "Single Row Group",
862                            ToggleButtonGroup::single_row(
863                                "single_row_test_outline",
864                                [
865                                    ToggleButtonSimple::new("First", |_, _, _| {}),
866                                    ToggleButtonSimple::new("Second", |_, _, _| {}),
867                                    ToggleButtonSimple::new("Third", |_, _, _| {}),
868                                ],
869                            )
870                            .selected_index(2)
871                            .style(ToggleButtonGroupStyle::Filled)
872                            .into_any_element(),
873                        ),
874                        single_example(
875                            "Single Row Group with icons",
876                            ToggleButtonGroup::single_row(
877                                "single_row_test_icon_outlined",
878                                [
879                                    ToggleButtonWithIcon::new(
880                                        "First",
881                                        IconName::AiZed,
882                                        |_, _, _| {},
883                                    ),
884                                    ToggleButtonWithIcon::new(
885                                        "Second",
886                                        IconName::AiZed,
887                                        |_, _, _| {},
888                                    ),
889                                    ToggleButtonWithIcon::new(
890                                        "Third",
891                                        IconName::AiZed,
892                                        |_, _, _| {},
893                                    ),
894                                ],
895                            )
896                            .selected_index(1)
897                            .style(ToggleButtonGroupStyle::Filled)
898                            .into_any_element(),
899                        ),
900                        single_example(
901                            "Multiple Row Group",
902                            ToggleButtonGroup::two_rows(
903                                "multiple_row_test",
904                                [
905                                    ToggleButtonSimple::new("First", |_, _, _| {}),
906                                    ToggleButtonSimple::new("Second", |_, _, _| {}),
907                                    ToggleButtonSimple::new("Third", |_, _, _| {}),
908                                ],
909                                [
910                                    ToggleButtonSimple::new("Fourth", |_, _, _| {}),
911                                    ToggleButtonSimple::new("Fifth", |_, _, _| {}),
912                                    ToggleButtonSimple::new("Sixth", |_, _, _| {}),
913                                ],
914                            )
915                            .selected_index(3)
916                            .width(rems_from_px(100.))
917                            .style(ToggleButtonGroupStyle::Filled)
918                            .into_any_element(),
919                        ),
920                        single_example(
921                            "Multiple Row Group with Icons",
922                            ToggleButtonGroup::two_rows(
923                                "multiple_row_test",
924                                [
925                                    ToggleButtonWithIcon::new(
926                                        "First",
927                                        IconName::AiZed,
928                                        |_, _, _| {},
929                                    ),
930                                    ToggleButtonWithIcon::new(
931                                        "Second",
932                                        IconName::AiZed,
933                                        |_, _, _| {},
934                                    ),
935                                    ToggleButtonWithIcon::new(
936                                        "Third",
937                                        IconName::AiZed,
938                                        |_, _, _| {},
939                                    ),
940                                ],
941                                [
942                                    ToggleButtonWithIcon::new(
943                                        "Fourth",
944                                        IconName::AiZed,
945                                        |_, _, _| {},
946                                    ),
947                                    ToggleButtonWithIcon::new(
948                                        "Fifth",
949                                        IconName::AiZed,
950                                        |_, _, _| {},
951                                    ),
952                                    ToggleButtonWithIcon::new(
953                                        "Sixth",
954                                        IconName::AiZed,
955                                        |_, _, _| {},
956                                    ),
957                                ],
958                            )
959                            .selected_index(3)
960                            .width(rems_from_px(100.))
961                            .style(ToggleButtonGroupStyle::Filled)
962                            .into_any_element(),
963                        ),
964                    ],
965                )])
966                .children(vec![single_example(
967                    "With Tooltips",
968                    ToggleButtonGroup::single_row(
969                        "with_tooltips",
970                        [
971                            ToggleButtonSimple::new("First", |_, _, _| {})
972                                .tooltip(Tooltip::text("This is a tooltip. Hello!")),
973                            ToggleButtonSimple::new("Second", |_, _, _| {})
974                                .tooltip(Tooltip::text("This is a tooltip. Hey?")),
975                            ToggleButtonSimple::new("Third", |_, _, _| {})
976                                .tooltip(Tooltip::text("This is a tooltip. Get out of here now!")),
977                        ],
978                    )
979                    .selected_index(1)
980                    .into_any_element(),
981                )])
982                .into_any_element(),
983        )
984    }
985}