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.
		
		
		
		
		
			
		
			
				
					
					
						
							125 lines
						
					
					
						
							3.0 KiB
						
					
					
				
			
		
		
	
	
							125 lines
						
					
					
						
							3.0 KiB
						
					
					
				| // @flow strict
 | |
| import * as React from 'react';
 | |
| import {
 | |
|   type State,
 | |
|   type Placement,
 | |
|   type PositioningStrategy,
 | |
|   type VirtualElement,
 | |
|   type StrictModifiers,
 | |
|   type Modifier,
 | |
| } from '@popperjs/core/lib';
 | |
| import { ManagerReferenceNodeContext } from './Manager';
 | |
| import type { Ref } from './RefTypes';
 | |
| import { unwrapArray, setRef } from './utils';
 | |
| import { usePopper } from './usePopper';
 | |
| 
 | |
| type ReferenceElement = ?(VirtualElement | HTMLElement);
 | |
| type Modifiers = Array<StrictModifiers | $Shape<Modifier<string, {}>>>;
 | |
| 
 | |
| export type PopperArrowProps = {|
 | |
|   ref: Ref,
 | |
|   style: CSSStyleDeclaration,
 | |
| |};
 | |
| export type PopperChildrenProps = {|
 | |
|   ref: Ref,
 | |
|   style: CSSStyleDeclaration,
 | |
| 
 | |
|   placement: Placement,
 | |
|   isReferenceHidden: ?boolean,
 | |
|   hasPopperEscaped: ?boolean,
 | |
| 
 | |
|   update: () => Promise<null | $Shape<State>>,
 | |
|   forceUpdate: () => void,
 | |
|   arrowProps: PopperArrowProps,
 | |
| |};
 | |
| export type PopperChildren = (PopperChildrenProps) => React.Node;
 | |
| 
 | |
| export type PopperProps = $ReadOnly<{|
 | |
|   children: PopperChildren,
 | |
|   innerRef?: Ref,
 | |
|   modifiers?: Modifiers,
 | |
|   placement?: Placement,
 | |
|   strategy?: PositioningStrategy,
 | |
|   referenceElement?: ReferenceElement,
 | |
|   onFirstUpdate?: ($Shape<State>) => void,
 | |
| |}>;
 | |
| 
 | |
| const NOOP = () => void 0;
 | |
| const NOOP_PROMISE = () => Promise.resolve(null);
 | |
| const EMPTY_MODIFIERS = [];
 | |
| 
 | |
| export function Popper({
 | |
|   placement = 'bottom',
 | |
|   strategy = 'absolute',
 | |
|   modifiers = EMPTY_MODIFIERS,
 | |
|   referenceElement,
 | |
|   onFirstUpdate,
 | |
|   innerRef,
 | |
|   children,
 | |
| }: PopperProps): React.Node {
 | |
|   const referenceNode = React.useContext(ManagerReferenceNodeContext);
 | |
| 
 | |
|   const [popperElement, setPopperElement] = React.useState(null);
 | |
|   const [arrowElement, setArrowElement] = React.useState(null);
 | |
| 
 | |
|   React.useEffect(() => {
 | |
|     setRef(innerRef, popperElement)
 | |
|   }, [innerRef, popperElement]);
 | |
| 
 | |
|   const options = React.useMemo(
 | |
|     () => ({
 | |
|       placement,
 | |
|       strategy,
 | |
|       onFirstUpdate,
 | |
|       modifiers: [
 | |
|         ...modifiers,
 | |
|         {
 | |
|           name: 'arrow',
 | |
|           enabled: arrowElement != null,
 | |
|           options: { element: arrowElement },
 | |
|         },
 | |
|       ],
 | |
|     }),
 | |
|     [placement, strategy, onFirstUpdate, modifiers, arrowElement]
 | |
|   );
 | |
| 
 | |
|   const { state, styles, forceUpdate, update } = usePopper(
 | |
|     referenceElement || referenceNode,
 | |
|     popperElement,
 | |
|     options
 | |
|   );
 | |
| 
 | |
|   const childrenProps = React.useMemo(
 | |
|     () => ({
 | |
|       ref: setPopperElement,
 | |
|       style: styles.popper,
 | |
|       placement: state ? state.placement : placement,
 | |
|       hasPopperEscaped:
 | |
|         state && state.modifiersData.hide
 | |
|           ? state.modifiersData.hide.hasPopperEscaped
 | |
|           : null,
 | |
|       isReferenceHidden:
 | |
|         state && state.modifiersData.hide
 | |
|           ? state.modifiersData.hide.isReferenceHidden
 | |
|           : null,
 | |
|       arrowProps: {
 | |
|         style: styles.arrow,
 | |
|         ref: setArrowElement,
 | |
|       },
 | |
|       forceUpdate: forceUpdate || NOOP,
 | |
|       update: update || NOOP_PROMISE,
 | |
|     }),
 | |
|     [
 | |
|       setPopperElement,
 | |
|       setArrowElement,
 | |
|       placement,
 | |
|       state,
 | |
|       styles,
 | |
|       update,
 | |
|       forceUpdate,
 | |
|     ]
 | |
|   );
 | |
| 
 | |
|   return unwrapArray(children)(childrenProps);
 | |
| }
 |