Kaynağa Gözat

Merge pull request #11941 from overleaf/ii-recompile-tooltip

[web] Recompile tooltip fix

GitOrigin-RevId: da3282b9da0133f5b6ec84c4453bd6ab19b739af
ilkin-overleaf 3 yıl önce
ebeveyn
işleme
41a706108c

+ 1 - 1
services/web/frontend/js/shared/components/split-menu.tsx

@@ -16,7 +16,7 @@ type SplitMenuBsStyle = Extract<BsStyle, 'primary' | 'secondary' | 'danger'>
 type SplitMenuBsSize = Extract<BsSize, 'md' | 'sm' | 'xs'>
 
 type SplitMenuButtonProps = {
-  tooltip?: TooltipProps
+  tooltip?: Omit<TooltipProps, 'children'>
   bsStyle?: SplitMenuBsStyle
   text: string
   icon?: IconProps

+ 15 - 5
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<OverlayTriggerProps, 'overlay'> & {
   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<TooltipProps> = ({
+function Tooltip({
   id,
   description,
   children,
   tooltipProps,
   overlayProps,
-}) => {
+}: TooltipProps) {
+  const hideTooltip = (e: React.MouseEvent) => {
+    if (e.currentTarget instanceof HTMLElement) {
+      e.currentTarget.blur()
+    }
+  }
+
   return (
     <OverlayTrigger
       overlay={
@@ -33,7 +41,9 @@ const Tooltip: FC<TooltipProps> = ({
       {...overlayProps}
       placement={overlayProps?.placement || 'top'}
     >
-      {children}
+      {cloneElement(children, {
+        onClick: callFnsInSequence(children.props.onClick, hideTooltip),
+      })}
     </OverlayTrigger>
   )
 }

+ 35 - 0
services/web/test/frontend/components/shared/tooltip.spec.tsx

@@ -0,0 +1,35 @@
+import Tooltip from '../../../../frontend/js/shared/components/tooltip'
+
+describe('<Tooltip />', 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(
+      <div
+        style={{
+          display: 'flex',
+          alignItems: 'center',
+          justifyContent: 'center',
+          height: '100vh',
+        }}
+      >
+        <Tooltip id="abc" description={description}>
+          <button onClick={clickHandler} onBlur={blurHandler}>
+            {btnText}
+          </button>
+        </Tooltip>
+      </div>
+    )
+
+    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')
+  })
+})