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/arrow.js.flow')
-rw-r--r--popperjs/package/lib/modifiers/arrow.js.flow142
1 files changed, 142 insertions, 0 deletions
diff --git a/popperjs/package/lib/modifiers/arrow.js.flow b/popperjs/package/lib/modifiers/arrow.js.flow
new file mode 100644
index 0000000..03666f5
--- /dev/null
+++ b/popperjs/package/lib/modifiers/arrow.js.flow
@@ -0,0 +1,142 @@
+// @flow
+import type { Modifier, ModifierArguments, Padding, Rect } from '../types';
+import type { Placement } from '../enums';
+import getBasePlacement from '../utils/getBasePlacement';
+import getLayoutRect from '../dom-utils/getLayoutRect';
+import contains from '../dom-utils/contains';
+import getOffsetParent from '../dom-utils/getOffsetParent';
+import getMainAxisFromPlacement from '../utils/getMainAxisFromPlacement';
+import { within } from '../utils/within';
+import mergePaddingObject from '../utils/mergePaddingObject';
+import expandToHashMap from '../utils/expandToHashMap';
+import { left, right, basePlacements, top, bottom } from '../enums';
+import { isHTMLElement } from '../dom-utils/instanceOf';
+
+// eslint-disable-next-line import/no-unused-modules
+export type Options = {
+ element: HTMLElement | string | null,
+ padding:
+ | Padding
+ | (({|
+ popper: Rect,
+ reference: Rect,
+ placement: Placement,
+ |}) => Padding),
+};
+
+const toPaddingObject = (padding, state) => {
+ padding =
+ typeof padding === 'function'
+ ? padding({ ...state.rects, placement: state.placement })
+ : padding;
+
+ return mergePaddingObject(
+ typeof padding !== 'number'
+ ? padding
+ : expandToHashMap(padding, basePlacements)
+ );
+};
+
+function arrow({ state, name, options }: ModifierArguments<Options>) {
+ const arrowElement = state.elements.arrow;
+ const popperOffsets = state.modifiersData.popperOffsets;
+ const basePlacement = getBasePlacement(state.placement);
+ const axis = getMainAxisFromPlacement(basePlacement);
+ const isVertical = [left, right].indexOf(basePlacement) >= 0;
+ const len = isVertical ? 'height' : 'width';
+
+ if (!arrowElement || !popperOffsets) {
+ return;
+ }
+
+ const paddingObject = toPaddingObject(options.padding, state);
+ const arrowRect = getLayoutRect(arrowElement);
+ const minProp = axis === 'y' ? top : left;
+ const maxProp = axis === 'y' ? bottom : right;
+
+ const endDiff =
+ state.rects.reference[len] +
+ state.rects.reference[axis] -
+ popperOffsets[axis] -
+ state.rects.popper[len];
+ const startDiff = popperOffsets[axis] - state.rects.reference[axis];
+
+ const arrowOffsetParent = getOffsetParent(arrowElement);
+ const clientSize = arrowOffsetParent
+ ? axis === 'y'
+ ? arrowOffsetParent.clientHeight || 0
+ : arrowOffsetParent.clientWidth || 0
+ : 0;
+
+ const centerToReference = endDiff / 2 - startDiff / 2;
+
+ // Make sure the arrow doesn't overflow the popper if the center point is
+ // outside of the popper bounds
+ const min = paddingObject[minProp];
+ const max = clientSize - arrowRect[len] - paddingObject[maxProp];
+ const center = clientSize / 2 - arrowRect[len] / 2 + centerToReference;
+ const offset = within(min, center, max);
+
+ // Prevents breaking syntax highlighting...
+ const axisProp: string = axis;
+ state.modifiersData[name] = {
+ [axisProp]: offset,
+ centerOffset: offset - center,
+ };
+}
+
+function effect({ state, options }: ModifierArguments<Options>) {
+ let { element: arrowElement = '[data-popper-arrow]' } = options;
+
+ if (arrowElement == null) {
+ return;
+ }
+
+ // CSS selector
+ if (typeof arrowElement === 'string') {
+ arrowElement = state.elements.popper.querySelector(arrowElement);
+
+ if (!arrowElement) {
+ return;
+ }
+ }
+
+ if (false) {
+ if (!isHTMLElement(arrowElement)) {
+ console.error(
+ [
+ 'Popper: "arrow" element must be an HTMLElement (not an SVGElement).',
+ 'To use an SVG arrow, wrap it in an HTMLElement that will be used as',
+ 'the arrow.',
+ ].join(' ')
+ );
+ }
+ }
+
+ if (!contains(state.elements.popper, arrowElement)) {
+ if (false) {
+ console.error(
+ [
+ 'Popper: "arrow" modifier\'s `element` must be a child of the popper',
+ 'element.',
+ ].join(' ')
+ );
+ }
+
+ return;
+ }
+
+ state.elements.arrow = arrowElement;
+}
+
+// eslint-disable-next-line import/no-unused-modules
+export type ArrowModifier = Modifier<'arrow', Options>;
+export default ({
+ name: 'arrow',
+ enabled: true,
+ phase: 'main',
+ fn: arrow,
+ effect,
+ requires: ['popperOffsets'],
+ requiresIfExists: ['preventOverflow'],
+}: ArrowModifier);