feat: add non-animation base classes to <AnimatedOutlet/> and <AnimatedRoutes/> (#877)

This commit is contained in:
Greg Johnston 2023-04-17 08:12:22 -04:00 committed by GitHub
parent 55fd6d44f9
commit efbe32e081
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 43 additions and 15 deletions

View file

@ -107,7 +107,11 @@ pub fn ContactList(cx: Scope) -> impl IntoView {
<Suspense fallback=move || view! { cx, <p>"Loading contacts..."</p> }>
{move || view! { cx, <ul>{contacts}</ul>}}
</Suspense>
<AnimatedOutlet outro="fadeOut" intro="fadeIn"/>
<AnimatedOutlet
class="outlet"
outro="fadeOut"
intro="fadeIn"
/>
</div>
}
}

View file

@ -2,6 +2,10 @@ a[aria-current] {
font-weight: bold;
}
.outlet {
border: 1px dotted grey;
}
.contact, .contact-list {
border: 1px solid #c0c0c0;
border-radius: 3px;

View file

@ -61,6 +61,9 @@ pub fn Outlet(cx: Scope) -> impl IntoView {
#[component]
pub fn AnimatedOutlet(
cx: Scope,
/// Base classes to be applied to the `<div>` wrapping the outlet during any animation state.
#[prop(optional, into)]
class: Option<TextProp>,
/// CSS class added when route is being unmounted
#[prop(optional)]
outro: Option<&'static str>,
@ -148,13 +151,20 @@ pub fn AnimatedOutlet(
}
});
let class = move || match current_animation.get() {
AnimationState::Outro => outro.unwrap_or_default(),
AnimationState::Start => start.unwrap_or_default(),
AnimationState::Intro => intro.unwrap_or_default(),
AnimationState::Finally => finally.unwrap_or_default(),
AnimationState::OutroBack => outro_back.unwrap_or_default(),
AnimationState::IntroBack => intro_back.unwrap_or_default(),
let class = move || {
let animation_class = match current_animation.get() {
AnimationState::Outro => outro.unwrap_or_default(),
AnimationState::Start => start.unwrap_or_default(),
AnimationState::Intro => intro.unwrap_or_default(),
AnimationState::Finally => finally.unwrap_or_default(),
AnimationState::OutroBack => outro_back.unwrap_or_default(),
AnimationState::IntroBack => intro_back.unwrap_or_default(),
};
if let Some(class) = &class {
format!("{} {animation_class}", class.get())
} else {
animation_class.to_string()
}
};
let animationend = move |ev: AnimationEvent| {
ev.stop_propagation();

View file

@ -93,6 +93,9 @@ pub fn Routes(
#[component]
pub fn AnimatedRoutes(
cx: Scope,
/// Base classes to be applied to the `<div>` wrapping the routes during any animation state.
#[prop(optional, into)]
class: Option<TextProp>,
/// Base path relative at which the routes are mounted.
#[prop(optional)]
base: Option<String>,
@ -210,13 +213,20 @@ pub fn AnimatedRoutes(
html::div(cx)
.attr(
"class",
(cx, move || match current_animation.get() {
AnimationState::Outro => outro.unwrap_or_default(),
AnimationState::Start => start.unwrap_or_default(),
AnimationState::Intro => intro.unwrap_or_default(),
AnimationState::Finally => finally.unwrap_or_default(),
AnimationState::OutroBack => outro_back.unwrap_or_default(),
AnimationState::IntroBack => intro_back.unwrap_or_default(),
(cx, move || {
let animation_class = match current_animation.get() {
AnimationState::Outro => outro.unwrap_or_default(),
AnimationState::Start => start.unwrap_or_default(),
AnimationState::Intro => intro.unwrap_or_default(),
AnimationState::Finally => finally.unwrap_or_default(),
AnimationState::OutroBack => outro_back.unwrap_or_default(),
AnimationState::IntroBack => intro_back.unwrap_or_default(),
};
if let Some(class) = &class {
format!("{} {animation_class}", class.get())
} else {
animation_class.to_string()
}
}),
)
.on(leptos::ev::animationend, move |_| {