Skip to content

Commit

Permalink
Merge pull request binary-com#70 from jim-deriv/Jim/79507/fix-parent-…
Browse files Browse the repository at this point in the history
…branch

Jim/79507/fix-parent-branch
  • Loading branch information
jim-deriv committed Oct 25, 2022
2 parents a97049f + 61f740e commit 83d11ca
Show file tree
Hide file tree
Showing 5 changed files with 18 additions and 19 deletions.
15 changes: 5 additions & 10 deletions packages/components/src/components/modal/modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,7 @@ import Body from './modal-body';
import Footer from './modal-footer';
import Text from '../text/text';
import Icon from '../icon/icon';
import { useOnClickOutside } from '../../hooks';

type TClickEvent = React.MouseEvent<HTMLElement, MouseEvent> & {
path?: HTMLElement[];
composedPath?: () => HTMLElement[];
};
import { useOnClickOutside, IClickEvent } from '../../hooks';

type TModalElement = {
className?: string;
Expand Down Expand Up @@ -82,20 +77,20 @@ const ModalElement = ({
const isPortalElementVisible = () =>
modal_root_ref.current?.querySelectorAll(portal_elements_selector.join(', ')).length;

const validateClickOutside = (e: TClickEvent): boolean => {
const validateClickOutside = (e: IClickEvent): boolean => {
const is_absolute_modal_visible = document.getElementById('modal_root_absolute')?.hasChildNodes();
const path = e.path ?? e.composedPath?.();
return (
has_close_icon &&
!isPortalElementVisible() &&
is_open &&
!is_absolute_modal_visible &&
!(elements_to_ignore && path?.find(el => elements_to_ignore.includes(el)))
!(elements_to_ignore && path?.find(el => elements_to_ignore.includes(el as HTMLElement)))
);
};

const closeModal = (e: React.MouseEvent<HTMLElement>) => {
if (is_open) toggleModal?.(e);
const closeModal = () => {
if (is_open) toggleModal?.();
};

useOnClickOutside(wrapper_ref, closeModal, validateClickOutside);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ const ThemedScrollbars = ({
style = {},
width,
}: React.PropsWithChildren<TThemedScrollbars>) => {
const [hoverRef, isHovered] = useHover(refSetter);
const [hoverRef, isHovered] = useHover<HTMLDivElement>(refSetter, false);

if (is_bypassed) return children;
return (
Expand Down
4 changes: 2 additions & 2 deletions packages/components/src/hooks/use-hover.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { RefObject } from 'react';

export const useHover = (refSetter: RefObject<HTMLElement> | null, should_prevent_bubbling: boolean) => {
export const useHover = <T extends HTMLElement>(refSetter: RefObject<T> | null, should_prevent_bubbling: boolean) => {
const [value, setValue] = React.useState(false);
const default_ref = React.useRef(null);
const ref = refSetter || default_ref;
Expand Down Expand Up @@ -32,7 +32,7 @@ export const useHover = (refSetter: RefObject<HTMLElement> | null, should_preven
return undefined;
}, [ref, should_prevent_bubbling]);

return [ref, value];
return [ref, value] as const;
};

export const useHoverCallback = () => {
Expand Down
2 changes: 1 addition & 1 deletion packages/components/src/hooks/use-interval.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';

export const useInterval = (callback: () => void, delay: number) => {
export const useInterval = (callback: () => void, delay: number | null) => {
const savedCallback = React.useRef<() => void | undefined>();
React.useEffect(() => {
savedCallback.current = callback;
Expand Down
14 changes: 9 additions & 5 deletions packages/components/src/hooks/use-onclickoutside.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,23 @@
import React, { RefObject } from 'react';

export interface IClickEvent extends MouseEvent {
path?: HTMLElement[];
}

export const useOnClickOutside = (
ref: RefObject<HTMLElement>,
handler: (event: MouseEvent) => void,
validationFn: (event: MouseEvent) => boolean
handler: (event?: IClickEvent) => void,
validationFn: (event: IClickEvent) => boolean
) => {
React.useEffect(() => {
const listener = (event: MouseEvent) => {
const path = event.composedPath?.()[0] ?? (event as MouseEvent & { path: HTMLElement }).path; //event.path is non-standard and will be deprecated
const listener = (event: IClickEvent) => {
const path = (event.composedPath?.()[0] ?? event.path) as HTMLElement; //event.path is non-standard and will be deprecated
// When component is isolated (e.g, iframe, shadow DOM) event.target refers to whole container not the component. path[0] is the node that the event originated from, it does not need to walk the array
if (
ref &&
ref.current &&
!ref.current.contains(event.target as HTMLElement) &&
!ref.current.contains(path as HTMLElement)
!ref.current.contains(path)
) {
if (validationFn && !validationFn(event)) return;
handler(event);
Expand Down

0 comments on commit 83d11ca

Please sign in to comment.