dioxus-compose 가이드

테마

색은 CSS 변수로

HTML 화면의 테마는 웹에서와 같습니다. 사용자 정의 속성, prefers-color-scheme 미디어 쿼리, 그리고 사용자가 시스템 설정을 덮어쓸 때의 클래스입니다. 이 크레이트가 그것을 대신하는 것은 없으므로, 브라우저용으로 쓴 스타일시트의 테마가 그대로 남습니다.

사용자 정의 속성

samples/theme 은 모든 색을 var() 로 씁니다. 밝은 세트가 기본이고, prefers-color-scheme: dark 아래에서는 어두운 세트가 적용되며, 앱 루트의 클래스가 둘 다를 이깁니다.

samples/theme/src/lib.rs, 줄임
:root, .app.light {
    --bg: #ffffff;
    --surface: #f3f4f6;
    --text: #111827;
    --accent: #2563eb;
}

@media (prefers-color-scheme: dark) {
    :root {
        --bg: #111827;
        --surface: #1f2937;
        --text: #f9fafb;
        --accent: #60a5fa;
    }
}

.app.dark {
    --bg: #111827;
    --surface: #1f2937;
    --text: #f9fafb;
    --accent: #60a5fa;
}

.app { height: 100%; padding: 24px; background-color: var(--bg); color: var(--text); }

밝은 테마와 어두운 테마

HtmlConfig::color_scheme 이 prefers-color-scheme 에 답합니다. 따로 정하지 않으면 ColorScheme::Light 입니다.

samples/theme/tests/theme.rs, 줄임
let dom = HtmlDom::with_config(
    theme::app,
    HtmlConfig {
        stylesheets: vec![theme::STYLE.to_string()],
        color_scheme: ColorScheme::Dark,
        ..HtmlConfig::default()
    },
);

앱에 클래스가 없으면 Dark 가 어두운 세트를 고릅니다. 테스트는 페이지의 모든 색을 두 세트와 비교합니다.

시스템 설정 덮어쓰기

토글 버튼은 루트 요소에 light 나 dark 를 붙입니다. 클래스만 바뀌므로 바뀌는 것은 색뿐입니다.

samples/theme/src/lib.rs, 줄임
// None follows the system through the media query.
let mut theme = use_signal(|| None::<Theme>);
let class = match theme.cloned() {
    None => "app",
    Some(Theme::Light) => "app light",
    Some(Theme::Dark) => "app dark",
};

rsx! {
    div { id: "app", class: "{class}",
        button {
            id: "theme-toggle",
            class: "toggle",
            onclick: move |_| {
                let next = match theme.cloned() {
                    Some(Theme::Dark) => Theme::Light,
                    _ => Theme::Dark,
                };
                theme.set(Some(next));
            },
            "Toggle theme"
        }
    }
}

테스트는 토글을 누르고 레이아웃 diff 를 확인합니다. 항목이 바뀌었고, 추가되거나 삭제된 것이 없고, 순서가 같고, 바뀐 항목은 모두 색만 달라졌습니다.

아직 없는 것