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
use crate::use_media_query;
use leptos::*;
use std::fmt::Display;

/// Reactive [prefers-contrast](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-contrast) media query.
///
/// ## Usage
///
/// ```
/// # use leptos::*;
/// # use leptos_use::use_preferred_contrast;
/// #
/// # #[component]
/// # fn Demo() -> impl IntoView {
/// #
/// let preferred_contrast = use_preferred_contrast();
/// #
/// #    view! { }
/// # }
/// ```
///
/// ## Server-Side Rendering
///
/// On the server this returns a `Signal` that always contains the value `PreferredContrast::NoPreference`.
///
/// ## See also
///
/// * [`use_media_query`]
/// * [`use_preferred_dark`]
pub fn use_preferred_contrast() -> Signal<PreferredContrast> {
    let is_more = use_media_query("(prefers-contrast: more)");
    let is_less = use_media_query("(prefers-contrast: less)");
    let is_custom = use_media_query("(prefers-contrast: custom)");

    Signal::derive(move || {
        if is_more.get() {
            PreferredContrast::More
        } else if is_less.get() {
            PreferredContrast::Less
        } else if is_custom.get() {
            PreferredContrast::Custom
        } else {
            PreferredContrast::NoPreference
        }
    })
}

/// Return value for [`use_preferred_contrast`]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum PreferredContrast {
    More,
    Less,
    Custom,
    #[default]
    NoPreference,
}

impl Display for PreferredContrast {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            PreferredContrast::More => write!(f, "more"),
            PreferredContrast::Less => write!(f, "less"),
            PreferredContrast::Custom => write!(f, "custom"),
            PreferredContrast::NoPreference => write!(f, "no-preference"),
        }
    }
}