UNPKG

1.6 kBJavaScriptView Raw
1import { OPEN_UP, ANCHOR_RIGHT } from '../constants';
2
3/**
4 * Calculate and return a CSS transform style to position a detached element
5 * next to a reference element. The open and anchor direction indicate wether
6 * it should be positioned above/below and/or to the left/right of the
7 * reference element.
8 *
9 * Assuming r(0,0), r(1,1), d(0,0), d(1,1) for the bottom-left and top-right
10 * corners of the reference and detached elements, respectively:
11 * - openDirection = DOWN, anchorDirection = LEFT => d(0,1) == r(0,1)
12 * - openDirection = UP, anchorDirection = LEFT => d(0,0) == r(0,0)
13 * - openDirection = DOWN, anchorDirection = RIGHT => d(1,1) == r(1,1)
14 * - openDirection = UP, anchorDirection = RIGHT => d(1,0) == r(1,0)
15 *
16 * By using a CSS transform, we allow to further position it using
17 * top/bottom CSS properties for the anchor gutter.
18 *
19 * @param {string} openDirection The vertical positioning of the popup
20 * @param {string} anchorDirection The horizontal position of the popup
21 * @param {HTMLElement} referenceEl The reference element
22 */
23export default function getDetachedContainerStyles(openDirection, anchorDirection, referenceEl) {
24 const referenceRect = referenceEl.getBoundingClientRect();
25 let offsetX = referenceRect.left;
26 let offsetY = referenceRect.top;
27
28 if (openDirection === OPEN_UP) {
29 offsetY = -(window.innerHeight - referenceRect.bottom);
30 }
31
32 if (anchorDirection === ANCHOR_RIGHT) {
33 offsetX = -(window.innerWidth - referenceRect.right);
34 }
35
36 return {
37 transform: `translate3d(${Math.round(offsetX)}px, ${Math.round(offsetY)}px, 0)`,
38 };
39}