Skip to main content

freya_components/scroll_views/
scroll_thumb.rs

1use dioxus::prelude::*;
2use freya_elements::{
3    self as dioxus_elements,
4    events::MouseEvent,
5};
6use freya_hooks::{
7    use_applied_theme,
8    ScrollBarThemeWith,
9};
10
11/// Properties for the [`ScrollThumb`] component.
12#[derive(Props, Clone, PartialEq)]
13pub struct ScrollThumbProps {
14    /// Theme override.
15    pub theme: Option<ScrollBarThemeWith>,
16    pub clicking_scrollbar: bool,
17    pub onmousedown: EventHandler<MouseEvent>,
18    #[props(into)]
19    pub width: String,
20    #[props(into)]
21    pub height: String,
22}
23
24enum ScrollThumbState {
25    Idle,
26    Hovering,
27}
28
29/// Scroll thumb used for [`crate::ScrollView`] and [`crate::VirtualScrollView`].
30#[allow(non_snake_case)]
31pub fn ScrollThumb(
32    ScrollThumbProps {
33        theme,
34        clicking_scrollbar,
35        onmousedown,
36        width,
37        height,
38    }: ScrollThumbProps,
39) -> Element {
40    let theme = use_applied_theme!(&theme, scroll_bar);
41    let mut state = use_signal(|| ScrollThumbState::Idle);
42    let thumb_background = match *state.read() {
43        _ if clicking_scrollbar => theme.active_thumb_background,
44        ScrollThumbState::Idle => theme.thumb_background,
45        ScrollThumbState::Hovering => theme.hover_thumb_background,
46    };
47
48    rsx!(
49        rect {
50            onmouseenter: move |_: MouseEvent| { state.set(ScrollThumbState::Hovering) },
51            onmouseleave: move |_| { state.set(ScrollThumbState::Idle) },
52            onmousedown: move |e| {
53                e.stop_propagation();
54                onmousedown.call(e);
55            },
56            width: "{width}",
57            height: "{height}",
58            padding: "4",
59            rect {
60                width: "100%",
61                height: "100%",
62                corner_radius: "8",
63                background: "{thumb_background}",
64            }
65        }
66    )
67}