Skip to main content

freya_components/
activable.rs

1use freya_core::prelude::*;
2
3use crate::activable_context::ActivableContext;
4
5/// User-controlled provider of [`ActivableContext`].
6///
7/// Exposes whether the descendants are considered active, useful to drive
8/// active styling of components like [`SideBarItem`](crate::sidebar::SideBarItem)
9/// or [`FloatingTab`](crate::floating_tab::FloatingTab) outside of a router context.
10#[derive(PartialEq, Clone)]
11pub struct Activable {
12    child: Element,
13    active: Readable<bool>,
14    key: DiffKey,
15}
16
17impl KeyExt for Activable {
18    fn write_key(&mut self) -> &mut DiffKey {
19        &mut self.key
20    }
21}
22
23impl Activable {
24    pub fn new(child: impl Into<Element>) -> Self {
25        Self {
26            child: child.into(),
27            active: false.into(),
28            key: DiffKey::None,
29        }
30    }
31
32    /// Set the active state.
33    pub fn active(mut self, active: impl Into<Readable<bool>>) -> Self {
34        self.active = active.into();
35        self
36    }
37}
38
39impl Component for Activable {
40    fn render(&self) -> impl IntoElement {
41        let is_active = *self.active.read();
42
43        let mut state = use_state(|| is_active);
44
45        if *state.peek() != is_active {
46            *state.write() = is_active;
47        }
48
49        use_provide_context::<ActivableContext>(|| ActivableContext(state.into_readable()));
50
51        self.child.clone()
52    }
53}