freya_router/contexts/
outlet.rs1use freya_core::prelude::{
2 Element,
3 provide_context,
4 try_consume_context,
5 use_hook,
6};
7
8use crate::{
9 routable::Routable,
10 utils::use_router_internal::use_router_internal,
11};
12
13#[derive(Clone, Default)]
22pub struct OutletContext<R> {
23 current_level: usize,
24 _marker: std::marker::PhantomData<R>,
25}
26
27impl<R> OutletContext<R> {
28 pub fn new() -> Self {
30 Self {
31 current_level: 0,
32 _marker: std::marker::PhantomData,
33 }
34 }
35
36 pub fn next(&self) -> Self {
38 Self {
39 current_level: self.current_level + 1,
40 _marker: std::marker::PhantomData,
41 }
42 }
43
44 pub fn level(&self) -> usize {
46 self.current_level
47 }
48
49 pub(crate) fn render() -> Element
50 where
51 R: Routable + Clone,
52 {
53 let router = use_router_internal().expect("Outlet must be inside of a router");
54 let outlet: OutletContext<R> = use_outlet_context();
55 let current_level = outlet.level();
56 provide_context(outlet.next());
57 router.current::<R>().render(current_level)
58 }
59}
60
61pub fn use_outlet_context<R: Clone + 'static>() -> OutletContext<R> {
62 use_hook(|| try_consume_context().unwrap_or_else(OutletContext::new))
63}