freya_components/theming/
hooks.rs

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