A non-complicated theme management library for Yew.
Note: Themer is NOT a CSS solution. You may use any CSS styling solution you wish (e.g. Stylist).
Ongoing development. No/little documentation, rapidly changing, etc.
Examples can be served with Trunk (e.g. trunk serve
)
- Minimal: Example using the browser's preferred theme.
- Read browser preference: Display your browser's theme preference (Light/Dark) on a label (no styling applied).
- Theme Switcher: A button which switches between 3 themes.
- Storage: Store user-saved theme preferences with a button and load those preferences automatically on refresh.
The API asks you to create a Theme template struct with the #[theme]
macro, and a key for access with the #[theme_key]
macro. The theme key is used to reduce memory footprint and provides ergonomics.
#[theme]
pub struct MyTheme {
// Foreground color
fg: &'static str,
// Background color
bg: &'static str,
// Font size
fs: &'static str,
}
#[theme_key]
pub enum MyThemeChoice {
Light,
Dark,
}
impl ThemeKey for MyThemeChoice {
type Theme = MyTheme;
fn theme(&self) -> &'static Self::Theme {
match self {
MyThemeChoice::Light => &MyTheme {
fg: "black",
bg: "white",
fs: "1.2em",
},
MyThemeChoice::Dark => &MyTheme {
fg: "white",
bg: "black",
fs: "1.2em",
},
}
}
}
To pass your theme to your app, you must register a ThemeProvider
with your theme choice. This works as a Context in Yew.
In this example, <App />
is a function component containing your app.
#[function_component(Root)]
pub fn root() -> Html {
let initial_theme = MyThemeChoice::Light;
html! {
<ThemeProvider<MyThemeChoice> theme={ initial_theme } >
<App />
</ThemeProvider<MyThemeChoice>>
}
}
You can match your browser's theme preference (Light/Dark) to help decide on an initial theme, via themer::BrowserPreference::get()
use_theme()
will dereference into your theme. This works as a Hook in Yew.
#[function_component(App)]
pub fn app() -> Html {
let theme = use_theme::<MyThemeChoice>();
let style = format!("color:{}; background-color:{};", theme.fg, theme.bg);
html! {
<label {style}>
{ "I am a themed label!" }
</label>
}
}