1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
use dioxus::prelude::*;
use std::{borrow::Cow, rc::Rc};

/// Theme component.
///
/// This component provides access to [`UseTheme`](UseTheme) to its children.
#[component]
pub fn Theme<'a>(
    cx: Scope<'a>,

    /// Primary color.
    #[props(into, default = Cow::Borrowed("#6750A4"))]
    primary_color: Cow<'static, str>,

    /// Background color.
    #[props(into, default = Cow::Borrowed("#eeeeee"))]
    background_color: Cow<'static, str>,

    /// Secondary container color.
    #[props(into, default = Cow::Borrowed("#E8DEF8"))]
    secondary_container_color: Cow<'static, str>,

    /// Border radius medium.
    #[props(into, default = Cow::Borrowed("25px"))]
    border_radius_medium: Cow<'static, str>,

    /// Border radius.
    #[props(into, default = Cow::Borrowed("8px"))]
    border_radius_small: Cow<'static, str>,

    /// Small label font size.
    #[props(default = 12.)]
    label_small: f32,

    /// Medium label font size.
    #[props(default = 16.)]
    label_medium: f32,

    children: Element<'a>,
) -> Element<'a> {
    use_context_provider(cx, move || {
        Rc::new(UseTheme {
            primary_color: primary_color.clone(),
            background_color: background_color.clone(),
            secondary_container_color: secondary_container_color.clone(),
            border_radius_medium: border_radius_medium.clone(),
            border_radius_small: border_radius_small.clone(),
            label_small: *label_small,
            label_medium: *label_medium,
        })
    });

    render!(children)
}

pub struct UseTheme {
    pub primary_color: Cow<'static, str>,
    pub background_color: Cow<'static, str>,
    pub secondary_container_color: Cow<'static, str>,
    pub border_radius_medium: Cow<'static, str>,
    pub border_radius_small: Cow<'static, str>,
    pub label_small: f32,
    pub label_medium: f32,
}

pub fn use_theme<T>(cx: Scope<T>) -> &UseTheme {
    let rc: &Rc<UseTheme> = use_context(cx).unwrap();
    rc.as_ref()
}