From 41a706108c31d9d0f9c5bc9ef8cc378d43e34ca6 Mon Sep 17 00:00:00 2001 From: ilkin-overleaf <100852799+ilkin-overleaf@users.noreply.github.com> Date: Tue, 28 Feb 2023 11:16:22 +0200 Subject: [PATCH] Merge pull request #11941 from overleaf/ii-recompile-tooltip [web] Recompile tooltip fix GitOrigin-RevId: da3282b9da0133f5b6ec84c4453bd6ab19b739af --- .../js/shared/components/split-menu.tsx | 2 +- .../frontend/js/shared/components/tooltip.tsx | 20 ++++++++--- .../components/shared/tooltip.spec.tsx | 35 +++++++++++++++++++ 3 files changed, 51 insertions(+), 6 deletions(-) create mode 100644 services/web/test/frontend/components/shared/tooltip.spec.tsx diff --git a/services/web/frontend/js/shared/components/split-menu.tsx b/services/web/frontend/js/shared/components/split-menu.tsx index 5dd9e690b6..da5fb8b13b 100644 --- a/services/web/frontend/js/shared/components/split-menu.tsx +++ b/services/web/frontend/js/shared/components/split-menu.tsx @@ -16,7 +16,7 @@ type SplitMenuBsStyle = Extract type SplitMenuBsSize = Extract type SplitMenuButtonProps = { - tooltip?: TooltipProps + tooltip?: Omit bsStyle?: SplitMenuBsStyle text: string icon?: IconProps diff --git a/services/web/frontend/js/shared/components/tooltip.tsx b/services/web/frontend/js/shared/components/tooltip.tsx index ad61955927..d0defbea23 100644 --- a/services/web/frontend/js/shared/components/tooltip.tsx +++ b/services/web/frontend/js/shared/components/tooltip.tsx @@ -1,28 +1,36 @@ -import type { FC, ReactNode } from 'react' +import { cloneElement } from 'react' import { OverlayTrigger, OverlayTriggerProps, Tooltip as BSTooltip, } from 'react-bootstrap' +import { callFnsInSequence } from '../../utils/functions' type OverlayProps = Omit & { shouldUpdatePosition?: boolean // Not officially documented https://stackoverflow.com/a/43138470 } export type TooltipProps = { - description: ReactNode + description: React.ReactNode id: string overlayProps?: OverlayProps tooltipProps?: BSTooltip.TooltipProps + children: React.ReactElement } -const Tooltip: FC = ({ +function Tooltip({ id, description, children, tooltipProps, overlayProps, -}) => { +}: TooltipProps) { + const hideTooltip = (e: React.MouseEvent) => { + if (e.currentTarget instanceof HTMLElement) { + e.currentTarget.blur() + } + } + return ( = ({ {...overlayProps} placement={overlayProps?.placement || 'top'} > - {children} + {cloneElement(children, { + onClick: callFnsInSequence(children.props.onClick, hideTooltip), + })} ) } diff --git a/services/web/test/frontend/components/shared/tooltip.spec.tsx b/services/web/test/frontend/components/shared/tooltip.spec.tsx new file mode 100644 index 0000000000..764f05b891 --- /dev/null +++ b/services/web/test/frontend/components/shared/tooltip.spec.tsx @@ -0,0 +1,35 @@ +import Tooltip from '../../../../frontend/js/shared/components/tooltip' + +describe('', function () { + it('calls the bound handler and blur then hides text on click', function () { + const clickHandler = cy.stub().as('clickHandler') + const blurHandler = cy.stub().as('blurHandler') + const description = 'foo' + const btnText = 'Click me!' + + cy.mount( +
+ + + +
+ ) + + cy.findByRole('button', { name: btnText }).as('button') + cy.get('@button').trigger('mouseover') + cy.findByText(description) + cy.get('@button').click() + cy.get('@clickHandler').should('have.been.calledOnce') + cy.get('@blurHandler').should('have.been.calledOnce') + cy.findByText(description).should('not.exist') + }) +})