Skip to content

Commit

Permalink
Fix memory leak in Popover component (#2430)
Browse files Browse the repository at this point in the history
* move `useTabDirection` and `handleFocus` to setup instead of render function

* update changelog
  • Loading branch information
RobinMalfait committed Apr 13, 2023
1 parent 095ec18 commit 3536745
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 32 deletions.
4 changes: 3 additions & 1 deletion packages/@headlessui-vue/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

- Nothing yet!
### Fixed

- Fix memory leak in `Popover` component ([#2430](https://github.com/tailwindlabs/headlessui/pull/2430))

## [1.7.13] - 2023-04-12

Expand Down
62 changes: 31 additions & 31 deletions packages/@headlessui-vue/src/components/popover/popover.ts
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,37 @@ export let PopoverButton = defineComponent({
event.stopPropagation()
}

let direction = useTabDirection()
function handleFocus() {
let el = dom(api.panel) as HTMLElement
if (!el) return

function run() {
let result = match(direction.value, {
[TabDirection.Forwards]: () => focusIn(el, Focus.First),
[TabDirection.Backwards]: () => focusIn(el, Focus.Last),
})

if (result === FocusResult.Error) {
focusIn(
getFocusableElements().filter((el) => el.dataset.headlessuiFocusGuard !== 'true'),
match(direction.value, {
[TabDirection.Forwards]: Focus.Next,
[TabDirection.Backwards]: Focus.Previous,
}),
{ relativeTo: dom(api.button) }
)
}
}

// TODO: Cleanup once we are using real browser tests
if (process.env.NODE_ENV === 'test') {
microTask(run)
} else {
run()
}
}

return () => {
let visible = api.popoverState.value === PopoverStates.Open
let slot = { open: visible }
Expand All @@ -406,37 +437,6 @@ export let PopoverButton = defineComponent({
onMousedown: handleMouseDown,
}

let direction = useTabDirection()
function handleFocus() {
let el = dom(api.panel) as HTMLElement
if (!el) return

function run() {
let result = match(direction.value, {
[TabDirection.Forwards]: () => focusIn(el, Focus.First),
[TabDirection.Backwards]: () => focusIn(el, Focus.Last),
})

if (result === FocusResult.Error) {
focusIn(
getFocusableElements().filter((el) => el.dataset.headlessuiFocusGuard !== 'true'),
match(direction.value, {
[TabDirection.Forwards]: Focus.Next,
[TabDirection.Backwards]: Focus.Previous,
}),
{ relativeTo: dom(api.button) }
)
}
}

// TODO: Cleanup once we are using real browser tests
if (process.env.NODE_ENV === 'test') {
microTask(run)
} else {
run()
}
}

return h(Fragment, [
render({
ourProps,
Expand Down

0 comments on commit 3536745

Please sign in to comment.