cbvirtua 1.0.5 → 1.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/v2/App.vue +56 -0
- package/v2/components/Dropdown.vue +28 -0
- package/v2/components/Menu.vue +9 -0
- package/{floating → v2}/components/Popper.js +1 -1
- package/v2/components/PopperContent.vue +270 -0
- package/v2/components/PopperWrapper.vue +101 -0
- package/v2/components/ResizeObserver.vue +151 -0
- package/v2/components/Tooltip.vue +22 -0
- package/v2/components/TooltipDirective.vue +171 -0
- package/v2/floating-ui/core/computeCoordsFromPlacement.js +39 -0
- package/v2/floating-ui/core/computePosition.js +52 -0
- package/v2/floating-ui/core/detectOverflow.js +36 -0
- package/v2/floating-ui/core/enums.js +7 -0
- package/v2/floating-ui/core/index.js +11 -0
- package/v2/floating-ui/core/middleware/arrow.js +52 -0
- package/v2/floating-ui/core/middleware/autoPlacement.js +84 -0
- package/v2/floating-ui/core/middleware/flip.js +82 -0
- package/v2/floating-ui/core/middleware/hide.js +36 -0
- package/v2/floating-ui/core/middleware/inline.js +100 -0
- package/v2/floating-ui/core/middleware/offset.js +26 -0
- package/v2/floating-ui/core/middleware/shift.js +99 -0
- package/v2/floating-ui/core/middleware/size.js +58 -0
- package/v2/floating-ui/core/types.js +11 -0
- package/v2/floating-ui/core/utils/expandPaddingObject.js +3 -0
- package/v2/floating-ui/core/utils/getAlignment.js +3 -0
- package/v2/floating-ui/core/utils/getAlignmentSides.js +23 -0
- package/v2/floating-ui/core/utils/getBasePlacement.js +3 -0
- package/v2/floating-ui/core/utils/getCrossAxis.js +3 -0
- package/v2/floating-ui/core/utils/getExpandedPlacements.js +10 -0
- package/v2/floating-ui/core/utils/getLengthFromAxis.js +3 -0
- package/v2/floating-ui/core/utils/getMainAxisFromPlacement.js +4 -0
- package/v2/floating-ui/core/utils/getOppositeAlignmentPlacement.js +4 -0
- package/v2/floating-ui/core/utils/getOppositePlacement.js +4 -0
- package/v2/floating-ui/core/utils/getPaddingObject.js +6 -0
- package/v2/floating-ui/core/utils/math.js +2 -0
- package/v2/floating-ui/core/utils/rectToClientRect.js +9 -0
- package/v2/floating-ui/core/utils/within.js +4 -0
- package/v2/floating-ui/dom/index.js +5 -0
- package/v2/floating-ui/dom/platform.js +20 -0
- package/v2/floating-ui/dom/utils/contains.js +22 -0
- package/v2/floating-ui/dom/utils/convertOffsetParentRelativeRectToViewportRelativeRect.js +35 -0
- package/v2/floating-ui/dom/utils/getBoundingClientRect.js +27 -0
- package/v2/floating-ui/dom/utils/getClippingClientRect.js +76 -0
- package/v2/floating-ui/dom/utils/getComputedStyle.js +4 -0
- package/v2/floating-ui/dom/utils/getDimensions.js +6 -0
- package/v2/floating-ui/dom/utils/getDocumentElement.js +4 -0
- package/v2/floating-ui/dom/utils/getDocumentRect.js +21 -0
- package/v2/floating-ui/dom/utils/getNodeName.js +4 -0
- package/v2/floating-ui/dom/utils/getNodeScroll.js +13 -0
- package/v2/floating-ui/dom/utils/getOffsetParent.js +43 -0
- package/v2/floating-ui/dom/utils/getParentNode.js +16 -0
- package/v2/floating-ui/dom/utils/getRectRelativeToOffsetParent.js +40 -0
- package/v2/floating-ui/dom/utils/getScrollParent.js +13 -0
- package/v2/floating-ui/dom/utils/getScrollParents.js +18 -0
- package/v2/floating-ui/dom/utils/getViewportRect.js +25 -0
- package/v2/floating-ui/dom/utils/getWindowScrollBarX.js +9 -0
- package/v2/floating-ui/dom/utils/is.js +38 -0
- package/v2/floating-ui/dom/utils/math.js +3 -0
- package/v2/floating-ui/dom/utils/window.js +13 -0
- package/{floating → v2}/index.js +2 -1
- package/floating/demo/TestDropdown.vue +0 -22
- package/floating/demo/TestSubMenu.vue +0 -87
- package/floating/demo/TestTooltip.vue +0 -19
- package/floating/directives/v-tooltip.spec.js +0 -28
- /package/{floating → v2}/components/PopperMethods.js +0 -0
- /package/{floating → v2}/components/ThemeClass.js +0 -0
- /package/{floating → v2}/config.js +0 -0
- /package/{floating → v2}/directives/v-close-popper.js +0 -0
- /package/{floating → v2}/directives/v-tooltip.js +0 -0
- /package/{floating → v2}/util/assign-deep.js +0 -0
- /package/{floating → v2}/util/env.js +0 -0
- /package/{floating → v2}/util/events.js +0 -0
- /package/{floating → v2}/util/frame.js +0 -0
- /package/{floating → v2}/util/lang.js +0 -0
- /package/{floating → v2}/util/popper.js +0 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { getBasePlacement } from '../utils/getBasePlacement';
|
|
2
|
+
import { getMainAxisFromPlacement } from '../utils/getMainAxisFromPlacement';
|
|
3
|
+
export function convertValueToCoords({ placement, rects, value, }) {
|
|
4
|
+
const basePlacement = getBasePlacement(placement);
|
|
5
|
+
const multiplier = ['left', 'top'].includes(basePlacement) ? -1 : 1;
|
|
6
|
+
const rawValue = typeof value === 'function' ? value({ ...rects, placement }) : value;
|
|
7
|
+
const { mainAxis, crossAxis } = typeof rawValue === 'number'
|
|
8
|
+
? { mainAxis: rawValue, crossAxis: 0 }
|
|
9
|
+
: { mainAxis: 0, crossAxis: 0, ...rawValue };
|
|
10
|
+
return getMainAxisFromPlacement(basePlacement) === 'x'
|
|
11
|
+
? { x: crossAxis, y: mainAxis * multiplier }
|
|
12
|
+
: { x: mainAxis * multiplier, y: crossAxis };
|
|
13
|
+
}
|
|
14
|
+
export const offset = (value = 0) => ({
|
|
15
|
+
name: 'offset',
|
|
16
|
+
options: value,
|
|
17
|
+
fn(middlewareArguments) {
|
|
18
|
+
const { x, y, placement, rects } = middlewareArguments;
|
|
19
|
+
const diffCoords = convertValueToCoords({ placement, rects, value });
|
|
20
|
+
return {
|
|
21
|
+
x: x + diffCoords.x,
|
|
22
|
+
y: y + diffCoords.y,
|
|
23
|
+
data: diffCoords,
|
|
24
|
+
};
|
|
25
|
+
},
|
|
26
|
+
});
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { getBasePlacement } from '../utils/getBasePlacement';
|
|
2
|
+
import { getMainAxisFromPlacement } from '../utils/getMainAxisFromPlacement';
|
|
3
|
+
import { getCrossAxis } from '../utils/getCrossAxis';
|
|
4
|
+
import { within } from '../utils/within';
|
|
5
|
+
import { detectOverflow, } from '../detectOverflow';
|
|
6
|
+
export const shift = (options = {}) => ({
|
|
7
|
+
name: 'shift',
|
|
8
|
+
options,
|
|
9
|
+
async fn(middlewareArguments) {
|
|
10
|
+
const { x, y, placement } = middlewareArguments;
|
|
11
|
+
const { mainAxis: checkMainAxis = true, crossAxis: checkCrossAxis = false, limiter = { fn: ({ x, y }) => ({ x, y }) }, ...detectOverflowOptions } = options;
|
|
12
|
+
const coords = { x, y };
|
|
13
|
+
const overflow = await detectOverflow(middlewareArguments, detectOverflowOptions);
|
|
14
|
+
const mainAxis = getMainAxisFromPlacement(getBasePlacement(placement));
|
|
15
|
+
const crossAxis = getCrossAxis(mainAxis);
|
|
16
|
+
let mainAxisCoord = coords[mainAxis];
|
|
17
|
+
let crossAxisCoord = coords[crossAxis];
|
|
18
|
+
if (checkMainAxis) {
|
|
19
|
+
const minSide = mainAxis === 'y' ? 'top' : 'left';
|
|
20
|
+
const maxSide = mainAxis === 'y' ? 'bottom' : 'right';
|
|
21
|
+
const min = mainAxisCoord + overflow[minSide];
|
|
22
|
+
const max = mainAxisCoord - overflow[maxSide];
|
|
23
|
+
mainAxisCoord = within(min, mainAxisCoord, max);
|
|
24
|
+
}
|
|
25
|
+
if (checkCrossAxis) {
|
|
26
|
+
const minSide = crossAxis === 'y' ? 'top' : 'left';
|
|
27
|
+
const maxSide = crossAxis === 'y' ? 'bottom' : 'right';
|
|
28
|
+
const min = crossAxisCoord + overflow[minSide];
|
|
29
|
+
const max = crossAxisCoord - overflow[maxSide];
|
|
30
|
+
crossAxisCoord = within(min, crossAxisCoord, max);
|
|
31
|
+
}
|
|
32
|
+
const limitedCoords = limiter.fn({
|
|
33
|
+
...middlewareArguments,
|
|
34
|
+
[mainAxis]: mainAxisCoord,
|
|
35
|
+
[crossAxis]: crossAxisCoord,
|
|
36
|
+
});
|
|
37
|
+
return {
|
|
38
|
+
...limitedCoords,
|
|
39
|
+
data: {
|
|
40
|
+
x: limitedCoords.x - x,
|
|
41
|
+
y: limitedCoords.y - y,
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
export const limitShift = (options = {}) => ({
|
|
47
|
+
options,
|
|
48
|
+
fn(middlewareArguments) {
|
|
49
|
+
var _a, _b, _c, _d;
|
|
50
|
+
const { x, y, placement, rects, middlewareData } = middlewareArguments;
|
|
51
|
+
const { offset = 0, mainAxis: checkMainAxis = true, crossAxis: checkCrossAxis = true, } = options;
|
|
52
|
+
const coords = { x, y };
|
|
53
|
+
const mainAxis = getMainAxisFromPlacement(placement);
|
|
54
|
+
const crossAxis = getCrossAxis(mainAxis);
|
|
55
|
+
let mainAxisCoord = coords[mainAxis];
|
|
56
|
+
let crossAxisCoord = coords[crossAxis];
|
|
57
|
+
const rawOffset = typeof offset === 'function' ? offset({ ...rects, placement }) : offset;
|
|
58
|
+
const computedOffset = typeof rawOffset === 'number'
|
|
59
|
+
? { mainAxis: rawOffset, crossAxis: 0 }
|
|
60
|
+
: { mainAxis: 0, crossAxis: 0, ...rawOffset };
|
|
61
|
+
if (checkMainAxis) {
|
|
62
|
+
const len = mainAxis === 'y' ? 'height' : 'width';
|
|
63
|
+
const limitMin = rects.reference[mainAxis] -
|
|
64
|
+
rects.floating[len] +
|
|
65
|
+
computedOffset.mainAxis;
|
|
66
|
+
const limitMax = rects.reference[mainAxis] +
|
|
67
|
+
rects.reference[len] -
|
|
68
|
+
computedOffset.mainAxis;
|
|
69
|
+
if (mainAxisCoord < limitMin) {
|
|
70
|
+
mainAxisCoord = limitMin;
|
|
71
|
+
}
|
|
72
|
+
else if (mainAxisCoord > limitMax) {
|
|
73
|
+
mainAxisCoord = limitMax;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
if (checkCrossAxis) {
|
|
77
|
+
const len = mainAxis === 'y' ? 'width' : 'height';
|
|
78
|
+
const isOriginSide = ['top', 'left'].includes(getBasePlacement(placement));
|
|
79
|
+
const limitMin = rects.reference[crossAxis] -
|
|
80
|
+
rects.floating[len] -
|
|
81
|
+
((_b = (_a = middlewareData.offset) === null || _a === void 0 ? void 0 : _a[mainAxis]) !== null && _b !== void 0 ? _b : 0) +
|
|
82
|
+
(isOriginSide ? 0 : computedOffset.crossAxis);
|
|
83
|
+
const limitMax = rects.reference[crossAxis] +
|
|
84
|
+
rects.reference[len] +
|
|
85
|
+
((_d = (_c = middlewareData.offset) === null || _c === void 0 ? void 0 : _c[mainAxis]) !== null && _d !== void 0 ? _d : 0) -
|
|
86
|
+
(isOriginSide ? computedOffset.crossAxis : 0);
|
|
87
|
+
if (crossAxisCoord < limitMin) {
|
|
88
|
+
crossAxisCoord = limitMin;
|
|
89
|
+
}
|
|
90
|
+
else if (crossAxisCoord > limitMax) {
|
|
91
|
+
crossAxisCoord = limitMax;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return {
|
|
95
|
+
[mainAxis]: mainAxisCoord,
|
|
96
|
+
[crossAxis]: crossAxisCoord,
|
|
97
|
+
};
|
|
98
|
+
},
|
|
99
|
+
});
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { detectOverflow, } from '../detectOverflow';
|
|
2
|
+
import { getBasePlacement } from '../utils/getBasePlacement';
|
|
3
|
+
import { getAlignment } from '../utils/getAlignment';
|
|
4
|
+
import { max } from '../utils/math';
|
|
5
|
+
export const size = (options = {}) => ({
|
|
6
|
+
name: 'size',
|
|
7
|
+
options,
|
|
8
|
+
async fn(middlewareArguments) {
|
|
9
|
+
var _a;
|
|
10
|
+
const { placement, rects, middlewareData } = middlewareArguments;
|
|
11
|
+
const { apply, ...detectOverflowOptions } = options;
|
|
12
|
+
if ((_a = middlewareData.size) === null || _a === void 0 ? void 0 : _a.skip) {
|
|
13
|
+
return {};
|
|
14
|
+
}
|
|
15
|
+
const overflow = await detectOverflow(middlewareArguments, detectOverflowOptions);
|
|
16
|
+
const basePlacement = getBasePlacement(placement);
|
|
17
|
+
const isEnd = getAlignment(placement) === 'end';
|
|
18
|
+
let heightSide;
|
|
19
|
+
let widthSide;
|
|
20
|
+
if (basePlacement === 'top' || basePlacement === 'bottom') {
|
|
21
|
+
heightSide = basePlacement;
|
|
22
|
+
widthSide = isEnd ? 'left' : 'right';
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
widthSide = basePlacement;
|
|
26
|
+
heightSide = isEnd ? 'top' : 'bottom';
|
|
27
|
+
}
|
|
28
|
+
const xMin = max(overflow.left, 0);
|
|
29
|
+
const xMax = max(overflow.right, 0);
|
|
30
|
+
const yMin = max(overflow.top, 0);
|
|
31
|
+
const yMax = max(overflow.bottom, 0);
|
|
32
|
+
const dimensions = {
|
|
33
|
+
height: rects.floating.height -
|
|
34
|
+
(['left', 'right'].includes(placement)
|
|
35
|
+
? 2 *
|
|
36
|
+
(yMin !== 0 || yMax !== 0
|
|
37
|
+
? yMin + yMax
|
|
38
|
+
: max(overflow.top, overflow.bottom))
|
|
39
|
+
: overflow[heightSide]),
|
|
40
|
+
width: rects.floating.width -
|
|
41
|
+
(['top', 'bottom'].includes(placement)
|
|
42
|
+
? 2 *
|
|
43
|
+
(xMin !== 0 || xMax !== 0
|
|
44
|
+
? xMin + xMax
|
|
45
|
+
: max(overflow.left, overflow.right))
|
|
46
|
+
: overflow[widthSide]),
|
|
47
|
+
};
|
|
48
|
+
apply === null || apply === void 0 ? void 0 : apply({ ...dimensions, ...rects });
|
|
49
|
+
return {
|
|
50
|
+
data: {
|
|
51
|
+
skip: true,
|
|
52
|
+
},
|
|
53
|
+
reset: {
|
|
54
|
+
rects: true,
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
},
|
|
58
|
+
});
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export { computePosition } from './computePosition';
|
|
2
|
+
export { rectToClientRect } from './utils/rectToClientRect';
|
|
3
|
+
export { detectOverflow } from './detectOverflow';
|
|
4
|
+
export { arrow } from './middleware/arrow';
|
|
5
|
+
export { autoPlacement } from './middleware/autoPlacement';
|
|
6
|
+
export { flip } from './middleware/flip';
|
|
7
|
+
export { hide } from './middleware/hide';
|
|
8
|
+
export { offset } from './middleware/offset';
|
|
9
|
+
export { shift, limitShift } from './middleware/shift';
|
|
10
|
+
export { size } from './middleware/size';
|
|
11
|
+
export { inline } from './middleware/inline';
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { getLengthFromAxis } from './getLengthFromAxis';
|
|
2
|
+
import { getMainAxisFromPlacement } from './getMainAxisFromPlacement';
|
|
3
|
+
import { getOppositePlacement } from './getOppositePlacement';
|
|
4
|
+
import { getAlignment } from './getAlignment';
|
|
5
|
+
export function getAlignmentSides(placement, rects) {
|
|
6
|
+
const isStart = getAlignment(placement) === 'start';
|
|
7
|
+
const mainAxis = getMainAxisFromPlacement(placement);
|
|
8
|
+
const length = getLengthFromAxis(mainAxis);
|
|
9
|
+
let mainAlignmentSide = mainAxis === 'x'
|
|
10
|
+
? isStart
|
|
11
|
+
? 'right'
|
|
12
|
+
: 'left'
|
|
13
|
+
: isStart
|
|
14
|
+
? 'bottom'
|
|
15
|
+
: 'top';
|
|
16
|
+
if (rects.reference[length] > rects.floating[length]) {
|
|
17
|
+
mainAlignmentSide = getOppositePlacement(mainAlignmentSide);
|
|
18
|
+
}
|
|
19
|
+
return {
|
|
20
|
+
main: mainAlignmentSide,
|
|
21
|
+
cross: getOppositePlacement(mainAlignmentSide),
|
|
22
|
+
};
|
|
23
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { getOppositePlacement } from './getOppositePlacement';
|
|
2
|
+
import { getOppositeAlignmentPlacement } from './getOppositeAlignmentPlacement';
|
|
3
|
+
export function getExpandedPlacements(placement) {
|
|
4
|
+
const oppositePlacement = getOppositePlacement(placement);
|
|
5
|
+
return [
|
|
6
|
+
getOppositeAlignmentPlacement(placement),
|
|
7
|
+
oppositePlacement,
|
|
8
|
+
getOppositeAlignmentPlacement(oppositePlacement),
|
|
9
|
+
];
|
|
10
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { computePosition as computePositionCore, } from '../core/index';
|
|
2
|
+
import { platform } from './platform';
|
|
3
|
+
export const computePosition = (reference, floating, options) => computePositionCore(reference, floating, { platform, ...options });
|
|
4
|
+
export { arrow, autoPlacement, flip, hide, offset, shift, limitShift, size, inline, detectOverflow, } from '../core/index';
|
|
5
|
+
export { getScrollParents } from './utils/getScrollParents';
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { getRectRelativeToOffsetParent } from './utils/getRectRelativeToOffsetParent';
|
|
2
|
+
import { getOffsetParent } from './utils/getOffsetParent';
|
|
3
|
+
import { getDimensions } from './utils/getDimensions';
|
|
4
|
+
import { convertOffsetParentRelativeRectToViewportRelativeRect } from './utils/convertOffsetParentRelativeRectToViewportRelativeRect';
|
|
5
|
+
import { isElement } from './utils/is';
|
|
6
|
+
import { getDocumentElement } from './utils/getDocumentElement';
|
|
7
|
+
import { getClippingClientRect } from './utils/getClippingClientRect';
|
|
8
|
+
export const platform = {
|
|
9
|
+
getElementRects: ({ reference, floating, strategy }) => ({
|
|
10
|
+
reference: getRectRelativeToOffsetParent(reference, getOffsetParent(floating), strategy),
|
|
11
|
+
floating: { ...getDimensions(floating), x: 0, y: 0 },
|
|
12
|
+
}),
|
|
13
|
+
convertOffsetParentRelativeRectToViewportRelativeRect: (args) => convertOffsetParentRelativeRectToViewportRelativeRect(args),
|
|
14
|
+
getOffsetParent: ({ element }) => getOffsetParent(element),
|
|
15
|
+
isElement: (value) => isElement(value),
|
|
16
|
+
getDocumentElement: ({ element }) => getDocumentElement(element),
|
|
17
|
+
getClippingClientRect: (args) => getClippingClientRect(args),
|
|
18
|
+
getDimensions: ({ element }) => getDimensions(element),
|
|
19
|
+
getClientRects: ({ element }) => element.getClientRects(),
|
|
20
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { isShadowRoot } from './is';
|
|
2
|
+
export function contains(parent, child) {
|
|
3
|
+
var _a;
|
|
4
|
+
const rootNode = (_a = child.getRootNode) === null || _a === void 0 ? void 0 : _a.call(child);
|
|
5
|
+
// First, attempt with faster native method
|
|
6
|
+
if (parent.contains(child)) {
|
|
7
|
+
return true;
|
|
8
|
+
}
|
|
9
|
+
// then fallback to custom implementation with Shadow DOM support
|
|
10
|
+
else if (rootNode && isShadowRoot(rootNode)) {
|
|
11
|
+
let next = child;
|
|
12
|
+
do {
|
|
13
|
+
// use `===` replace node.isSameNode()
|
|
14
|
+
if (next && parent === next) {
|
|
15
|
+
return true;
|
|
16
|
+
}
|
|
17
|
+
// @ts-ignore: need a better way to handle this...
|
|
18
|
+
next = next.parentNode || next.host;
|
|
19
|
+
} while (next);
|
|
20
|
+
}
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { getBoundingClientRect } from './getBoundingClientRect';
|
|
2
|
+
import { getNodeScroll } from './getNodeScroll';
|
|
3
|
+
import { getNodeName } from './getNodeName';
|
|
4
|
+
import { getDocumentElement } from './getDocumentElement';
|
|
5
|
+
import { isHTMLElement, isScrollParent } from './is';
|
|
6
|
+
export function convertOffsetParentRelativeRectToViewportRelativeRect({ rect, offsetParent, strategy, }) {
|
|
7
|
+
const isOffsetParentAnElement = isHTMLElement(offsetParent);
|
|
8
|
+
const documentElement = getDocumentElement(offsetParent);
|
|
9
|
+
if (offsetParent === documentElement) {
|
|
10
|
+
return rect;
|
|
11
|
+
}
|
|
12
|
+
let scroll = { scrollLeft: 0, scrollTop: 0 };
|
|
13
|
+
const offsets = { x: 0, y: 0 };
|
|
14
|
+
if (isOffsetParentAnElement ||
|
|
15
|
+
(!isOffsetParentAnElement && strategy !== 'fixed')) {
|
|
16
|
+
if (getNodeName(offsetParent) !== 'body' ||
|
|
17
|
+
isScrollParent(documentElement)) {
|
|
18
|
+
scroll = getNodeScroll(offsetParent);
|
|
19
|
+
}
|
|
20
|
+
if (isHTMLElement(offsetParent)) {
|
|
21
|
+
const offsetRect = getBoundingClientRect(offsetParent, true);
|
|
22
|
+
offsets.x = offsetRect.x + offsetParent.clientLeft;
|
|
23
|
+
offsets.y = offsetRect.y + offsetParent.clientTop;
|
|
24
|
+
}
|
|
25
|
+
// This doesn't appear to be need to be negated.
|
|
26
|
+
// else if (documentElement) {
|
|
27
|
+
// offsets.x = getWindowScrollBarX(documentElement);
|
|
28
|
+
// }
|
|
29
|
+
}
|
|
30
|
+
return {
|
|
31
|
+
...rect,
|
|
32
|
+
x: rect.x - scroll.scrollLeft + offsets.x,
|
|
33
|
+
y: rect.y - scroll.scrollTop + offsets.y,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { isHTMLElement } from './is';
|
|
2
|
+
import { round } from './math';
|
|
3
|
+
export function getBoundingClientRect(element, includeScale = false) {
|
|
4
|
+
const clientRect = element.getBoundingClientRect();
|
|
5
|
+
let scaleX = 1;
|
|
6
|
+
let scaleY = 1;
|
|
7
|
+
if (includeScale && isHTMLElement(element)) {
|
|
8
|
+
scaleX =
|
|
9
|
+
element.offsetWidth > 0
|
|
10
|
+
? round(clientRect.width) / element.offsetWidth || 1
|
|
11
|
+
: 1;
|
|
12
|
+
scaleY =
|
|
13
|
+
element.offsetHeight > 0
|
|
14
|
+
? round(clientRect.height) / element.offsetHeight || 1
|
|
15
|
+
: 1;
|
|
16
|
+
}
|
|
17
|
+
return {
|
|
18
|
+
width: clientRect.width / scaleX,
|
|
19
|
+
height: clientRect.height / scaleY,
|
|
20
|
+
top: clientRect.top / scaleY,
|
|
21
|
+
right: clientRect.right / scaleX,
|
|
22
|
+
bottom: clientRect.bottom / scaleY,
|
|
23
|
+
left: clientRect.left / scaleX,
|
|
24
|
+
x: clientRect.left / scaleX,
|
|
25
|
+
y: clientRect.top / scaleY,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { rectToClientRect, } from '../../core/';
|
|
2
|
+
import { getViewportRect } from './getViewportRect';
|
|
3
|
+
import { getDocumentRect } from './getDocumentRect';
|
|
4
|
+
import { getScrollParents } from './getScrollParents';
|
|
5
|
+
import { getOffsetParent } from './getOffsetParent';
|
|
6
|
+
import { getDocumentElement } from './getDocumentElement';
|
|
7
|
+
import { getComputedStyle } from './getComputedStyle';
|
|
8
|
+
import { isElement, isHTMLElement } from './is';
|
|
9
|
+
import { getBoundingClientRect } from './getBoundingClientRect';
|
|
10
|
+
import { getParentNode } from './getParentNode';
|
|
11
|
+
import { contains } from './contains';
|
|
12
|
+
import { getNodeName } from './getNodeName';
|
|
13
|
+
import { max, min } from './math';
|
|
14
|
+
function getInnerBoundingClientRect(element) {
|
|
15
|
+
const clientRect = getBoundingClientRect(element);
|
|
16
|
+
const top = clientRect.top + element.clientTop;
|
|
17
|
+
const left = clientRect.left + element.clientLeft;
|
|
18
|
+
return {
|
|
19
|
+
top,
|
|
20
|
+
left,
|
|
21
|
+
x: left,
|
|
22
|
+
y: top,
|
|
23
|
+
right: left + element.clientWidth,
|
|
24
|
+
bottom: top + element.clientHeight,
|
|
25
|
+
width: element.clientWidth,
|
|
26
|
+
height: element.clientHeight,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
function getClientRectFromClippingParent(element, clippingParent) {
|
|
30
|
+
if (clippingParent === 'viewport') {
|
|
31
|
+
return rectToClientRect(getViewportRect(element));
|
|
32
|
+
}
|
|
33
|
+
if (isElement(clippingParent)) {
|
|
34
|
+
return getInnerBoundingClientRect(clippingParent);
|
|
35
|
+
}
|
|
36
|
+
return rectToClientRect(getDocumentRect(getDocumentElement(element)));
|
|
37
|
+
}
|
|
38
|
+
// A "clipping parent" is an overflowable container with the characteristic of
|
|
39
|
+
// clipping (or hiding) overflowing elements with a position different from
|
|
40
|
+
// `initial`
|
|
41
|
+
function getClippingParents(element) {
|
|
42
|
+
const clippingParents = getScrollParents(getParentNode(element));
|
|
43
|
+
const canEscapeClipping = ['absolute', 'fixed'].includes(getComputedStyle(element).position);
|
|
44
|
+
const clipperElement = canEscapeClipping && isHTMLElement(element)
|
|
45
|
+
? getOffsetParent(element)
|
|
46
|
+
: element;
|
|
47
|
+
if (!isElement(clipperElement)) {
|
|
48
|
+
return [];
|
|
49
|
+
}
|
|
50
|
+
// @ts-ignore isElement check ensures we return Array<Element>
|
|
51
|
+
return clippingParents.filter((clippingParent) => isElement(clippingParent) &&
|
|
52
|
+
contains(clippingParent, clipperElement) &&
|
|
53
|
+
getNodeName(clippingParent) !== 'body');
|
|
54
|
+
}
|
|
55
|
+
// Gets the maximum area that the element is visible in due to any number of
|
|
56
|
+
// clipping parents
|
|
57
|
+
export function getClippingClientRect({ element, boundary, rootBoundary, }) {
|
|
58
|
+
const mainClippingParents = boundary === 'clippingParents'
|
|
59
|
+
? getClippingParents(element)
|
|
60
|
+
: [].concat(boundary);
|
|
61
|
+
const clippingParents = [...mainClippingParents, rootBoundary];
|
|
62
|
+
const firstClippingParent = clippingParents[0];
|
|
63
|
+
const clippingRect = clippingParents.reduce((accRect, clippingParent) => {
|
|
64
|
+
const rect = getClientRectFromClippingParent(element, clippingParent);
|
|
65
|
+
accRect.top = max(rect.top, accRect.top);
|
|
66
|
+
accRect.right = min(rect.right, accRect.right);
|
|
67
|
+
accRect.bottom = min(rect.bottom, accRect.bottom);
|
|
68
|
+
accRect.left = max(rect.left, accRect.left);
|
|
69
|
+
return accRect;
|
|
70
|
+
}, getClientRectFromClippingParent(element, firstClippingParent));
|
|
71
|
+
clippingRect.width = clippingRect.right - clippingRect.left;
|
|
72
|
+
clippingRect.height = clippingRect.bottom - clippingRect.top;
|
|
73
|
+
clippingRect.x = clippingRect.left;
|
|
74
|
+
clippingRect.y = clippingRect.top;
|
|
75
|
+
return clippingRect;
|
|
76
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { getDocumentElement } from './getDocumentElement';
|
|
2
|
+
import { getComputedStyle } from './getComputedStyle';
|
|
3
|
+
import getWindowScrollBarX from './getWindowScrollBarX';
|
|
4
|
+
import { getNodeScroll } from './getNodeScroll';
|
|
5
|
+
import { max } from './math';
|
|
6
|
+
// Gets the entire size of the scrollable document area, even extending outside
|
|
7
|
+
// of the `<html>` and `<body>` rect bounds if horizontally scrollable
|
|
8
|
+
export function getDocumentRect(element) {
|
|
9
|
+
var _a;
|
|
10
|
+
const html = getDocumentElement(element);
|
|
11
|
+
const scroll = getNodeScroll(element);
|
|
12
|
+
const body = (_a = element.ownerDocument) === null || _a === void 0 ? void 0 : _a.body;
|
|
13
|
+
const width = max(html.scrollWidth, html.clientWidth, body ? body.scrollWidth : 0, body ? body.clientWidth : 0);
|
|
14
|
+
const height = max(html.scrollHeight, html.clientHeight, body ? body.scrollHeight : 0, body ? body.clientHeight : 0);
|
|
15
|
+
let x = -scroll.scrollLeft + getWindowScrollBarX(element);
|
|
16
|
+
const y = -scroll.scrollTop;
|
|
17
|
+
if (getComputedStyle(body || html).direction === 'rtl') {
|
|
18
|
+
x += max(html.clientWidth, body ? body.clientWidth : 0) - width;
|
|
19
|
+
}
|
|
20
|
+
return { width, height, x, y };
|
|
21
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { isWindow } from './window';
|
|
2
|
+
export function getNodeScroll(element) {
|
|
3
|
+
if (isWindow(element)) {
|
|
4
|
+
return {
|
|
5
|
+
scrollLeft: element.pageXOffset,
|
|
6
|
+
scrollTop: element.pageYOffset,
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
return {
|
|
10
|
+
scrollLeft: element.scrollLeft,
|
|
11
|
+
scrollTop: element.scrollTop,
|
|
12
|
+
};
|
|
13
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { getNodeName } from './getNodeName';
|
|
2
|
+
import { getParentNode } from './getParentNode';
|
|
3
|
+
import { getWindow } from './window';
|
|
4
|
+
import { isContainingBlock, isHTMLElement, isTableElement } from './is';
|
|
5
|
+
function getTrueOffsetParent(element) {
|
|
6
|
+
if (!isHTMLElement(element) ||
|
|
7
|
+
getComputedStyle(element).position === 'fixed') {
|
|
8
|
+
return null;
|
|
9
|
+
}
|
|
10
|
+
return element.offsetParent;
|
|
11
|
+
}
|
|
12
|
+
function getContainingBlock(element) {
|
|
13
|
+
let currentNode = getParentNode(element);
|
|
14
|
+
while (isHTMLElement(currentNode) &&
|
|
15
|
+
!['html', 'body'].includes(getNodeName(currentNode))) {
|
|
16
|
+
if (isContainingBlock(currentNode)) {
|
|
17
|
+
return currentNode;
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
currentNode = currentNode.parentNode;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
// Gets the closest ancestor positioned element. Handles some edge cases,
|
|
26
|
+
// such as table ancestors and cross browser bugs.
|
|
27
|
+
export function getOffsetParent(element) {
|
|
28
|
+
const window = getWindow(element);
|
|
29
|
+
let offsetParent = getTrueOffsetParent(element);
|
|
30
|
+
while (offsetParent &&
|
|
31
|
+
isTableElement(offsetParent) &&
|
|
32
|
+
getComputedStyle(offsetParent).position === 'static') {
|
|
33
|
+
offsetParent = getTrueOffsetParent(offsetParent);
|
|
34
|
+
}
|
|
35
|
+
if (offsetParent &&
|
|
36
|
+
(getNodeName(offsetParent) === 'html' ||
|
|
37
|
+
(getNodeName(offsetParent) === 'body' &&
|
|
38
|
+
getComputedStyle(offsetParent).position === 'static' &&
|
|
39
|
+
!isContainingBlock(offsetParent)))) {
|
|
40
|
+
return window;
|
|
41
|
+
}
|
|
42
|
+
return offsetParent || getContainingBlock(element) || window;
|
|
43
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { getNodeName } from './getNodeName';
|
|
2
|
+
import { getDocumentElement } from './getDocumentElement';
|
|
3
|
+
import { isShadowRoot } from './is';
|
|
4
|
+
export function getParentNode(node) {
|
|
5
|
+
if (getNodeName(node) === 'html') {
|
|
6
|
+
return node;
|
|
7
|
+
}
|
|
8
|
+
return (
|
|
9
|
+
// this is a quicker (but less type safe) way to save quite some bytes from the bundle
|
|
10
|
+
// @ts-ignore
|
|
11
|
+
node.assignedSlot || // step into the shadow DOM of the parent of a slotted node
|
|
12
|
+
node.parentNode || // DOM Element detected
|
|
13
|
+
(isShadowRoot(node) ? node.host : null) || // ShadowRoot detected
|
|
14
|
+
getDocumentElement(node) // fallback
|
|
15
|
+
);
|
|
16
|
+
}
|