outlet.rs 1.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041
  1. use dioxus::prelude::*;
  2. use crate::{routable::Routable, utils::use_router_internal::use_router_internal};
  3. #[derive(Clone)]
  4. pub(crate) struct OutletContext {
  5. pub current_level: usize,
  6. }
  7. pub(crate) fn use_outlet_context(cx: &ScopeState) -> &OutletContext {
  8. let outlet_context = cx.use_hook(|| {
  9. cx.consume_context()
  10. .unwrap_or(OutletContext { current_level: 0 })
  11. });
  12. outlet_context
  13. }
  14. impl OutletContext {
  15. pub(crate) fn render<R: Routable + Clone>(cx: Scope) -> Element<'_> {
  16. let router = use_router_internal::<R>(cx)
  17. .as_ref()
  18. .expect("Outlet must be inside of a router");
  19. let outlet = use_outlet_context(cx);
  20. let current_level = outlet.current_level;
  21. cx.provide_context({
  22. OutletContext {
  23. current_level: current_level + 1,
  24. }
  25. });
  26. if let Some(error) = router.render_error(cx) {
  27. if current_level == 0 {
  28. return Some(error);
  29. } else {
  30. return None;
  31. }
  32. }
  33. router.current().render(cx, current_level)
  34. }
  35. }