@fluent-windows/hooks
Version:
Fluent-Windows React hooks.
60 lines (55 loc) • 1.65 kB
JavaScript
/**
* Create popper, based on `popper.js`
*
* Demo
* import { usePopper } from '@fluent-windows/hooks'
*
* const [referenceRef, popperRef] = usePopper({ placement = 'bottom' })
*
* <button ref={referenceRef}></button>
* <div ref={popperRef}>I am popper</div>
*/
import * as React from 'react';
import PopperJS from 'popper.js'; // eslint-disable-next-line
function usePopper({
placement = 'bottom',
positionFixed = true,
eventsEnabled = true,
...otherOptions
}) {
const popperInstance = React.useRef(null);
const referenceRef = React.useRef(null);
const popperRef = React.useRef(null);
React.useEffect(() => {
if (popperInstance.current !== null) {
popperInstance.current.destroy();
}
if (referenceRef.current === null || popperRef.current === null) return; // @ts-ignore
popperInstance.current = new PopperJS(referenceRef.current, popperRef.current, {
placement,
positionFixed,
eventsEnabled,
...otherOptions
});
return () => {
if (popperInstance.current !== null) {
popperInstance.current.destroy();
}
};
}, [placement, positionFixed, eventsEnabled, otherOptions]);
React.useEffect(() => {
if (popperInstance.current === null) return;
if (eventsEnabled) {
popperInstance.current.enableEventListeners();
} else {
popperInstance.current.disableEventListeners();
}
}, [popperInstance, eventsEnabled]);
React.useEffect(() => {
if (popperInstance.current !== null) {
popperInstance.current.scheduleUpdate();
}
}, [popperInstance]);
return [referenceRef, popperRef];
}
export default usePopper;