101 lines
3.8 KiB
JavaScript
101 lines
3.8 KiB
JavaScript
|
import getBasePlacement from "../utils/getBasePlacement.js";
|
||
|
import getLayoutRect from "../dom-utils/getLayoutRect.js";
|
||
|
import contains from "../dom-utils/contains.js";
|
||
|
import getOffsetParent from "../dom-utils/getOffsetParent.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";
|
||
|
import { isHTMLElement } from "../dom-utils/instanceOf.js"; // eslint-disable-next-line import/no-unused-modules
|
||
|
|
||
|
var toPaddingObject = function toPaddingObject(padding, state) {
|
||
|
padding = typeof padding === 'function' ? padding(Object.assign({}, state.rects, {
|
||
|
placement: state.placement
|
||
|
})) : padding;
|
||
|
return mergePaddingObject(typeof padding !== 'number' ? padding : expandToHashMap(padding, basePlacements));
|
||
|
};
|
||
|
|
||
|
function arrow(_ref) {
|
||
|
var _state$modifiersData$;
|
||
|
|
||
|
var state = _ref.state,
|
||
|
name = _ref.name,
|
||
|
options = _ref.options;
|
||
|
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 || !popperOffsets) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
var paddingObject = toPaddingObject(options.padding, state);
|
||
|
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 arrowOffsetParent = getOffsetParent(arrowElement);
|
||
|
var clientSize = arrowOffsetParent ? axis === 'y' ? arrowOffsetParent.clientHeight || 0 : arrowOffsetParent.clientWidth || 0 : 0;
|
||
|
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 min = paddingObject[minProp];
|
||
|
var max = clientSize - arrowRect[len] - paddingObject[maxProp];
|
||
|
var center = clientSize / 2 - arrowRect[len] / 2 + centerToReference;
|
||
|
var offset = within(min, center, max); // Prevents breaking syntax highlighting...
|
||
|
|
||
|
var axisProp = axis;
|
||
|
state.modifiersData[name] = (_state$modifiersData$ = {}, _state$modifiersData$[axisProp] = offset, _state$modifiersData$.centerOffset = offset - center, _state$modifiersData$);
|
||
|
}
|
||
|
|
||
|
function effect(_ref2) {
|
||
|
var state = _ref2.state,
|
||
|
options = _ref2.options;
|
||
|
var _options$element = options.element,
|
||
|
arrowElement = _options$element === void 0 ? '[data-popper-arrow]' : _options$element;
|
||
|
|
||
|
if (arrowElement == null) {
|
||
|
return;
|
||
|
} // CSS selector
|
||
|
|
||
|
|
||
|
if (typeof arrowElement === 'string') {
|
||
|
arrowElement = state.elements.popper.querySelector(arrowElement);
|
||
|
|
||
|
if (!arrowElement) {
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (process.env.NODE_ENV !== "production") {
|
||
|
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 (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;
|
||
|
} // eslint-disable-next-line import/no-unused-modules
|
||
|
|
||
|
|
||
|
export default {
|
||
|
name: 'arrow',
|
||
|
enabled: true,
|
||
|
phase: 'main',
|
||
|
fn: arrow,
|
||
|
effect: effect,
|
||
|
requires: ['popperOffsets'],
|
||
|
requiresIfExists: ['preventOverflow']
|
||
|
};
|