freya_components/
animated_router.rs1use dioxus::prelude::*;
2use dioxus_router::prelude::{
3 use_route,
4 Routable,
5};
6
7#[derive(Clone)]
8pub enum AnimatedRouterContext<R: Routable + PartialEq> {
9 FromTo(R, R),
11 In(R),
13}
14
15impl<R: Routable + PartialEq> AnimatedRouterContext<R> {
16 pub fn target_route(&self) -> &R {
18 match self {
19 Self::FromTo(_, to) => to,
20 Self::In(to) => to,
21 }
22 }
23
24 pub fn set_target_route(&mut self, to: R) {
26 match self {
27 Self::FromTo(old_from, old_to) => {
28 *old_from = old_to.clone();
29 *old_to = to
30 }
31 Self::In(old_to) => *self = Self::FromTo(old_to.clone(), to),
32 }
33 }
34
35 pub fn settle(&mut self) {
37 if let Self::FromTo(_, to) = self {
38 *self = Self::In(to.clone())
39 }
40 }
41}
42
43#[derive(Props, Clone, PartialEq)]
44pub struct AnimatedRouterProps {
45 children: Element,
46}
47
48#[allow(non_snake_case)]
52pub fn AnimatedRouter<R: Routable + PartialEq + Clone>(
53 AnimatedRouterProps { children }: AnimatedRouterProps,
54) -> Element {
55 let route = use_route::<R>();
56 let mut prev_route = use_signal(|| AnimatedRouterContext::In(route.clone()));
57 use_context_provider(move || prev_route);
58
59 if prev_route.peek().target_route() != &route {
60 prev_route.write().set_target_route(route);
61 }
62
63 rsx!({ children })
64}
65
66pub fn use_animated_router<Route: Routable + PartialEq>() -> Signal<AnimatedRouterContext<Route>> {
68 use_context()
69}