Skip to content

Commit

Permalink
feat(examples): add Context API state management example (#3657)
Browse files Browse the repository at this point in the history
* feat(examples): add Context API state management example (fixes #3612)

* refactor: code cleanup
  • Loading branch information
Danish903 authored Jan 31, 2025
1 parent 5bb7f51 commit 68ca4c3
Show file tree
Hide file tree
Showing 3 changed files with 134 additions and 0 deletions.
2 changes: 2 additions & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ cargo run --example hello_world

### State Management

[context_api](./context_api.rs) - Cross-component state sharing via Context API

### Async

[login_form](./login_form.rs) - Login endpoint example
Expand Down
43 changes: 43 additions & 0 deletions examples/assets/context_api.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
.main-container {
font-family: system-ui, sans-serif;
max-width: 600px;
margin: 2rem auto;
padding: 2rem;
}

.light-theme {
background: #ffffff;
color: #1a1a1a;
border: 1px solid #e0e0e0;
}

.dark-theme {
background: #1a1a1a;
color: #ffffff;
border: 1px solid #333;
}

.controls {
display: flex;
gap: 1rem;
margin: 2rem 0;
}

.btn {
padding: 0.5rem 1rem;
border: none;
border-radius: 4px;
cursor: pointer;
transition: opacity 0.2s;
}

.btn:disabled {
opacity: 0.7;
cursor: not-allowed;
}

.display {
padding: 2rem;
border-radius: 8px;
margin-top: 2rem;
}
89 changes: 89 additions & 0 deletions examples/context_api.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
//! Demonstrates cross-component state sharing using Dioxus' Context API
//!
//! Features:
//! - Context provider initialization
//! - Nested component consumption
//! - Reactive state updates
//! - Error handling for missing context
//! - Platform-agnostic implementation
use dioxus::prelude::*;

const STYLE: Asset = asset!("/examples/assets/context_api.css");

fn main() {
launch(app);
}

#[component]
fn app() -> Element {
// Provide theme context at root level
use_context_provider(|| Signal::new(Theme::Light));

rsx! {
document::Link { rel: "stylesheet", href: STYLE }
main {
class: "main-container",

h1 { "Theme Switcher" }
ThemeControls {}
ThemeDisplay {}
}
}
}

#[derive(Clone, Copy, PartialEq, Debug)]
enum Theme {
Light,
Dark,
}

impl Theme {
fn stylesheet(&self) -> &'static str {
match self {
Theme::Light => "light-theme",
Theme::Dark => "dark-theme",
}
}
}

#[component]
fn ThemeControls() -> Element {
let mut theme = use_theme_context();
let current_theme = *theme.read();
rsx! {
div {
class: "controls",
button {
class: "btn",
onclick: move |_| theme.set(Theme::Light),
disabled: current_theme== Theme::Light,
"Switch to Light"
}
button {
class: "btn",
onclick: move |_| theme.set(Theme::Dark),
disabled: current_theme == Theme::Dark,
"Switch to Dark"
}
}
}
}

#[component]
fn ThemeDisplay() -> Element {
let theme = use_theme_context();

rsx! {
div {
class: "display {theme.read().stylesheet()}",
p { "Current theme: {theme:?}" }
p { "Try switching themes using the buttons above!" }
}
}
}

fn use_theme_context() -> Signal<Theme> {
try_use_context::<Signal<Theme>>()
.expect("Theme context not found. Ensure <App> is the root component.")
}

0 comments on commit 68ca4c3

Please sign in to comment.