Skip to content

Commit

Permalink
Merge pull request #29857 from kubabutkiewicz/ts-migration/PopoverPro…
Browse files Browse the repository at this point in the history
…vider/component

[No QA] [TS migration] Migrate 'PopoverProvider' component to TypeScript
  • Loading branch information
cristipaval authored Nov 3, 2023
2 parents 935096d + c15d77b commit 7ea89c9
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 41 deletions.
Original file line number Diff line number Diff line change
@@ -1,20 +1,14 @@
import PropTypes from 'prop-types';
import React from 'react';
import {PopoverContextProps, PopoverContextValue} from './types';

const propTypes = {
children: PropTypes.node.isRequired,
};

const defaultProps = {};

const PopoverContext = React.createContext({
const PopoverContext = React.createContext<PopoverContextValue>({
onOpen: () => {},
popover: {},
close: () => {},
isOpen: false,
});

function PopoverContextProvider(props) {
function PopoverContextProvider(props: PopoverContextProps) {
const contextValue = React.useMemo(
() => ({
onOpen: () => {},
Expand All @@ -28,8 +22,6 @@ function PopoverContextProvider(props) {
return <PopoverContext.Provider value={contextValue}>{props.children}</PopoverContext.Provider>;
}

PopoverContextProvider.defaultProps = defaultProps;
PopoverContextProvider.propTypes = propTypes;
PopoverContextProvider.displayName = 'PopoverContextProvider';

export default PopoverContextProvider;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,24 +1,18 @@
import PropTypes from 'prop-types';
import React from 'react';
import {AnchorRef, PopoverContextProps, PopoverContextValue} from './types';

const propTypes = {
children: PropTypes.node.isRequired,
};

const defaultProps = {};

const PopoverContext = React.createContext({
const PopoverContext = React.createContext<PopoverContextValue>({
onOpen: () => {},
popover: {},
close: () => {},
isOpen: false,
});

function PopoverContextProvider(props) {
function PopoverContextProvider(props: PopoverContextProps) {
const [isOpen, setIsOpen] = React.useState(false);
const activePopoverRef = React.useRef(null);
const activePopoverRef = React.useRef<AnchorRef | null>(null);

const closePopover = React.useCallback((anchorRef) => {
const closePopover = React.useCallback((anchorRef?: React.RefObject<HTMLElement>) => {
if (!activePopoverRef.current || (anchorRef && anchorRef !== activePopoverRef.current.anchorRef)) {
return;
}
Expand All @@ -32,17 +26,12 @@ function PopoverContextProvider(props) {
}, []);

React.useEffect(() => {
const listener = (e) => {
if (
!activePopoverRef.current ||
!activePopoverRef.current.ref ||
!activePopoverRef.current.ref.current ||
activePopoverRef.current.ref.current.contains(e.target) ||
(activePopoverRef.current.anchorRef && activePopoverRef.current.anchorRef.current && activePopoverRef.current.anchorRef.current.contains(e.target))
) {
const listener = (e: Event) => {
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
if (activePopoverRef.current?.ref?.current?.contains(e.target as Node) || activePopoverRef.current?.anchorRef?.current?.contains(e.target as Node)) {
return;
}
const ref = activePopoverRef.current.anchorRef;
const ref = activePopoverRef.current?.anchorRef;
closePopover(ref);
};
document.addEventListener('click', listener, true);
Expand All @@ -52,8 +41,8 @@ function PopoverContextProvider(props) {
}, [closePopover]);

React.useEffect(() => {
const listener = (e) => {
if (!activePopoverRef.current || !activePopoverRef.current.ref || !activePopoverRef.current.ref.current || activePopoverRef.current.ref.current.contains(e.target)) {
const listener = (e: Event) => {
if (activePopoverRef.current?.ref?.current?.contains(e.target as Node)) {
return;
}
closePopover();
Expand All @@ -65,7 +54,7 @@ function PopoverContextProvider(props) {
}, [closePopover]);

React.useEffect(() => {
const listener = (e) => {
const listener = (e: KeyboardEvent) => {
if (e.key !== 'Escape') {
return;
}
Expand All @@ -91,8 +80,8 @@ function PopoverContextProvider(props) {
}, [closePopover]);

React.useEffect(() => {
const listener = (e) => {
if (activePopoverRef.current && activePopoverRef.current.ref && activePopoverRef.current.ref.current && activePopoverRef.current.ref.current.contains(e.target)) {
const listener = (e: Event) => {
if (activePopoverRef.current?.ref?.current?.contains(e.target as Node)) {
return;
}

Expand All @@ -105,12 +94,12 @@ function PopoverContextProvider(props) {
}, [closePopover]);

const onOpen = React.useCallback(
(popoverParams) => {
if (activePopoverRef.current && activePopoverRef.current.ref !== popoverParams.ref) {
(popoverParams: AnchorRef) => {
if (activePopoverRef.current && activePopoverRef.current.ref !== popoverParams?.ref) {
closePopover(activePopoverRef.current.anchorRef);
}
activePopoverRef.current = popoverParams;
if (popoverParams && popoverParams.onOpenCallback) {
if (popoverParams?.onOpenCallback) {
popoverParams.onOpenCallback();
}
setIsOpen(true);
Expand All @@ -131,8 +120,6 @@ function PopoverContextProvider(props) {
return <PopoverContext.Provider value={contextValue}>{props.children}</PopoverContext.Provider>;
}

PopoverContextProvider.defaultProps = defaultProps;
PopoverContextProvider.propTypes = propTypes;
PopoverContextProvider.displayName = 'PopoverContextProvider';

export default PopoverContextProvider;
Expand Down
20 changes: 20 additions & 0 deletions src/components/PopoverProvider/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
type PopoverContextProps = {
children: React.ReactNode;
};

type PopoverContextValue = {
onOpen?: (popoverParams: AnchorRef) => void;
popover?: AnchorRef | Record<string, never> | null;
close: (anchorRef?: React.RefObject<HTMLElement>) => void;
isOpen: boolean;
};

type AnchorRef = {
ref: React.RefObject<HTMLElement>;
close: (anchorRef?: React.RefObject<HTMLElement>) => void;
anchorRef: React.RefObject<HTMLElement>;
onOpenCallback?: () => void;
onCloseCallback?: () => void;
};

export type {PopoverContextProps, PopoverContextValue, AnchorRef};

0 comments on commit 7ea89c9

Please sign in to comment.