dioxus_docs_kit/components/
theme_toggle.rs1use dioxus::prelude::*;
2use dioxus_free_icons::Icon;
3use dioxus_free_icons::icons::ld_icons::{LdMoon, LdSun};
4
5use super::docs_layout::CurrentTheme;
6use crate::registry::DocsRegistry;
7
8#[component]
15pub fn ThemeToggle() -> Element {
16 let registry = use_context::<&'static DocsRegistry>();
17
18 let toggle = match registry
19 .theme
20 .as_ref()
21 .and_then(|t| t.toggle_themes.as_ref())
22 {
23 Some(t) => t.clone(),
24 None => return rsx! {},
25 };
26
27 let storage_key = registry
28 .theme
29 .as_ref()
30 .map(|t| t.storage_key.clone())
31 .unwrap_or_default();
32
33 let CurrentTheme(mut current_theme) = use_context::<CurrentTheme>();
34
35 let (light, dark) = toggle;
36 let is_dark = current_theme() == dark;
37
38 rsx! {
39 button {
40 class: "btn btn-ghost btn-sm btn-square",
41 title: if is_dark { "Switch to light mode" } else { "Switch to dark mode" },
42 onclick: move |_| {
43 let new_theme = if (current_theme)() == dark { light.clone() } else { dark.clone() };
44 current_theme.set(new_theme.clone());
45 let key = storage_key.clone();
46 spawn(async move {
47 let _ = document::eval(&format!(
48 r#"document.documentElement.setAttribute('data-theme', '{new_theme}');
49 try {{ localStorage.setItem('{key}', '{new_theme}'); }} catch(e) {{}}"#
50 ));
51 });
52 },
53 if is_dark {
54 Icon { class: "size-5", icon: LdSun }
55 } else {
56 Icon { class: "size-5", icon: LdMoon }
57 }
58 }
59 }
60}