source: imaps-frontend/node_modules/@popperjs/core/lib/modifiers/arrow.js.flow

main
Last change on this file was 79a0317, checked in by stefan toskovski <stefantoska84@…>, 4 days ago

F4 Finalna Verzija

  • Property mode set to 100644
File size: 3.6 KB
Line 
1// @flow
2import type { Modifier, ModifierArguments, Padding, Rect } from '../types';
3import type { Placement } from '../enums';
4import getBasePlacement from '../utils/getBasePlacement';
5import getLayoutRect from '../dom-utils/getLayoutRect';
6import contains from '../dom-utils/contains';
7import getOffsetParent from '../dom-utils/getOffsetParent';
8import getMainAxisFromPlacement from '../utils/getMainAxisFromPlacement';
9import { within } from '../utils/within';
10import mergePaddingObject from '../utils/mergePaddingObject';
11import expandToHashMap from '../utils/expandToHashMap';
12import { left, right, basePlacements, top, bottom } from '../enums';
13
14// eslint-disable-next-line import/no-unused-modules
15export type Options = {
16 element: HTMLElement | string | null,
17 padding:
18 | Padding
19 | (({|
20 popper: Rect,
21 reference: Rect,
22 placement: Placement,
23 |}) => Padding),
24};
25
26const toPaddingObject = (padding, state) => {
27 padding =
28 typeof padding === 'function'
29 ? padding({ ...state.rects, placement: state.placement })
30 : padding;
31
32 return mergePaddingObject(
33 typeof padding !== 'number'
34 ? padding
35 : expandToHashMap(padding, basePlacements)
36 );
37};
38
39function arrow({ state, name, options }: ModifierArguments<Options>) {
40 const arrowElement = state.elements.arrow;
41 const popperOffsets = state.modifiersData.popperOffsets;
42 const basePlacement = getBasePlacement(state.placement);
43 const axis = getMainAxisFromPlacement(basePlacement);
44 const isVertical = [left, right].indexOf(basePlacement) >= 0;
45 const len = isVertical ? 'height' : 'width';
46
47 if (!arrowElement || !popperOffsets) {
48 return;
49 }
50
51 const paddingObject = toPaddingObject(options.padding, state);
52 const arrowRect = getLayoutRect(arrowElement);
53 const minProp = axis === 'y' ? top : left;
54 const maxProp = axis === 'y' ? bottom : right;
55
56 const endDiff =
57 state.rects.reference[len] +
58 state.rects.reference[axis] -
59 popperOffsets[axis] -
60 state.rects.popper[len];
61 const startDiff = popperOffsets[axis] - state.rects.reference[axis];
62
63 const arrowOffsetParent = getOffsetParent(arrowElement);
64 const clientSize = arrowOffsetParent
65 ? axis === 'y'
66 ? arrowOffsetParent.clientHeight || 0
67 : arrowOffsetParent.clientWidth || 0
68 : 0;
69
70 const centerToReference = endDiff / 2 - startDiff / 2;
71
72 // Make sure the arrow doesn't overflow the popper if the center point is
73 // outside of the popper bounds
74 const min = paddingObject[minProp];
75 const max = clientSize - arrowRect[len] - paddingObject[maxProp];
76 const center = clientSize / 2 - arrowRect[len] / 2 + centerToReference;
77 const offset = within(min, center, max);
78
79 // Prevents breaking syntax highlighting...
80 const axisProp: string = axis;
81 state.modifiersData[name] = {
82 [axisProp]: offset,
83 centerOffset: offset - center,
84 };
85}
86
87function effect({ state, options }: ModifierArguments<Options>) {
88 let { element: arrowElement = '[data-popper-arrow]' } = options;
89
90 if (arrowElement == null) {
91 return;
92 }
93
94 // CSS selector
95 if (typeof arrowElement === 'string') {
96 arrowElement = state.elements.popper.querySelector(arrowElement);
97
98 if (!arrowElement) {
99 return;
100 }
101 }
102
103 if (!contains(state.elements.popper, arrowElement)) {
104 return;
105 }
106
107 state.elements.arrow = arrowElement;
108}
109
110// eslint-disable-next-line import/no-unused-modules
111export type ArrowModifier = Modifier<'arrow', Options>;
112export default ({
113 name: 'arrow',
114 enabled: true,
115 phase: 'main',
116 fn: arrow,
117 effect,
118 requires: ['popperOffsets'],
119 requiresIfExists: ['preventOverflow'],
120}: ArrowModifier);
Note: See TracBrowser for help on using the repository browser.