| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142 | // @flowimport type { Modifier, ModifierArguments, Padding, Rect } from '../types';import type { Placement } from '../enums';import getBasePlacement from '../utils/getBasePlacement';import getLayoutRect from '../dom-utils/getLayoutRect';import contains from '../dom-utils/contains';import getOffsetParent from '../dom-utils/getOffsetParent';import getMainAxisFromPlacement from '../utils/getMainAxisFromPlacement';import { within } from '../utils/within';import mergePaddingObject from '../utils/mergePaddingObject';import expandToHashMap from '../utils/expandToHashMap';import { left, right, basePlacements, top, bottom } from '../enums';import { isHTMLElement } from '../dom-utils/instanceOf';// eslint-disable-next-line import/no-unused-modulesexport type Options = {  element: HTMLElement | string | null,  padding:    | Padding    | (({|        popper: Rect,        reference: Rect,        placement: Placement,      |}) => Padding),};const toPaddingObject = (padding, state) => {  padding =    typeof padding === 'function'      ? padding({ ...state.rects, placement: state.placement })      : padding;  return mergePaddingObject(    typeof padding !== 'number'      ? padding      : expandToHashMap(padding, basePlacements)  );};function arrow({ state, name, options }: ModifierArguments<Options>) {  const arrowElement = state.elements.arrow;  const popperOffsets = state.modifiersData.popperOffsets;  const basePlacement = getBasePlacement(state.placement);  const axis = getMainAxisFromPlacement(basePlacement);  const isVertical = [left, right].indexOf(basePlacement) >= 0;  const len = isVertical ? 'height' : 'width';  if (!arrowElement || !popperOffsets) {    return;  }  const paddingObject = toPaddingObject(options.padding, state);  const arrowRect = getLayoutRect(arrowElement);  const minProp = axis === 'y' ? top : left;  const maxProp = axis === 'y' ? bottom : right;  const endDiff =    state.rects.reference[len] +    state.rects.reference[axis] -    popperOffsets[axis] -    state.rects.popper[len];  const startDiff = popperOffsets[axis] - state.rects.reference[axis];  const arrowOffsetParent = getOffsetParent(arrowElement);  const clientSize = arrowOffsetParent    ? axis === 'y'      ? arrowOffsetParent.clientHeight || 0      : arrowOffsetParent.clientWidth || 0    : 0;  const centerToReference = endDiff / 2 - startDiff / 2;  // Make sure the arrow doesn't overflow the popper if the center point is  // outside of the popper bounds  const min = paddingObject[minProp];  const max = clientSize - arrowRect[len] - paddingObject[maxProp];  const center = clientSize / 2 - arrowRect[len] / 2 + centerToReference;  const offset = within(min, center, max);  // Prevents breaking syntax highlighting...  const axisProp: string = axis;  state.modifiersData[name] = {    [axisProp]: offset,    centerOffset: offset - center,  };}function effect({ state, options }: ModifierArguments<Options>) {  let { element: arrowElement = '[data-popper-arrow]' } = options;  if (arrowElement == null) {    return;  }  // CSS selector  if (typeof arrowElement === 'string') {    arrowElement = state.elements.popper.querySelector(arrowElement);    if (!arrowElement) {      return;    }  }  if (false) {    if (!isHTMLElement(arrowElement)) {      console.error(        [          'Popper: "arrow" element must be an HTMLElement (not an SVGElement).',          'To use an SVG arrow, wrap it in an HTMLElement that will be used as',          'the arrow.',        ].join(' ')      );    }  }  if (!contains(state.elements.popper, arrowElement)) {    if (false) {      console.error(        [          'Popper: "arrow" modifier\'s `element` must be a child of the popper',          'element.',        ].join(' ')      );    }    return;  }  state.elements.arrow = arrowElement;}// eslint-disable-next-line import/no-unused-modulesexport type ArrowModifier = Modifier<'arrow', Options>;export default ({  name: 'arrow',  enabled: true,  phase: 'main',  fn: arrow,  effect,  requires: ['popperOffsets'],  requiresIfExists: ['preventOverflow'],}: ArrowModifier);
 |