Ensure interactability with Popover.Panel contents in static mode (#857)

* ensure interactability with Popover.Panel contents in static mode

* update changelog
This commit is contained in:
Robin Malfait
2021-10-08 15:53:24 +02:00
committed by GitHub
parent f9e0d30795
commit fd9a2d20b2
4 changed files with 156 additions and 2 deletions
+1
View File
@@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Stop the event from propagating in the `Popover` component ([#798](https://github.com/tailwindlabs/headlessui/pull/798))
- Allow to click on elements inside a `Dialog.Overlay` ([#816](https://github.com/tailwindlabs/headlessui/pull/816))
- Ensure interactability with `Popover.Panel` contents when using the `static` prop ([#857](https://github.com/tailwindlabs/headlessui/pull/857))
## [Unreleased - Vue]
@@ -1,5 +1,5 @@
import React, { createElement, useEffect, useRef } from 'react'
import { render } from '@testing-library/react'
import { render, screen } from '@testing-library/react'
import { Popover } from './popover'
import { suppressConsoleLogs } from '../../test-utils/suppress-console-logs'
@@ -2125,4 +2125,78 @@ describe('Mouse interactions', () => {
assertActiveElement(getPopoverButton())
})
)
it(
'should not close the Popover when clicking on a focusable element inside a static Popover.Panel',
suppressConsoleLogs(async () => {
let clickFn = jest.fn()
render(
<Popover>
<Popover.Button>Open</Popover.Button>
<Popover.Panel static>
<button onClick={clickFn}>btn</button>
</Popover.Panel>
</Popover>
)
// Open the popover
await click(getPopoverButton())
// The button should not close the popover
await click(getByText('btn'))
// Verify it is still open
assertPopoverButton({ state: PopoverState.Visible })
// Verify we actually clicked the button
expect(clickFn).toHaveBeenCalledTimes(1)
})
)
it(
'should not close the Popover when clicking on a non-focusable element inside a static Popover.Panel',
suppressConsoleLogs(async () => {
render(
<Popover>
<Popover.Button>Open</Popover.Button>
<Popover.Panel static>
<span>element</span>
</Popover.Panel>
</Popover>
)
// Open the popover
await click(getPopoverButton())
// The element should not close the popover
await click(getByText('element'))
// Verify it is still open
assertPopoverButton({ state: PopoverState.Visible })
})
)
it(
'should close the Popover when clicking outside of a static Popover.Panel',
suppressConsoleLogs(async () => {
render(
<Popover>
<Popover.Button>Open</Popover.Button>
<Popover.Panel static>
<span>element</span>
</Popover.Panel>
</Popover>
)
// Open the popover
await click(getPopoverButton())
// The element should close the popover
await click(document.body)
// Verify it is still open
assertPopoverButton({ state: PopoverState.InvisibleHidden })
})
)
})
@@ -619,10 +619,12 @@ let Panel = forwardRefWithAs(function Panel<TTag extends ElementType = typeof DE
// Unlink on "unmount" children
useEffect(() => {
if (props.static) return
if (state.popoverState === PopoverStates.Closed && (props.unmount ?? true)) {
dispatch({ type: ActionTypes.SetPanel, panel: null })
}
}, [state.popoverState, props.unmount, dispatch])
}, [state.popoverState, props.unmount, props.static, dispatch])
// Move focus within panel
useEffect(() => {
@@ -2323,4 +2323,81 @@ describe('Mouse interactions', () => {
assertActiveElement(getPopoverButton())
})
)
it(
'should not close the Popover when clicking on a focusable element inside a static PopoverPanel',
suppressConsoleLogs(async () => {
let clickFn = jest.fn()
renderTemplate({
template: html`
<Popover>
<PopoverButton>Open</PopoverButton>
<PopoverPanel static>
<button @click="clickFn">btn</button>
</PopoverPanel>
</Popover>
`,
setup: () => ({ clickFn }),
})
// Open the popover
await click(getPopoverButton())
// The button should not close the popover
await click(getByText('btn'))
// Verify it is still open
assertPopoverButton({ state: PopoverState.Visible })
// Verify we actually clicked the button
expect(clickFn).toHaveBeenCalledTimes(1)
})
)
it(
'should not close the Popover when clicking on a non-focusable element inside a static PopoverPanel',
suppressConsoleLogs(async () => {
renderTemplate(html`
<Popover>
<PopoverButton>Open</PopoverButton>
<PopoverPanel static>
<span>element</span>
</PopoverPanel>
</Popover>
`)
// Open the popover
await click(getPopoverButton())
// The element should not close the popover
await click(getByText('element'))
// Verify it is still open
assertPopoverButton({ state: PopoverState.Visible })
})
)
it(
'should close the Popover when clicking outside of a static PopoverPanel',
suppressConsoleLogs(async () => {
renderTemplate(html`
<Popover>
<PopoverButton>Open</PopoverButton>
<PopoverPanel static>
<span>element</span>
</PopoverPanel>
</Popover>
`)
// Open the popover
await click(getPopoverButton())
// The element should close the popover
await click(document.body)
// Verify it is still open
assertPopoverButton({ state: PopoverState.InvisibleHidden })
})
)
})