1#![allow(non_snake_case)]
2
3use std::rc::Rc;
4use std::sync::atomic::Ordering;
5
6use repose_core::*;
7use repose_ui::{Box, FlowRow, Row, ViewExt, anim::animate_color};
8
9use super::util::FILTERCHIP_COUNTER;
10use super::*;
11
12#[derive(Clone, Copy, Debug)]
14pub struct ChipColors {
15 pub container_color: Color,
16 pub label_color: Color,
17 pub leading_icon_color: Color,
18 pub trailing_icon_color: Color,
19 pub disabled_container_color: Color,
20 pub disabled_label_color: Color,
21 pub disabled_leading_icon_color: Color,
22 pub disabled_trailing_icon_color: Color,
23 pub selected_container_color: Color,
24 pub selected_label_color: Color,
25 pub selected_leading_icon_color: Color,
26 pub selected_trailing_icon_color: Color,
27 pub disabled_selected_container_color: Color,
28}
29
30impl ChipColors {
31 pub fn container(&self, enabled: bool, selected: bool) -> Color {
32 match (enabled, selected) {
33 (true, true) => self.selected_container_color,
34 (true, false) => self.container_color,
35 (false, true) => self.disabled_selected_container_color,
36 (false, false) => self.disabled_container_color,
37 }
38 }
39 pub fn label(&self, enabled: bool, selected: bool) -> Color {
40 if !enabled {
41 self.disabled_label_color
42 } else if selected {
43 self.selected_label_color
44 } else {
45 self.label_color
46 }
47 }
48 pub fn leading_icon(&self, enabled: bool, selected: bool) -> Color {
49 if !enabled {
50 self.disabled_leading_icon_color
51 } else if selected {
52 self.selected_leading_icon_color
53 } else {
54 self.leading_icon_color
55 }
56 }
57 pub fn trailing_icon(&self, enabled: bool, selected: bool) -> Color {
58 if !enabled {
59 self.disabled_trailing_icon_color
60 } else if selected {
61 self.selected_trailing_icon_color
62 } else {
63 self.trailing_icon_color
64 }
65 }
66}
67
68#[derive(Clone, Copy, Debug)]
70pub struct ChipElevation {
71 pub default: f32,
72 pub hovered: f32,
73 pub focused: f32,
74 pub pressed: f32,
75 pub dragged: f32,
76 pub disabled: f32,
77}
78
79impl ChipElevation {
80 pub fn to_state_elevation(&self) -> StateElevation {
81 StateElevation {
82 default: self.default,
83 hovered: self.hovered,
84 focused: self.focused,
85 pressed: self.pressed,
86 dragged: self.dragged,
87 disabled: self.disabled,
88 }
89 }
90}
91
92impl Default for ChipElevation {
93 fn default() -> Self {
94 Self {
95 default: ChipDefaults::elevation_default(),
96 hovered: ChipDefaults::elevation_hovered(),
97 focused: ChipDefaults::elevation_focused(),
98 pressed: ChipDefaults::elevation_pressed(),
99 dragged: ChipDefaults::elevation_dragged(),
100 disabled: ChipDefaults::elevation_disabled(),
101 }
102 }
103}
104
105#[derive(Clone, Debug)]
107pub struct ChipConfig {
108 pub modifier: Modifier,
109 pub enabled: bool,
110 pub colors: ChipColors,
111 pub elevation: ChipElevation,
112 pub border_width: f32,
113 pub border_color: Color,
114 pub selected_border_color: Color,
115 pub disabled_border_color: Color,
116 pub disabled_selected_border_color: Color,
117 pub shape_radius: f32,
118 pub horizontal_padding: f32,
119 pub interaction_source: Option<MutableInteractionSource>,
120}
121
122impl Default for ChipConfig {
123 fn default() -> Self {
124 Self {
125 modifier: Modifier::new(),
126 enabled: true,
127 colors: ChipColors {
128 container_color: ChipDefaults::container_color(),
129 label_color: ChipDefaults::label_color(),
130 leading_icon_color: ChipDefaults::leading_icon_color(),
131 trailing_icon_color: ChipDefaults::trailing_icon_color(),
132 disabled_container_color: ChipDefaults::disabled_container_color(),
133 disabled_label_color: ChipDefaults::disabled_label_color(),
134 disabled_leading_icon_color: ChipDefaults::disabled_leading_icon_color(),
135 disabled_trailing_icon_color: ChipDefaults::disabled_trailing_icon_color(),
136 selected_container_color: ChipDefaults::selected_container_color(),
137 selected_label_color: ChipDefaults::selected_label_color(),
138 selected_leading_icon_color: ChipDefaults::selected_leading_icon_color(),
139 selected_trailing_icon_color: ChipDefaults::selected_trailing_icon_color(),
140 disabled_selected_container_color: ChipDefaults::disabled_selected_container_color(
141 ),
142 },
143 elevation: ChipElevation::default(),
144 border_width: ChipDefaults::BORDER_WIDTH,
145 border_color: ChipDefaults::border_color(),
146 selected_border_color: ChipDefaults::selected_border_color(),
147 disabled_border_color: ChipDefaults::disabled_border_color(),
148 disabled_selected_border_color: ChipDefaults::disabled_selected_border_color(),
149 shape_radius: ChipDefaults::SHAPE_RADIUS,
150 horizontal_padding: ChipDefaults::HORIZONTAL_PADDING,
151 interaction_source: None,
152 }
153 }
154}
155
156pub fn AssistChip(
158 on_click: impl Fn() + 'static,
159 label: View,
160 leading_icon: Option<View>,
161 trailing_icon: Option<View>,
162 config: ChipConfig,
163) -> View {
164 let th = theme();
165 let is_enabled = config.enabled;
166 let colors = &config.colors;
167 let bg = colors.container(is_enabled, false);
168 let label_color = colors.label(is_enabled, false);
169 let leading_color = colors.leading_icon(is_enabled, false);
170 let trailing_color = colors.trailing_icon(is_enabled, false);
171 let border = if is_enabled {
172 config.border_color
173 } else {
174 config.disabled_border_color
175 };
176 let shape = config.shape_radius;
177 let ch_source: Rc<MutableInteractionSource> = config
178 .interaction_source
179 .clone()
180 .map(Rc::new)
181 .unwrap_or_else(|| remember(MutableInteractionSource::new));
182
183 let mut m = Modifier::new()
184 .flex_shrink(0.0)
185 .state_colors(StateColors {
186 default: Color::TRANSPARENT,
187 hovered: Color::TRANSPARENT,
188 focused: Color::TRANSPARENT,
189 pressed: Color::TRANSPARENT,
190 dragged: th.on_surface.with_alpha_f32(0.12),
191 disabled: Color::TRANSPARENT,
192 })
193 .padding_values(PaddingValues {
194 left: config.horizontal_padding,
195 right: config.horizontal_padding,
196 top: 8.0,
197 bottom: 8.0,
198 })
199 .background(bg)
200 .clip_rounded(shape)
201 .interaction_source(&ch_source)
202 .indication(crate::ripple::ripple(crate::ripple::RippleConfig {
203 color: Some(label_color),
204 bounded: true,
205 ..Default::default()
206 }))
207 .then(config.modifier);
208
209 if config.border_width > 0.0 && border != Color::TRANSPARENT {
210 m = m.border(config.border_width, border, shape);
211 }
212
213 if is_enabled {
214 m = m.clickable().on_click(on_click);
215 }
216
217 Box(m).child(
218 Row(Modifier::new().align_items(AlignItems::CENTER)).child((
219 leading_icon
220 .map(|v| {
221 Box(Modifier::new().padding_values(PaddingValues {
222 left: 0.0,
223 right: 8.0,
224 top: 0.0,
225 bottom: 0.0,
226 }))
227 .child(with_content_color(leading_color, move || v))
228 })
229 .unwrap_or(Box(Modifier::new())),
230 with_content_color(label_color, move || label),
231 trailing_icon
232 .map(|v| {
233 Box(Modifier::new().padding_values(PaddingValues {
234 left: 8.0,
235 right: 0.0,
236 top: 0.0,
237 bottom: 0.0,
238 }))
239 .child(with_content_color(trailing_color, move || v))
240 })
241 .unwrap_or(Box(Modifier::new())),
242 )),
243 )
244}
245
246pub fn ElevatedAssistChip(
248 on_click: impl Fn() + 'static,
249 label: View,
250 leading_icon: Option<View>,
251 trailing_icon: Option<View>,
252 config: ChipConfig,
253) -> View {
254 let th = theme();
255 let is_enabled = config.enabled;
256 let colors = &config.colors;
257 let bg = colors.container(is_enabled, false);
258 let label_color = colors.label(is_enabled, false);
259 let leading_color = colors.leading_icon(is_enabled, false);
260 let trailing_color = colors.trailing_icon(is_enabled, false);
261 let shape = config.shape_radius;
262 let ch_source: Rc<MutableInteractionSource> = config
263 .interaction_source
264 .clone()
265 .map(Rc::new)
266 .unwrap_or_else(|| remember(MutableInteractionSource::new));
267
268 let mut m = Modifier::new()
269 .flex_shrink(0.0)
270 .state_colors(StateColors {
271 default: Color::TRANSPARENT,
272 hovered: Color::TRANSPARENT,
273 focused: Color::TRANSPARENT,
274 pressed: Color::TRANSPARENT,
275 dragged: th.on_surface.with_alpha_f32(0.12),
276 disabled: Color::TRANSPARENT,
277 })
278 .state_elevation(config.elevation.to_state_elevation())
279 .padding_values(PaddingValues {
280 left: config.horizontal_padding,
281 right: config.horizontal_padding,
282 top: 8.0,
283 bottom: 8.0,
284 })
285 .background(bg)
286 .clip_rounded(shape)
287 .interaction_source(&ch_source)
288 .indication(crate::ripple::ripple(crate::ripple::RippleConfig {
289 color: Some(label_color),
290 bounded: true,
291 ..Default::default()
292 }))
293 .then(config.modifier);
294
295 if is_enabled {
296 m = m.clickable().on_click(on_click);
297 }
298
299 Box(m).child(
300 Row(Modifier::new().align_items(AlignItems::CENTER)).child((
301 leading_icon
302 .map(|v| {
303 Box(Modifier::new().padding_values(PaddingValues {
304 left: 0.0,
305 right: 8.0,
306 top: 0.0,
307 bottom: 0.0,
308 }))
309 .child(with_content_color(leading_color, move || v))
310 })
311 .unwrap_or(Box(Modifier::new())),
312 with_content_color(label_color, move || label),
313 trailing_icon
314 .map(|v| {
315 Box(Modifier::new().padding_values(PaddingValues {
316 left: 8.0,
317 right: 0.0,
318 top: 0.0,
319 bottom: 0.0,
320 }))
321 .child(with_content_color(trailing_color, move || v))
322 })
323 .unwrap_or(Box(Modifier::new())),
324 )),
325 )
326}
327
328pub fn FilterChip(
329 selected: bool,
330 on_click: impl Fn() + 'static,
331 label: View,
332 leading_icon: Option<View>,
333 trailing_icon: Option<View>,
334 config: ChipConfig,
335) -> View {
336 let th = theme();
337 let id = remember(|| FILTERCHIP_COUNTER.fetch_add(1, Ordering::Relaxed));
338 let spec = th.motion.color;
339 let is_enabled = config.enabled;
340 let colors = &config.colors;
341
342 let bg = animate_color(
343 format!("fc_bg_{}", id),
344 colors.container(is_enabled, selected),
345 spec,
346 );
347 let label_color = animate_color(
348 format!("fc_lc_{}", id),
349 colors.label(is_enabled, selected),
350 spec,
351 );
352 let leading_color = animate_color(
353 format!("fc_lic_{}", id),
354 colors.leading_icon(is_enabled, selected),
355 spec,
356 );
357 let trailing_color = animate_color(
358 format!("fc_tic_{}", id),
359 colors.trailing_icon(is_enabled, selected),
360 spec,
361 );
362 let border = if !is_enabled {
363 if selected {
364 config.disabled_selected_border_color
365 } else {
366 config.disabled_border_color
367 }
368 } else {
369 if selected {
370 config.selected_border_color
371 } else {
372 config.border_color
373 }
374 };
375 let shape = config.shape_radius;
376
377 let ch_source: Rc<MutableInteractionSource> = config
378 .interaction_source
379 .clone()
380 .map(Rc::new)
381 .unwrap_or_else(|| remember(MutableInteractionSource::new));
382
383 let mut m = Modifier::new()
384 .flex_shrink(0.0)
385 .state_colors(StateColors {
386 default: Color::TRANSPARENT,
387 hovered: Color::TRANSPARENT,
388 focused: Color::TRANSPARENT,
389 pressed: Color::TRANSPARENT,
390 dragged: th.on_surface.with_alpha_f32(0.12),
391 disabled: Color::TRANSPARENT,
392 })
393 .padding_values(PaddingValues {
394 left: config.horizontal_padding,
395 right: config.horizontal_padding,
396 top: 8.0,
397 bottom: 8.0,
398 })
399 .background(bg)
400 .clip_rounded(shape)
401 .interaction_source(&ch_source)
402 .indication(crate::ripple::ripple(crate::ripple::RippleConfig {
403 color: Some(label_color),
404 bounded: true,
405 ..Default::default()
406 }))
407 .then(config.modifier);
408
409 if config.border_width > 0.0 && border != Color::TRANSPARENT {
410 m = m.border(config.border_width, border, shape);
411 }
412 if is_enabled {
413 m = m.clickable().on_click(on_click);
414 }
415
416 Box(m).child(
417 Row(Modifier::new().align_items(AlignItems::CENTER)).child((
418 leading_icon
419 .map(|v| {
420 Box(Modifier::new().padding_values(PaddingValues {
421 left: 0.0,
422 right: 8.0,
423 top: 0.0,
424 bottom: 0.0,
425 }))
426 .child(with_content_color(leading_color, move || v))
427 })
428 .unwrap_or(Box(Modifier::new())),
429 with_content_color(label_color, move || label),
430 trailing_icon
431 .map(|v| {
432 Box(Modifier::new().padding_values(PaddingValues {
433 left: 8.0,
434 right: 0.0,
435 top: 0.0,
436 bottom: 0.0,
437 }))
438 .child(with_content_color(trailing_color, move || v))
439 })
440 .unwrap_or(Box(Modifier::new())),
441 )),
442 )
443}
444
445pub fn ElevatedFilterChip(
447 selected: bool,
448 on_click: impl Fn() + 'static,
449 label: View,
450 leading_icon: Option<View>,
451 trailing_icon: Option<View>,
452 config: ChipConfig,
453) -> View {
454 let th = theme();
455 let id = remember(|| FILTERCHIP_COUNTER.fetch_add(1, Ordering::Relaxed));
456 let spec = th.motion.color;
457 let is_enabled = config.enabled;
458 let colors = &config.colors;
459
460 let bg = animate_color(
461 format!("efc_bg_{}", id),
462 colors.container(is_enabled, selected),
463 spec,
464 );
465 let label_color = animate_color(
466 format!("efc_lc_{}", id),
467 colors.label(is_enabled, selected),
468 spec,
469 );
470 let leading_color = animate_color(
471 format!("efc_lic_{}", id),
472 colors.leading_icon(is_enabled, selected),
473 spec,
474 );
475 let trailing_color = animate_color(
476 format!("efc_tic_{}", id),
477 colors.trailing_icon(is_enabled, selected),
478 spec,
479 );
480 let shape = config.shape_radius;
481
482 let ch_source: Rc<MutableInteractionSource> = config
483 .interaction_source
484 .clone()
485 .map(Rc::new)
486 .unwrap_or_else(|| remember(MutableInteractionSource::new));
487
488 let mut m = Modifier::new()
489 .flex_shrink(0.0)
490 .state_colors(StateColors {
491 default: Color::TRANSPARENT,
492 hovered: Color::TRANSPARENT,
493 focused: Color::TRANSPARENT,
494 pressed: Color::TRANSPARENT,
495 dragged: th.on_surface.with_alpha_f32(0.12),
496 disabled: Color::TRANSPARENT,
497 })
498 .state_elevation(config.elevation.to_state_elevation())
499 .padding_values(PaddingValues {
500 left: config.horizontal_padding,
501 right: config.horizontal_padding,
502 top: 8.0,
503 bottom: 8.0,
504 })
505 .background(bg)
506 .clip_rounded(shape)
507 .interaction_source(&ch_source)
508 .indication(crate::ripple::ripple(crate::ripple::RippleConfig {
509 color: Some(label_color),
510 bounded: true,
511 ..Default::default()
512 }))
513 .then(config.modifier);
514
515 if is_enabled {
516 m = m.clickable().on_click(on_click);
517 }
518
519 Box(m).child(
520 Row(Modifier::new().align_items(AlignItems::CENTER)).child((
521 leading_icon
522 .map(|v| {
523 Box(Modifier::new().padding_values(PaddingValues {
524 left: 0.0,
525 right: 8.0,
526 top: 0.0,
527 bottom: 0.0,
528 }))
529 .child(with_content_color(leading_color, move || v))
530 })
531 .unwrap_or(Box(Modifier::new())),
532 with_content_color(label_color, move || label),
533 trailing_icon
534 .map(|v| {
535 Box(Modifier::new().padding_values(PaddingValues {
536 left: 8.0,
537 right: 0.0,
538 top: 0.0,
539 bottom: 0.0,
540 }))
541 .child(with_content_color(trailing_color, move || v))
542 })
543 .unwrap_or(Box(Modifier::new())),
544 )),
545 )
546}
547
548pub fn SuggestionChip(
549 on_click: impl Fn() + 'static,
550 label: View,
551 icon: Option<View>,
552 config: ChipConfig,
553) -> View {
554 let th = theme();
555 let is_enabled = config.enabled;
556 let colors = &config.colors;
557 let bg = colors.container(is_enabled, false);
558 let label_color = colors.label(is_enabled, false);
559 let leading_color = colors.leading_icon(is_enabled, false);
560 let border = if is_enabled {
561 config.border_color
562 } else {
563 config.disabled_border_color
564 };
565 let shape = config.shape_radius;
566
567 let ch_source: Rc<MutableInteractionSource> = config
568 .interaction_source
569 .clone()
570 .map(Rc::new)
571 .unwrap_or_else(|| remember(MutableInteractionSource::new));
572
573 let mut m = Modifier::new()
574 .flex_shrink(0.0)
575 .state_colors(StateColors {
576 default: Color::TRANSPARENT,
577 hovered: Color::TRANSPARENT,
578 focused: Color::TRANSPARENT,
579 pressed: Color::TRANSPARENT,
580 dragged: th.on_surface.with_alpha_f32(0.12),
581 disabled: Color::TRANSPARENT,
582 })
583 .padding_values(PaddingValues {
584 left: config.horizontal_padding,
585 right: config.horizontal_padding,
586 top: 8.0,
587 bottom: 8.0,
588 })
589 .background(bg)
590 .clip_rounded(shape)
591 .interaction_source(&ch_source)
592 .indication(crate::ripple::ripple(crate::ripple::RippleConfig {
593 color: Some(label_color),
594 bounded: true,
595 ..Default::default()
596 }))
597 .then(config.modifier);
598
599 if config.border_width > 0.0 && border != Color::TRANSPARENT {
600 m = m.border(config.border_width, border, shape);
601 }
602 if is_enabled {
603 m = m.clickable().on_click(on_click);
604 }
605
606 Box(m).child(
607 Row(Modifier::new().align_items(AlignItems::CENTER)).child((
608 icon.map(|v| {
609 Box(Modifier::new().padding_values(PaddingValues {
610 left: 0.0,
611 right: 8.0,
612 top: 0.0,
613 bottom: 0.0,
614 }))
615 .child(with_content_color(leading_color, move || v))
616 })
617 .unwrap_or(Box(Modifier::new())),
618 with_content_color(label_color, move || label),
619 )),
620 )
621}
622
623pub fn ElevatedSuggestionChip(
625 on_click: impl Fn() + 'static,
626 label: View,
627 icon: Option<View>,
628 config: ChipConfig,
629) -> View {
630 let th = theme();
631 let is_enabled = config.enabled;
632 let colors = &config.colors;
633 let bg = colors.container(is_enabled, false);
634 let label_color = colors.label(is_enabled, false);
635 let leading_color = colors.leading_icon(is_enabled, false);
636 let shape = config.shape_radius;
637
638 let ch_source: Rc<MutableInteractionSource> = config
639 .interaction_source
640 .clone()
641 .map(Rc::new)
642 .unwrap_or_else(|| remember(MutableInteractionSource::new));
643
644 let mut m = Modifier::new()
645 .flex_shrink(0.0)
646 .state_colors(StateColors {
647 default: Color::TRANSPARENT,
648 hovered: Color::TRANSPARENT,
649 focused: Color::TRANSPARENT,
650 pressed: Color::TRANSPARENT,
651 dragged: th.on_surface.with_alpha_f32(0.12),
652 disabled: Color::TRANSPARENT,
653 })
654 .state_elevation(config.elevation.to_state_elevation())
655 .padding_values(PaddingValues {
656 left: config.horizontal_padding,
657 right: config.horizontal_padding,
658 top: 8.0,
659 bottom: 8.0,
660 })
661 .background(bg)
662 .clip_rounded(shape)
663 .interaction_source(&ch_source)
664 .indication(crate::ripple::ripple(crate::ripple::RippleConfig {
665 color: Some(label_color),
666 bounded: true,
667 ..Default::default()
668 }))
669 .then(config.modifier);
670
671 if is_enabled {
672 m = m.clickable().on_click(on_click);
673 }
674
675 Box(m).child(
676 Row(Modifier::new().align_items(AlignItems::CENTER)).child((
677 icon.map(|v| {
678 Box(Modifier::new().padding_values(PaddingValues {
679 left: 0.0,
680 right: 8.0,
681 top: 0.0,
682 bottom: 0.0,
683 }))
684 .child(with_content_color(leading_color, move || v))
685 })
686 .unwrap_or(Box(Modifier::new())),
687 with_content_color(label_color, move || label),
688 )),
689 )
690}
691
692pub fn InputChip(
693 selected: bool,
694 on_click: impl Fn() + 'static,
695 label: View,
696 leading_icon: Option<View>,
697 avatar: Option<View>,
698 trailing_icon: Option<View>,
699 config: ChipConfig,
700) -> View {
701 let th = theme();
702 let id = remember(|| FILTERCHIP_COUNTER.fetch_add(1, Ordering::Relaxed));
703 let spec = th.motion.color;
704 let is_enabled = config.enabled;
705 let colors = &config.colors;
706
707 let bg = animate_color(
708 format!("ic_bg_{}", id),
709 colors.container(is_enabled, selected),
710 spec,
711 );
712 let label_color = animate_color(
713 format!("ic_lc_{}", id),
714 colors.label(is_enabled, selected),
715 spec,
716 );
717 let leading_color = animate_color(
718 format!("ic_lic_{}", id),
719 colors.leading_icon(is_enabled, selected),
720 spec,
721 );
722 let trailing_color = animate_color(
723 format!("ic_tic_{}", id),
724 colors.trailing_icon(is_enabled, selected),
725 spec,
726 );
727 let border = if !is_enabled {
728 if selected {
729 config.disabled_selected_border_color
730 } else {
731 config.disabled_border_color
732 }
733 } else {
734 if selected {
735 config.selected_border_color
736 } else {
737 config.border_color
738 }
739 };
740 let shape = config.shape_radius;
741
742 let ch_source: Rc<MutableInteractionSource> = config
743 .interaction_source
744 .clone()
745 .map(Rc::new)
746 .unwrap_or_else(|| remember(MutableInteractionSource::new));
747
748 let mut m = Modifier::new()
749 .flex_shrink(0.0)
750 .state_colors(StateColors {
751 default: Color::TRANSPARENT,
752 hovered: Color::TRANSPARENT,
753 focused: Color::TRANSPARENT,
754 pressed: Color::TRANSPARENT,
755 dragged: th.on_surface.with_alpha_f32(0.12),
756 disabled: Color::TRANSPARENT,
757 })
758 .padding_values(PaddingValues {
759 left: config.horizontal_padding,
760 right: config.horizontal_padding,
761 top: 8.0,
762 bottom: 8.0,
763 })
764 .background(bg)
765 .clip_rounded(shape)
766 .interaction_source(&ch_source)
767 .indication(crate::ripple::ripple(crate::ripple::RippleConfig {
768 color: Some(label_color),
769 bounded: true,
770 ..Default::default()
771 }))
772 .then(config.modifier);
773
774 if config.border_width > 0.0 && border != Color::TRANSPARENT {
775 m = m.border(config.border_width, border, shape);
776 }
777 if is_enabled {
778 m = m.clickable().on_click(on_click);
779 }
780
781 Box(m).child(
782 Row(Modifier::new().align_items(AlignItems::CENTER)).child((
783 avatar
784 .or(leading_icon)
785 .map(|v| {
786 Box(Modifier::new().padding_values(PaddingValues {
787 left: 0.0,
788 right: 8.0,
789 top: 0.0,
790 bottom: 0.0,
791 }))
792 .child(with_content_color(leading_color, move || v))
793 })
794 .unwrap_or(Box(Modifier::new())),
795 with_content_color(label_color, move || label),
796 trailing_icon
797 .map(|v| {
798 Box(Modifier::new().padding_values(PaddingValues {
799 left: 8.0,
800 right: 0.0,
801 top: 0.0,
802 bottom: 0.0,
803 }))
804 .child(with_content_color(trailing_color, move || v))
805 })
806 .unwrap_or(Box(Modifier::new())),
807 )),
808 )
809}
810
811pub fn chip_group_flow(modifier: Modifier, children: impl repose_ui::IntoChildren) -> View {
815 FlowRow(
816 Modifier::new()
817 .fill_max_width()
818 .gap(8.0)
819 .align_items(AlignItems::CENTER)
820 .then(modifier),
821 )
822 .child(children)
823}
824
825pub fn FilterChipGroup(modifier: Modifier, children: impl repose_ui::IntoChildren) -> View {
827 chip_group_flow(modifier, children)
828}
829
830pub fn ElevatedFilterChipGroup(modifier: Modifier, children: impl repose_ui::IntoChildren) -> View {
832 chip_group_flow(modifier, children)
833}
834
835pub fn AssistChipGroup(modifier: Modifier, children: impl repose_ui::IntoChildren) -> View {
837 chip_group_flow(modifier, children)
838}
839
840pub fn ElevatedAssistChipGroup(modifier: Modifier, children: impl repose_ui::IntoChildren) -> View {
843 chip_group_flow(modifier, children)
844}
845
846pub fn SuggestionChipGroup(modifier: Modifier, children: impl repose_ui::IntoChildren) -> View {
848 chip_group_flow(modifier, children)
849}
850
851pub fn ElevatedSuggestionChipGroup(
853 modifier: Modifier,
854 children: impl repose_ui::IntoChildren,
855) -> View {
856 chip_group_flow(modifier, children)
857}
858
859pub fn InputChipGroup(modifier: Modifier, children: impl repose_ui::IntoChildren) -> View {
861 chip_group_flow(modifier, children)
862}