From 846ec883d4aa01388e8c68fcf2d6f55a507a52a7 Mon Sep 17 00:00:00 2001 From: Alexander Zinchuk Date: Sun, 22 Feb 2026 23:43:16 +0100 Subject: [PATCH] Modal: Freeze children and header during close animation (#6667) --- src/components/ui/Modal.tsx | 67 +++++++++++++++++++++---------------- 1 file changed, 38 insertions(+), 29 deletions(-) diff --git a/src/components/ui/Modal.tsx b/src/components/ui/Modal.tsx index b446dd288..01fe588a1 100644 --- a/src/components/ui/Modal.tsx +++ b/src/components/ui/Modal.tsx @@ -1,4 +1,4 @@ -import type { ElementRef, FC, TeactNode } from '../../lib/teact/teact'; +import type { ElementRef, TeactNode } from '../../lib/teact/teact'; import type React from '../../lib/teact/teact'; import { beginHeavyAnimation, useEffect, useRef } from '../../lib/teact/teact'; @@ -10,6 +10,7 @@ import { disableDirectTextInput, enableDirectTextInput } from '../../util/direct import trapFocus from '../../util/trapFocus'; import useContextMenuHandlers from '../../hooks/useContextMenuHandlers'; +import useFrozenProps from '../../hooks/useFrozenProps'; import useHistoryBack from '../../hooks/useHistoryBack'; import useLastCallback from '../../hooks/useLastCallback'; import useLayoutEffectWithPrevDeps from '../../hooks/useLayoutEffectWithPrevDeps'; @@ -52,36 +53,20 @@ export type OwnProps = { withBalanceBar?: boolean; currencyInBalanceBar?: 'TON' | 'XTR'; isCondensedHeader?: boolean; + noFreezeOnClose?: boolean; }; -const Modal: FC = ({ - dialogRef, - title, - className, - contentClassName, - headerClassName, - isOpen, - isSlim, - header, - hasCloseButton, - hasAbsoluteCloseButton, - absoluteCloseButtonColor = 'translucent', - noBackdrop, - noBackdropClose, - children, - style, - dialogStyle, - isLowStackPriority, - dialogContent, - dialogClassName, - moreMenuItems, - onClose, - onCloseAnimationEnd, - onEnter, - withBalanceBar, - isCondensedHeader, - currencyInBalanceBar = 'XTR', -}) => { +const Modal = (props: OwnProps) => { + const { + dialogRef, + isOpen, + noBackdropClose, + onClose, + onCloseAnimationEnd, + onEnter, + noFreezeOnClose, + } = props; + const { ref: modalRef, shouldRender, @@ -91,6 +76,30 @@ const Modal: FC = ({ withShouldRender: true, }); + const shouldFreeze = !noFreezeOnClose && !isOpen; + const { + title, + isLowStackPriority, + header, + children, + className, + contentClassName, + headerClassName, + dialogClassName, + isSlim, + hasCloseButton, + hasAbsoluteCloseButton, + absoluteCloseButtonColor = 'translucent', + noBackdrop, + style, + dialogStyle, + dialogContent, + moreMenuItems, + withBalanceBar, + isCondensedHeader, + currencyInBalanceBar = 'XTR', + } = useFrozenProps(props, shouldFreeze); + const localDialogRef = useRef(); const moreButtonRef = useRef(); const menuRef = useRef();