From f253fad33fbac75fa6cd6c95831b6135ebc87119 Mon Sep 17 00:00:00 2001 From: Blazej Kustra Date: Mon, 22 Dec 2025 11:33:32 +0100 Subject: [PATCH 1/3] Add shouldDisplayUnderSidePanel prop to modals and popovers - Introduced `shouldDisplayUnderSidePanel` prop in `BaseModal`, `Popover`, and `PopoverWithoutOverlay` components to control display behavior under side panels. - Updated relevant types and styles to accommodate the new prop. - Added a new z-index variable for popovers displayed under side panels. --- src/components/DatePicker/DatePickerModal.tsx | 1 + src/components/Modal/BaseModal.tsx | 3 +++ src/components/Modal/types.ts | 5 +++++ src/components/Popover/types.ts | 3 +++ src/components/PopoverWithMeasuredContent/index.tsx | 2 +- src/components/PopoverWithoutOverlay/index.tsx | 8 +++++--- src/components/PopoverWithoutOverlay/types.ts | 3 +++ src/styles/utils/generators/ModalStyleUtils.ts | 3 +++ src/styles/variables.ts | 1 + 9 files changed, 25 insertions(+), 4 deletions(-) diff --git a/src/components/DatePicker/DatePickerModal.tsx b/src/components/DatePicker/DatePickerModal.tsx index 561e0c6ea03..45bf6d82ce3 100644 --- a/src/components/DatePicker/DatePickerModal.tsx +++ b/src/components/DatePicker/DatePickerModal.tsx @@ -76,6 +76,7 @@ function DatePickerModal({ shouldMeasureAnchorPositionFromTop={shouldPositionFromTop} shouldSkipRemeasurement forwardedFSClass={forwardedFSClass} + shouldDisplayUnderSidePanel > & * Reference to the outer element. */ ref?: ForwardedRef; + + /** + * Whether the modal should display under the side panel. + */ + shouldDisplayUnderSidePanel?: boolean; }; export default BaseModalProps; diff --git a/src/components/Popover/types.ts b/src/components/Popover/types.ts index 7f724e0c6d1..5ddf729e8de 100644 --- a/src/components/Popover/types.ts +++ b/src/components/Popover/types.ts @@ -35,6 +35,9 @@ type PopoverProps = BaseModalProps & /** Whether we should close when browser navigation change. This doesn't affect native platform */ shouldCloseWhenBrowserNavigationChanged?: boolean; + + /** Whether we should display the popover under the side panel */ + shouldDisplayUnderSidePanel?: boolean; }; export default PopoverProps; diff --git a/src/components/PopoverWithMeasuredContent/index.tsx b/src/components/PopoverWithMeasuredContent/index.tsx index 99337b1b592..7cf5a65d088 100644 --- a/src/components/PopoverWithMeasuredContent/index.tsx +++ b/src/components/PopoverWithMeasuredContent/index.tsx @@ -11,7 +11,7 @@ import type PopoverWithMeasuredContentProps from './types'; * This component is a perf optimization, it return BOTTOM_DOCKED early, for small screens avoiding Popover measurement logic calculations. * It defers rendering of PopoverWithMeasuredContentBase to idle time to avoid blocking more priority UI updates with measurements. */ -function PopoverWithMeasuredContent({...props}: PopoverWithMeasuredContentProps) { +function PopoverWithMeasuredContent(props: PopoverWithMeasuredContentProps) { // eslint-disable-next-line rulesdir/prefer-shouldUseNarrowLayout-instead-of-isSmallScreenWidth const {isSmallScreenWidth} = useResponsiveLayout(); diff --git a/src/components/PopoverWithoutOverlay/index.tsx b/src/components/PopoverWithoutOverlay/index.tsx index 8f84bfbbefa..3041b0bcef5 100644 --- a/src/components/PopoverWithoutOverlay/index.tsx +++ b/src/components/PopoverWithoutOverlay/index.tsx @@ -7,7 +7,7 @@ import useStyleUtils from '@hooks/useStyleUtils'; import useThemeStyles from '@hooks/useThemeStyles'; import useWindowDimensions from '@hooks/useWindowDimensions'; import {onModalDidClose, setCloseModal, willAlertModalBecomeVisible} from '@libs/actions/Modal'; -import variables from '@styles/variables'; +import CONST from '@src/CONST'; import viewRef from '@src/types/utils/viewRef'; import type PopoverWithoutOverlayProps from './types'; @@ -25,6 +25,7 @@ function PopoverWithoutOverlay({ onModalHide = () => {}, children, ref, + shouldDisplayUnderSidePanel = false, }: PopoverWithoutOverlayProps) { const styles = useThemeStyles(); const StyleUtils = useStyleUtils(); @@ -33,7 +34,7 @@ function PopoverWithoutOverlay({ const insets = useSafeAreaInsets(); const {modalStyle, modalContainerStyle, shouldAddTopSafeAreaMargin, shouldAddBottomSafeAreaMargin, shouldAddTopSafeAreaPadding, shouldAddBottomSafeAreaPadding} = StyleUtils.getModalStyles( - 'popover', + CONST.MODAL.MODAL_TYPE.POPOVER, { windowWidth, windowHeight, @@ -42,6 +43,7 @@ function PopoverWithoutOverlay({ anchorPosition, innerContainerStyle, outerStyle, + shouldDisplayUnderSidePanel, ); useEffect(() => { @@ -91,7 +93,7 @@ function PopoverWithoutOverlay({ return ( e.stopPropagation()} diff --git a/src/components/PopoverWithoutOverlay/types.ts b/src/components/PopoverWithoutOverlay/types.ts index d7009d8783e..60a186b92c5 100644 --- a/src/components/PopoverWithoutOverlay/types.ts +++ b/src/components/PopoverWithoutOverlay/types.ts @@ -28,6 +28,9 @@ type PopoverWithoutOverlayProps = ChildrenProps & /** Reference to the outer element */ ref?: ForwardedRef; + + /** Whether we should display the popover under the side panel */ + shouldDisplayUnderSidePanel?: boolean; }; export default PopoverWithoutOverlayProps; diff --git a/src/styles/utils/generators/ModalStyleUtils.ts b/src/styles/utils/generators/ModalStyleUtils.ts index baa2bbb7fab..d41f80ee2fd 100644 --- a/src/styles/utils/generators/ModalStyleUtils.ts +++ b/src/styles/utils/generators/ModalStyleUtils.ts @@ -48,6 +48,7 @@ type GetModalStylesStyleUtil = { shouldDisableBottomSafeAreaPadding?: boolean; modalOverlapsWithTopSafeArea?: boolean; }, + shouldDisplayUnderSidePanel?: boolean, ) => GetModalStyles; }; @@ -60,6 +61,7 @@ const createModalStyleUtils: StyleUtilGenerator = ({the outerStyle = {}, shouldUseModalPaddingStyle = true, safeAreaOptions = {modalOverlapsWithTopSafeArea: false, shouldDisableBottomSafeAreaPadding: false}, + shouldDisplayUnderSidePanel = false, ): GetModalStyles => { const {windowWidth, isSmallScreenWidth} = windowDimensions; @@ -254,6 +256,7 @@ const createModalStyleUtils: StyleUtilGenerator = ({the position: 'absolute', alignItems: 'center', justifyContent: 'flex-end', + zIndex: shouldDisplayUnderSidePanel ? variables.popoverUnderSidePanelZIndex : variables.popoverZIndex, }; modalContainerStyle = { borderRadius: variables.componentBorderRadiusLarge, diff --git a/src/styles/variables.ts b/src/styles/variables.ts index e694e98f04e..559c05eec5c 100644 --- a/src/styles/variables.ts +++ b/src/styles/variables.ts @@ -226,6 +226,7 @@ export default { modalBaseZIndex: 9999, sidePanelZIndex: 9998, modalRightDockedZIndex: 9997, + popoverUnderSidePanelZIndex: 9996, popoverZIndex: 10000, workspaceTypeIconWidth: 34, sectionMargin: 16, From e72bfbb7ec45d57fd432f52dc9723e197ef43f03 Mon Sep 17 00:00:00 2001 From: Blazej Kustra Date: Mon, 22 Dec 2025 11:55:39 +0100 Subject: [PATCH 2/3] Change namings, improve logic on smaller screens --- src/components/DatePicker/DatePickerModal.tsx | 2 +- src/components/Modal/BaseModal.tsx | 6 +++--- src/components/Modal/types.ts | 2 +- src/components/Popover/types.ts | 2 +- src/components/PopoverWithoutOverlay/index.tsx | 4 ++-- src/components/PopoverWithoutOverlay/types.ts | 2 +- src/styles/utils/generators/ModalStyleUtils.ts | 7 ++++--- src/styles/variables.ts | 4 ++-- 8 files changed, 15 insertions(+), 14 deletions(-) diff --git a/src/components/DatePicker/DatePickerModal.tsx b/src/components/DatePicker/DatePickerModal.tsx index 45bf6d82ce3..88f71d53cab 100644 --- a/src/components/DatePicker/DatePickerModal.tsx +++ b/src/components/DatePicker/DatePickerModal.tsx @@ -76,7 +76,7 @@ function DatePickerModal({ shouldMeasureAnchorPositionFromTop={shouldPositionFromTop} shouldSkipRemeasurement forwardedFSClass={forwardedFSClass} - shouldDisplayUnderSidePanel + shouldDisplayBelowModals > & /** * Whether the modal should display under the side panel. */ - shouldDisplayUnderSidePanel?: boolean; + shouldDisplayBelowModals?: boolean; }; export default BaseModalProps; diff --git a/src/components/Popover/types.ts b/src/components/Popover/types.ts index 5ddf729e8de..56a3546dd96 100644 --- a/src/components/Popover/types.ts +++ b/src/components/Popover/types.ts @@ -37,7 +37,7 @@ type PopoverProps = BaseModalProps & shouldCloseWhenBrowserNavigationChanged?: boolean; /** Whether we should display the popover under the side panel */ - shouldDisplayUnderSidePanel?: boolean; + shouldDisplayBelowModals?: boolean; }; export default PopoverProps; diff --git a/src/components/PopoverWithoutOverlay/index.tsx b/src/components/PopoverWithoutOverlay/index.tsx index 3041b0bcef5..9f7ecaa53d3 100644 --- a/src/components/PopoverWithoutOverlay/index.tsx +++ b/src/components/PopoverWithoutOverlay/index.tsx @@ -25,7 +25,7 @@ function PopoverWithoutOverlay({ onModalHide = () => {}, children, ref, - shouldDisplayUnderSidePanel = false, + shouldDisplayBelowModals = false, }: PopoverWithoutOverlayProps) { const styles = useThemeStyles(); const StyleUtils = useStyleUtils(); @@ -43,7 +43,7 @@ function PopoverWithoutOverlay({ anchorPosition, innerContainerStyle, outerStyle, - shouldDisplayUnderSidePanel, + shouldDisplayBelowModals, ); useEffect(() => { diff --git a/src/components/PopoverWithoutOverlay/types.ts b/src/components/PopoverWithoutOverlay/types.ts index 60a186b92c5..cff25e99191 100644 --- a/src/components/PopoverWithoutOverlay/types.ts +++ b/src/components/PopoverWithoutOverlay/types.ts @@ -30,7 +30,7 @@ type PopoverWithoutOverlayProps = ChildrenProps & ref?: ForwardedRef; /** Whether we should display the popover under the side panel */ - shouldDisplayUnderSidePanel?: boolean; + shouldDisplayBelowModals?: boolean; }; export default PopoverWithoutOverlayProps; diff --git a/src/styles/utils/generators/ModalStyleUtils.ts b/src/styles/utils/generators/ModalStyleUtils.ts index d41f80ee2fd..5c0082cf851 100644 --- a/src/styles/utils/generators/ModalStyleUtils.ts +++ b/src/styles/utils/generators/ModalStyleUtils.ts @@ -48,7 +48,7 @@ type GetModalStylesStyleUtil = { shouldDisableBottomSafeAreaPadding?: boolean; modalOverlapsWithTopSafeArea?: boolean; }, - shouldDisplayUnderSidePanel?: boolean, + shouldDisplayBelowModals?: boolean, ) => GetModalStyles; }; @@ -61,7 +61,7 @@ const createModalStyleUtils: StyleUtilGenerator = ({the outerStyle = {}, shouldUseModalPaddingStyle = true, safeAreaOptions = {modalOverlapsWithTopSafeArea: false, shouldDisableBottomSafeAreaPadding: false}, - shouldDisplayUnderSidePanel = false, + shouldDisplayBelowModals = false, ): GetModalStyles => { const {windowWidth, isSmallScreenWidth} = windowDimensions; @@ -224,6 +224,7 @@ const createModalStyleUtils: StyleUtilGenerator = ({the alignItems: 'center', justifyContent: 'flex-end', height: '100%', + zIndex: shouldDisplayBelowModals ? variables.modalLowestZIndex : variables.modalBaseZIndex, }; modalContainerStyle = { width: '100%', @@ -256,7 +257,7 @@ const createModalStyleUtils: StyleUtilGenerator = ({the position: 'absolute', alignItems: 'center', justifyContent: 'flex-end', - zIndex: shouldDisplayUnderSidePanel ? variables.popoverUnderSidePanelZIndex : variables.popoverZIndex, + zIndex: shouldDisplayBelowModals ? variables.modalLowestZIndex : variables.popoverZIndex, }; modalContainerStyle = { borderRadius: variables.componentBorderRadiusLarge, diff --git a/src/styles/variables.ts b/src/styles/variables.ts index 559c05eec5c..c85cacbbff5 100644 --- a/src/styles/variables.ts +++ b/src/styles/variables.ts @@ -223,11 +223,11 @@ export default { reportActionImagesDoubleImageHeight: 138, reportActionImagesMultipleImageHeight: 110, reportActionItemImagesMoreCornerTriangleWidth: 40, + popoverZIndex: 10000, modalBaseZIndex: 9999, sidePanelZIndex: 9998, modalRightDockedZIndex: 9997, - popoverUnderSidePanelZIndex: 9996, - popoverZIndex: 10000, + modalLowestZIndex: 9996, workspaceTypeIconWidth: 34, sectionMargin: 16, workspaceSectionMaxWidth: 680, From 9526c3042ccb26e217c8ce671ee3a1d35b151181 Mon Sep 17 00:00:00 2001 From: Blazej Kustra Date: Mon, 22 Dec 2025 12:53:26 +0100 Subject: [PATCH 3/3] Update Popover and PopoverWithoutOverlay types to clarify prop description for shouldDisplayBelowModals --- src/components/Popover/types.ts | 2 +- src/components/PopoverWithoutOverlay/types.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/Popover/types.ts b/src/components/Popover/types.ts index 56a3546dd96..f7917bee6d7 100644 --- a/src/components/Popover/types.ts +++ b/src/components/Popover/types.ts @@ -36,7 +36,7 @@ type PopoverProps = BaseModalProps & /** Whether we should close when browser navigation change. This doesn't affect native platform */ shouldCloseWhenBrowserNavigationChanged?: boolean; - /** Whether we should display the popover under the side panel */ + /** Whether we should display the popover below other modals (e.g. SidePanel, RHP) */ shouldDisplayBelowModals?: boolean; }; diff --git a/src/components/PopoverWithoutOverlay/types.ts b/src/components/PopoverWithoutOverlay/types.ts index cff25e99191..afd8bc8a053 100644 --- a/src/components/PopoverWithoutOverlay/types.ts +++ b/src/components/PopoverWithoutOverlay/types.ts @@ -29,7 +29,7 @@ type PopoverWithoutOverlayProps = ChildrenProps & /** Reference to the outer element */ ref?: ForwardedRef; - /** Whether we should display the popover under the side panel */ + /** Whether we should display the popover below other modals (e.g. SidePanel, RHP) */ shouldDisplayBelowModals?: boolean; };