Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/gohugoio/hugo-mod-jslibs-dist.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'popperjs/package/lib/modifiers/flip.js.flow')
-rw-r--r--popperjs/package/lib/modifiers/flip.js.flow177
1 files changed, 177 insertions, 0 deletions
diff --git a/popperjs/package/lib/modifiers/flip.js.flow b/popperjs/package/lib/modifiers/flip.js.flow
new file mode 100644
index 0000000..c74b852
--- /dev/null
+++ b/popperjs/package/lib/modifiers/flip.js.flow
@@ -0,0 +1,177 @@
+// @flow
+import type { Placement, Boundary, RootBoundary } from '../enums';
+import type { ModifierArguments, Modifier, Padding } from '../types';
+import getOppositePlacement from '../utils/getOppositePlacement';
+import getBasePlacement from '../utils/getBasePlacement';
+import getOppositeVariationPlacement from '../utils/getOppositeVariationPlacement';
+import detectOverflow from '../utils/detectOverflow';
+import computeAutoPlacement from '../utils/computeAutoPlacement';
+import { bottom, top, start, right, left, auto } from '../enums';
+import getVariation from '../utils/getVariation';
+
+// eslint-disable-next-line import/no-unused-modules
+export type Options = {
+ mainAxis: boolean,
+ altAxis: boolean,
+ fallbackPlacements: Array<Placement>,
+ padding: Padding,
+ boundary: Boundary,
+ rootBoundary: RootBoundary,
+ altBoundary: boolean,
+ flipVariations: boolean,
+ allowedAutoPlacements: Array<Placement>,
+};
+
+function getExpandedFallbackPlacements(placement: Placement): Array<Placement> {
+ if (getBasePlacement(placement) === auto) {
+ return [];
+ }
+
+ const oppositePlacement = getOppositePlacement(placement);
+
+ return [
+ getOppositeVariationPlacement(placement),
+ oppositePlacement,
+ getOppositeVariationPlacement(oppositePlacement),
+ ];
+}
+
+function flip({ state, options, name }: ModifierArguments<Options>) {
+ if (state.modifiersData[name]._skip) {
+ return;
+ }
+
+ const {
+ mainAxis: checkMainAxis = true,
+ altAxis: checkAltAxis = true,
+ fallbackPlacements: specifiedFallbackPlacements,
+ padding,
+ boundary,
+ rootBoundary,
+ altBoundary,
+ flipVariations = true,
+ allowedAutoPlacements,
+ } = options;
+
+ const preferredPlacement = state.options.placement;
+ const basePlacement = getBasePlacement(preferredPlacement);
+ const isBasePlacement = basePlacement === preferredPlacement;
+
+ const fallbackPlacements =
+ specifiedFallbackPlacements ||
+ (isBasePlacement || !flipVariations
+ ? [getOppositePlacement(preferredPlacement)]
+ : getExpandedFallbackPlacements(preferredPlacement));
+
+ const placements = [preferredPlacement, ...fallbackPlacements].reduce(
+ (acc, placement) => {
+ return acc.concat(
+ getBasePlacement(placement) === auto
+ ? computeAutoPlacement(state, {
+ placement,
+ boundary,
+ rootBoundary,
+ padding,
+ flipVariations,
+ allowedAutoPlacements,
+ })
+ : placement
+ );
+ },
+ []
+ );
+
+ const referenceRect = state.rects.reference;
+ const popperRect = state.rects.popper;
+
+ const checksMap = new Map();
+ let makeFallbackChecks = true;
+ let firstFittingPlacement = placements[0];
+
+ for (let i = 0; i < placements.length; i++) {
+ const placement = placements[i];
+ const basePlacement = getBasePlacement(placement);
+ const isStartVariation = getVariation(placement) === start;
+ const isVertical = [top, bottom].indexOf(basePlacement) >= 0;
+ const len = isVertical ? 'width' : 'height';
+
+ const overflow = detectOverflow(state, {
+ placement,
+ boundary,
+ rootBoundary,
+ altBoundary,
+ padding,
+ });
+
+ let mainVariationSide: any = isVertical
+ ? isStartVariation
+ ? right
+ : left
+ : isStartVariation
+ ? bottom
+ : top;
+
+ if (referenceRect[len] > popperRect[len]) {
+ mainVariationSide = getOppositePlacement(mainVariationSide);
+ }
+
+ const altVariationSide: any = getOppositePlacement(mainVariationSide);
+
+ const checks = [];
+
+ if (checkMainAxis) {
+ checks.push(overflow[basePlacement] <= 0);
+ }
+
+ if (checkAltAxis) {
+ checks.push(
+ overflow[mainVariationSide] <= 0,
+ overflow[altVariationSide] <= 0
+ );
+ }
+
+ if (checks.every((check) => check)) {
+ firstFittingPlacement = placement;
+ makeFallbackChecks = false;
+ break;
+ }
+
+ checksMap.set(placement, checks);
+ }
+
+ if (makeFallbackChecks) {
+ // `2` may be desired in some cases – research later
+ const numberOfChecks = flipVariations ? 3 : 1;
+
+ for (let i = numberOfChecks; i > 0; i--) {
+ const fittingPlacement = placements.find((placement) => {
+ const checks = checksMap.get(placement);
+ if (checks) {
+ return checks.slice(0, i).every((check) => check);
+ }
+ });
+
+ if (fittingPlacement) {
+ firstFittingPlacement = fittingPlacement;
+ break;
+ }
+ }
+ }
+
+ if (state.placement !== firstFittingPlacement) {
+ state.modifiersData[name]._skip = true;
+ state.placement = firstFittingPlacement;
+ state.reset = true;
+ }
+}
+
+// eslint-disable-next-line import/no-unused-modules
+export type FlipModifier = Modifier<'flip', Options>;
+export default ({
+ name: 'flip',
+ enabled: true,
+ phase: 'main',
+ fn: flip,
+ requiresIfExists: ['offset'],
+ data: { _skip: false },
+}: FlipModifier);