diff --git a/.flowconfig b/.flowconfig index 0d47238..fdd7016 100644 --- a/.flowconfig +++ b/.flowconfig @@ -9,7 +9,7 @@ [lints] [options] -suppress_comment=\\(.\\|\n\\)*\\$FlowExpectError +suppress_comment=\\(.\\|\n\\)*\\$\\(FlowExpectError\\|FlowFixMe\\) [strict] diff --git a/src/__typings__/main-test.js b/src/__typings__/main-test.js index bdabe39..e6e46fc 100644 --- a/src/__typings__/main-test.js +++ b/src/__typings__/main-test.js @@ -4,7 +4,8 @@ // be found under `/typings/tests` please. Thanks! 🤗 import React from 'react'; -import { Manager, Reference, Popper } from '..'; +import { Manager, Reference, Popper, usePopper } from '..'; +import type { Modifier, StrictModifiers } from '@popperjs/core'; export const Test = () => ( @@ -33,7 +34,10 @@ export const Test = () => ( }) => (
update()} > @@ -51,3 +55,76 @@ export const Test = () => ( ); + +export const HookTest = () => { + const [referenceElement, setReferenceElement] = React.useState( + null + ); + const [popperElement, setPopperElement] = React.useState(null); + const [arrowElement, setArrowElement] = React.useState(null); + const { styles, attributes, update } = usePopper( + referenceElement, + popperElement, + { + modifiers: [ + { + name: 'arrow', + options: { element: arrowElement }, + }, + ], + } + ); + + usePopper(referenceElement, popperElement, { + modifiers: [ + // $FlowExpectError: offset tuple accepts only numbers + { + name: 'offset', + options: { offset: [0, ''] }, + }, + ], + }); + + type CustomModifier = $Shape>; + usePopper(referenceElement, popperElement, { + modifiers: [ + { + name: 'custom', + options: { foo: true }, + }, + ], + }); + + usePopper( + referenceElement, + popperElement, + // $FlowExpectError: foo should be boolean + { + modifiers: [ + { + name: 'custom', + options: { foo: 'str' }, + }, + ], + } + ); + + return ( + <> + + +
+ Popper element +
+
+ + ); +}; diff --git a/src/usePopper.js b/src/usePopper.js index 762170e..fbd0207 100644 --- a/src/usePopper.js +++ b/src/usePopper.js @@ -2,14 +2,16 @@ import * as React from 'react'; import { createPopper as defaultCreatePopper, - type Options as PopperOptions, type VirtualElement, + type Modifier, + type OptionsGeneric, + type StrictModifiers, } from '@popperjs/core'; import isEqual from 'react-fast-compare'; import { fromEntries, useIsomorphicLayoutEffect } from './utils'; -type Options = $Shape<{ - ...PopperOptions, +type Options = $Shape<{ + ...OptionsGeneric, createPopper: typeof defaultCreatePopper, }>; @@ -22,14 +24,20 @@ type State = { }, }; +type UpdateStateModifier = Modifier<'updateState', {||}>; + const EMPTY_MODIFIERS = []; -export const usePopper = ( +type DefaultModifiers = StrictModifiers | $Shape>; + +export const usePopper = ( referenceElement: ?(Element | VirtualElement), popperElement: ?HTMLElement, - options: Options = {} + options: Options = {} ) => { - const prevOptions = React.useRef(null); + type InternalModifiers = Modifiers | $Shape; + + const prevOptions = React.useRef>(null); const optionsWithDefaults = { onFirstUpdate: options.onFirstUpdate, @@ -49,7 +57,7 @@ export const usePopper = ( attributes: {}, }); - const updateStateModifier = React.useMemo( + const updateStateModifier = React.useMemo( () => ({ name: 'updateState', enabled: true, @@ -71,7 +79,7 @@ export const usePopper = ( [] ); - const popperOptions = React.useMemo(() => { + const popperOptions = React.useMemo>(() => { const newOptions = { onFirstUpdate: optionsWithDefaults.onFirstUpdate, placement: optionsWithDefaults.placement, @@ -83,8 +91,11 @@ export const usePopper = ( ], }; - if (isEqual(prevOptions.current, newOptions)) { - return prevOptions.current || newOptions; + if ( + prevOptions.current != null && + isEqual(prevOptions.current, newOptions) + ) { + return prevOptions.current; } else { prevOptions.current = newOptions; return newOptions; @@ -111,7 +122,7 @@ export const usePopper = ( } const createPopper = options.createPopper || defaultCreatePopper; - const popperInstance = createPopper( + const popperInstance = createPopper( referenceElement, popperElement, popperOptions diff --git a/yarn.lock b/yarn.lock index 5749a3a..172b815 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1253,7 +1253,7 @@ "@popperjs/core@^2.3.3": version "2.3.3" - resolved "https://registry.npmjs.org/@popperjs/core/-/core-2.3.3.tgz#8731722aeb7330e8fd9eb5d424be6b98dea7d6da" + resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.3.3.tgz#8731722aeb7330e8fd9eb5d424be6b98dea7d6da" integrity sha512-yEvVC8RfhRPkD9TUn7cFcLcgoJePgZRAOR7T21rcRY5I8tpuhzeWfGa7We7tB14fe9R7wENdqUABcMdwD4SQLw== "@rollup/plugin-commonjs@^11.0.2":