Commit 6cc198bf authored by Sangjune Bae's avatar Sangjune Bae
Browse files

first commit

parent 81c6da4b
import getWindow from "../dom-utils/getWindow.js"; // eslint-disable-next-line import/no-unused-modules
var passive = {
passive: true
};
function effect(_ref) {
var state = _ref.state,
instance = _ref.instance,
options = _ref.options;
var _options$scroll = options.scroll,
scroll = _options$scroll === void 0 ? true : _options$scroll,
_options$resize = options.resize,
resize = _options$resize === void 0 ? true : _options$resize;
var window = getWindow(state.elements.popper);
var scrollParents = [].concat(state.scrollParents.reference, state.scrollParents.popper);
if (scroll) {
scrollParents.forEach(function (scrollParent) {
scrollParent.addEventListener('scroll', instance.update, passive);
});
}
if (resize) {
window.addEventListener('resize', instance.update, passive);
}
return function () {
if (scroll) {
scrollParents.forEach(function (scrollParent) {
scrollParent.removeEventListener('scroll', instance.update, passive);
});
}
if (resize) {
window.removeEventListener('resize', instance.update, passive);
}
};
} // eslint-disable-next-line import/no-unused-modules
export default {
name: 'eventListeners',
enabled: true,
phase: 'write',
fn: function fn() {},
effect: effect,
data: {}
};
\ No newline at end of file
// @flow
import type { ModifierArguments, Modifier } from '../types';
import getWindow from '../dom-utils/getWindow';
// eslint-disable-next-line import/no-unused-modules
export type Options = {
scroll: boolean,
resize: boolean,
};
const passive = { passive: true };
function effect({ state, instance, options }: ModifierArguments<Options>) {
const { scroll = true, resize = true } = options;
const window = getWindow(state.elements.popper);
const scrollParents = [
...state.scrollParents.reference,
...state.scrollParents.popper,
];
if (scroll) {
scrollParents.forEach(scrollParent => {
scrollParent.addEventListener('scroll', instance.update, passive);
});
}
if (resize) {
window.addEventListener('resize', instance.update, passive);
}
return () => {
if (scroll) {
scrollParents.forEach(scrollParent => {
scrollParent.removeEventListener('scroll', instance.update, passive);
});
}
if (resize) {
window.removeEventListener('resize', instance.update, passive);
}
};
}
// eslint-disable-next-line import/no-unused-modules
export type EventListenersModifier = Modifier<'eventListeners', Options>;
export default ({
name: 'eventListeners',
enabled: true,
phase: 'write',
fn: () => {},
effect,
data: {},
}: EventListenersModifier);
import { Placement, Boundary, RootBoundary } from "../enums";
import { Modifier, Padding } from "../types";
export declare type Options = {
mainAxis: boolean;
altAxis: boolean;
fallbackPlacements: Array<Placement>;
padding: Padding;
boundary: Boundary;
rootBoundary: RootBoundary;
altBoundary: boolean;
flipVariations: boolean;
allowedAutoPlacements: Array<Placement>;
};
export declare type FlipModifier = Modifier<"flip", Options>;
declare const _default: Modifier<"flip", Options>;
export default _default;
import getOppositePlacement from "../utils/getOppositePlacement.js";
import getBasePlacement from "../utils/getBasePlacement.js";
import getOppositeVariationPlacement from "../utils/getOppositeVariationPlacement.js";
import detectOverflow from "../utils/detectOverflow.js";
import computeAutoPlacement from "../utils/computeAutoPlacement.js";
import { bottom, top, start, right, left, auto } from "../enums.js";
import getVariation from "../utils/getVariation.js"; // eslint-disable-next-line import/no-unused-modules
function getExpandedFallbackPlacements(placement) {
if (getBasePlacement(placement) === auto) {
return [];
}
var oppositePlacement = getOppositePlacement(placement);
return [getOppositeVariationPlacement(placement), oppositePlacement, getOppositeVariationPlacement(oppositePlacement)];
}
function flip(_ref) {
var state = _ref.state,
options = _ref.options,
name = _ref.name;
if (state.modifiersData[name]._skip) {
return;
}
var _options$mainAxis = options.mainAxis,
checkMainAxis = _options$mainAxis === void 0 ? true : _options$mainAxis,
_options$altAxis = options.altAxis,
checkAltAxis = _options$altAxis === void 0 ? true : _options$altAxis,
specifiedFallbackPlacements = options.fallbackPlacements,
padding = options.padding,
boundary = options.boundary,
rootBoundary = options.rootBoundary,
altBoundary = options.altBoundary,
_options$flipVariatio = options.flipVariations,
flipVariations = _options$flipVariatio === void 0 ? true : _options$flipVariatio,
allowedAutoPlacements = options.allowedAutoPlacements;
var preferredPlacement = state.options.placement;
var basePlacement = getBasePlacement(preferredPlacement);
var isBasePlacement = basePlacement === preferredPlacement;
var fallbackPlacements = specifiedFallbackPlacements || (isBasePlacement || !flipVariations ? [getOppositePlacement(preferredPlacement)] : getExpandedFallbackPlacements(preferredPlacement));
var placements = [preferredPlacement].concat(fallbackPlacements).reduce(function (acc, placement) {
return acc.concat(getBasePlacement(placement) === auto ? computeAutoPlacement(state, {
placement: placement,
boundary: boundary,
rootBoundary: rootBoundary,
padding: padding,
flipVariations: flipVariations,
allowedAutoPlacements: allowedAutoPlacements
}) : placement);
}, []);
var referenceRect = state.rects.reference;
var popperRect = state.rects.popper;
var checksMap = new Map();
var makeFallbackChecks = true;
var firstFittingPlacement = placements[0];
for (var i = 0; i < placements.length; i++) {
var placement = placements[i];
var _basePlacement = getBasePlacement(placement);
var isStartVariation = getVariation(placement) === start;
var isVertical = [top, bottom].indexOf(_basePlacement) >= 0;
var len = isVertical ? 'width' : 'height';
var overflow = detectOverflow(state, {
placement: placement,
boundary: boundary,
rootBoundary: rootBoundary,
altBoundary: altBoundary,
padding: padding
});
var mainVariationSide = isVertical ? isStartVariation ? right : left : isStartVariation ? bottom : top;
if (referenceRect[len] > popperRect[len]) {
mainVariationSide = getOppositePlacement(mainVariationSide);
}
var altVariationSide = getOppositePlacement(mainVariationSide);
var checks = [];
if (checkMainAxis) {
checks.push(overflow[_basePlacement] <= 0);
}
if (checkAltAxis) {
checks.push(overflow[mainVariationSide] <= 0, overflow[altVariationSide] <= 0);
}
if (checks.every(function (check) {
return check;
})) {
firstFittingPlacement = placement;
makeFallbackChecks = false;
break;
}
checksMap.set(placement, checks);
}
if (makeFallbackChecks) {
// `2` may be desired in some cases – research later
var numberOfChecks = flipVariations ? 3 : 1;
var _loop = function _loop(_i) {
var fittingPlacement = placements.find(function (placement) {
var checks = checksMap.get(placement);
if (checks) {
return checks.slice(0, _i).every(function (check) {
return check;
});
}
});
if (fittingPlacement) {
firstFittingPlacement = fittingPlacement;
return "break";
}
};
for (var _i = numberOfChecks; _i > 0; _i--) {
var _ret = _loop(_i);
if (_ret === "break") 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 default {
name: 'flip',
enabled: true,
phase: 'main',
fn: flip,
requiresIfExists: ['offset'],
data: {
_skip: false
}
};
\ No newline at end of file
// @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);
import { Modifier } from "../types";
export declare type HideModifier = Modifier<"hide", {}>;
declare const _default: Modifier<"hide", {}>;
export default _default;
import { top, bottom, left, right } from "../enums.js";
import detectOverflow from "../utils/detectOverflow.js";
function getSideOffsets(overflow, rect, preventedOffsets) {
if (preventedOffsets === void 0) {
preventedOffsets = {
x: 0,
y: 0
};
}
return {
top: overflow.top - rect.height - preventedOffsets.y,
right: overflow.right - rect.width + preventedOffsets.x,
bottom: overflow.bottom - rect.height + preventedOffsets.y,
left: overflow.left - rect.width - preventedOffsets.x
};
}
function isAnySideFullyClipped(overflow) {
return [top, right, bottom, left].some(function (side) {
return overflow[side] >= 0;
});
}
function hide(_ref) {
var state = _ref.state,
name = _ref.name;
var referenceRect = state.rects.reference;
var popperRect = state.rects.popper;
var preventedOffsets = state.modifiersData.preventOverflow;
var referenceOverflow = detectOverflow(state, {
elementContext: 'reference'
});
var popperAltOverflow = detectOverflow(state, {
altBoundary: true
});
var referenceClippingOffsets = getSideOffsets(referenceOverflow, referenceRect);
var popperEscapeOffsets = getSideOffsets(popperAltOverflow, popperRect, preventedOffsets);
var isReferenceHidden = isAnySideFullyClipped(referenceClippingOffsets);
var hasPopperEscaped = isAnySideFullyClipped(popperEscapeOffsets);
state.modifiersData[name] = {
referenceClippingOffsets: referenceClippingOffsets,
popperEscapeOffsets: popperEscapeOffsets,
isReferenceHidden: isReferenceHidden,
hasPopperEscaped: hasPopperEscaped
};
state.attributes.popper = Object.assign(Object.assign({}, state.attributes.popper), {}, {
'data-popper-reference-hidden': isReferenceHidden,
'data-popper-escaped': hasPopperEscaped
});
} // eslint-disable-next-line import/no-unused-modules
export default {
name: 'hide',
enabled: true,
phase: 'main',
requiresIfExists: ['preventOverflow'],
fn: hide
};
\ No newline at end of file
// @flow
import type {
ModifierArguments,
Modifier,
Rect,
SideObject,
Offsets,
} from '../types';
import { top, bottom, left, right } from '../enums';
import detectOverflow from '../utils/detectOverflow';
function getSideOffsets(
overflow: SideObject,
rect: Rect,
preventedOffsets: Offsets = { x: 0, y: 0 }
): SideObject {
return {
top: overflow.top - rect.height - preventedOffsets.y,
right: overflow.right - rect.width + preventedOffsets.x,
bottom: overflow.bottom - rect.height + preventedOffsets.y,
left: overflow.left - rect.width - preventedOffsets.x,
};
}
function isAnySideFullyClipped(overflow: SideObject): boolean {
return [top, right, bottom, left].some((side) => overflow[side] >= 0);
}
function hide({ state, name }: ModifierArguments<{||}>) {
const referenceRect = state.rects.reference;
const popperRect = state.rects.popper;
const preventedOffsets = state.modifiersData.preventOverflow;
const referenceOverflow = detectOverflow(state, {
elementContext: 'reference',
});
const popperAltOverflow = detectOverflow(state, {
altBoundary: true,
});
const referenceClippingOffsets = getSideOffsets(
referenceOverflow,
referenceRect
);
const popperEscapeOffsets = getSideOffsets(
popperAltOverflow,
popperRect,
preventedOffsets
);
const isReferenceHidden = isAnySideFullyClipped(referenceClippingOffsets);
const hasPopperEscaped = isAnySideFullyClipped(popperEscapeOffsets);
state.modifiersData[name] = {
referenceClippingOffsets,
popperEscapeOffsets,
isReferenceHidden,
hasPopperEscaped,
};
state.attributes.popper = {
...state.attributes.popper,
'data-popper-reference-hidden': isReferenceHidden,
'data-popper-escaped': hasPopperEscaped,
};
}
// eslint-disable-next-line import/no-unused-modules
export type HideModifier = Modifier<'hide', {||}>;
export default ({
name: 'hide',
enabled: true,
phase: 'main',
requiresIfExists: ['preventOverflow'],
fn: hide,
}: HideModifier);
export { default as applyStyles } from "./applyStyles";
export { default as arrow } from "./arrow";
export { default as computeStyles } from "./computeStyles";
export { default as eventListeners } from "./eventListeners";
export { default as flip } from "./flip";
export { default as hide } from "./hide";
export { default as offset } from "./offset";
export { default as popperOffsets } from "./popperOffsets";
export { default as preventOverflow } from "./preventOverflow";
export { default as applyStyles } from "./applyStyles.js";
export { default as arrow } from "./arrow.js";
export { default as computeStyles } from "./computeStyles.js";
export { default as eventListeners } from "./eventListeners.js";
export { default as flip } from "./flip.js";
export { default as hide } from "./hide.js";
export { default as offset } from "./offset.js";
export { default as popperOffsets } from "./popperOffsets.js";
export { default as preventOverflow } from "./preventOverflow.js";
\ No newline at end of file
// @flow
export { default as applyStyles } from './applyStyles';
export { default as arrow } from './arrow';
export { default as computeStyles } from './computeStyles';
export { default as eventListeners } from './eventListeners';
export { default as flip } from './flip';
export { default as hide } from './hide';
export { default as offset } from './offset';
export { default as popperOffsets } from './popperOffsets';
export { default as preventOverflow } from './preventOverflow';
import { Placement } from "../enums";
import { Modifier, Rect, Offsets } from "../types";
declare type OffsetsFunction = (arg0: {
popper: Rect;
reference: Rect;
placement: Placement;
}) => [number | null | undefined, number | null | undefined];
declare type Offset = OffsetsFunction | [number | null | undefined, number | null | undefined];
export declare type Options = {
offset: Offset;
};
export declare function distanceAndSkiddingToXY(placement: Placement, rects: {
popper: Rect;
reference: Rect;
}, offset: Offset): Offsets;
export declare type OffsetModifier = Modifier<"offset", Options>;
declare const _default: Modifier<"offset", Options>;
export default _default;
import getBasePlacement from "../utils/getBasePlacement.js";
import { top, left, right, placements } from "../enums.js";
export function distanceAndSkiddingToXY(placement, rects, offset) {
var basePlacement = getBasePlacement(placement);
var invertDistance = [left, top].indexOf(basePlacement) >= 0 ? -1 : 1;
var _ref = typeof offset === 'function' ? offset(Object.assign(Object.assign({}, rects), {}, {
placement: placement
})) : offset,
skidding = _ref[0],
distance = _ref[1];
skidding = skidding || 0;
distance = (distance || 0) * invertDistance;
return [left, right].indexOf(basePlacement) >= 0 ? {
x: distance,
y: skidding
} : {
x: skidding,
y: distance
};
}
function offset(_ref2) {
var state = _ref2.state,
options = _ref2.options,
name = _ref2.name;
var _options$offset = options.offset,
offset = _options$offset === void 0 ? [0, 0] : _options$offset;
var data = placements.reduce(function (acc, placement) {
acc[placement] = distanceAndSkiddingToXY(placement, state.rects, offset);
return acc;
}, {});
var _data$state$placement = data[state.placement],
x = _data$state$placement.x,
y = _data$state$placement.y;
if (state.modifiersData.popperOffsets != null) {
state.modifiersData.popperOffsets.x += x;
state.modifiersData.popperOffsets.y += y;
}
state.modifiersData[name] = data;
} // eslint-disable-next-line import/no-unused-modules
export default {
name: 'offset',
enabled: true,
phase: 'main',
requires: ['popperOffsets'],
fn: offset
};
\ No newline at end of file
// @flow
import type { Placement } from '../enums';
import type { ModifierArguments, Modifier, Rect, Offsets } from '../types';
import getBasePlacement from '../utils/getBasePlacement';
import { top, left, right, placements } from '../enums';
type OffsetsFunction = ({
popper: Rect,
reference: Rect,
placement: Placement,
}) => [?number, ?number];
type Offset = OffsetsFunction | [?number, ?number];
// eslint-disable-next-line import/no-unused-modules
export type Options = {
offset: Offset,
};
export function distanceAndSkiddingToXY(
placement: Placement,
rects: { popper: Rect, reference: Rect },
offset: Offset
): Offsets {
const basePlacement = getBasePlacement(placement);
const invertDistance = [left, top].indexOf(basePlacement) >= 0 ? -1 : 1;
let [skidding, distance] =
typeof offset === 'function'
? offset({
...rects,
placement,
})
: offset;
skidding = skidding || 0;
distance = (distance || 0) * invertDistance;
return [left, right].indexOf(basePlacement) >= 0
? { x: distance, y: skidding }
: { x: skidding, y: distance };
}
function offset({ state, options, name }: ModifierArguments<Options>) {
const { offset = [0, 0] } = options;
const data = placements.reduce((acc, placement) => {
acc[placement] = distanceAndSkiddingToXY(placement, state.rects, offset);
return acc;
}, {});
const { x, y } = data[state.placement];
if (state.modifiersData.popperOffsets != null) {
state.modifiersData.popperOffsets.x += x;
state.modifiersData.popperOffsets.y += y;
}
state.modifiersData[name] = data;
}
// eslint-disable-next-line import/no-unused-modules
export type OffsetModifier = Modifier<'offset', Options>;
export default ({
name: 'offset',
enabled: true,
phase: 'main',
requires: ['popperOffsets'],
fn: offset,
}: OffsetModifier);
import { Modifier } from "../types";
export declare type PopperOffsetsModifier = Modifier<"popperOffsets", {}>;
declare const _default: Modifier<"popperOffsets", {}>;
export default _default;
import computeOffsets from "../utils/computeOffsets.js";
function popperOffsets(_ref) {
var state = _ref.state,
name = _ref.name;
// Offsets are the actual position the popper needs to have to be
// properly positioned near its reference element
// This is the most basic placement, and will be adjusted by
// the modifiers in the next step
state.modifiersData[name] = computeOffsets({
reference: state.rects.reference,
element: state.rects.popper,
strategy: 'absolute',
placement: state.placement
});
} // eslint-disable-next-line import/no-unused-modules
export default {
name: 'popperOffsets',
enabled: true,
phase: 'read',
fn: popperOffsets,
data: {}
};
\ No newline at end of file
// @flow
import type { ModifierArguments, Modifier } from '../types';
import computeOffsets from '../utils/computeOffsets';
function popperOffsets({ state, name }: ModifierArguments<{||}>) {
// Offsets are the actual position the popper needs to have to be
// properly positioned near its reference element
// This is the most basic placement, and will be adjusted by
// the modifiers in the next step
state.modifiersData[name] = computeOffsets({
reference: state.rects.reference,
element: state.rects.popper,
strategy: 'absolute',
placement: state.placement,
});
}
// eslint-disable-next-line import/no-unused-modules
export type PopperOffsetsModifier = Modifier<'popperOffsets', {||}>;
export default ({
name: 'popperOffsets',
enabled: true,
phase: 'read',
fn: popperOffsets,
data: {},
}: PopperOffsetsModifier);
import { Placement, Boundary, RootBoundary } from "../enums";
import { Rect, Modifier, Padding } from "../types";
declare type TetherOffset = ((arg0: {
popper: Rect;
reference: Rect;
placement: Placement;
}) => number) | number;
export declare type Options = {
mainAxis: boolean;
altAxis: boolean;
boundary: Boundary;
rootBoundary: RootBoundary;
altBoundary: boolean;
/**
* Allows the popper to overflow from its boundaries to keep it near its
* reference element
*/
tether: boolean;
tetherOffset: TetherOffset;
padding: Padding;
};
export declare type PreventOverflowModifier = Modifier<"preventOverflow", Options>;
declare const _default: Modifier<"preventOverflow", Options>;
export default _default;
import { top, left, right, bottom, start } from "../enums.js";
import getBasePlacement from "../utils/getBasePlacement.js";
import getMainAxisFromPlacement from "../utils/getMainAxisFromPlacement.js";
import getAltAxis from "../utils/getAltAxis.js";
import within from "../utils/within.js";
import getLayoutRect from "../dom-utils/getLayoutRect.js";
import getOffsetParent from "../dom-utils/getOffsetParent.js";
import detectOverflow from "../utils/detectOverflow.js";
import getVariation from "../utils/getVariation.js";
import getFreshSideObject from "../utils/getFreshSideObject.js";
function preventOverflow(_ref) {
var state = _ref.state,
options = _ref.options,
name = _ref.name;
var _options$mainAxis = options.mainAxis,
checkMainAxis = _options$mainAxis === void 0 ? true : _options$mainAxis,
_options$altAxis = options.altAxis,
checkAltAxis = _options$altAxis === void 0 ? false : _options$altAxis,
boundary = options.boundary,
rootBoundary = options.rootBoundary,
altBoundary = options.altBoundary,
padding = options.padding,
_options$tether = options.tether,
tether = _options$tether === void 0 ? true : _options$tether,
_options$tetherOffset = options.tetherOffset,
tetherOffset = _options$tetherOffset === void 0 ? 0 : _options$tetherOffset;
var overflow = detectOverflow(state, {
boundary: boundary,
rootBoundary: rootBoundary,
padding: padding,
altBoundary: altBoundary
});
var basePlacement = getBasePlacement(state.placement);
var variation = getVariation(state.placement);
var isBasePlacement = !variation;
var mainAxis = getMainAxisFromPlacement(basePlacement);
var altAxis = getAltAxis(mainAxis);
var popperOffsets = state.modifiersData.popperOffsets;
var referenceRect = state.rects.reference;
var popperRect = state.rects.popper;
var tetherOffsetValue = typeof tetherOffset === 'function' ? tetherOffset(Object.assign(Object.assign({}, state.rects), {}, {
placement: state.placement
})) : tetherOffset;
var data = {
x: 0,
y: 0
};
if (!popperOffsets) {
return;
}
if (checkMainAxis) {
var mainSide = mainAxis === 'y' ? top : left;
var altSide = mainAxis === 'y' ? bottom : right;
var len = mainAxis === 'y' ? 'height' : 'width';
var offset = popperOffsets[mainAxis];
var min = popperOffsets[mainAxis] + overflow[mainSide];
var max = popperOffsets[mainAxis] - overflow[altSide];
var additive = tether ? -popperRect[len] / 2 : 0;
var minLen = variation === start ? referenceRect[len] : popperRect[len];
var maxLen = variation === start ? -popperRect[len] : -referenceRect[len]; // We need to include the arrow in the calculation so the arrow doesn't go
// outside the reference bounds
var arrowElement = state.elements.arrow;
var arrowRect = tether && arrowElement ? getLayoutRect(arrowElement) : {
width: 0,
height: 0
};
var arrowPaddingObject = state.modifiersData['arrow#persistent'] ? state.modifiersData['arrow#persistent'].padding : getFreshSideObject();
var arrowPaddingMin = arrowPaddingObject[mainSide];
var arrowPaddingMax = arrowPaddingObject[altSide]; // If the reference length is smaller than the arrow length, we don't want
// to include its full size in the calculation. If the reference is small
// and near the edge of a boundary, the popper can overflow even if the
// reference is not overflowing as well (e.g. virtual elements with no
// width or height)
var arrowLen = within(0, referenceRect[len], arrowRect[len]);
var minOffset = isBasePlacement ? referenceRect[len] / 2 - additive - arrowLen - arrowPaddingMin - tetherOffsetValue : minLen - arrowLen - arrowPaddingMin - tetherOffsetValue;
var maxOffset = isBasePlacement ? -referenceRect[len] / 2 + additive + arrowLen + arrowPaddingMax + tetherOffsetValue : maxLen + arrowLen + arrowPaddingMax + tetherOffsetValue;
var arrowOffsetParent = state.elements.arrow && getOffsetParent(state.elements.arrow);
var clientOffset = arrowOffsetParent ? mainAxis === 'y' ? arrowOffsetParent.clientTop || 0 : arrowOffsetParent.clientLeft || 0 : 0;
var offsetModifierValue = state.modifiersData.offset ? state.modifiersData.offset[state.placement][mainAxis] : 0;
var tetherMin = popperOffsets[mainAxis] + minOffset - offsetModifierValue - clientOffset;
var tetherMax = popperOffsets[mainAxis] + maxOffset - offsetModifierValue;
var preventedOffset = within(tether ? Math.min(min, tetherMin) : min, offset, tether ? Math.max(max, tetherMax) : max);
popperOffsets[mainAxis] = preventedOffset;
data[mainAxis] = preventedOffset - offset;
}
if (checkAltAxis) {
var _mainSide = mainAxis === 'x' ? top : left;
var _altSide = mainAxis === 'x' ? bottom : right;
var _offset = popperOffsets[altAxis];
var _min = _offset + overflow[_mainSide];
var _max = _offset - overflow[_altSide];
var _preventedOffset = within(_min, _offset, _max);
popperOffsets[altAxis] = _preventedOffset;
data[altAxis] = _preventedOffset - _offset;
}
state.modifiersData[name] = data;
} // eslint-disable-next-line import/no-unused-modules
export default {
name: 'preventOverflow',
enabled: true,
phase: 'main',
fn: preventOverflow,
requiresIfExists: ['offset']
};
\ No newline at end of file
// @flow
import { top, left, right, bottom, start } from '../enums';
import type { Placement, Boundary, RootBoundary } from '../enums';
import type { Rect, ModifierArguments, Modifier, Padding } from '../types';
import getBasePlacement from '../utils/getBasePlacement';
import getMainAxisFromPlacement from '../utils/getMainAxisFromPlacement';
import getAltAxis from '../utils/getAltAxis';
import within from '../utils/within';
import getLayoutRect from '../dom-utils/getLayoutRect';
import getOffsetParent from '../dom-utils/getOffsetParent';
import detectOverflow from '../utils/detectOverflow';
import getVariation from '../utils/getVariation';
import getFreshSideObject from '../utils/getFreshSideObject';
type TetherOffset =
| (({
popper: Rect,
reference: Rect,
placement: Placement,
}) => number)
| number;
// eslint-disable-next-line import/no-unused-modules
export type Options = {
/* Prevents boundaries overflow on the main axis */
mainAxis: boolean,
/* Prevents boundaries overflow on the alternate axis */
altAxis: boolean,
/* The area to check the popper is overflowing in */
boundary: Boundary,
/* If the popper is not overflowing the main area, fallback to this one */
rootBoundary: RootBoundary,
/* Use the reference's "clippingParents" boundary context */
altBoundary: boolean,
/**
* Allows the popper to overflow from its boundaries to keep it near its
* reference element
*/
tether: boolean,
/* Offsets when the `tether` option should activate */
tetherOffset: TetherOffset,
/* Sets a padding to the provided boundary */
padding: Padding,
};
function preventOverflow({ state, options, name }: ModifierArguments<Options>) {
const {
mainAxis: checkMainAxis = true,
altAxis: checkAltAxis = false,
boundary,
rootBoundary,
altBoundary,
padding,
tether = true,
tetherOffset = 0,
} = options;
const overflow = detectOverflow(state, {
boundary,
rootBoundary,
padding,
altBoundary,
});
const basePlacement = getBasePlacement(state.placement);
const variation = getVariation(state.placement);
const isBasePlacement = !variation;
const mainAxis = getMainAxisFromPlacement(basePlacement);
const altAxis = getAltAxis(mainAxis);
const popperOffsets = state.modifiersData.popperOffsets;
const referenceRect = state.rects.reference;
const popperRect = state.rects.popper;
const tetherOffsetValue =
typeof tetherOffset === 'function'
? tetherOffset({
...state.rects,
placement: state.placement,
})
: tetherOffset;
const data = { x: 0, y: 0 };
if (!popperOffsets) {
return;
}
if (checkMainAxis) {
const mainSide = mainAxis === 'y' ? top : left;
const altSide = mainAxis === 'y' ? bottom : right;
const len = mainAxis === 'y' ? 'height' : 'width';
const offset = popperOffsets[mainAxis];
const min = popperOffsets[mainAxis] + overflow[mainSide];
const max = popperOffsets[mainAxis] - overflow[altSide];
const additive = tether ? -popperRect[len] / 2 : 0;
const minLen = variation === start ? referenceRect[len] : popperRect[len];
const maxLen = variation === start ? -popperRect[len] : -referenceRect[len];
// We need to include the arrow in the calculation so the arrow doesn't go
// outside the reference bounds
const arrowElement = state.elements.arrow;
const arrowRect =
tether && arrowElement
? getLayoutRect(arrowElement)
: { width: 0, height: 0 };
const arrowPaddingObject = state.modifiersData['arrow#persistent']
? state.modifiersData['arrow#persistent'].padding
: getFreshSideObject();
const arrowPaddingMin = arrowPaddingObject[mainSide];
const arrowPaddingMax = arrowPaddingObject[altSide];
// If the reference length is smaller than the arrow length, we don't want
// to include its full size in the calculation. If the reference is small
// and near the edge of a boundary, the popper can overflow even if the
// reference is not overflowing as well (e.g. virtual elements with no
// width or height)
const arrowLen = within(0, referenceRect[len], arrowRect[len]);
const minOffset = isBasePlacement
? referenceRect[len] / 2 -
additive -
arrowLen -
arrowPaddingMin -
tetherOffsetValue
: minLen - arrowLen - arrowPaddingMin - tetherOffsetValue;
const maxOffset = isBasePlacement
? -referenceRect[len] / 2 +
additive +
arrowLen +
arrowPaddingMax +
tetherOffsetValue
: maxLen + arrowLen + arrowPaddingMax + tetherOffsetValue;
const arrowOffsetParent =
state.elements.arrow && getOffsetParent(state.elements.arrow);
const clientOffset = arrowOffsetParent
? mainAxis === 'y'
? arrowOffsetParent.clientTop || 0
: arrowOffsetParent.clientLeft || 0
: 0;
const offsetModifierValue = state.modifiersData.offset
? state.modifiersData.offset[state.placement][mainAxis]
: 0;
const tetherMin =
popperOffsets[mainAxis] + minOffset - offsetModifierValue - clientOffset;
const tetherMax = popperOffsets[mainAxis] + maxOffset - offsetModifierValue;
const preventedOffset = within(
tether ? Math.min(min, tetherMin) : min,
offset,
tether ? Math.max(max, tetherMax) : max
);
popperOffsets[mainAxis] = preventedOffset;
data[mainAxis] = preventedOffset - offset;
}
if (checkAltAxis) {
const mainSide = mainAxis === 'x' ? top : left;
const altSide = mainAxis === 'x' ? bottom : right;
const offset = popperOffsets[altAxis];
const min = offset + overflow[mainSide];
const max = offset - overflow[altSide];
const preventedOffset = within(min, offset, max);
popperOffsets[altAxis] = preventedOffset;
data[altAxis] = preventedOffset - offset;
}
state.modifiersData[name] = data;
}
// eslint-disable-next-line import/no-unused-modules
export type PreventOverflowModifier = Modifier<'preventOverflow', Options>;
export default ({
name: 'preventOverflow',
enabled: true,
phase: 'main',
fn: preventOverflow,
requiresIfExists: ['offset'],
}: PreventOverflowModifier);
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment