1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
//! Location agnostic shared state for yew components.
//! ## Usage
//!
//! Give your component `GlobalHandle` properties and wrap it with `SharedStateComponent`.
//! This may be done for any `T` that implements `Clone` + `Default`.
//! ```rust
//! struct Model {
//!     handle: GlobalHandle<T>,
//! }
//!
//! impl Component for Model {
//!     type Properties = GlobalHandle<T>;
//!     ...
//! }
//!
//! type MyComponent = SharedStateComponent<Model>;
//! ```
//!
//! Access current state with `state`.
//! ```rust
//! let state: &T = self.handle.state();
//! ```
//!
//! Modify shared state from anywhere using `reduce`
//! ```rust
//! // GlobalHandle<MyAppState>
//! self.handle.reduce(|state| state.user = new_user);
//! ```
//!
//! or from a callback with `reduce_callback`.
//! ```rust
//! // GlobalHandle<usize>
//! let onclick = self.handle.reduce_callback(|state| *state += 1);
//! html! {
//!     <button onclick = onclick>{"+1"}</button>
//! }
//! ```
//!
//! `reduce_callback_with` provides the fired event.
//! ```rust
//! let oninput = self
//!     .handle
//!     .reduce_callback_with(|state, i: InputData| state.user.name = i.value);
//!
//! html! {
//!     <input type="text" placeholder = "Enter your name" oninput = oninput />
//! }
//! ```
//!
//! ### Properties with Shared State
//!
//! Get shared state in custom props with `SharedState`.
//! ```rust
//! #[derive(Clone, Properties)]
//! pub struct Props {
//!     #[prop_or_default]
//!     pub handle: GlobalHandle<AppState>,
//! }
//!
//! impl SharedState for Props {
//!     type Handle = GlobalHandle<AppState>;
//!
//!     fn handle(&mut self) -> &mut Self::Handle {
//!         &mut self.handle
//!     }
//! }
//! ```
//!
//! ### State Persistence
//!
//! Persistent storage requires that `T` also implement `Serialize`,
//! `Deserialize`, and `Storable`.
//! ```rust
//! use serde::{Serialize, Deserialize};
//! use yew_state::Storable;
//! use yew::services::storage::Area;
//!
//! #[derive(Serialize, Deserialize)]
//! struct T;
//!
//! impl Storable for T {
//!     fn key() -> &'static str {
//!         "myapp.storage.t"
//!     }
//!
//!     fn area() -> Area {
//!         // or Area::Session
//!         Area::Local
//!     }
//! }
//! ```
//!
//! Then use `StorageHandle` instead of `GlobalHandle`.
mod component;
mod handle;
mod handler;

pub use yew::services::storage::Area;

pub use component::SharedStateComponent;
pub use handle::{GlobalHandle, Handle, SharedState, StorageHandle};
pub use handler::Storable;