Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/components/DatePicker/DatePickerModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ function DatePickerModal({
shouldMeasureAnchorPositionFromTop={shouldPositionFromTop}
shouldSkipRemeasurement
forwardedFSClass={forwardedFSClass}
shouldDisplayBelowModals
>
<CalendarPicker
minDate={minDate}
Expand Down
3 changes: 3 additions & 0 deletions src/components/Modal/BaseModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ function BaseModal({
shouldIgnoreBackHandlerDuringTransition = false,
forwardedFSClass = CONST.FULLSTORY.CLASS.UNMASK,
ref,
shouldDisplayBelowModals = false,
}: BaseModalProps) {
// When the `enableEdgeToEdgeBottomSafeAreaPadding` prop is explicitly set, we enable edge-to-edge mode.
const isUsingEdgeToEdgeMode = enableEdgeToEdgeBottomSafeAreaPadding !== undefined;
Expand Down Expand Up @@ -241,6 +242,7 @@ function BaseModal({
modalOverlapsWithTopSafeArea,
shouldDisableBottomSafeAreaPadding: !!shouldDisableBottomSafeAreaPadding,
},
shouldDisplayBelowModals,
),
[
StyleUtils,
Expand All @@ -255,6 +257,7 @@ function BaseModal({
shouldUseModalPaddingStyle,
modalOverlapsWithTopSafeArea,
shouldDisableBottomSafeAreaPadding,
shouldDisplayBelowModals,
],
);

Expand Down
5 changes: 5 additions & 0 deletions src/components/Modal/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,11 @@ type BaseModalProps = Partial<ReanimatedModalProps> &
* Reference to the outer element.
*/
ref?: ForwardedRef<View>;

/**
* Whether the modal should display under the side panel.
*/
shouldDisplayBelowModals?: boolean;
};

export default BaseModalProps;
Expand Down
3 changes: 3 additions & 0 deletions src/components/Popover/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 below other modals (e.g. SidePanel, RHP) */
shouldDisplayBelowModals?: boolean;
};

export default PopoverProps;
2 changes: 1 addition & 1 deletion src/components/PopoverWithMeasuredContent/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down
8 changes: 5 additions & 3 deletions src/components/PopoverWithoutOverlay/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand All @@ -25,6 +25,7 @@ function PopoverWithoutOverlay({
onModalHide = () => {},
children,
ref,
shouldDisplayBelowModals = false,
}: PopoverWithoutOverlayProps) {
const styles = useThemeStyles();
const StyleUtils = useStyleUtils();
Expand All @@ -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,
Expand All @@ -42,6 +43,7 @@ function PopoverWithoutOverlay({
anchorPosition,
innerContainerStyle,
outerStyle,
shouldDisplayBelowModals,
);

useEffect(() => {
Expand Down Expand Up @@ -91,7 +93,7 @@ function PopoverWithoutOverlay({

return (
<View
style={[modalStyle, {zIndex: variables.popoverZIndex}]}
style={modalStyle}
ref={viewRef(withoutOverlayRef)}
// Prevent the parent element to capture a click. This is useful when the modal component is put inside a pressable.
onClick={(e) => e.stopPropagation()}
Expand Down
3 changes: 3 additions & 0 deletions src/components/PopoverWithoutOverlay/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ type PopoverWithoutOverlayProps = ChildrenProps &

/** Reference to the outer element */
ref?: ForwardedRef<View>;

/** Whether we should display the popover below other modals (e.g. SidePanel, RHP) */
shouldDisplayBelowModals?: boolean;
};

export default PopoverWithoutOverlayProps;
4 changes: 4 additions & 0 deletions src/styles/utils/generators/ModalStyleUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ type GetModalStylesStyleUtil = {
shouldDisableBottomSafeAreaPadding?: boolean;
modalOverlapsWithTopSafeArea?: boolean;
},
shouldDisplayBelowModals?: boolean,
) => GetModalStyles;
};

Expand All @@ -60,6 +61,7 @@ const createModalStyleUtils: StyleUtilGenerator<GetModalStylesStyleUtil> = ({the
outerStyle = {},
shouldUseModalPaddingStyle = true,
safeAreaOptions = {modalOverlapsWithTopSafeArea: false, shouldDisableBottomSafeAreaPadding: false},
shouldDisplayBelowModals = false,
): GetModalStyles => {
const {windowWidth, isSmallScreenWidth} = windowDimensions;

Expand Down Expand Up @@ -222,6 +224,7 @@ const createModalStyleUtils: StyleUtilGenerator<GetModalStylesStyleUtil> = ({the
alignItems: 'center',
justifyContent: 'flex-end',
height: '100%',
zIndex: shouldDisplayBelowModals ? variables.modalLowestZIndex : variables.modalBaseZIndex,
};
modalContainerStyle = {
width: '100%',
Expand Down Expand Up @@ -254,6 +257,7 @@ const createModalStyleUtils: StyleUtilGenerator<GetModalStylesStyleUtil> = ({the
position: 'absolute',
alignItems: 'center',
justifyContent: 'flex-end',
zIndex: shouldDisplayBelowModals ? variables.modalLowestZIndex : variables.popoverZIndex,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Staging regression test is already complete.
As the PR will be CP'ed to staging, let's make sure that this change doesn't cause any other regressions before reaching production.

@blazejkustra blazejkustra Dec 22, 2025

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should only affect components that use shouldDisplayBelowModals prop set to true, for now that's only CalenderPicker! I agree we should double check it doesn't cause any further regressions

};
modalContainerStyle = {
borderRadius: variables.componentBorderRadiusLarge,
Expand Down
3 changes: 2 additions & 1 deletion src/styles/variables.ts
Original file line number Diff line number Diff line change
Expand Up @@ -223,10 +223,11 @@ export default {
reportActionImagesDoubleImageHeight: 138,
reportActionImagesMultipleImageHeight: 110,
reportActionItemImagesMoreCornerTriangleWidth: 40,
popoverZIndex: 10000,
Comment thread
blazejkustra marked this conversation as resolved.
modalBaseZIndex: 9999,
sidePanelZIndex: 9998,
modalRightDockedZIndex: 9997,
popoverZIndex: 10000,
modalLowestZIndex: 9996,
workspaceTypeIconWidth: 34,
sectionMargin: 16,
workspaceSectionMaxWidth: 680,
Expand Down
Loading