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