@yandex/ui
Version:
Yandex UI components
58 lines (57 loc) • 2.68 kB
JavaScript
import { __assign } from "tslib";
import { detectOverflow } from '@popperjs/core';
import { top, bottom, left, right } from '../utils';
/**
* Модификатор, позволяющий скрыть попап, если якорь или папап находится вне видимой области.
*/
export var hide = {
name: 'hide',
enabled: true,
phase: 'main',
requiresIfExists: ['preventOverflow'],
fn: hideFn,
};
/**
* Не используем модификатор из popper, т.к. у него отсутствует возможность задать границу,
* относительно которой будут производится вычисления.
* Выпилить, если это поддержат в самом @popperjs/core
* FIXME: https://github.com/popperjs/popper-core/issues/1252
*/
function hideFn(_a) {
var state = _a.state, name = _a.name, options = _a.options;
var boundary = options.boundary;
var referenceRect = state.rects.reference;
var popperRect = state.rects.popper;
var preventedOffsets = state.modifiersData.preventOverflow;
var referenceOverflow = detectOverflow(state, {
elementContext: 'reference',
boundary: boundary,
});
var popperAltOverflow = detectOverflow(state, {
altBoundary: true,
boundary: boundary,
});
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 = __assign(__assign({}, state.attributes.popper), { 'data-popper-reference-hidden': isReferenceHidden, 'data-popper-escaped': hasPopperEscaped });
}
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; });
}