Transition: Fix unmounting active slide

This commit is contained in:
Alexander Zinchuk 2023-04-26 21:14:44 +04:00
parent ce9e5b03d8
commit 2ca0079f9e
3 changed files with 46 additions and 35 deletions

View File

@ -42,8 +42,8 @@ type StateProps = {
enum AppScreens { enum AppScreens {
auth, auth,
lock,
main, main,
lock,
inactive, inactive,
} }

View File

@ -175,11 +175,11 @@ function Transition({
activeKey, activeKey,
currentKeyRef, currentKeyRef,
container, container,
childNodes[activeIndex],
childNodes[prevActiveIndex],
shouldRestoreHeight, shouldRestoreHeight,
onStart, onStart,
onStop, onStop,
childNodes[activeIndex] as HTMLElement,
childNodes[prevActiveIndex] as HTMLElement,
); );
return; return;
@ -347,27 +347,27 @@ function performSlideOptimized(
activeKey: number, activeKey: number,
currentKeyRef: { current: number | undefined }, currentKeyRef: { current: number | undefined },
container: HTMLElement, container: HTMLElement,
toSlide: ChildNode,
fromSlide?: ChildNode,
shouldRestoreHeight?: boolean, shouldRestoreHeight?: boolean,
onStart?: NoneToVoidFunction, onStart?: NoneToVoidFunction,
onStop?: NoneToVoidFunction, onStop?: NoneToVoidFunction,
toSlide?: HTMLElement,
fromSlide?: HTMLElement,
) { ) {
if (!fromSlide || !toSlide) {
return;
}
if (shouldDisableAnimation) { if (shouldDisableAnimation) {
toggleExtraClass(container, `Transition-${name}`, !isBackwards); toggleExtraClass(container, `Transition-${name}`, !isBackwards);
toggleExtraClass(container, `Transition-${name}Backwards`, isBackwards); toggleExtraClass(container, `Transition-${name}Backwards`, isBackwards);
fromSlide.style.transition = 'none'; if (fromSlide instanceof HTMLElement) {
fromSlide.style.transform = ''; fromSlide.style.transition = 'none';
removeExtraClass(fromSlide, CLASSES.active); fromSlide.style.transform = '';
removeExtraClass(fromSlide, CLASSES.active);
}
toSlide.style.transition = 'none'; if (toSlide instanceof HTMLElement) {
toSlide.style.transform = 'translate3d(0, 0, 0)'; toSlide.style.transition = 'none';
addExtraClass(toSlide, CLASSES.active); toSlide.style.transform = 'translate3d(0, 0, 0)';
addExtraClass(toSlide, CLASSES.active);
}
cleanup(); cleanup();
@ -385,39 +385,50 @@ function performSlideOptimized(
toggleExtraClass(container, `Transition-${name}`, !isBackwards); toggleExtraClass(container, `Transition-${name}`, !isBackwards);
toggleExtraClass(container, `Transition-${name}Backwards`, isBackwards); toggleExtraClass(container, `Transition-${name}Backwards`, isBackwards);
fromSlide.style.transition = 'none'; if (fromSlide instanceof HTMLElement) {
fromSlide.style.transform = 'translate3d(0, 0, 0)'; fromSlide.style.transition = 'none';
fromSlide.style.transform = 'translate3d(0, 0, 0)';
}
toSlide.style.transition = 'none'; if (toSlide instanceof HTMLElement) {
toSlide.style.transform = `translate3d(${isBackwards ? '-' : ''}100%, 0, 0)`; toSlide.style.transition = 'none';
toSlide.style.transform = `translate3d(${isBackwards ? '-' : ''}100%, 0, 0)`;
}
requestForcedReflow(() => { requestForcedReflow(() => {
forceReflow(toSlide); if (toSlide instanceof HTMLElement) {
forceReflow(toSlide);
}
return () => { return () => {
fromSlide.style.transition = ''; if (fromSlide instanceof HTMLElement) {
fromSlide.style.transform = `translate3d(${isBackwards ? '' : '-'}100%, 0, 0)`; fromSlide.style.transition = '';
fromSlide.style.transform = `translate3d(${isBackwards ? '' : '-'}100%, 0, 0)`;
removeExtraClass(fromSlide, CLASSES.active);
}
toSlide.style.transition = ''; if (toSlide instanceof HTMLElement) {
toSlide.style.transform = 'translate3d(0, 0, 0)'; toSlide.style.transition = '';
toSlide.style.transform = 'translate3d(0, 0, 0)';
removeExtraClass(fromSlide, CLASSES.active); addExtraClass(toSlide, CLASSES.active);
addExtraClass(toSlide, CLASSES.active); }
}; };
}); });
waitForTransitionEnd(fromSlide, () => { waitForTransitionEnd(toSlide, () => {
const { clientHeight } = toSlide; const clientHeight = toSlide instanceof HTMLElement ? toSlide.clientHeight : undefined;
requestMutation(() => { requestMutation(() => {
if (activeKey !== currentKeyRef.current) { if (activeKey !== currentKeyRef.current) {
return; return;
} }
fromSlide.style.transition = 'none'; if (fromSlide instanceof HTMLElement) {
fromSlide.style.transform = ''; fromSlide.style.transition = 'none';
fromSlide.style.transform = '';
}
if (shouldRestoreHeight) { if (shouldRestoreHeight && clientHeight && toSlide instanceof HTMLElement) {
toSlide.style.height = 'auto'; toSlide.style.height = 'auto';
container.style.height = `${clientHeight}px`; container.style.height = `${clientHeight}px`;
} }

View File

@ -710,7 +710,7 @@ function updateClassName(element: HTMLElement, value: string) {
export function addExtraClass(element: Element, className: string, forceSingle = false) { export function addExtraClass(element: Element, className: string, forceSingle = false) {
if (!forceSingle) { if (!forceSingle) {
const classNames = className.split(' '); const classNames = className.split(' ');
if (className.length > 1) { if (classNames.length > 1) {
classNames.forEach((cn) => { classNames.forEach((cn) => {
addExtraClass(element, cn, true); addExtraClass(element, cn, true);
}); });
@ -732,7 +732,7 @@ export function addExtraClass(element: Element, className: string, forceSingle =
export function removeExtraClass(element: Element, className: string, forceSingle = false) { export function removeExtraClass(element: Element, className: string, forceSingle = false) {
if (!forceSingle) { if (!forceSingle) {
const classNames = className.split(' '); const classNames = className.split(' ');
if (className.length > 1) { if (classNames.length > 1) {
classNames.forEach((cn) => { classNames.forEach((cn) => {
removeExtraClass(element, cn, true); removeExtraClass(element, cn, true);
}); });
@ -756,7 +756,7 @@ export function removeExtraClass(element: Element, className: string, forceSingl
export function toggleExtraClass(element: Element, className: string, force?: boolean, forceSingle = false) { export function toggleExtraClass(element: Element, className: string, force?: boolean, forceSingle = false) {
if (!forceSingle) { if (!forceSingle) {
const classNames = className.split(' '); const classNames = className.split(' ');
if (className.length > 1) { if (classNames.length > 1) {
classNames.forEach((cn) => { classNames.forEach((cn) => {
toggleExtraClass(element, cn, force, true); toggleExtraClass(element, cn, force, true);
}); });