22import * as React from 'react' ;
33import {
44 createPopper as defaultCreatePopper ,
5- type Options as PopperOptions ,
65 type VirtualElement ,
6+ type Modifier ,
7+ type OptionsGeneric ,
8+ type StrictModifiers ,
79} from '@popperjs/core' ;
810import isEqual from 'react-fast-compare' ;
911import { fromEntries , useIsomorphicLayoutEffect } from './utils' ;
1012
11- type Options = $Shape < {
12- ...PopperOptions ,
13+ type Options < TModifiers > = $Shape < {
14+ ...OptionsGeneric < TModifiers > ,
1315 createPopper : typeof defaultCreatePopper ,
1416} > ;
1517
@@ -22,14 +24,20 @@ type State = {
2224 } ,
2325} ;
2426
27+ type UpdateStateModifier = Modifier < 'updateState' , { || } > ;
28+
2529const EMPTY_MODIFIERS = [ ] ;
2630
27- export const usePopper = (
31+ export const usePopper = <
32+ TModifiers : StrictModifiers | $Shape < Modifier < string , { } > >
33+ > (
2834 referenceElement : ?( Element | VirtualElement ) ,
2935 popperElement : ?HTMLElement ,
30- options : Options = { }
36+ options : Options < TModifiers > = { }
3137) => {
32- const prevOptions = React . useRef < ?PopperOptions > ( null ) ;
38+ type TExtendedModifier = TModifiers | $Shape < UpdateStateModifier > ;
39+
40+ const prevOptions = React . useRef < ?OptionsGeneric < TExtendedModifier >> ( null ) ;
3341
3442 const optionsWithDefaults = {
3543 onFirstUpdate : options . onFirstUpdate ,
@@ -49,7 +57,7 @@ export const usePopper = (
4957 attributes : { } ,
5058 } ) ;
5159
52- const updateStateModifier = React . useMemo (
60+ const updateStateModifier = React . useMemo < UpdateStateModifier > (
5361 ( ) => ( {
5462 name : 'updateState' ,
5563 enabled : true ,
@@ -71,7 +79,7 @@ export const usePopper = (
7179 [ ]
7280 ) ;
7381
74- const popperOptions = React . useMemo ( ( ) => {
82+ const popperOptions = React . useMemo < OptionsGeneric < TExtendedModifier >> ( ( ) => {
7583 const newOptions = {
7684 onFirstUpdate : optionsWithDefaults . onFirstUpdate ,
7785 placement : optionsWithDefaults . placement ,
@@ -83,8 +91,11 @@ export const usePopper = (
8391 ] ,
8492 } ;
8593
86- if ( isEqual ( prevOptions . current , newOptions ) ) {
87- return prevOptions . current || newOptions ;
94+ if (
95+ prevOptions . current != null &&
96+ isEqual ( prevOptions . current , newOptions )
97+ ) {
98+ return prevOptions . current ;
8899 } else {
89100 prevOptions . current = newOptions ;
90101 return newOptions ;
0 commit comments