Skip to content

Commit

Permalink
Fix ActionMenu with IconButton (#2084)
Browse files Browse the repository at this point in the history
* Fix IconButton for ActionMenu

* Add test case
  • Loading branch information
siddharthkp committed May 19, 2022
1 parent 3252b74 commit 3204599
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 11 deletions.
21 changes: 11 additions & 10 deletions src/Tooltip/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from 'react'
import {useSSRSafeId} from '@react-aria/ssr'
import type {AnchorPosition, AnchorSide, AnchorAlignment} from '@primer/behaviors'
import Box from '../Box'
import {useAnchoredPosition} from '../hooks'
import {useAnchoredPosition, useProvidedRefOrCreate} from '../hooks'
import {SxProp, merge, BetterSystemStyleObject} from '../sx'

type TooltipDirection = 'nw' | 'n' | 'ne' | 'e' | 'se' | 's' | 'sw' | 'w'
Expand All @@ -21,7 +21,7 @@ export type TooltipProps = {
/** Use aria-describedby or aria-labelledby */
type?: 'description' | 'label'
/** Tooltip target */
children: React.ReactElement
children: React.ReactElement & {ref?: React.RefObject<HTMLElement>}
/** When set to true, tooltip appears without any delay */
noDelay?: boolean
/** @deprecated Always set to true now. */
Expand Down Expand Up @@ -55,8 +55,16 @@ export const Tooltip: React.FC<TooltipProps> = ({
sx = {},
...props
}) => {
const tooltipId = useSSRSafeId()

const childRef = children.ref
const anchorElementRef = useProvidedRefOrCreate(childRef)
const tooltipRef = React.useRef<HTMLDivElement>(null)
const anchorElementRef = React.useRef<HTMLElement>(null)

const child = React.cloneElement(children, {
ref: anchorElementRef,
[type === 'description' ? 'aria-describedby' : 'aria-labelledby']: tooltipId
})

const {position} = useAnchoredPosition({
side: directionToPosition[direction].side,
Expand All @@ -66,13 +74,6 @@ export const Tooltip: React.FC<TooltipProps> = ({
anchorElementRef
})

const tooltipId = useSSRSafeId()

const child = React.cloneElement(children, {
ref: anchorElementRef,
[type === 'description' ? 'aria-describedby' : 'aria-labelledby']: tooltipId
})

const tooltipText = text || props['aria-label']

return (
Expand Down
29 changes: 28 additions & 1 deletion src/__tests__/ActionMenu.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ import 'babel-polyfill'
import {axe, toHaveNoViolations} from 'jest-axe'
import React from 'react'
import theme from '../theme'
import {ActionMenu, ActionList, BaseStyles, ThemeProvider, SSRProvider} from '..'
import {ActionMenu, ActionList, BaseStyles, ThemeProvider, SSRProvider, IconButton} from '..'
import {behavesAsComponent, checkExports, checkStoriesForAxeViolations} from '../utils/testing'
import {SingleSelection, MixedSelection} from '../stories/ActionMenu/examples.stories'
import '@testing-library/jest-dom'
import {TriangleDownIcon} from '@primer/octicons-react'
expect.extend(toHaveNoViolations)

function Example(): JSX.Element {
Expand Down Expand Up @@ -136,6 +137,32 @@ describe('ActionMenu', () => {
cleanup()
})

it('should open Menu on MenuAnchor click with IconButton', async () => {
const component = HTMLRender(
<ThemeProvider theme={theme}>
<SSRProvider>
<BaseStyles>
<ActionMenu>
<ActionMenu.Anchor>
<IconButton aria-label="Toggle Menu" icon={TriangleDownIcon} />
</ActionMenu.Anchor>
<ActionMenu.Overlay>
<ActionList>
<ActionList.Item>New file</ActionList.Item>
<ActionList.Item>Copy link</ActionList.Item>
</ActionList>
</ActionMenu.Overlay>
</ActionMenu>
</BaseStyles>
</SSRProvider>
</ThemeProvider>
)
const button = component.getByLabelText('Toggle Menu')
fireEvent.click(button)
expect(component.getByRole('menu')).toBeInTheDocument()
cleanup()
})

it('should have no axe violations', async () => {
const {container} = HTMLRender(<Example />)
const results = await axe(container)
Expand Down

0 comments on commit 3204599

Please sign in to comment.