Skip to main content

leptos/
provider.rs

1use crate::{children::TypedChildren, component, IntoView};
2use reactive_graph::owner::{provide_context, Owner};
3use tachys::reactive_graph::OwnedView;
4
5#[component]
6/// Uses the context API to [`provide_context`] to its children and descendants,
7/// without overwriting any contexts of the same type in its own reactive scope.
8///
9/// This prevents issues related to “context shadowing.”
10///
11/// ```rust
12/// use leptos::{context::Provider, prelude::*};
13///
14/// #[component]
15/// pub fn App() -> impl IntoView {
16///     // each Provider will only provide the value to its children
17///     view! {
18///         <Provider value=1u8>
19///             // correctly gets 1 from context
20///             {use_context::<u8>().unwrap_or(0)}
21///         </Provider>
22///         <Provider value=2u8>
23///             // correctly gets 2 from context
24///             {use_context::<u8>().unwrap_or(0)}
25///         </Provider>
26///         // does not find any u8 in context
27///         {use_context::<u8>().unwrap_or(0)}
28///     }
29/// }
30/// ```
31pub fn Provider<T, Chil>(
32    /// The value to be provided via context.
33    value: T,
34    children: TypedChildren<Chil>,
35) -> impl IntoView
36where
37    T: Send + Sync + 'static,
38    Chil: IntoView + 'static,
39{
40    let owner = Owner::current()
41        .expect("no current reactive Owner found")
42        .child();
43    let children = children.into_inner();
44    let children = owner.with(|| {
45        provide_context(value);
46        children()
47    });
48    OwnedView::new_with_owner(children, owner)
49}