Last commit not found
import getCompositeRect from "./dom-utils/getCompositeRect.js"; | |
import getLayoutRect from "./dom-utils/getLayoutRect.js"; | |
import listScrollParents from "./dom-utils/listScrollParents.js"; | |
import getOffsetParent from "./dom-utils/getOffsetParent.js"; | |
import orderModifiers from "./utils/orderModifiers.js"; | |
import debounce from "./utils/debounce.js"; | |
import mergeByName from "./utils/mergeByName.js"; | |
import detectOverflow from "./utils/detectOverflow.js"; | |
import { isElement } from "./dom-utils/instanceOf.js"; | |
var DEFAULT_OPTIONS = { | |
placement: 'bottom', | |
modifiers: [], | |
strategy: 'absolute' | |
}; | |
function areValidElements() { | |
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { | |
args[_key] = arguments[_key]; | |
} | |
return !args.some(function (element) { | |
return !(element && typeof element.getBoundingClientRect === 'function'); | |
}); | |
} | |
export function popperGenerator(generatorOptions) { | |
if (generatorOptions === void 0) { | |
generatorOptions = {}; | |
} | |
var _generatorOptions = generatorOptions, | |
_generatorOptions$def = _generatorOptions.defaultModifiers, | |
defaultModifiers = _generatorOptions$def === void 0 ? [] : _generatorOptions$def, | |
_generatorOptions$def2 = _generatorOptions.defaultOptions, | |
defaultOptions = _generatorOptions$def2 === void 0 ? DEFAULT_OPTIONS : _generatorOptions$def2; | |
return function createPopper(reference, popper, options) { | |
if (options === void 0) { | |
options = defaultOptions; | |
} | |
var state = { | |
placement: 'bottom', | |
orderedModifiers: [], | |
options: Object.assign({}, DEFAULT_OPTIONS, defaultOptions), | |
modifiersData: {}, | |
elements: { | |
reference: reference, | |
popper: popper | |
}, | |
attributes: {}, | |
styles: {} | |
}; | |
var effectCleanupFns = []; | |
var isDestroyed = false; | |
var instance = { | |
state: state, | |
setOptions: function setOptions(setOptionsAction) { | |
var options = typeof setOptionsAction === 'function' ? setOptionsAction(state.options) : setOptionsAction; | |
cleanupModifierEffects(); | |
state.options = Object.assign({}, defaultOptions, state.options, options); | |
state.scrollParents = { | |
reference: isElement(reference) ? listScrollParents(reference) : reference.contextElement ? listScrollParents(reference.contextElement) : [], | |
popper: listScrollParents(popper) | |
}; // Orders the modifiers based on their dependencies and `phase` | |
// properties | |
var orderedModifiers = orderModifiers(mergeByName([].concat(defaultModifiers, state.options.modifiers))); // Strip out disabled modifiers | |
state.orderedModifiers = orderedModifiers.filter(function (m) { | |
return m.enabled; | |
}); | |
runModifierEffects(); | |
return instance.update(); | |
}, | |
// Sync update – it will always be executed, even if not necessary. This | |
// is useful for low frequency updates where sync behavior simplifies the | |
// logic. | |
// For high frequency updates (e.g. `resize` and `scroll` events), always | |
// prefer the async Popper#update method | |
forceUpdate: function forceUpdate() { | |
if (isDestroyed) { | |
return; | |
} | |
var _state$elements = state.elements, | |
reference = _state$elements.reference, | |
popper = _state$elements.popper; // Don't proceed if `reference` or `popper` are not valid elements | |
// anymore | |
if (!areValidElements(reference, popper)) { | |
return; | |
} // Store the reference and popper rects to be read by modifiers | |
state.rects = { | |
reference: getCompositeRect(reference, getOffsetParent(popper), state.options.strategy === 'fixed'), | |
popper: getLayoutRect(popper) | |
}; // Modifiers have the ability to reset the current update cycle. The | |
// most common use case for this is the `flip` modifier changing the | |
// placement, which then needs to re-run all the modifiers, because the | |
// logic was previously ran for the previous placement and is therefore | |
// stale/incorrect | |
state.reset = false; | |
state.placement = state.options.placement; // On each update cycle, the `modifiersData` property for each modifier | |
// is filled with the initial data specified by the modifier. This means | |
// it doesn't persist and is fresh on each update. | |
// To ensure persistent data, use `${name}#persistent` | |
state.orderedModifiers.forEach(function (modifier) { | |
return state.modifiersData[modifier.name] = Object.assign({}, modifier.data); | |
}); | |
for (var index = 0; index < state.orderedModifiers.length; index++) { | |
if (state.reset === true) { | |
state.reset = false; | |
index = -1; | |
continue; | |
} | |
var _state$orderedModifie = state.orderedModifiers[index], | |
fn = _state$orderedModifie.fn, | |
_state$orderedModifie2 = _state$orderedModifie.options, | |
_options = _state$orderedModifie2 === void 0 ? {} : _state$orderedModifie2, | |
name = _state$orderedModifie.name; | |
if (typeof fn === 'function') { | |
state = fn({ | |
state: state, | |
options: _options, | |
name: name, | |
instance: instance | |
}) || state; | |
} | |
} | |
}, | |
// Async and optimistically optimized update – it will not be executed if | |
// not necessary (debounced to run at most once-per-tick) | |
update: debounce(function () { | |
return new Promise(function (resolve) { | |
instance.forceUpdate(); | |
resolve(state); | |
}); | |
}), | |
destroy: function destroy() { | |
cleanupModifierEffects(); | |
isDestroyed = true; | |
} | |
}; | |
if (!areValidElements(reference, popper)) { | |
return instance; | |
} | |
instance.setOptions(options).then(function (state) { | |
if (!isDestroyed && options.onFirstUpdate) { | |
options.onFirstUpdate(state); | |
} | |
}); // Modifiers have the ability to execute arbitrary code before the first | |
// update cycle runs. They will be executed in the same order as the update | |
// cycle. This is useful when a modifier adds some persistent data that | |
// other modifiers need to use, but the modifier is run after the dependent | |
// one. | |
function runModifierEffects() { | |
state.orderedModifiers.forEach(function (_ref) { | |
var name = _ref.name, | |
_ref$options = _ref.options, | |
options = _ref$options === void 0 ? {} : _ref$options, | |
effect = _ref.effect; | |
if (typeof effect === 'function') { | |
var cleanupFn = effect({ | |
state: state, | |
name: name, | |
instance: instance, | |
options: options | |
}); | |
var noopFn = function noopFn() {}; | |
effectCleanupFns.push(cleanupFn || noopFn); | |
} | |
}); | |
} | |
function cleanupModifierEffects() { | |
effectCleanupFns.forEach(function (fn) { | |
return fn(); | |
}); | |
effectCleanupFns = []; | |
} | |
return instance; | |
}; | |
} | |
export var createPopper = /*#__PURE__*/popperGenerator(); // eslint-disable-next-line import/no-unused-modules | |
export { detectOverflow }; |