diff --git a/services/web/frontend/js/features/history/components/change-list/dropdown/actions-dropdown.tsx b/services/web/frontend/js/features/history/components/change-list/dropdown/actions-dropdown.tsx index 9029260057..df31a6c58f 100644 --- a/services/web/frontend/js/features/history/components/change-list/dropdown/actions-dropdown.tsx +++ b/services/web/frontend/js/features/history/components/change-list/dropdown/actions-dropdown.tsx @@ -2,20 +2,21 @@ import React, { ReactNode } from 'react' import { Dropdown, DropdownMenu, + DropdownToggle, } from '@/features/ui/components/bootstrap-5/dropdown-menu' -import DropdownToggleWithTooltip from '@/features/ui/components/bootstrap-5/dropdown-toggle-with-tooltip' +import OLTooltip from '@/features/ui/components/ol/ol-tooltip' type ActionDropdownProps = { id: string children: React.ReactNode isOpened: boolean iconTag: ReactNode - toolTipDescription: string + tooltipDescription: string setIsOpened: (isOpened: boolean) => void } function ActionsDropdown(props: ActionDropdownProps) { - const { id, children, isOpened, iconTag, setIsOpened, toolTipDescription } = + const { id, children, isOpened, iconTag, setIsOpened, tooltipDescription } = props return ( setIsOpened(open)} > - + {/* OverlayTrigger won't fire unless the child is a non-react html element (e.g div, span) */} + + + {iconTag} + + + {children} diff --git a/services/web/frontend/js/features/history/components/change-list/dropdown/compare-version-dropdown.tsx b/services/web/frontend/js/features/history/components/change-list/dropdown/compare-version-dropdown.tsx index 91f0bf991a..11967e3302 100644 --- a/services/web/frontend/js/features/history/components/change-list/dropdown/compare-version-dropdown.tsx +++ b/services/web/frontend/js/features/history/components/change-list/dropdown/compare-version-dropdown.tsx @@ -21,7 +21,7 @@ function CompareVersionDropdown({ id={id} isOpened={isOpened} setIsOpened={setIsOpened} - toolTipDescription={t('compare')} + tooltipDescription={t('compare')} iconTag={ diff --git a/services/web/frontend/js/features/history/components/change-list/dropdown/menu-item/compare-items.tsx b/services/web/frontend/js/features/history/components/change-list/dropdown/menu-item/compare-items.tsx index 78ba0aae75..dd236ed98b 100644 --- a/services/web/frontend/js/features/history/components/change-list/dropdown/menu-item/compare-items.tsx +++ b/services/web/frontend/js/features/history/components/change-list/dropdown/menu-item/compare-items.tsx @@ -34,7 +34,7 @@ function CompareItems({ toVTimestamp: selRange.toVTimestamp, }} closeDropdown={closeDropdown} - toolTipDescription={t('history_compare_from_this_version')} + tooltipDescription={t('history_compare_from_this_version')} icon={ void } function Compare({ comparisonRange, closeDropdown, - toolTipDescription, + tooltipDescription, icon, }: CompareProps) { const { setSelection } = useHistoryContext() @@ -32,12 +32,12 @@ function Compare({ return ( diff --git a/services/web/frontend/js/features/ui/components/bootstrap-5/dropdown-toggle-with-tooltip.tsx b/services/web/frontend/js/features/ui/components/bootstrap-5/dropdown-toggle-with-tooltip.tsx deleted file mode 100644 index 719b936581..0000000000 --- a/services/web/frontend/js/features/ui/components/bootstrap-5/dropdown-toggle-with-tooltip.tsx +++ /dev/null @@ -1,52 +0,0 @@ -import { ReactNode, forwardRef } from 'react' -import { BsPrefixRefForwardingComponent } from 'react-bootstrap/helpers' -import type { DropdownToggleProps } from '@/features/ui/components/types/dropdown-menu-props' -import { - DropdownToggle as BS5DropdownToggle, - OverlayTrigger, - OverlayTriggerProps, - Tooltip, -} from 'react-bootstrap' -import type { MergeAndOverride } from '../../../../../../types/utils' - -type DropdownToggleWithTooltipProps = MergeAndOverride< - DropdownToggleProps, - { - children: ReactNode - overlayTriggerProps?: Omit - toolTipDescription: string - tooltipProps?: Omit, 'children'> - 'aria-label'?: string - } -> -const DropdownToggleWithTooltip = forwardRef< - BsPrefixRefForwardingComponent<'button', DropdownToggleProps>, - DropdownToggleWithTooltipProps ->( - ( - { - children, - toolTipDescription, - overlayTriggerProps, - tooltipProps, - id: _id, - ...toggleProps - }, - ref - ) => { - return ( - {toolTipDescription}} - {...overlayTriggerProps} - > - - {children} - - - ) - } -) - -DropdownToggleWithTooltip.displayName = 'DropdownToggleWithTooltip' - -export default DropdownToggleWithTooltip diff --git a/services/web/frontend/js/features/ui/components/bootstrap-5/tooltip.tsx b/services/web/frontend/js/features/ui/components/bootstrap-5/tooltip.tsx index f16bcb5425..39a45e96e0 100644 --- a/services/web/frontend/js/features/ui/components/bootstrap-5/tooltip.tsx +++ b/services/web/frontend/js/features/ui/components/bootstrap-5/tooltip.tsx @@ -1,4 +1,10 @@ -import { cloneElement, useEffect, forwardRef } from 'react' +import { + cloneElement, + useEffect, + forwardRef, + useState, + useCallback, +} from 'react' import { OverlayTrigger, OverlayTriggerProps, @@ -41,6 +47,30 @@ function Tooltip({ overlayProps, hidden, }: TooltipProps) { + const [show, setShow] = useState(false) + + const handleKeyDown = useCallback( + (e: KeyboardEvent) => { + if (show && e.key === 'Escape') { + setShow(false) + e.stopPropagation() + } + }, + [show, setShow] + ) + + useEffect(() => { + document.addEventListener('keydown', handleKeyDown, true) + return () => document.removeEventListener('keydown', handleKeyDown, true) + }, [handleKeyDown]) + + const hideTooltip = (e: React.MouseEvent) => { + if (e.currentTarget instanceof HTMLElement) { + e.currentTarget.blur() + } + setShow(false) + } + const delay = overlayProps?.delay let delayShow = 300 let delayHide = 300 @@ -49,12 +79,6 @@ function Tooltip({ delayHide = typeof delay === 'number' ? delay : delay.hide } - const hideTooltip = (e: React.MouseEvent) => { - if (e.currentTarget instanceof HTMLElement) { - e.currentTarget.blur() - } - } - return ( {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 index 29b2c75ede..b78a559c35 100644 --- a/services/web/test/frontend/components/shared/tooltip.spec.tsx +++ b/services/web/test/frontend/components/shared/tooltip.spec.tsx @@ -32,4 +32,33 @@ describe('', function () { cy.get('@blurHandler').should('have.been.calledOnce') cy.findByText(description).should('not.exist') }) + + it('hides the tooltip when Escape key is pressed', function () { + const description = 'Press Escape to close' + const btnText = 'Hover me!' + + cy.mount( +
+ + + +
+ ) + + cy.findByRole('button', { name: btnText }).as('button') + cy.get('@button').trigger('mouseover') + cy.findByText(description) + cy.get('@button').trigger('mouseout') + cy.get('@button').focus() + cy.findByText(description) + cy.get('body').type('{esc}') + cy.findByText(description).should('not.exist') + }) }) diff --git a/services/web/test/frontend/features/history/components/change-list.spec.tsx b/services/web/test/frontend/features/history/components/change-list.spec.tsx index b3a1071015..763845db54 100644 --- a/services/web/test/frontend/features/history/components/change-list.spec.tsx +++ b/services/web/test/frontend/features/history/components/change-list.spec.tsx @@ -372,7 +372,7 @@ describe('change list (Bootstrap 5)', function () { cy.findAllByTestId('history-version-details') .eq(1) .within(() => { - cy.get('[aria-label="Compare"]').click() + cy.findByRole('button', { name: /compare/i }).click() cy.findByRole('menu').within(() => { cy.findByRole('menuitem', { name: /compare up to this version/i,