Skip to main content

freya_material_design/
floating_tab.rs

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