freya_components/theming/
hooks.rs

1use freya_core::{
2    prelude::{
3        State,
4        provide_context,
5        provide_context_for_scope_id,
6        try_consume_context,
7        use_consume,
8        use_hook,
9    },
10    scope_id::ScopeId,
11};
12
13use crate::theming::component_themes::Theme;
14
15/// Provides a custom [`Theme`].
16pub fn use_init_theme(theme_cb: impl FnOnce() -> Theme) -> State<Theme> {
17    use_hook(|| {
18        let state = State::create(theme_cb());
19        provide_context(state);
20        state
21    })
22}
23
24pub fn use_init_root_theme(theme_cb: impl FnOnce() -> Theme) -> State<Theme> {
25    use_hook(|| {
26        let state = State::create_in_scope(theme_cb(), ScopeId::ROOT);
27        provide_context_for_scope_id(state, ScopeId::ROOT);
28        state
29    })
30}
31
32/// Subscribe to [`Theme`] changes.
33pub fn use_theme() -> State<Theme> {
34    use_consume::<State<Theme>>()
35}
36
37/// Subscribe to [`Theme`] changes, default theme will be used if there is no provided [`Theme`].
38///
39/// Primarily used by built-in components that have no control of whether they will inherit a [`Theme`] or not.
40pub fn get_theme_or_default() -> Theme {
41    try_consume_context::<State<Theme>>()
42        .map(|theme| theme.read().to_owned())
43        .unwrap_or_default()
44}
45
46/// Indicates what type of surface to use.
47#[derive(Clone, Copy, PartialEq, Debug, Default)]
48pub enum SurfaceThemeIndicator {
49    #[default]
50    Primary,
51    Opposite,
52}
53
54/// Provide a [SurfaceThemeIndicator] down to the components.
55pub fn use_init_surface_theme_indicator(theme: impl FnOnce() -> SurfaceThemeIndicator) {
56    use_hook(|| provide_context(theme()))
57}
58
59/// Get the inherited [SurfaceThemeIndicator].
60pub fn use_surface_theme_indicator() -> SurfaceThemeIndicator {
61    use_hook(|| try_consume_context().unwrap_or_default())
62}