Skip to content

Commit

Permalink
Merge pull request #30624 from kubabutkiewicz/ts-migration/ConfirmPop…
Browse files Browse the repository at this point in the history
…over/component

[TS migration] Migrate 'Popover.js' component to TypeScript
  • Loading branch information
chiragsalian authored Nov 29, 2023
2 parents ff18fdd + 627ac09 commit 5197b40
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 41 deletions.
1 change: 1 addition & 0 deletions src/components/Modal/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,4 @@ type BaseModalProps = WindowDimensionsProps &
};

export default BaseModalProps;
export type {PopoverAnchorPosition};
35 changes: 0 additions & 35 deletions src/components/Popover/index.native.js

This file was deleted.

27 changes: 27 additions & 0 deletions src/components/Popover/index.native.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import React from 'react';
import Modal from '@components/Modal';
import CONST from '@src/CONST';
import {PopoverProps} from './types';

/*
* This is a convenience wrapper around the Modal component for a responsive Popover.
* On small screen widths, it uses BottomDocked modal type, and a Popover type on wide screen widths.
*/
function Popover({animationIn, animationOut, popoverAnchorPosition, disableAnimation, anchorPosition = {}, fromSidebarMediumScreen, ...propsWithoutAnimation}: PopoverProps) {
return (
<Modal
type={fromSidebarMediumScreen ? CONST.MODAL.MODAL_TYPE.POPOVER : CONST.MODAL.MODAL_TYPE.BOTTOM_DOCKED}
popoverAnchorPosition={fromSidebarMediumScreen ? anchorPosition : undefined}
// eslint-disable-next-line react/jsx-props-no-spreading
{...propsWithoutAnimation}
// Mobile will always has fullscreen menu
fullscreen
animationIn="slideInUp"
animationOut="slideOutDown"
/>
);
}

Popover.displayName = 'Popover';

export default Popover;
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,30 @@ import {PopoverContext} from '@components/PopoverProvider';
import PopoverWithoutOverlay from '@components/PopoverWithoutOverlay';
import withWindowDimensions from '@components/withWindowDimensions';
import CONST from '@src/CONST';
import {defaultProps, propTypes} from './popoverPropTypes';
import {PopoverWithWindowDimensionsProps} from './types';

/*
* This is a convenience wrapper around the Modal component for a responsive Popover.
* On small screen widths, it uses BottomDocked modal type, and a Popover type on wide screen widths.
*/
function Popover(props) {
const {isVisible, onClose, isSmallScreenWidth, fullscreen, animationInTiming, onLayout, animationOutTiming, disableAnimation, withoutOverlay, anchorPosition, anchorRef} = props;

function Popover(props: PopoverWithWindowDimensionsProps) {
const {
isVisible,
onClose,
isSmallScreenWidth,
fullscreen,
animationInTiming = CONST.ANIMATED_TRANSITION,
onLayout,
animationOutTiming,
disableAnimation = true,
withoutOverlay,
anchorPosition = {},
anchorRef = () => {},
animationIn = 'fadeIn',
animationOut = 'fadeOut',
} = props;

const withoutOverlayRef = useRef(null);
const {close, popover} = React.useContext(PopoverContext);

Expand All @@ -33,7 +49,7 @@ function Popover(props) {
}, [onClose, isVisible]);

const onCloseWithPopoverContext = () => {
if (popover) {
if (popover && 'current' in anchorRef) {
close(anchorRef);
}
onClose();
Expand All @@ -51,6 +67,8 @@ function Popover(props) {
animationOutTiming={disableAnimation ? 1 : animationOutTiming}
shouldCloseOnOutsideClick
onLayout={onLayout}
animationIn={animationIn}
animationOut={animationOut}
/>,
document.body,
);
Expand All @@ -62,6 +80,8 @@ function Popover(props) {
// eslint-disable-next-line react/jsx-props-no-spreading
{...props}
withoutOverlayRef={withoutOverlayRef}
animationIn={animationIn}
animationOut={animationOut}
/>,
document.body,
);
Expand All @@ -78,12 +98,12 @@ function Popover(props) {
animationInTiming={disableAnimation && !isSmallScreenWidth ? 1 : animationInTiming}
animationOutTiming={disableAnimation && !isSmallScreenWidth ? 1 : animationOutTiming}
onLayout={onLayout}
animationIn={animationIn}
animationOut={animationOut}
/>
);
}

Popover.propTypes = propTypes;
Popover.defaultProps = defaultProps;
Popover.displayName = 'Popover';

export default withWindowDimensions(Popover);
42 changes: 42 additions & 0 deletions src/components/Popover/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import BaseModalProps, {PopoverAnchorPosition} from '@components/Modal/types';
import {WindowDimensionsProps} from '@components/withWindowDimensions/types';

type AnchorAlignment = {horizontal: string; vertical: string};

type PopoverDimensions = {
width: number;
height: number;
};

type PopoverProps = BaseModalProps & {
/** The anchor position of the popover */
anchorPosition?: PopoverAnchorPosition;

/** The anchor alignment of the popover */
anchorAlignment: AnchorAlignment;

/** The anchor ref of the popover */
anchorRef: React.RefObject<HTMLElement>;

/** Whether disable the animations */
disableAnimation: boolean;

/** Whether we don't want to show overlay */
withoutOverlay: boolean;

/** The dimensions of the popover */
popoverDimensions?: PopoverDimensions;

/** The ref of the popover */
withoutOverlayRef?: React.RefObject<HTMLElement>;

/** Whether we want to show the popover on the right side of the screen */
fromSidebarMediumScreen?: boolean;

/** The popover children */
children: React.ReactNode;
};

type PopoverWithWindowDimensionsProps = PopoverProps & WindowDimensionsProps;

export type {PopoverProps, PopoverWithWindowDimensionsProps};

0 comments on commit 5197b40

Please sign in to comment.