@atlaskit/popper
Version:
A wrapper for React Popper for situations which require a bespoke popup where other ADS components are deemed unsuitable
69 lines (66 loc) • 2.15 kB
JavaScript
import React, { useMemo } from 'react';
import { Popper as ReactPopper } from 'react-popper';
import { getMaxSizeModifiers } from './max-size';
export { placements } from '@popperjs/core';
// Export types from PopperJS / React Popper
const viewportPadding = 5;
const constantModifiers = [{
name: 'flip',
options: {
flipVariations: false,
padding: viewportPadding,
boundary: 'clippingParents',
rootBoundary: 'viewport'
}
}];
function defaultChildrenFn() {
return null;
}
const defaultOffset = [0, 8];
export function Popper({
children = defaultChildrenFn,
offset = defaultOffset,
placement = 'bottom-start',
referenceElement = undefined,
modifiers,
strategy = 'fixed',
shouldFitViewport = false
}) {
const [offsetX, offsetY] = offset;
const internalModifiers = useMemo(() => {
const preventOverflowModifier = {
name: 'preventOverflow',
options: {
padding: viewportPadding,
rootBoundary: shouldFitViewport ? 'viewport' : 'document'
}
};
const offsetModifier = {
name: 'offset',
options: {
offset: [offsetX, offsetY]
}
};
const maxSizeModifiers = shouldFitViewport ? getMaxSizeModifiers({
viewportPadding
}) : [];
// @ts-ignore Type errors from incompatible @popperjs/core versions between Jira and AFM Platform... we are using ts-ignore here because ts-expect-error will cause an "Unused '@ts-expect-error' directive." error
return [...constantModifiers, preventOverflowModifier, offsetModifier, ...maxSizeModifiers];
}, [offsetX, offsetY, shouldFitViewport]);
// Merge custom props and memoize
const mergedModifiers = useMemo(() => {
if (modifiers == null) {
return internalModifiers;
}
return [...internalModifiers, ...modifiers];
}, [internalModifiers, modifiers]);
return /*#__PURE__*/React.createElement(ReactPopper
// @ts-expect-error - No overload matches this call
// This error was introduced after upgrading to TypeScript 5
, {
modifiers: mergedModifiers,
placement: placement,
strategy: strategy,
referenceElement: referenceElement
}, children);
}