UNPKG

@popperjs/core

Version:

Tooltip and Popover Positioning Engine

80 lines (67 loc) 3.05 kB
import getBasePlacement from "../utils/getBasePlacement.js"; import getLayoutRect from "../dom-utils/getLayoutRect.js"; import contains from "../dom-utils/contains.js"; import getMainAxisFromPlacement from "../utils/getMainAxisFromPlacement.js"; import within from "../utils/within.js"; import mergePaddingObject from "../utils/mergePaddingObject.js"; import expandToHashMap from "../utils/expandToHashMap.js"; import { left, right, basePlacements, top, bottom } from "../enums.js"; function arrow(_ref) { var _state$modifiersData$; var state = _ref.state, name = _ref.name; var arrowElement = state.elements.arrow; var popperOffsets = state.modifiersData.popperOffsets; var basePlacement = getBasePlacement(state.placement); var axis = getMainAxisFromPlacement(basePlacement); var isVertical = [left, right].indexOf(basePlacement) >= 0; var len = isVertical ? 'height' : 'width'; if (!arrowElement) { return; } var paddingObject = state.modifiersData[name + "#persistent"].padding; var arrowRect = getLayoutRect(arrowElement); var minProp = axis === 'y' ? top : left; var maxProp = axis === 'y' ? bottom : right; var endDiff = state.rects.reference[len] + state.rects.reference[axis] - popperOffsets[axis] - state.rects.popper[len]; var startDiff = popperOffsets[axis] - state.rects.reference[axis]; var centerToReference = endDiff / 2 - startDiff / 2; // Make sure the arrow doesn't overflow the popper if the center point is // outside of the popper bounds var center = within(paddingObject[minProp], state.rects.popper[len] / 2 - arrowRect[len] / 2 + centerToReference, state.rects.popper[len] - arrowRect[len] - paddingObject[maxProp]); // Prevents breaking syntax highlighting... var axisProp = axis; state.modifiersData[name] = (_state$modifiersData$ = {}, _state$modifiersData$[axisProp] = center, _state$modifiersData$); } function effect(_ref2) { var state = _ref2.state, options = _ref2.options, name = _ref2.name; var _options$element = options.element, arrowElement = _options$element === void 0 ? '[data-popper-arrow]' : _options$element, _options$padding = options.padding, padding = _options$padding === void 0 ? 0 : _options$padding; // CSS selector if (typeof arrowElement === 'string') { arrowElement = state.elements.popper.querySelector(arrowElement); if (!arrowElement) { return; } } if (!contains(state.elements.popper, arrowElement)) { if (process.env.NODE_ENV !== "production") { console.error(['Popper: "arrow" modifier\'s `element` must be a child of the popper', 'element.'].join(' ')); } return; } state.elements.arrow = arrowElement; state.modifiersData[name + "#persistent"] = { padding: mergePaddingObject(typeof padding !== 'number' ? padding : expandToHashMap(padding, basePlacements)) }; } export default { name: 'arrow', enabled: true, phase: 'main', fn: arrow, effect: effect, requires: ['popperOffsets'], requiresIfExists: ['preventOverflow'] };