Theme RS
Theme Yew Usage
Adding Theme to your project is simple:
-
Make sure your project is set up with Yew. Follow their Getting Started Guide for setup instructions.
-
Add the Theme component to your dependencies by including it in your
Cargo.toml
file:cargo add theme --features=yew
-
Import the
ThemeProvider
component into your Yew component and start using it in your app.
🛠️ Usage
Follow these steps to integrate theme
into your Yew application:
1. Import the Required Components
Import the ThemeProvider
and related types into your Yew project:
use yew::prelude::*;
use theme::yew::ThemeProvider;
use theme::{Theme, StorageType};
2. Define Custom Themes (Optional)
You can define and register custom themes using the CustomTheme
type:
use std::collections::HashMap;
use std::rc::Rc;
use theme::{CustomTheme, ColorTokens};
let mut custom_themes = HashMap::new();
custom_themes.insert(
"solarized".to_string(),
Rc::new(CustomTheme {
name: "solarized".to_string(),
base: None, // or Some("light".to_string()) if you want to inherit
tokens: ColorTokens {
primary: "#268bd2".to_string(),
secondary: "#2aa198".to_string(),
background: "#fdf6e3".to_string(),
text: "#657b83".to_string(),
error: Some("#dc322f".to_string()),
warning: Some("#cb4b16".to_string()),
success: Some("#859900".to_string()),
},
}),
);
3. Wrap Your App with the ThemeProvider
Wrap your main app component inside the ThemeProvider
to provide theme context and behavior to your app:
use std::rc::Rc;
use yew::prelude::*;
use theme::yew::ThemeProvider;
use std::collections::HashMap;
use theme::{Theme, StorageType, CustomTheme, ColorTokens};
#[function_component(App)]
pub fn app() -> Html {
let mut custom_themes = HashMap::new();
custom_themes.insert(
"solarized".to_string(),
Rc::new(CustomTheme {
name: "solarized".to_string(),
base: None,
tokens: ColorTokens {
primary: "#268bd2".to_string(),
secondary: "#2aa198".to_string(),
background: "#fdf6e3".to_string(),
text: "#657b83".to_string(),
error: Some("#dc322f".to_string()),
warning: Some("#cb4b16".to_string()),
success: Some("#859900".to_string()),
},
}),
);
html! {
<ThemeProvider
default_theme={Theme::System}
storage_type={StorageType::LocalStorage}
storage_name={"theme"}
custom_themes={custom_themes}
forced_theme={None}
>
<MainApp />
</ThemeProvider>
}
}
#[function_component(MainApp)]
pub fn main_app() -> Html {
html! {
<h1>{ "Welcome to the themed app!" }</h1>
}
}
fn main() {
// yew::Renderer::<App>::new().render();
}
4. Access the Theme Context with the use_theme
Hook
Use the use_theme
hook to access the current theme, resolved theme, and control functions within your components:
use yew::prelude::*;
use theme::yew::use_theme;
use theme::Theme;
#[function_component(MainApp)]
pub fn main_app() -> Html {
let ctx = use_theme();
let onclick = {
let set_theme = ctx.set_theme.clone();
Callback::from(move |_| set_theme.emit(Theme::Dark))
};
html! {
<div>
<h2>{ format!("Current Theme: {:?}", *ctx.resolved_theme) }</h2>
<button onclick={onclick}>{ "Switch to Dark Theme" }</button>
</div>
}
}
fn main() {
// yew::Renderer::<MainApp>::new().render();
}
🔧 Props
ThemeProviderProps
Props
Main Props
Property | Type | Description | Default |
---|---|---|---|
default_theme | Theme | The theme to use if nothing is stored or detected. | Theme::System |
storage_type | StorageType | Whether to persist the theme in LocalStorage or SessionStorage . | LocalStorage |
storage_name | &'static str | Key name for storing the selected theme in browser storage. | "theme" |
forced_theme | Option<Theme> | Overrides all other theme logic if provided. | None |
custom_themes | HashMap<String, Rc<CustomTheme>> | Map of user-defined themes. Can be applied and previewed. | {} |
children | Html | Child components that will have access to the theme context. | Required |
Behavioral Props
Property | Type | Description | Default |
---|---|---|---|
reset_to_system | Callback<()> | Reverts the theme to follow the system theme. | no-op |
apply_preview | Callback<Theme> | Applies a temporary theme preview (doesn't persist or update state). | no-op |
set_custom_theme | Callback<Rc<CustomTheme>> | Adds a new custom theme if it passes validation. | no-op |
💡 Notes
-
Auto System Theme Support: When
Theme::System
is used, the component tracksprefers-color-scheme
and switches between light and dark automatically based on system settings. -
Time-Based Theme Switching: If no preference is stored,
Theme::System
will fall back to light mode during 7 AM - 6:59 PM and dark mode otherwise. -
Forced Theme: When
forced_theme
is provided, it overrides all system, storage, or runtime theme choices, effectively locking the app to that theme. -
Custom Themes: Add your own themes and styles dynamically. Each must implement the
validate()
method to ensure it's structured correctly. -
Tailwind Compatibility (v3 or lower): This provider works with Tailwind CSS's
data-theme=
andclass=
bindings, making it compatible with libraries like DaisyUI. It sets:data-theme
class
style="color-scheme:..."
on the root HTML element.
-
Storage Syncing: Theme changes are synced across tabs and windows using the
storage
event. -
Easy API: Use
set_theme
,reset_to_system
, orapply_preview
to control appearance from any component. -
Hooks First: Just use
use_theme()
to access all theme information and actions within your components.
Usage
CLI Usage
You can import Theme RS directly into your project to customize and modify it using the opensass cli:
os add theme yew