first commit
This commit is contained in:
73
F4SDwebService/Scripts/src/modifiers/applyStyle.js
Normal file
73
F4SDwebService/Scripts/src/modifiers/applyStyle.js
Normal file
@@ -0,0 +1,73 @@
|
||||
import setStyles from '../utils/setStyles';
|
||||
import setAttributes from '../utils/setAttributes';
|
||||
import getReferenceOffsets from '../utils/getReferenceOffsets';
|
||||
import computeAutoPlacement from '../utils/computeAutoPlacement';
|
||||
|
||||
/**
|
||||
* @function
|
||||
* @memberof Modifiers
|
||||
* @argument {Object} data - The data object generated by `update` method
|
||||
* @argument {Object} data.styles - List of style properties - values to apply to popper element
|
||||
* @argument {Object} data.attributes - List of attribute properties - values to apply to popper element
|
||||
* @argument {Object} options - Modifiers configuration and options
|
||||
* @returns {Object} The same data object
|
||||
*/
|
||||
export default function applyStyle(data) {
|
||||
// any property present in `data.styles` will be applied to the popper,
|
||||
// in this way we can make the 3rd party modifiers add custom styles to it
|
||||
// Be aware, modifiers could override the properties defined in the previous
|
||||
// lines of this modifier!
|
||||
setStyles(data.instance.popper, data.styles);
|
||||
|
||||
// any property present in `data.attributes` will be applied to the popper,
|
||||
// they will be set as HTML attributes of the element
|
||||
setAttributes(data.instance.popper, data.attributes);
|
||||
|
||||
// if arrowElement is defined and arrowStyles has some properties
|
||||
if (data.arrowElement && Object.keys(data.arrowStyles).length) {
|
||||
setStyles(data.arrowElement, data.arrowStyles);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the x-placement attribute before everything else because it could be used
|
||||
* to add margins to the popper margins needs to be calculated to get the
|
||||
* correct popper offsets.
|
||||
* @method
|
||||
* @memberof Popper.modifiers
|
||||
* @param {HTMLElement} reference - The reference element used to position the popper
|
||||
* @param {HTMLElement} popper - The HTML element used as popper
|
||||
* @param {Object} options - Popper.js options
|
||||
*/
|
||||
export function applyStyleOnLoad(
|
||||
reference,
|
||||
popper,
|
||||
options,
|
||||
modifierOptions,
|
||||
state
|
||||
) {
|
||||
// compute reference element offsets
|
||||
const referenceOffsets = getReferenceOffsets(state, popper, reference, options.positionFixed);
|
||||
|
||||
// compute auto placement, store placement inside the data object,
|
||||
// modifiers will be able to edit `placement` if needed
|
||||
// and refer to originalPlacement to know the original value
|
||||
const placement = computeAutoPlacement(
|
||||
options.placement,
|
||||
referenceOffsets,
|
||||
popper,
|
||||
reference,
|
||||
options.modifiers.flip.boundariesElement,
|
||||
options.modifiers.flip.padding
|
||||
);
|
||||
|
||||
popper.setAttribute('x-placement', placement);
|
||||
|
||||
// Apply `position` to popper before anything else because
|
||||
// without the position applied we can't guarantee correct computations
|
||||
setStyles(popper, { position: options.positionFixed ? 'fixed' : 'absolute' });
|
||||
|
||||
return options;
|
||||
}
|
||||
89
F4SDwebService/Scripts/src/modifiers/arrow.js
Normal file
89
F4SDwebService/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;
|
||||
}
|
||||
112
F4SDwebService/Scripts/src/modifiers/computeStyle.js
Normal file
112
F4SDwebService/Scripts/src/modifiers/computeStyle.js
Normal file
@@ -0,0 +1,112 @@
|
||||
import getSupportedPropertyName from '../utils/getSupportedPropertyName';
|
||||
import find from '../utils/find';
|
||||
import getOffsetParent from '../utils/getOffsetParent';
|
||||
import getBoundingClientRect from '../utils/getBoundingClientRect';
|
||||
import getRoundedOffsets from '../utils/getRoundedOffsets';
|
||||
import isBrowser from '../utils/isBrowser';
|
||||
|
||||
const isFirefox = isBrowser && /Firefox/i.test(navigator.userAgent);
|
||||
|
||||
/**
|
||||
* @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 computeStyle(data, options) {
|
||||
const { x, y } = options;
|
||||
const { popper } = data.offsets;
|
||||
|
||||
// Remove this legacy support in Popper.js v2
|
||||
const legacyGpuAccelerationOption = find(
|
||||
data.instance.modifiers,
|
||||
modifier => modifier.name === 'applyStyle'
|
||||
).gpuAcceleration;
|
||||
if (legacyGpuAccelerationOption !== undefined) {
|
||||
console.warn(
|
||||
'WARNING: `gpuAcceleration` option moved to `computeStyle` modifier and will not be supported in future versions of Popper.js!'
|
||||
);
|
||||
}
|
||||
const gpuAcceleration =
|
||||
legacyGpuAccelerationOption !== undefined
|
||||
? legacyGpuAccelerationOption
|
||||
: options.gpuAcceleration;
|
||||
|
||||
const offsetParent = getOffsetParent(data.instance.popper);
|
||||
const offsetParentRect = getBoundingClientRect(offsetParent);
|
||||
|
||||
// Styles
|
||||
const styles = {
|
||||
position: popper.position,
|
||||
};
|
||||
|
||||
const offsets = getRoundedOffsets(
|
||||
data,
|
||||
window.devicePixelRatio < 2 || !isFirefox
|
||||
);
|
||||
|
||||
const sideA = x === 'bottom' ? 'top' : 'bottom';
|
||||
const sideB = y === 'right' ? 'left' : 'right';
|
||||
|
||||
// if gpuAcceleration is set to `true` and transform is supported,
|
||||
// we use `translate3d` to apply the position to the popper we
|
||||
// automatically use the supported prefixed version if needed
|
||||
const prefixedProperty = getSupportedPropertyName('transform');
|
||||
|
||||
// now, let's make a step back and look at this code closely (wtf?)
|
||||
// If the content of the popper grows once it's been positioned, it
|
||||
// may happen that the popper gets misplaced because of the new content
|
||||
// overflowing its reference element
|
||||
// To avoid this problem, we provide two options (x and y), which allow
|
||||
// the consumer to define the offset origin.
|
||||
// If we position a popper on top of a reference element, we can set
|
||||
// `x` to `top` to make the popper grow towards its top instead of
|
||||
// its bottom.
|
||||
let left, top;
|
||||
if (sideA === 'bottom') {
|
||||
// when offsetParent is <html> the positioning is relative to the bottom of the screen (excluding the scrollbar)
|
||||
// and not the bottom of the html element
|
||||
if (offsetParent.nodeName === 'HTML') {
|
||||
top = -offsetParent.clientHeight + offsets.bottom;
|
||||
} else {
|
||||
top = -offsetParentRect.height + offsets.bottom;
|
||||
}
|
||||
} else {
|
||||
top = offsets.top;
|
||||
}
|
||||
if (sideB === 'right') {
|
||||
if (offsetParent.nodeName === 'HTML') {
|
||||
left = -offsetParent.clientWidth + offsets.right;
|
||||
} else {
|
||||
left = -offsetParentRect.width + offsets.right;
|
||||
}
|
||||
} else {
|
||||
left = offsets.left;
|
||||
}
|
||||
if (gpuAcceleration && prefixedProperty) {
|
||||
styles[prefixedProperty] = `translate3d(${left}px, ${top}px, 0)`;
|
||||
styles[sideA] = 0;
|
||||
styles[sideB] = 0;
|
||||
styles.willChange = 'transform';
|
||||
} else {
|
||||
// othwerise, we use the standard `top`, `left`, `bottom` and `right` properties
|
||||
const invertTop = sideA === 'bottom' ? -1 : 1;
|
||||
const invertLeft = sideB === 'right' ? -1 : 1;
|
||||
styles[sideA] = top * invertTop;
|
||||
styles[sideB] = left * invertLeft;
|
||||
styles.willChange = `${sideA}, ${sideB}`;
|
||||
}
|
||||
|
||||
// Attributes
|
||||
const attributes = {
|
||||
'x-placement': data.placement,
|
||||
};
|
||||
|
||||
// Update `data` attributes, styles and arrowStyles
|
||||
data.attributes = { ...attributes, ...data.attributes };
|
||||
data.styles = { ...styles, ...data.styles };
|
||||
data.arrowStyles = { ...data.offsets.arrow, ...data.arrowStyles };
|
||||
|
||||
return data;
|
||||
}
|
||||
146
F4SDwebService/Scripts/src/modifiers/flip.js
Normal file
146
F4SDwebService/Scripts/src/modifiers/flip.js
Normal file
@@ -0,0 +1,146 @@
|
||||
import getOppositePlacement from '../utils/getOppositePlacement';
|
||||
import getOppositeVariation from '../utils/getOppositeVariation';
|
||||
import getPopperOffsets from '../utils/getPopperOffsets';
|
||||
import runModifiers from '../utils/runModifiers';
|
||||
import getBoundaries from '../utils/getBoundaries';
|
||||
import isModifierEnabled from '../utils/isModifierEnabled';
|
||||
import clockwise from '../utils/clockwise';
|
||||
|
||||
const BEHAVIORS = {
|
||||
FLIP: 'flip',
|
||||
CLOCKWISE: 'clockwise',
|
||||
COUNTERCLOCKWISE: 'counterclockwise',
|
||||
};
|
||||
|
||||
/**
|
||||
* @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 flip(data, options) {
|
||||
// if `inner` modifier is enabled, we can't use the `flip` modifier
|
||||
if (isModifierEnabled(data.instance.modifiers, 'inner')) {
|
||||
return data;
|
||||
}
|
||||
|
||||
if (data.flipped && data.placement === data.originalPlacement) {
|
||||
// seems like flip is trying to loop, probably there's not enough space on any of the flippable sides
|
||||
return data;
|
||||
}
|
||||
|
||||
const boundaries = getBoundaries(
|
||||
data.instance.popper,
|
||||
data.instance.reference,
|
||||
options.padding,
|
||||
options.boundariesElement,
|
||||
data.positionFixed
|
||||
);
|
||||
|
||||
let placement = data.placement.split('-')[0];
|
||||
let placementOpposite = getOppositePlacement(placement);
|
||||
let variation = data.placement.split('-')[1] || '';
|
||||
|
||||
let flipOrder = [];
|
||||
|
||||
switch (options.behavior) {
|
||||
case BEHAVIORS.FLIP:
|
||||
flipOrder = [placement, placementOpposite];
|
||||
break;
|
||||
case BEHAVIORS.CLOCKWISE:
|
||||
flipOrder = clockwise(placement);
|
||||
break;
|
||||
case BEHAVIORS.COUNTERCLOCKWISE:
|
||||
flipOrder = clockwise(placement, true);
|
||||
break;
|
||||
default:
|
||||
flipOrder = options.behavior;
|
||||
}
|
||||
|
||||
flipOrder.forEach((step, index) => {
|
||||
if (placement !== step || flipOrder.length === index + 1) {
|
||||
return data;
|
||||
}
|
||||
|
||||
placement = data.placement.split('-')[0];
|
||||
placementOpposite = getOppositePlacement(placement);
|
||||
|
||||
const popperOffsets = data.offsets.popper;
|
||||
const refOffsets = data.offsets.reference;
|
||||
|
||||
// using floor because the reference offsets may contain decimals we are not going to consider here
|
||||
const floor = Math.floor;
|
||||
const overlapsRef =
|
||||
(placement === 'left' &&
|
||||
floor(popperOffsets.right) > floor(refOffsets.left)) ||
|
||||
(placement === 'right' &&
|
||||
floor(popperOffsets.left) < floor(refOffsets.right)) ||
|
||||
(placement === 'top' &&
|
||||
floor(popperOffsets.bottom) > floor(refOffsets.top)) ||
|
||||
(placement === 'bottom' &&
|
||||
floor(popperOffsets.top) < floor(refOffsets.bottom));
|
||||
|
||||
const overflowsLeft = floor(popperOffsets.left) < floor(boundaries.left);
|
||||
const overflowsRight = floor(popperOffsets.right) > floor(boundaries.right);
|
||||
const overflowsTop = floor(popperOffsets.top) < floor(boundaries.top);
|
||||
const overflowsBottom =
|
||||
floor(popperOffsets.bottom) > floor(boundaries.bottom);
|
||||
|
||||
const overflowsBoundaries =
|
||||
(placement === 'left' && overflowsLeft) ||
|
||||
(placement === 'right' && overflowsRight) ||
|
||||
(placement === 'top' && overflowsTop) ||
|
||||
(placement === 'bottom' && overflowsBottom);
|
||||
|
||||
// flip the variation if required
|
||||
const isVertical = ['top', 'bottom'].indexOf(placement) !== -1;
|
||||
|
||||
// flips variation if reference element overflows boundaries
|
||||
const flippedVariationByRef =
|
||||
!!options.flipVariations &&
|
||||
((isVertical && variation === 'start' && overflowsLeft) ||
|
||||
(isVertical && variation === 'end' && overflowsRight) ||
|
||||
(!isVertical && variation === 'start' && overflowsTop) ||
|
||||
(!isVertical && variation === 'end' && overflowsBottom));
|
||||
|
||||
// flips variation if popper content overflows boundaries
|
||||
const flippedVariationByContent =
|
||||
!!options.flipVariationsByContent &&
|
||||
((isVertical && variation === 'start' && overflowsRight) ||
|
||||
(isVertical && variation === 'end' && overflowsLeft) ||
|
||||
(!isVertical && variation === 'start' && overflowsBottom) ||
|
||||
(!isVertical && variation === 'end' && overflowsTop));
|
||||
|
||||
const flippedVariation = flippedVariationByRef || flippedVariationByContent;
|
||||
|
||||
if (overlapsRef || overflowsBoundaries || flippedVariation) {
|
||||
// this boolean to detect any flip loop
|
||||
data.flipped = true;
|
||||
|
||||
if (overlapsRef || overflowsBoundaries) {
|
||||
placement = flipOrder[index + 1];
|
||||
}
|
||||
|
||||
if (flippedVariation) {
|
||||
variation = getOppositeVariation(variation);
|
||||
}
|
||||
|
||||
data.placement = placement + (variation ? '-' + variation : '');
|
||||
|
||||
// this object contains `position`, we want to preserve it along with
|
||||
// any additional property we may add in the future
|
||||
data.offsets.popper = {
|
||||
...data.offsets.popper,
|
||||
...getPopperOffsets(
|
||||
data.instance.popper,
|
||||
data.offsets.reference,
|
||||
data.placement
|
||||
),
|
||||
};
|
||||
|
||||
data = runModifiers(data.instance.modifiers, data, 'flip');
|
||||
}
|
||||
});
|
||||
return data;
|
||||
}
|
||||
46
F4SDwebService/Scripts/src/modifiers/hide.js
Normal file
46
F4SDwebService/Scripts/src/modifiers/hide.js
Normal file
@@ -0,0 +1,46 @@
|
||||
import isModifierRequired from '../utils/isModifierRequired';
|
||||
import find from '../utils/find';
|
||||
|
||||
/**
|
||||
* @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 hide(data) {
|
||||
if (!isModifierRequired(data.instance.modifiers, 'hide', 'preventOverflow')) {
|
||||
return data;
|
||||
}
|
||||
|
||||
const refRect = data.offsets.reference;
|
||||
const bound = find(
|
||||
data.instance.modifiers,
|
||||
modifier => modifier.name === 'preventOverflow'
|
||||
).boundaries;
|
||||
|
||||
if (
|
||||
refRect.bottom < bound.top ||
|
||||
refRect.left > bound.right ||
|
||||
refRect.top > bound.bottom ||
|
||||
refRect.right < bound.left
|
||||
) {
|
||||
// Avoid unnecessary DOM access if visibility hasn't changed
|
||||
if (data.hide === true) {
|
||||
return data;
|
||||
}
|
||||
|
||||
data.hide = true;
|
||||
data.attributes['x-out-of-boundaries'] = '';
|
||||
} else {
|
||||
// Avoid unnecessary DOM access if visibility hasn't changed
|
||||
if (data.hide === false) {
|
||||
return data;
|
||||
}
|
||||
|
||||
data.hide = false;
|
||||
data.attributes['x-out-of-boundaries'] = false;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
369
F4SDwebService/Scripts/src/modifiers/index.js
Normal file
369
F4SDwebService/Scripts/src/modifiers/index.js
Normal file
@@ -0,0 +1,369 @@
|
||||
import applyStyle, { applyStyleOnLoad } from './applyStyle';
|
||||
import computeStyle from './computeStyle';
|
||||
import arrow from './arrow';
|
||||
import flip from './flip';
|
||||
import keepTogether from './keepTogether';
|
||||
import offset from './offset';
|
||||
import preventOverflow from './preventOverflow';
|
||||
import shift from './shift';
|
||||
import hide from './hide';
|
||||
import inner from './inner';
|
||||
|
||||
/**
|
||||
* Modifier function, each modifier can have a function of this type assigned
|
||||
* to its `fn` property.<br />
|
||||
* These functions will be called on each update, this means that you must
|
||||
* make sure they are performant enough to avoid performance bottlenecks.
|
||||
*
|
||||
* @function ModifierFn
|
||||
* @argument {dataObject} data - The data object generated by `update` method
|
||||
* @argument {Object} options - Modifiers configuration and options
|
||||
* @returns {dataObject} The data object, properly modified
|
||||
*/
|
||||
|
||||
/**
|
||||
* Modifiers are plugins used to alter the behavior of your poppers.<br />
|
||||
* Popper.js uses a set of 9 modifiers to provide all the basic functionalities
|
||||
* needed by the library.
|
||||
*
|
||||
* Usually you don't want to override the `order`, `fn` and `onLoad` props.
|
||||
* All the other properties are configurations that could be tweaked.
|
||||
* @namespace modifiers
|
||||
*/
|
||||
export default {
|
||||
/**
|
||||
* Modifier used to shift the popper on the start or end of its reference
|
||||
* element.<br />
|
||||
* It will read the variation of the `placement` property.<br />
|
||||
* It can be one either `-end` or `-start`.
|
||||
* @memberof modifiers
|
||||
* @inner
|
||||
*/
|
||||
shift: {
|
||||
/** @prop {number} order=100 - Index used to define the order of execution */
|
||||
order: 100,
|
||||
/** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */
|
||||
enabled: true,
|
||||
/** @prop {ModifierFn} */
|
||||
fn: shift,
|
||||
},
|
||||
|
||||
/**
|
||||
* The `offset` modifier can shift your popper on both its axis.
|
||||
*
|
||||
* It accepts the following units:
|
||||
* - `px` or unit-less, interpreted as pixels
|
||||
* - `%` or `%r`, percentage relative to the length of the reference element
|
||||
* - `%p`, percentage relative to the length of the popper element
|
||||
* - `vw`, CSS viewport width unit
|
||||
* - `vh`, CSS viewport height unit
|
||||
*
|
||||
* For length is intended the main axis relative to the placement of the popper.<br />
|
||||
* This means that if the placement is `top` or `bottom`, the length will be the
|
||||
* `width`. In case of `left` or `right`, it will be the `height`.
|
||||
*
|
||||
* You can provide a single value (as `Number` or `String`), or a pair of values
|
||||
* as `String` divided by a comma or one (or more) white spaces.<br />
|
||||
* The latter is a deprecated method because it leads to confusion and will be
|
||||
* removed in v2.<br />
|
||||
* Additionally, it accepts additions and subtractions between different units.
|
||||
* Note that multiplications and divisions aren't supported.
|
||||
*
|
||||
* Valid examples are:
|
||||
* ```
|
||||
* 10
|
||||
* '10%'
|
||||
* '10, 10'
|
||||
* '10%, 10'
|
||||
* '10 + 10%'
|
||||
* '10 - 5vh + 3%'
|
||||
* '-10px + 5vh, 5px - 6%'
|
||||
* ```
|
||||
* > **NB**: If you desire to apply offsets to your poppers in a way that may make them overlap
|
||||
* > with their reference element, unfortunately, you will have to disable the `flip` modifier.
|
||||
* > You can read more on this at this [issue](https://github.com/FezVrasta/popper.js/issues/373).
|
||||
*
|
||||
* @memberof modifiers
|
||||
* @inner
|
||||
*/
|
||||
offset: {
|
||||
/** @prop {number} order=200 - Index used to define the order of execution */
|
||||
order: 200,
|
||||
/** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */
|
||||
enabled: true,
|
||||
/** @prop {ModifierFn} */
|
||||
fn: offset,
|
||||
/** @prop {Number|String} offset=0
|
||||
* The offset value as described in the modifier description
|
||||
*/
|
||||
offset: 0,
|
||||
},
|
||||
|
||||
/**
|
||||
* Modifier used to prevent the popper from being positioned outside the boundary.
|
||||
*
|
||||
* A scenario exists where the reference itself is not within the boundaries.<br />
|
||||
* We can say it has "escaped the boundaries" — or just "escaped".<br />
|
||||
* In this case we need to decide whether the popper should either:
|
||||
*
|
||||
* - detach from the reference and remain "trapped" in the boundaries, or
|
||||
* - if it should ignore the boundary and "escape with its reference"
|
||||
*
|
||||
* When `escapeWithReference` is set to`true` and reference is completely
|
||||
* outside its boundaries, the popper will overflow (or completely leave)
|
||||
* the boundaries in order to remain attached to the edge of the reference.
|
||||
*
|
||||
* @memberof modifiers
|
||||
* @inner
|
||||
*/
|
||||
preventOverflow: {
|
||||
/** @prop {number} order=300 - Index used to define the order of execution */
|
||||
order: 300,
|
||||
/** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */
|
||||
enabled: true,
|
||||
/** @prop {ModifierFn} */
|
||||
fn: preventOverflow,
|
||||
/**
|
||||
* @prop {Array} [priority=['left','right','top','bottom']]
|
||||
* Popper will try to prevent overflow following these priorities by default,
|
||||
* then, it could overflow on the left and on top of the `boundariesElement`
|
||||
*/
|
||||
priority: ['left', 'right', 'top', 'bottom'],
|
||||
/**
|
||||
* @prop {number} padding=5
|
||||
* Amount of pixel used to define a minimum distance between the boundaries
|
||||
* and the popper. This makes sure the popper always has a little padding
|
||||
* between the edges of its container
|
||||
*/
|
||||
padding: 5,
|
||||
/**
|
||||
* @prop {String|HTMLElement} boundariesElement='scrollParent'
|
||||
* Boundaries used by the modifier. Can be `scrollParent`, `window`,
|
||||
* `viewport` or any DOM element.
|
||||
*/
|
||||
boundariesElement: 'scrollParent',
|
||||
},
|
||||
|
||||
/**
|
||||
* Modifier used to make sure the reference and its popper stay near each other
|
||||
* without leaving any gap between the two. Especially useful when the arrow is
|
||||
* enabled and you want to ensure that it points to its reference element.
|
||||
* It cares only about the first axis. You can still have poppers with margin
|
||||
* between the popper and its reference element.
|
||||
* @memberof modifiers
|
||||
* @inner
|
||||
*/
|
||||
keepTogether: {
|
||||
/** @prop {number} order=400 - Index used to define the order of execution */
|
||||
order: 400,
|
||||
/** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */
|
||||
enabled: true,
|
||||
/** @prop {ModifierFn} */
|
||||
fn: keepTogether,
|
||||
},
|
||||
|
||||
/**
|
||||
* This modifier is used to move the `arrowElement` of the popper to make
|
||||
* sure it is positioned between the reference element and its popper element.
|
||||
* It will read the outer size of the `arrowElement` node to detect how many
|
||||
* pixels of conjunction are needed.
|
||||
*
|
||||
* It has no effect if no `arrowElement` is provided.
|
||||
* @memberof modifiers
|
||||
* @inner
|
||||
*/
|
||||
arrow: {
|
||||
/** @prop {number} order=500 - Index used to define the order of execution */
|
||||
order: 500,
|
||||
/** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */
|
||||
enabled: true,
|
||||
/** @prop {ModifierFn} */
|
||||
fn: arrow,
|
||||
/** @prop {String|HTMLElement} element='[x-arrow]' - Selector or node used as arrow */
|
||||
element: '[x-arrow]',
|
||||
},
|
||||
|
||||
/**
|
||||
* Modifier used to flip the popper's placement when it starts to overlap its
|
||||
* reference element.
|
||||
*
|
||||
* Requires the `preventOverflow` modifier before it in order to work.
|
||||
*
|
||||
* **NOTE:** this modifier will interrupt the current update cycle and will
|
||||
* restart it if it detects the need to flip the placement.
|
||||
* @memberof modifiers
|
||||
* @inner
|
||||
*/
|
||||
flip: {
|
||||
/** @prop {number} order=600 - Index used to define the order of execution */
|
||||
order: 600,
|
||||
/** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */
|
||||
enabled: true,
|
||||
/** @prop {ModifierFn} */
|
||||
fn: flip,
|
||||
/**
|
||||
* @prop {String|Array} behavior='flip'
|
||||
* The behavior used to change the popper's placement. It can be one of
|
||||
* `flip`, `clockwise`, `counterclockwise` or an array with a list of valid
|
||||
* placements (with optional variations)
|
||||
*/
|
||||
behavior: 'flip',
|
||||
/**
|
||||
* @prop {number} padding=5
|
||||
* The popper will flip if it hits the edges of the `boundariesElement`
|
||||
*/
|
||||
padding: 5,
|
||||
/**
|
||||
* @prop {String|HTMLElement} boundariesElement='viewport'
|
||||
* The element which will define the boundaries of the popper position.
|
||||
* The popper will never be placed outside of the defined boundaries
|
||||
* (except if `keepTogether` is enabled)
|
||||
*/
|
||||
boundariesElement: 'viewport',
|
||||
/**
|
||||
* @prop {Boolean} flipVariations=false
|
||||
* The popper will switch placement variation between `-start` and `-end` when
|
||||
* the reference element overlaps its boundaries.
|
||||
*
|
||||
* The original placement should have a set variation.
|
||||
*/
|
||||
flipVariations: false,
|
||||
/**
|
||||
* @prop {Boolean} flipVariationsByContent=false
|
||||
* The popper will switch placement variation between `-start` and `-end` when
|
||||
* the popper element overlaps its reference boundaries.
|
||||
*
|
||||
* The original placement should have a set variation.
|
||||
*/
|
||||
flipVariationsByContent: false,
|
||||
},
|
||||
|
||||
/**
|
||||
* Modifier used to make the popper flow toward the inner of the reference element.
|
||||
* By default, when this modifier is disabled, the popper will be placed outside
|
||||
* the reference element.
|
||||
* @memberof modifiers
|
||||
* @inner
|
||||
*/
|
||||
inner: {
|
||||
/** @prop {number} order=700 - Index used to define the order of execution */
|
||||
order: 700,
|
||||
/** @prop {Boolean} enabled=false - Whether the modifier is enabled or not */
|
||||
enabled: false,
|
||||
/** @prop {ModifierFn} */
|
||||
fn: inner,
|
||||
},
|
||||
|
||||
/**
|
||||
* Modifier used to hide the popper when its reference element is outside of the
|
||||
* popper boundaries. It will set a `x-out-of-boundaries` attribute which can
|
||||
* be used to hide with a CSS selector the popper when its reference is
|
||||
* out of boundaries.
|
||||
*
|
||||
* Requires the `preventOverflow` modifier before it in order to work.
|
||||
* @memberof modifiers
|
||||
* @inner
|
||||
*/
|
||||
hide: {
|
||||
/** @prop {number} order=800 - Index used to define the order of execution */
|
||||
order: 800,
|
||||
/** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */
|
||||
enabled: true,
|
||||
/** @prop {ModifierFn} */
|
||||
fn: hide,
|
||||
},
|
||||
|
||||
/**
|
||||
* Computes the style that will be applied to the popper element to gets
|
||||
* properly positioned.
|
||||
*
|
||||
* Note that this modifier will not touch the DOM, it just prepares the styles
|
||||
* so that `applyStyle` modifier can apply it. This separation is useful
|
||||
* in case you need to replace `applyStyle` with a custom implementation.
|
||||
*
|
||||
* This modifier has `850` as `order` value to maintain backward compatibility
|
||||
* with previous versions of Popper.js. Expect the modifiers ordering method
|
||||
* to change in future major versions of the library.
|
||||
*
|
||||
* @memberof modifiers
|
||||
* @inner
|
||||
*/
|
||||
computeStyle: {
|
||||
/** @prop {number} order=850 - Index used to define the order of execution */
|
||||
order: 850,
|
||||
/** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */
|
||||
enabled: true,
|
||||
/** @prop {ModifierFn} */
|
||||
fn: computeStyle,
|
||||
/**
|
||||
* @prop {Boolean} gpuAcceleration=true
|
||||
* If true, it uses the CSS 3D transformation to position the popper.
|
||||
* Otherwise, it will use the `top` and `left` properties
|
||||
*/
|
||||
gpuAcceleration: true,
|
||||
/**
|
||||
* @prop {string} [x='bottom']
|
||||
* Where to anchor the X axis (`bottom` or `top`). AKA X offset origin.
|
||||
* Change this if your popper should grow in a direction different from `bottom`
|
||||
*/
|
||||
x: 'bottom',
|
||||
/**
|
||||
* @prop {string} [x='left']
|
||||
* Where to anchor the Y axis (`left` or `right`). AKA Y offset origin.
|
||||
* Change this if your popper should grow in a direction different from `right`
|
||||
*/
|
||||
y: 'right',
|
||||
},
|
||||
|
||||
/**
|
||||
* Applies the computed styles to the popper element.
|
||||
*
|
||||
* All the DOM manipulations are limited to this modifier. This is useful in case
|
||||
* you want to integrate Popper.js inside a framework or view library and you
|
||||
* want to delegate all the DOM manipulations to it.
|
||||
*
|
||||
* Note that if you disable this modifier, you must make sure the popper element
|
||||
* has its position set to `absolute` before Popper.js can do its work!
|
||||
*
|
||||
* Just disable this modifier and define your own to achieve the desired effect.
|
||||
*
|
||||
* @memberof modifiers
|
||||
* @inner
|
||||
*/
|
||||
applyStyle: {
|
||||
/** @prop {number} order=900 - Index used to define the order of execution */
|
||||
order: 900,
|
||||
/** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */
|
||||
enabled: true,
|
||||
/** @prop {ModifierFn} */
|
||||
fn: applyStyle,
|
||||
/** @prop {Function} */
|
||||
onLoad: applyStyleOnLoad,
|
||||
/**
|
||||
* @deprecated since version 1.10.0, the property moved to `computeStyle` modifier
|
||||
* @prop {Boolean} gpuAcceleration=true
|
||||
* If true, it uses the CSS 3D transformation to position the popper.
|
||||
* Otherwise, it will use the `top` and `left` properties
|
||||
*/
|
||||
gpuAcceleration: undefined,
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* The `dataObject` is an object containing all the information used by Popper.js.
|
||||
* This object is passed to modifiers and to the `onCreate` and `onUpdate` callbacks.
|
||||
* @name dataObject
|
||||
* @property {Object} data.instance The Popper.js instance
|
||||
* @property {String} data.placement Placement applied to popper
|
||||
* @property {String} data.originalPlacement Placement originally defined on init
|
||||
* @property {Boolean} data.flipped True if popper has been flipped by flip modifier
|
||||
* @property {Boolean} data.hide True if the reference element is out of boundaries, useful to know when to hide the popper
|
||||
* @property {HTMLElement} data.arrowElement Node used as arrow by arrow modifier
|
||||
* @property {Object} data.styles Any CSS property defined here will be applied to the popper. It expects the JavaScript nomenclature (eg. `marginBottom`)
|
||||
* @property {Object} data.arrowStyles Any CSS property defined here will be applied to the popper arrow. It expects the JavaScript nomenclature (eg. `marginBottom`)
|
||||
* @property {Object} data.boundaries Offsets of the popper boundaries
|
||||
* @property {Object} data.offsets The measurements of popper, reference and arrow elements
|
||||
* @property {Object} data.offsets.popper `top`, `left`, `width`, `height` values
|
||||
* @property {Object} data.offsets.reference `top`, `left`, `width`, `height` values
|
||||
* @property {Object} data.offsets.arrow] `top` and `left` offsets, only one of them will be different from 0
|
||||
*/
|
||||
27
F4SDwebService/Scripts/src/modifiers/inner.js
Normal file
27
F4SDwebService/Scripts/src/modifiers/inner.js
Normal file
@@ -0,0 +1,27 @@
|
||||
import getClientRect from '../utils/getClientRect';
|
||||
import getOppositePlacement from '../utils/getOppositePlacement';
|
||||
|
||||
/**
|
||||
* @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 inner(data) {
|
||||
const placement = data.placement;
|
||||
const basePlacement = placement.split('-')[0];
|
||||
const { popper, reference } = data.offsets;
|
||||
const isHoriz = ['left', 'right'].indexOf(basePlacement) !== -1;
|
||||
|
||||
const subtractLength = ['top', 'left'].indexOf(basePlacement) === -1;
|
||||
|
||||
popper[isHoriz ? 'left' : 'top'] =
|
||||
reference[basePlacement] -
|
||||
(subtractLength ? popper[isHoriz ? 'width' : 'height'] : 0);
|
||||
|
||||
data.placement = getOppositePlacement(placement);
|
||||
data.offsets.popper = getClientRect(popper);
|
||||
|
||||
return data;
|
||||
}
|
||||
26
F4SDwebService/Scripts/src/modifiers/keepTogether.js
Normal file
26
F4SDwebService/Scripts/src/modifiers/keepTogether.js
Normal file
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* @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 keepTogether(data) {
|
||||
const { popper, reference } = data.offsets;
|
||||
const placement = data.placement.split('-')[0];
|
||||
const floor = Math.floor;
|
||||
const isVertical = ['top', 'bottom'].indexOf(placement) !== -1;
|
||||
const side = isVertical ? 'right' : 'bottom';
|
||||
const opSide = isVertical ? 'left' : 'top';
|
||||
const measurement = isVertical ? 'width' : 'height';
|
||||
|
||||
if (popper[side] < floor(reference[opSide])) {
|
||||
data.offsets.popper[opSide] =
|
||||
floor(reference[opSide]) - popper[measurement];
|
||||
}
|
||||
if (popper[opSide] > floor(reference[side])) {
|
||||
data.offsets.popper[opSide] = floor(reference[side]);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
194
F4SDwebService/Scripts/src/modifiers/offset.js
Normal file
194
F4SDwebService/Scripts/src/modifiers/offset.js
Normal file
@@ -0,0 +1,194 @@
|
||||
import isNumeric from '../utils/isNumeric';
|
||||
import getClientRect from '../utils/getClientRect';
|
||||
import find from '../utils/find';
|
||||
|
||||
/**
|
||||
* Converts a string containing value + unit into a px value number
|
||||
* @function
|
||||
* @memberof {modifiers~offset}
|
||||
* @private
|
||||
* @argument {String} str - Value + unit string
|
||||
* @argument {String} measurement - `height` or `width`
|
||||
* @argument {Object} popperOffsets
|
||||
* @argument {Object} referenceOffsets
|
||||
* @returns {Number|String}
|
||||
* Value in pixels, or original string if no values were extracted
|
||||
*/
|
||||
export function toValue(str, measurement, popperOffsets, referenceOffsets) {
|
||||
// separate value from unit
|
||||
const split = str.match(/((?:\-|\+)?\d*\.?\d*)(.*)/);
|
||||
const value = +split[1];
|
||||
const unit = split[2];
|
||||
|
||||
// If it's not a number it's an operator, I guess
|
||||
if (!value) {
|
||||
return str;
|
||||
}
|
||||
|
||||
if (unit.indexOf('%') === 0) {
|
||||
let element;
|
||||
switch (unit) {
|
||||
case '%p':
|
||||
element = popperOffsets;
|
||||
break;
|
||||
case '%':
|
||||
case '%r':
|
||||
default:
|
||||
element = referenceOffsets;
|
||||
}
|
||||
|
||||
const rect = getClientRect(element);
|
||||
return rect[measurement] / 100 * value;
|
||||
} else if (unit === 'vh' || unit === 'vw') {
|
||||
// if is a vh or vw, we calculate the size based on the viewport
|
||||
let size;
|
||||
if (unit === 'vh') {
|
||||
size = Math.max(
|
||||
document.documentElement.clientHeight,
|
||||
window.innerHeight || 0
|
||||
);
|
||||
} else {
|
||||
size = Math.max(
|
||||
document.documentElement.clientWidth,
|
||||
window.innerWidth || 0
|
||||
);
|
||||
}
|
||||
return size / 100 * value;
|
||||
} else {
|
||||
// if is an explicit pixel unit, we get rid of the unit and keep the value
|
||||
// if is an implicit unit, it's px, and we return just the value
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse an `offset` string to extrapolate `x` and `y` numeric offsets.
|
||||
* @function
|
||||
* @memberof {modifiers~offset}
|
||||
* @private
|
||||
* @argument {String} offset
|
||||
* @argument {Object} popperOffsets
|
||||
* @argument {Object} referenceOffsets
|
||||
* @argument {String} basePlacement
|
||||
* @returns {Array} a two cells array with x and y offsets in numbers
|
||||
*/
|
||||
export function parseOffset(
|
||||
offset,
|
||||
popperOffsets,
|
||||
referenceOffsets,
|
||||
basePlacement
|
||||
) {
|
||||
const offsets = [0, 0];
|
||||
|
||||
// Use height if placement is left or right and index is 0 otherwise use width
|
||||
// in this way the first offset will use an axis and the second one
|
||||
// will use the other one
|
||||
const useHeight = ['right', 'left'].indexOf(basePlacement) !== -1;
|
||||
|
||||
// Split the offset string to obtain a list of values and operands
|
||||
// The regex addresses values with the plus or minus sign in front (+10, -20, etc)
|
||||
const fragments = offset.split(/(\+|\-)/).map(frag => frag.trim());
|
||||
|
||||
// Detect if the offset string contains a pair of values or a single one
|
||||
// they could be separated by comma or space
|
||||
const divider = fragments.indexOf(
|
||||
find(fragments, frag => frag.search(/,|\s/) !== -1)
|
||||
);
|
||||
|
||||
if (fragments[divider] && fragments[divider].indexOf(',') === -1) {
|
||||
console.warn(
|
||||
'Offsets separated by white space(s) are deprecated, use a comma (,) instead.'
|
||||
);
|
||||
}
|
||||
|
||||
// If divider is found, we divide the list of values and operands to divide
|
||||
// them by ofset X and Y.
|
||||
const splitRegex = /\s*,\s*|\s+/;
|
||||
let ops = divider !== -1
|
||||
? [
|
||||
fragments
|
||||
.slice(0, divider)
|
||||
.concat([fragments[divider].split(splitRegex)[0]]),
|
||||
[fragments[divider].split(splitRegex)[1]].concat(
|
||||
fragments.slice(divider + 1)
|
||||
),
|
||||
]
|
||||
: [fragments];
|
||||
|
||||
// Convert the values with units to absolute pixels to allow our computations
|
||||
ops = ops.map((op, index) => {
|
||||
// Most of the units rely on the orientation of the popper
|
||||
const measurement = (index === 1 ? !useHeight : useHeight)
|
||||
? 'height'
|
||||
: 'width';
|
||||
let mergeWithPrevious = false;
|
||||
return (
|
||||
op
|
||||
// This aggregates any `+` or `-` sign that aren't considered operators
|
||||
// e.g.: 10 + +5 => [10, +, +5]
|
||||
.reduce((a, b) => {
|
||||
if (a[a.length - 1] === '' && ['+', '-'].indexOf(b) !== -1) {
|
||||
a[a.length - 1] = b;
|
||||
mergeWithPrevious = true;
|
||||
return a;
|
||||
} else if (mergeWithPrevious) {
|
||||
a[a.length - 1] += b;
|
||||
mergeWithPrevious = false;
|
||||
return a;
|
||||
} else {
|
||||
return a.concat(b);
|
||||
}
|
||||
}, [])
|
||||
// Here we convert the string values into number values (in px)
|
||||
.map(str => toValue(str, measurement, popperOffsets, referenceOffsets))
|
||||
);
|
||||
});
|
||||
|
||||
// Loop trough the offsets arrays and execute the operations
|
||||
ops.forEach((op, index) => {
|
||||
op.forEach((frag, index2) => {
|
||||
if (isNumeric(frag)) {
|
||||
offsets[index] += frag * (op[index2 - 1] === '-' ? -1 : 1);
|
||||
}
|
||||
});
|
||||
});
|
||||
return offsets;
|
||||
}
|
||||
|
||||
/**
|
||||
* @function
|
||||
* @memberof Modifiers
|
||||
* @argument {Object} data - The data object generated by update method
|
||||
* @argument {Object} options - Modifiers configuration and options
|
||||
* @argument {Number|String} options.offset=0
|
||||
* The offset value as described in the modifier description
|
||||
* @returns {Object} The data object, properly modified
|
||||
*/
|
||||
export default function offset(data, { offset }) {
|
||||
const { placement, offsets: { popper, reference } } = data;
|
||||
const basePlacement = placement.split('-')[0];
|
||||
|
||||
let offsets;
|
||||
if (isNumeric(+offset)) {
|
||||
offsets = [+offset, 0];
|
||||
} else {
|
||||
offsets = parseOffset(offset, popper, reference, basePlacement);
|
||||
}
|
||||
|
||||
if (basePlacement === 'left') {
|
||||
popper.top += offsets[0];
|
||||
popper.left -= offsets[1];
|
||||
} else if (basePlacement === 'right') {
|
||||
popper.top += offsets[0];
|
||||
popper.left += offsets[1];
|
||||
} else if (basePlacement === 'top') {
|
||||
popper.left += offsets[0];
|
||||
popper.top -= offsets[1];
|
||||
} else if (basePlacement === 'bottom') {
|
||||
popper.left += offsets[0];
|
||||
popper.top += offsets[1];
|
||||
}
|
||||
|
||||
data.popper = popper;
|
||||
return data;
|
||||
}
|
||||
89
F4SDwebService/Scripts/src/modifiers/preventOverflow.js
Normal file
89
F4SDwebService/Scripts/src/modifiers/preventOverflow.js
Normal file
@@ -0,0 +1,89 @@
|
||||
import getOffsetParent from '../utils/getOffsetParent';
|
||||
import getBoundaries from '../utils/getBoundaries';
|
||||
import getSupportedPropertyName from '../utils/getSupportedPropertyName';
|
||||
|
||||
/**
|
||||
* @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 preventOverflow(data, options) {
|
||||
let boundariesElement =
|
||||
options.boundariesElement || getOffsetParent(data.instance.popper);
|
||||
|
||||
// If offsetParent is the reference element, we really want to
|
||||
// go one step up and use the next offsetParent as reference to
|
||||
// avoid to make this modifier completely useless and look like broken
|
||||
if (data.instance.reference === boundariesElement) {
|
||||
boundariesElement = getOffsetParent(boundariesElement);
|
||||
}
|
||||
|
||||
// NOTE: DOM access here
|
||||
// resets the popper's position so that the document size can be calculated excluding
|
||||
// the size of the popper element itself
|
||||
const transformProp = getSupportedPropertyName('transform');
|
||||
const popperStyles = data.instance.popper.style; // assignment to help minification
|
||||
const { top, left, [transformProp]: transform } = popperStyles;
|
||||
popperStyles.top = '';
|
||||
popperStyles.left = '';
|
||||
popperStyles[transformProp] = '';
|
||||
|
||||
const boundaries = getBoundaries(
|
||||
data.instance.popper,
|
||||
data.instance.reference,
|
||||
options.padding,
|
||||
boundariesElement,
|
||||
data.positionFixed
|
||||
);
|
||||
|
||||
// NOTE: DOM access here
|
||||
// restores the original style properties after the offsets have been computed
|
||||
popperStyles.top = top;
|
||||
popperStyles.left = left;
|
||||
popperStyles[transformProp] = transform;
|
||||
|
||||
options.boundaries = boundaries;
|
||||
|
||||
const order = options.priority;
|
||||
let popper = data.offsets.popper;
|
||||
|
||||
const check = {
|
||||
primary(placement) {
|
||||
let value = popper[placement];
|
||||
if (
|
||||
popper[placement] < boundaries[placement] &&
|
||||
!options.escapeWithReference
|
||||
) {
|
||||
value = Math.max(popper[placement], boundaries[placement]);
|
||||
}
|
||||
return { [placement]: value };
|
||||
},
|
||||
secondary(placement) {
|
||||
const mainSide = placement === 'right' ? 'left' : 'top';
|
||||
let value = popper[mainSide];
|
||||
if (
|
||||
popper[placement] > boundaries[placement] &&
|
||||
!options.escapeWithReference
|
||||
) {
|
||||
value = Math.min(
|
||||
popper[mainSide],
|
||||
boundaries[placement] -
|
||||
(placement === 'right' ? popper.width : popper.height)
|
||||
);
|
||||
}
|
||||
return { [mainSide]: value };
|
||||
},
|
||||
};
|
||||
|
||||
order.forEach(placement => {
|
||||
const side =
|
||||
['left', 'top'].indexOf(placement) !== -1 ? 'primary' : 'secondary';
|
||||
popper = { ...popper, ...check[side](placement) };
|
||||
});
|
||||
|
||||
data.offsets.popper = popper;
|
||||
|
||||
return data;
|
||||
}
|
||||
31
F4SDwebService/Scripts/src/modifiers/shift.js
Normal file
31
F4SDwebService/Scripts/src/modifiers/shift.js
Normal file
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
* @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 shift(data) {
|
||||
const placement = data.placement;
|
||||
const basePlacement = placement.split('-')[0];
|
||||
const shiftvariation = placement.split('-')[1];
|
||||
|
||||
// if shift shiftvariation is specified, run the modifier
|
||||
if (shiftvariation) {
|
||||
const { reference, popper } = data.offsets;
|
||||
const isVertical = ['bottom', 'top'].indexOf(basePlacement) !== -1;
|
||||
const side = isVertical ? 'left' : 'top';
|
||||
const measurement = isVertical ? 'width' : 'height';
|
||||
|
||||
const shiftOffsets = {
|
||||
start: { [side]: reference[side] },
|
||||
end: {
|
||||
[side]: reference[side] + reference[measurement] - popper[measurement],
|
||||
},
|
||||
};
|
||||
|
||||
data.offsets.popper = { ...popper, ...shiftOffsets[shiftvariation] };
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
Reference in New Issue
Block a user