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