Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
/* eslint-disable no-undef */
import { fireEvent, render, screen, act } from '@testing-library/react'
import { axe } from 'jest-axe'
import '@testing-library/jest-dom'
import styled from 'styled-components'
import { Tooltip, Button } from '../../'
import { createRef } from 'react'

const StyledTooltip = styled(Tooltip)`
background: red;
Expand Down Expand Up @@ -30,6 +32,9 @@ describe('Tooltip', () => {
const content = screen.getByText('Test')
fireEvent.mouseEnter(content)
const tooltip = await screen.findByRole('tooltip')

// Remove the auto-generated ID to make snapshot deterministic
tooltip.removeAttribute('id')
expect(tooltip).toMatchSnapshot()
})
it('Should pass a11y test', async () => {
Expand Down Expand Up @@ -76,7 +81,7 @@ describe('Tooltip', () => {
await act(() => new Promise((r) => setTimeout(r, openDelay)))

const tooltip = await screen.findByRole('tooltip')
expect(tooltip).toHaveStyleRule('background', 'red')
expect(tooltip).toHaveStyle('background: red')
})
it('is visible when content is being hovered', async () => {
render(
Expand Down Expand Up @@ -174,4 +179,28 @@ describe('Tooltip', () => {

expect(handler).toBeCalled()
})
it('should render correctly when the wrapped component has a ref', async () => {
const buttonRef = createRef<HTMLButtonElement>()
render(
<Tooltip title="Tooltip" enterDelay={0}>
<Button ref={buttonRef}>Test</Button>
</Tooltip>,
)

const button = screen.getByText('Test')

fireEvent.focus(button)

expect(await screen.findByRole('tooltip')).toBeInTheDocument()
})
it('should forward refs to the wrapped component', () => {
const ref = createRef()
render(
<Tooltip title="Tooltip">
<Button ref={ref}>Test</Button>
</Tooltip>,
)

expect(ref.current).toBeInstanceOf(HTMLButtonElement)
})
})
26 changes: 16 additions & 10 deletions packages/eds-core-react/src/components/Tooltip/Tooltip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
useMemo,
useEffect,
ReactNode,
ReactElement,
} from 'react'
import { createPortal } from 'react-dom'
import styled from 'styled-components'
Expand Down Expand Up @@ -136,9 +137,9 @@ export const Tooltip = forwardRef<HTMLDivElement, TooltipProps>(
],
whileElementsMounted: autoUpdate,
})
const anchorRef = useMemo(
() => mergeRefs<HTMLElement>(refs.setReference, children?.ref),
[refs.setReference, children?.ref],
const mergedAnchorRef = useMemo(
() => mergeRefs<HTMLElement>(refs.setReference),
[refs.setReference],
)
const tooltipRef = useMemo(
() => mergeRefs<HTMLDivElement>(refs.setFloating, ref),
Expand Down Expand Up @@ -188,12 +189,17 @@ export const Tooltip = forwardRef<HTMLDivElement, TooltipProps>(
}
})

const updatedChildren = cloneElement(children, {
...getReferenceProps({
...children.props,
ref: anchorRef,
}),
})
const updatedChildren = cloneElement(
children as ReactElement<any>, // eslint-disable-line @typescript-eslint/no-explicit-any
{
...getReferenceProps(children.props),
ref: mergeRefs(
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-member-access
(children as ReactElement<any>).props.ref,
mergedAnchorRef,
),
},
)

useEffect(() => {
if (!elements.floating) return
Expand Down Expand Up @@ -228,14 +234,14 @@ export const Tooltip = forwardRef<HTMLDivElement, TooltipProps>(

return (
<>
{updatedChildren}
{shouldOpen &&
open &&
!disabled &&
createPortal(
TooltipEl,
portalContainer ?? rootElement ?? document.body,
)}
{updatedChildren}
</>
)
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ exports[`Tooltip Matches snapshot 1`] = `
<div
class="c0 eds-tooltip "
data-floating-ui-focusable=""
id="«r0»"
popover="manual"
role="tooltip"
style="position: absolute; top: 14px; left: 8px;"
Expand Down
Loading