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