1pub mod contrast;
6
7use crate::style::register_global_style;
8
9#[derive(Clone, Debug)]
11pub struct FocusStyle {
12 pub outline_color: String,
13 pub outline_width: String,
14 pub outline_offset: String,
15}
16
17impl FocusStyle {
18 pub fn new() -> Self {
20 Self {
21 outline_color: "var(--color-primary-500, #3b82f6)".to_string(),
22 outline_width: "2px".to_string(),
23 outline_offset: "2px".to_string(),
24 }
25 }
26
27 pub fn to_css(&self) -> String {
29 format!(
30 ":focus-visible {{ outline: {} solid {}; outline-offset: {}; }}",
31 self.outline_width, self.outline_color, self.outline_offset
32 )
33 }
34}
35
36impl Default for FocusStyle {
37 fn default() -> Self {
38 Self::new()
39 }
40}
41
42pub fn register_focus_styles(style: &FocusStyle) {
44 let css = style.to_css();
45 register_global_style(&css);
46
47 #[cfg(all(feature = "csr", target_arch = "wasm32"))]
48 {
49 crate::csr::inject_styles_csr(&css);
50 }
51}
52
53pub fn reduced_motion_css() -> String {
55 r#"
56 @media (prefers-reduced-motion: reduce) {
57 *,
58 *::before,
59 *::after {
60 animation-duration: 0.01ms !important;
61 animation-iteration-count: 1 !important;
62 transition-duration: 0.01ms !important;
63 scroll-behavior: auto !important;
64 }
65 }
66 "#
67 .to_string()
68}
69
70pub fn register_reduced_motion() {
72 let css = reduced_motion_css();
73 register_global_style(&css);
74
75 #[cfg(all(feature = "csr", target_arch = "wasm32"))]
76 {
77 crate::csr::inject_styles_csr(&css);
78 }
79}