first commit
This commit is contained in:
89
F4SDwebService/Publish/Scripts/src/modifiers/arrow.js
Normal file
89
F4SDwebService/Publish/Scripts/src/modifiers/arrow.js
Normal file
@@ -0,0 +1,89 @@
|
||||
import getClientRect from '../utils/getClientRect';
|
||||
import getOuterSizes from '../utils/getOuterSizes';
|
||||
import isModifierRequired from '../utils/isModifierRequired';
|
||||
import getStyleComputedProperty from '../utils/getStyleComputedProperty';
|
||||
|
||||
/**
|
||||
* @function
|
||||
* @memberof Modifiers
|
||||
* @argument {Object} data - The data object generated by update method
|
||||
* @argument {Object} options - Modifiers configuration and options
|
||||
* @returns {Object} The data object, properly modified
|
||||
*/
|
||||
export default function arrow(data, options) {
|
||||
// arrow depends on keepTogether in order to work
|
||||
if (!isModifierRequired(data.instance.modifiers, 'arrow', 'keepTogether')) {
|
||||
return data;
|
||||
}
|
||||
|
||||
let arrowElement = options.element;
|
||||
|
||||
// if arrowElement is a string, suppose it's a CSS selector
|
||||
if (typeof arrowElement === 'string') {
|
||||
arrowElement = data.instance.popper.querySelector(arrowElement);
|
||||
|
||||
// if arrowElement is not found, don't run the modifier
|
||||
if (!arrowElement) {
|
||||
return data;
|
||||
}
|
||||
} else {
|
||||
// if the arrowElement isn't a query selector we must check that the
|
||||
// provided DOM node is child of its popper node
|
||||
if (!data.instance.popper.contains(arrowElement)) {
|
||||
console.warn(
|
||||
'WARNING: `arrow.element` must be child of its popper element!'
|
||||
);
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
const placement = data.placement.split('-')[0];
|
||||
const { popper, reference } = data.offsets;
|
||||
const isVertical = ['left', 'right'].indexOf(placement) !== -1;
|
||||
|
||||
const len = isVertical ? 'height' : 'width';
|
||||
const sideCapitalized = isVertical ? 'Top' : 'Left';
|
||||
const side = sideCapitalized.toLowerCase();
|
||||
const altSide = isVertical ? 'left' : 'top';
|
||||
const opSide = isVertical ? 'bottom' : 'right';
|
||||
const arrowElementSize = getOuterSizes(arrowElement)[len];
|
||||
|
||||
//
|
||||
// extends keepTogether behavior making sure the popper and its
|
||||
// reference have enough pixels in conjunction
|
||||
//
|
||||
|
||||
// top/left side
|
||||
if (reference[opSide] - arrowElementSize < popper[side]) {
|
||||
data.offsets.popper[side] -=
|
||||
popper[side] - (reference[opSide] - arrowElementSize);
|
||||
}
|
||||
// bottom/right side
|
||||
if (reference[side] + arrowElementSize > popper[opSide]) {
|
||||
data.offsets.popper[side] +=
|
||||
reference[side] + arrowElementSize - popper[opSide];
|
||||
}
|
||||
data.offsets.popper = getClientRect(data.offsets.popper);
|
||||
|
||||
// compute center of the popper
|
||||
const center = reference[side] + reference[len] / 2 - arrowElementSize / 2;
|
||||
|
||||
// Compute the sideValue using the updated popper offsets
|
||||
// take popper margin in account because we don't have this info available
|
||||
const css = getStyleComputedProperty(data.instance.popper);
|
||||
const popperMarginSide = parseFloat(css[`margin${sideCapitalized}`]);
|
||||
const popperBorderSide = parseFloat(css[`border${sideCapitalized}Width`]);
|
||||
let sideValue =
|
||||
center - data.offsets.popper[side] - popperMarginSide - popperBorderSide;
|
||||
|
||||
// prevent arrowElement from being placed not contiguously to its popper
|
||||
sideValue = Math.max(Math.min(popper[len] - arrowElementSize, sideValue), 0);
|
||||
|
||||
data.arrowElement = arrowElement;
|
||||
data.offsets.arrow = {
|
||||
[side]: Math.round(sideValue),
|
||||
[altSide]: '', // make sure to unset any eventual altSide value from the DOM node
|
||||
};
|
||||
|
||||
return data;
|
||||
}
|
||||
Reference in New Issue
Block a user