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