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