UNPKG

@yandex/ui

Version:

Yandex UI components

58 lines (57 loc) 2.68 kB
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; }); }