Skip to main content

freya_material_design/
floating_tab.rs

1use std::time::Duration;
2
3use freya_components::{
4    floating_tab::{
5        FloatingTab,
6        FloatingTabThemePreference,
7    },
8    get_theme,
9};
10use freya_core::prelude::*;
11
12use crate::ripple::Ripple;
13
14/// Extension trait that adds ripple effect support to [FloatingTab].
15///
16/// This trait provides the [FloatingTabRippleExt::ripple] method that wraps the tab's children
17/// in a [Ripple] component, creating a Material Design-style ripple effect on click.
18///
19/// # Example
20///
21/// ```rust
22/// # use freya::{material_design::*, prelude::*};
23/// fn app() -> impl IntoElement {
24///     FloatingTab::new().ripple().child("Home")
25/// }
26/// ```
27pub trait FloatingTabRippleExt {
28    /// Enable ripple effect on this floating tab.
29    /// Returns a [RippleFloatingTab] that allows adding children and configuring the ripple.
30    fn ripple(self) -> RippleFloatingTab;
31}
32
33impl FloatingTabRippleExt for FloatingTab {
34    fn ripple(self) -> RippleFloatingTab {
35        RippleFloatingTab {
36            tab: self,
37            ripple: Ripple::new(),
38        }
39    }
40}
41
42/// A FloatingTab with a Ripple effect wrapper.
43///
44/// Created by calling [FloatingTabRippleExt::ripple] on a FloatingTab.
45/// Allows adding children to the ripple and configuring its color/duration.
46#[derive(Clone, PartialEq)]
47pub struct RippleFloatingTab {
48    tab: FloatingTab,
49    ripple: Ripple,
50}
51
52impl ChildrenExt for RippleFloatingTab {
53    fn get_children(&mut self) -> &mut Vec<Element> {
54        self.ripple.get_children()
55    }
56}
57
58impl KeyExt for RippleFloatingTab {
59    fn write_key(&mut self) -> &mut DiffKey {
60        self.tab.write_key()
61    }
62}
63
64impl RippleFloatingTab {
65    /// Set the color of the ripple effect.
66    pub fn color(mut self, color: impl Into<Color>) -> Self {
67        self.ripple = self.ripple.color(color);
68        self
69    }
70
71    /// Set the duration of the ripple animation.
72    pub fn duration(mut self, duration: Duration) -> Self {
73        self.ripple = self.ripple.duration(duration);
74        self
75    }
76}
77
78impl Component for RippleFloatingTab {
79    fn render(&self) -> impl IntoElement {
80        let mut tab = self.tab.clone();
81
82        let theme = get_theme!(&tab.get_theme(), FloatingTabThemePreference, "floating_tab");
83
84        let ripple = self.ripple.clone().padding(theme.padding);
85
86        let theme_override = tab.get_theme().cloned().unwrap_or_default().padding(0.);
87
88        tab.get_children().clear();
89        tab.get_children().push(ripple.into());
90        tab.theme(theme_override)
91    }
92
93    fn render_key(&self) -> DiffKey {
94        self.tab.render_key()
95    }
96}