Skip to content

Commit

Permalink
Fix false positive warning about using multiple <Popover.Button> co…
Browse files Browse the repository at this point in the history
…mponents (#2146)

* fix false positive warning about using multiple `<Popover.Button>` components

Fixes: #2143

* update changelog
  • Loading branch information
RobinMalfait authored Jan 4, 2023
1 parent e8b7b7f commit 69b953a
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 11 deletions.
1 change: 1 addition & 0 deletions packages/@headlessui-react/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- Fix SSR tab rendering on React 17 ([#2102](https://github.com/tailwindlabs/headlessui/pull/2102))
- Fix arrow key handling in `Tab` (after DOM order changes) ([#2145](https://github.com/tailwindlabs/headlessui/pull/2145))
- Fix false positive warning about using multiple `<Popover.Button>` components ([#2146](https://github.com/tailwindlabs/headlessui/pull/2146))

## [1.7.7] - 2022-12-16

Expand Down
24 changes: 13 additions & 11 deletions packages/@headlessui-react/src/components/popover/popover.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ import { useEvent } from '../../hooks/use-event'
import { useTabDirection, Direction as TabDirection } from '../../hooks/use-tab-direction'
import { microTask } from '../../utils/micro-task'
import { useLatestValue } from '../../hooks/use-latest-value'
import { useIsoMorphicEffect } from '../../hooks/use-iso-morphic-effect'

type MouseEvent<T> = Parameters<MouseEventHandler<T>>[0]

Expand All @@ -56,7 +57,7 @@ enum PopoverStates {
interface StateDefinition {
popoverState: PopoverStates

buttons: string[]
buttons: MutableRefObject<string[]>

button: HTMLElement | null
buttonId: string | null
Expand Down Expand Up @@ -200,9 +201,10 @@ let PopoverRoot = forwardRefWithAs(function Popover<
})
)

let buttons = useRef([])
let reducerBag = useReducer(stateReducer, {
popoverState: PopoverStates.Closed,
buttons: [],
buttons,
button: null,
buttonId: null,
panel: null,
Expand Down Expand Up @@ -390,15 +392,15 @@ let Button = forwardRefWithAs(function Button<TTag extends ElementType = typeof
let closeOthers = groupContext?.closeOthers

let panelContext = usePopoverPanelContext()
let isWithinPanel = panelContext === null ? false : panelContext === state.panelId
let isWithinPanel = panelContext !== null

useEffect(() => {
if (isWithinPanel) return
dispatch({ type: ActionTypes.SetButtonId, buttonId: id })
return () => {
dispatch({ type: ActionTypes.SetButtonId, buttonId: null })
}
}, [id, dispatch])
}, [isWithinPanel, id, dispatch])

let buttonRef = useSyncRefs(
internalButtonRef,
Expand All @@ -407,13 +409,13 @@ let Button = forwardRefWithAs(function Button<TTag extends ElementType = typeof
? null
: (button) => {
if (button) {
state.buttons.push(id)
state.buttons.current.push(id)
} else {
let idx = state.buttons.indexOf(id)
if (idx !== -1) state.buttons.splice(idx, 1)
let idx = state.buttons.current.indexOf(id)
if (idx !== -1) state.buttons.current.splice(idx, 1)
}

if (state.buttons.length > 1) {
if (state.buttons.current.length > 1) {
console.warn(
'You are already using a <Popover.Button /> but only 1 <Popover.Button /> is supported.'
)
Expand Down Expand Up @@ -652,7 +654,7 @@ let Panel = forwardRefWithAs(function Panel<TTag extends ElementType = typeof DE
})
let ownerDocument = useOwnerDocument(internalPanelRef)

useEffect(() => {
useIsoMorphicEffect(() => {
dispatch({ type: ActionTypes.SetPanelId, panelId: id })
return () => {
dispatch({ type: ActionTypes.SetPanelId, panelId: null })
Expand Down Expand Up @@ -715,7 +717,7 @@ let Panel = forwardRefWithAs(function Panel<TTag extends ElementType = typeof DE

let ourProps = {
ref: panelRef,
id: state.panelId,
id,
onKeyDown: handleKeyDown,
onBlur:
focus && state.popoverState === PopoverStates.Open
Expand Down Expand Up @@ -807,7 +809,7 @@ let Panel = forwardRefWithAs(function Panel<TTag extends ElementType = typeof DE
})

return (
<PopoverPanelContext.Provider value={state.panelId}>
<PopoverPanelContext.Provider value={id}>
{visible && isPortalled && (
<Hidden
id={beforePanelSentinelId}
Expand Down

0 comments on commit 69b953a

Please sign in to comment.