You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					102 lines
				
				3.3 KiB
			
		
		
			
		
	
	
					102 lines
				
				3.3 KiB
			| 
								 
											3 years ago
										 
									 | 
							
								import * as React from 'react';
							 | 
						||
| 
								 | 
							
								import * as ReactDOM from 'react-dom';
							 | 
						||
| 
								 | 
							
								import { createPopper as defaultCreatePopper } from '@popperjs/core';
							 | 
						||
| 
								 | 
							
								import isEqual from 'react-fast-compare';
							 | 
						||
| 
								 | 
							
								import { fromEntries, useIsomorphicLayoutEffect } from './utils';
							 | 
						||
| 
								 | 
							
								var EMPTY_MODIFIERS = [];
							 | 
						||
| 
								 | 
							
								export var usePopper = function usePopper(referenceElement, popperElement, options) {
							 | 
						||
| 
								 | 
							
								  if (options === void 0) {
							 | 
						||
| 
								 | 
							
								    options = {};
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  var prevOptions = React.useRef(null);
							 | 
						||
| 
								 | 
							
								  var optionsWithDefaults = {
							 | 
						||
| 
								 | 
							
								    onFirstUpdate: options.onFirstUpdate,
							 | 
						||
| 
								 | 
							
								    placement: options.placement || 'bottom',
							 | 
						||
| 
								 | 
							
								    strategy: options.strategy || 'absolute',
							 | 
						||
| 
								 | 
							
								    modifiers: options.modifiers || EMPTY_MODIFIERS
							 | 
						||
| 
								 | 
							
								  };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  var _React$useState = React.useState({
							 | 
						||
| 
								 | 
							
								    styles: {
							 | 
						||
| 
								 | 
							
								      popper: {
							 | 
						||
| 
								 | 
							
								        position: optionsWithDefaults.strategy,
							 | 
						||
| 
								 | 
							
								        left: '0',
							 | 
						||
| 
								 | 
							
								        top: '0'
							 | 
						||
| 
								 | 
							
								      },
							 | 
						||
| 
								 | 
							
								      arrow: {
							 | 
						||
| 
								 | 
							
								        position: 'absolute'
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								    attributes: {}
							 | 
						||
| 
								 | 
							
								  }),
							 | 
						||
| 
								 | 
							
								      state = _React$useState[0],
							 | 
						||
| 
								 | 
							
								      setState = _React$useState[1];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  var updateStateModifier = React.useMemo(function () {
							 | 
						||
| 
								 | 
							
								    return {
							 | 
						||
| 
								 | 
							
								      name: 'updateState',
							 | 
						||
| 
								 | 
							
								      enabled: true,
							 | 
						||
| 
								 | 
							
								      phase: 'write',
							 | 
						||
| 
								 | 
							
								      fn: function fn(_ref) {
							 | 
						||
| 
								 | 
							
								        var state = _ref.state;
							 | 
						||
| 
								 | 
							
								        var elements = Object.keys(state.elements);
							 | 
						||
| 
								 | 
							
								        ReactDOM.flushSync(function () {
							 | 
						||
| 
								 | 
							
								          setState({
							 | 
						||
| 
								 | 
							
								            styles: fromEntries(elements.map(function (element) {
							 | 
						||
| 
								 | 
							
								              return [element, state.styles[element] || {}];
							 | 
						||
| 
								 | 
							
								            })),
							 | 
						||
| 
								 | 
							
								            attributes: fromEntries(elements.map(function (element) {
							 | 
						||
| 
								 | 
							
								              return [element, state.attributes[element]];
							 | 
						||
| 
								 | 
							
								            }))
							 | 
						||
| 
								 | 
							
								          });
							 | 
						||
| 
								 | 
							
								        });
							 | 
						||
| 
								 | 
							
								      },
							 | 
						||
| 
								 | 
							
								      requires: ['computeStyles']
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								  }, []);
							 | 
						||
| 
								 | 
							
								  var popperOptions = React.useMemo(function () {
							 | 
						||
| 
								 | 
							
								    var newOptions = {
							 | 
						||
| 
								 | 
							
								      onFirstUpdate: optionsWithDefaults.onFirstUpdate,
							 | 
						||
| 
								 | 
							
								      placement: optionsWithDefaults.placement,
							 | 
						||
| 
								 | 
							
								      strategy: optionsWithDefaults.strategy,
							 | 
						||
| 
								 | 
							
								      modifiers: [].concat(optionsWithDefaults.modifiers, [updateStateModifier, {
							 | 
						||
| 
								 | 
							
								        name: 'applyStyles',
							 | 
						||
| 
								 | 
							
								        enabled: false
							 | 
						||
| 
								 | 
							
								      }])
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (isEqual(prevOptions.current, newOptions)) {
							 | 
						||
| 
								 | 
							
								      return prevOptions.current || newOptions;
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								      prevOptions.current = newOptions;
							 | 
						||
| 
								 | 
							
								      return newOptions;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }, [optionsWithDefaults.onFirstUpdate, optionsWithDefaults.placement, optionsWithDefaults.strategy, optionsWithDefaults.modifiers, updateStateModifier]);
							 | 
						||
| 
								 | 
							
								  var popperInstanceRef = React.useRef();
							 | 
						||
| 
								 | 
							
								  useIsomorphicLayoutEffect(function () {
							 | 
						||
| 
								 | 
							
								    if (popperInstanceRef.current) {
							 | 
						||
| 
								 | 
							
								      popperInstanceRef.current.setOptions(popperOptions);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }, [popperOptions]);
							 | 
						||
| 
								 | 
							
								  useIsomorphicLayoutEffect(function () {
							 | 
						||
| 
								 | 
							
								    if (referenceElement == null || popperElement == null) {
							 | 
						||
| 
								 | 
							
								      return;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    var createPopper = options.createPopper || defaultCreatePopper;
							 | 
						||
| 
								 | 
							
								    var popperInstance = createPopper(referenceElement, popperElement, popperOptions);
							 | 
						||
| 
								 | 
							
								    popperInstanceRef.current = popperInstance;
							 | 
						||
| 
								 | 
							
								    return function () {
							 | 
						||
| 
								 | 
							
								      popperInstance.destroy();
							 | 
						||
| 
								 | 
							
								      popperInstanceRef.current = null;
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								  }, [referenceElement, popperElement, options.createPopper]);
							 | 
						||
| 
								 | 
							
								  return {
							 | 
						||
| 
								 | 
							
								    state: popperInstanceRef.current ? popperInstanceRef.current.state : null,
							 | 
						||
| 
								 | 
							
								    styles: state.styles,
							 | 
						||
| 
								 | 
							
								    attributes: state.attributes,
							 | 
						||
| 
								 | 
							
								    update: popperInstanceRef.current ? popperInstanceRef.current.update : null,
							 | 
						||
| 
								 | 
							
								    forceUpdate: popperInstanceRef.current ? popperInstanceRef.current.forceUpdate : null
							 | 
						||
| 
								 | 
							
								  };
							 | 
						||
| 
								 | 
							
								};
							 |