Skip to content

Commit

Permalink
Merge pull request #171 from softconstruct/release/2.16.x
Browse files Browse the repository at this point in the history
  • Loading branch information
hamikhambardzumyan authored Sep 20, 2024
2 parents 823dd53 + 2fdb7a9 commit 311f0c5
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 40 deletions.
7 changes: 0 additions & 7 deletions src/lib/molecules/Tooltip/Tooltip.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,6 @@ describe('Tooltip', () => {
expect(provider().find(`.${position}`).exists()).toBeTruthy();
});

it('handle onClick', () => {
const jestFn = jest.fn();
const wrapper = setup.setProps({ onClick: jestFn });
wrapper.find('.test').simulate('click');
expect(jestFn).toHaveBeenCalled();
});

it('handle onMouseEnter', () => {
setup.find('.test').simulate('mouseEnter');
expect(provider().find('.tooltip-c-p').exists()).toBeTruthy();
Expand Down
78 changes: 45 additions & 33 deletions src/lib/molecules/Tooltip/Tooltip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,20 @@ import React, {
useContext,
CSSProperties,
JSX,
MouseEvent,
FC,
PointerEvent,
cloneElement,
Children,
Fragment
Fragment,
useEffect,
RefObject,
useMemo
} from 'react';
import { shift, flip, offset } from '@floating-ui/core';
import { FloatingPortal, autoUpdate, useFloating } from '@floating-ui/react';
import { Placement } from '@floating-ui/utils';
import { ReferenceType } from '@floating-ui/react-dom';
import { isForwardRef } from 'react-is';

// Utils
//@ts-ignore
import { noop } from 'utils';

// Hooks
//@ts-ignore
import { useDeviceType } from 'hooks';
Expand Down Expand Up @@ -82,39 +79,49 @@ export interface ITooltipProps {
* In case of `false` value, the children component will rendered without Tooltip.
*/
isVisible?: boolean;
/**
* The action will triggered when the Tooltip component will clicked.
*/
onClick?: (e: MouseEvent) => void;
}

const FindAndMergeRef = <T extends { onClick: (e: PointerEvent, el: JSX.Element) => void }>(
type JSXWithRef = JSX.Element & { ref: RefObject<unknown> };

const FindAndSetRef = <T extends object>(
children: JSX.Element | JSX.Element[],
childProps: T,
componentRef: (node: ReferenceType | null) => void
) =>
Children.map(children, (el, i) => {
const newProps = {
...childProps,
onClick: (e: PointerEvent) => childProps?.onClick(e, el),
ref: i === 0 ? componentRef : {}
) => {
return Children.map(children, (node, i) => {
const el = node as JSXWithRef;

let newProps = {
...childProps
};

if (el?.type === Fragment && el.props.children) {
return FindAndMergeRef(el.props.children, childProps, componentRef);
return FindAndSetRef(el.props.children, newProps, componentRef);
}

if (isForwardRef(el)) {
return FindAndMergeRef(el.type.render(el.props), newProps, componentRef);
return FindAndSetRef(el.type.render(el.props, el.ref), newProps, componentRef);
}

if (typeof el?.type === 'string') {
if (!el.ref && i === 0) {
newProps = { ...newProps, ref: componentRef };
}

return cloneElement(el, newProps);
}

if (typeof el?.type === 'function') {
return FindAndMergeRef(el.type(el.props), newProps, componentRef);
if (!el.ref) {
newProps = { ...newProps, ref: componentRef };
}

return cloneElement(el.type(el.props), newProps);
}

return el && cloneElement(el, newProps);
});
};

const Tooltip: FC<ITooltipProps> = ({
children,
Expand All @@ -125,7 +132,6 @@ const Tooltip: FC<ITooltipProps> = ({
title,
customPosition,
alwaysShow,
onClick = noop,
padding = 5,
screenType = 'desktop',
isVisible = true,
Expand All @@ -135,10 +141,9 @@ const Tooltip: FC<ITooltipProps> = ({
const { geneUIProviderRef } = useContext(GeneUIDesignSystemContext);
const { isMobile } = useDeviceType(screenType);
const [isPopoverOpen, setIsPopoverState] = useState(false);

const mouseEnterHandler = () => !alwaysShow && setIsPopoverState(true);
const mouseLeaveHandler = () => {
!alwaysShow && setIsPopoverState(false);
};
const mouseLeaveHandler = () => !alwaysShow && setIsPopoverState(false);

const { refs, floatingStyles, context } = useFloating({
open: alwaysShow || isPopoverOpen,
Expand Down Expand Up @@ -169,17 +174,23 @@ const Tooltip: FC<ITooltipProps> = ({

const childProps = {
onMouseEnter: mouseEnterHandler,
onMouseLeave: mouseLeaveHandler,
onClick: (e: PointerEvent, el: JSX.Element) => {
const { onClick: onClickHandler } = el?.props;
typeof onClickHandler === 'function' && onClickHandler(e);
onClick(e);
}
onMouseLeave: mouseLeaveHandler
};

const component = useMemo(() => FindAndSetRef(children, childProps, refs.setReference), [children, childProps]);

useEffect(() => {
component.forEach((element: JSX.Element) => {
const node = element as JSXWithRef;
if (node?.ref?.current) {
refs.setReference(node.ref.current as ReferenceType);
}
});
}, [component]);

return (
<>
{FindAndMergeRef(children, childProps, refs.setReference)}
{component}
{isVisible && (alwaysShow || isPopoverOpen) && (
<FloatingPortal root={geneUIProviderRef.current}>
{checkNudged({ nudgedLeft: context.x, nudgedTop: context.y }) && (
Expand All @@ -188,7 +199,8 @@ const Tooltip: FC<ITooltipProps> = ({
ref={refs.setFloating}
style={{
...style,
...floatingStyles
...floatingStyles,
zIndex: 400 //TODO: Remove after 3.0.0
}}
{...props}
>
Expand Down

0 comments on commit 311f0c5

Please sign in to comment.