From 263dd95989fb3b8a88aa7e91e92c3af09bb9d27a Mon Sep 17 00:00:00 2001
From: CJ Cenizal
Date: Tue, 20 Mar 2018 17:49:33 -0700
Subject: [PATCH 1/6] Update calculatePopoverPosition to seek the position with
the largest amount of visible surface area of the popover.
---
src-docs/src/views/tool_tip/tool_tip.js | 4 +-
src/components/tool_tip/tool_tip.js | 12 +-
src/components/tool_tip/tool_tip_popover.js | 22 ++--
.../popover/popover_calculate_position.js | 110 ++++++++++--------
4 files changed, 77 insertions(+), 71 deletions(-)
diff --git a/src-docs/src/views/tool_tip/tool_tip.js b/src-docs/src/views/tool_tip/tool_tip.js
index ea7d5ca0fc7..d82979cf137 100644
--- a/src-docs/src/views/tool_tip/tool_tip.js
+++ b/src-docs/src/views/tool_tip/tool_tip.js
@@ -55,8 +55,8 @@ export default () => (
-
- alert('Buttons are still clickable within tooltips.')}>Hover over me
+ Works on any kind of element — buttons, inputs, you name it!
}>
+ alert('Buttons are still clickable within tooltips.')}>Hover me
);
diff --git a/src/components/tool_tip/tool_tip.js b/src/components/tool_tip/tool_tip.js
index b56bc3da12a..3c375e81468 100644
--- a/src/components/tool_tip/tool_tip.js
+++ b/src/components/tool_tip/tool_tip.js
@@ -38,12 +38,12 @@ export class EuiToolTip extends Component {
this.setState({ visible: true });
};
- positionToolTip = (toolTipRect) => {
- const wrapperRect = this.wrapper.getBoundingClientRect();
- const userPosition = this.props.position;
+ positionToolTip = (toolTipBounds) => {
+ const anchorBounds = this.anchor.getBoundingClientRect();
+ const requestedPosition = this.props.position;
- const calculatedPosition = calculatePopoverPosition(wrapperRect, toolTipRect, userPosition);
- const toolTipStyles = calculatePopoverStyles(wrapperRect, toolTipRect, calculatedPosition);
+ const calculatedPosition = calculatePopoverPosition(anchorBounds, toolTipBounds, requestedPosition);
+ const toolTipStyles = calculatePopoverStyles(anchorBounds, toolTipBounds, calculatedPosition);
this.setState({
visible: true,
@@ -111,7 +111,7 @@ export class EuiToolTip extends Component {
}
const trigger = (
- this.wrapper = wrapper}>
+ this.anchor = anchor}>
{cloneElement(children, {
onFocus: this.showToolTip,
onBlur: this.hideToolTip,
diff --git a/src/components/tool_tip/tool_tip_popover.js b/src/components/tool_tip/tool_tip_popover.js
index 41063bff46b..3d5c1789c22 100644
--- a/src/components/tool_tip/tool_tip_popover.js
+++ b/src/components/tool_tip/tool_tip_popover.js
@@ -12,26 +12,20 @@ export class EuiToolTipPopover extends Component {
positionToolTip: PropTypes.func.isRequired,
}
- constructor(props) {
- super(props);
-
- this.updateDimensions = this.updateDimensions.bind(this);
- }
-
- componentDidMount() {
- document.body.classList.add('euiBody-hasToolTip');
-
- this.updateDimensions();
- window.addEventListener('resize', this.updateDimensions);
- }
-
- updateDimensions() {
+ updateDimensions = () => {
requestAnimationFrame(() => {
// Because of this delay, sometimes `positionToolTip` becomes unavailable.
if (this.popover) {
this.props.positionToolTip(this.popover.getBoundingClientRect());
}
});
+ };
+
+ componentDidMount() {
+ document.body.classList.add('euiBody-hasToolTip');
+
+ this.updateDimensions();
+ window.addEventListener('resize', this.updateDimensions);
}
componentWillUnmount() {
diff --git a/src/services/popover/popover_calculate_position.js b/src/services/popover/popover_calculate_position.js
index afa6e9f3ab5..c3115783e60 100644
--- a/src/services/popover/popover_calculate_position.js
+++ b/src/services/popover/popover_calculate_position.js
@@ -1,60 +1,72 @@
-
/**
- * Determine the best position for a popup that avoids clipping by the window view port.
+ * Determine the best position for a popover that avoids clipping by the window view port.
*
- * @param {native DOM Element} wrapperRect - getBoundingClientRect() of wrapping node around the popover.
- * @param {native DOM Element} popupRect - getBoundingClientRect() of the popup node.
+ * @param {native DOM Element} anchorBounds - getBoundingClientRect() of the node the popover is tethered to (e.g. a button).
+ * @param {native DOM Element} popoverBounds - getBoundingClientRect() of the popover node (e.g. the tooltip).
* @param {string} requestedPosition - Position the user wants. One of ["top", "right", "bottom", "left"]
- * @param {number} buffer - The space between the wrapper and the popup. Also the minimum space between the popup and the window.
+ * @param {number} buffer - The space between the wrapper and the popover. Also the minimum space between the popover and the window.
*
- * @returns {string} One of ["top", "right", "bottom", "left"] that ensures no window overflow.
+ * @returns {string} One of ["top", "right", "bottom", "left"] that ensures the least amount of window overflow.
*/
-export function calculatePopoverPosition(wrapperRect, popupRect, requestedPosition, buffer = 16) {
-
- // determine popup overflow in each direction
- // negative values signal window overflow, large values signal lots of free space
- const popupOverflow = {
- top: wrapperRect.top - (popupRect.height + (2 * buffer)),
- right: window.innerWidth - wrapperRect.right - (popupRect.width + (2 * buffer)),
- left: wrapperRect.left - (popupRect.width + (2 * buffer)),
- bottom: window.innerHeight - wrapperRect.bottom - (popupRect.height + (2 * buffer)),
- };
- function hasCrossDimensionOverflow(key) {
- if (key === 'left' || key === 'right') {
- const domNodeCenterY = wrapperRect.top + (wrapperRect.height / 2);
- const tooltipTop = domNodeCenterY - ((popupRect.height / 2) + buffer);
- if (tooltipTop <= 0) {
- return true;
- }
- const tooltipBottom = domNodeCenterY + (popupRect.height / 2) + buffer;
- if (tooltipBottom >= window.innerHeight) {
- return true;
- }
- } else {
- const domNodeCenterX = wrapperRect.left + (wrapperRect.width / 2);
- const tooltipLeft = domNodeCenterX - ((popupRect.width / 2) + buffer);
- if (tooltipLeft <= 0) {
- return true;
- }
- const tooltipRight = domNodeCenterX + (popupRect.width / 2) + buffer;
- if (tooltipRight >= window.innerWidth) {
- return true;
- }
- }
- return false;
- }
+const getVisibleArea = (bounds, windowWidth, windowHeight) => {
+ const { left, top, width, height } = bounds;
+ // This is a common algorithm for finding the intersected area among two rectangles.
+ const dx = Math.min(left + width, windowWidth) - Math.max(left, 0);
+ const dy = Math.min(top + height, windowHeight) - Math.max(top, 0);
+ return dx * dy;
+};
+
+const positionAtTop = (anchorBounds, width, height, buffer) => {
+ const widthDifference = width - anchorBounds.width;
+ const left = (anchorBounds.left - widthDifference) * 0.5;
+ const top = anchorBounds.top - height - buffer;
+ return { left, top, width, height };
+};
+
+const positionAtRight = (anchorBounds, width, height, buffer) => {
+ const left = anchorBounds.right + buffer;
+ const heightDifference = (height - anchorBounds.height) * 0.5;
+ const top = anchorBounds.top - heightDifference;
+ return { left, top, width, height };
+};
+
+const positionAtBottom = (anchorBounds, width, height, buffer) => {
+ const widthDifference = width - anchorBounds.width;
+ const left = (anchorBounds.left - widthDifference) * 0.5;
+ const top = anchorBounds.bottom + buffer;
+ return { left, top, width, height };
+};
+const positionAtLeft = (anchorBounds, width, height, buffer) => {
+ const left = anchorBounds.left - width - buffer;
+ const heightDifference = (height - anchorBounds.height) * 0.5;
+ const top = anchorBounds.top - heightDifference;
+ return { left, top, width, height };
+};
+
+export function calculatePopoverPosition(anchorBounds, popoverBounds, requestedPosition, buffer = 16) {
+ const windowWidth = window.innerWidth;
+ const windowHeight = window.innerHeight;
+ const { width: popoverWidth, height: popoverHeight } = popoverBounds;
+
+ // Calculate how much area of the popover is visible at each position.
+ const positionToVisibleAreaMap = {
+ top: getVisibleArea(positionAtTop(anchorBounds, popoverWidth, popoverHeight, buffer), windowWidth, windowHeight),
+ right: getVisibleArea(positionAtRight(anchorBounds, popoverWidth, popoverHeight, buffer), windowWidth, windowHeight),
+ bottom: getVisibleArea(positionAtBottom(anchorBounds, popoverWidth, popoverHeight, buffer), windowWidth, windowHeight),
+ left: getVisibleArea(positionAtLeft(anchorBounds, popoverWidth, popoverHeight, buffer), windowWidth, windowHeight),
+ };
+
+ // Default to use the requested position.
let calculatedPopoverPosition = requestedPosition;
- if (popupOverflow[requestedPosition] <= 0 || hasCrossDimensionOverflow(requestedPosition)) {
- // requested position overflows window bounds
- // select direction what has the most free space
- Object.keys(popupOverflow).forEach((key) => {
- if (popupOverflow[key] > popupOverflow[calculatedPopoverPosition] && !hasCrossDimensionOverflow(key)) {
- calculatedPopoverPosition = key;
- }
- });
- }
+
+ // If the requested position clips the popover, find the position which clips the popover the least.
+ Object.keys(positionToVisibleAreaMap).forEach((position) => {
+ if (positionToVisibleAreaMap[position] > positionToVisibleAreaMap[calculatedPopoverPosition]) {
+ calculatedPopoverPosition = position;
+ }
+ });
return calculatedPopoverPosition;
}
From c376e4b6f2b1633e977560f54b8143866baa4633 Mon Sep 17 00:00:00 2001
From: CJ Cenizal
Date: Tue, 20 Mar 2018 18:33:55 -0700
Subject: [PATCH 2/6] Return position data from calculatePopoverPosition. - Fix
mistakes with calculating height and width differences. - Remove
calculatePopoverStyles.
---
src/components/tool_tip/tool_tip.js | 12 ++++--
src/services/index.js | 1 -
src/services/popover/index.js | 1 -
.../popover/popover_calculate_position.js | 39 ++++++++++++-------
.../popover/popover_calculate_styles.js | 19 ---------
5 files changed, 33 insertions(+), 39 deletions(-)
delete mode 100644 src/services/popover/popover_calculate_styles.js
diff --git a/src/components/tool_tip/tool_tip.js b/src/components/tool_tip/tool_tip.js
index 3c375e81468..a9883c3f94f 100644
--- a/src/components/tool_tip/tool_tip.js
+++ b/src/components/tool_tip/tool_tip.js
@@ -8,7 +8,7 @@ import classNames from 'classnames';
import { EuiPortal } from '../portal';
import { EuiToolTipPopover } from './tool_tip_popover';
-import { calculatePopoverPosition, calculatePopoverStyles } from '../../services';
+import { calculatePopoverPosition } from '../../services';
import makeId from '../form/form_row/make_id';
@@ -42,12 +42,16 @@ export class EuiToolTip extends Component {
const anchorBounds = this.anchor.getBoundingClientRect();
const requestedPosition = this.props.position;
- const calculatedPosition = calculatePopoverPosition(anchorBounds, toolTipBounds, requestedPosition);
- const toolTipStyles = calculatePopoverStyles(anchorBounds, toolTipBounds, calculatedPosition);
+ const { position, left, top } = calculatePopoverPosition(anchorBounds, toolTipBounds, requestedPosition);
+
+ const toolTipStyles = {
+ top: top + window.scrollY,
+ left,
+ };
this.setState({
visible: true,
- calculatedPosition,
+ calculatedPosition: position,
toolTipStyles,
});
};
diff --git a/src/services/index.js b/src/services/index.js
index b4598f5f9e1..e4f06d64ea8 100644
--- a/src/services/index.js
+++ b/src/services/index.js
@@ -64,5 +64,4 @@ export {
export {
calculatePopoverPosition,
- calculatePopoverStyles,
} from './popover';
diff --git a/src/services/popover/index.js b/src/services/popover/index.js
index 28cdd4279cc..28fd6132873 100644
--- a/src/services/popover/index.js
+++ b/src/services/popover/index.js
@@ -1,2 +1 @@
export { calculatePopoverPosition } from './popover_calculate_position';
-export { calculatePopoverStyles } from './popover_calculate_styles';
diff --git a/src/services/popover/popover_calculate_position.js b/src/services/popover/popover_calculate_position.js
index c3115783e60..aaac139cf5d 100644
--- a/src/services/popover/popover_calculate_position.js
+++ b/src/services/popover/popover_calculate_position.js
@@ -19,29 +19,29 @@ const getVisibleArea = (bounds, windowWidth, windowHeight) => {
const positionAtTop = (anchorBounds, width, height, buffer) => {
const widthDifference = width - anchorBounds.width;
- const left = (anchorBounds.left - widthDifference) * 0.5;
+ const left = anchorBounds.left - widthDifference * 0.5;
const top = anchorBounds.top - height - buffer;
return { left, top, width, height };
};
const positionAtRight = (anchorBounds, width, height, buffer) => {
const left = anchorBounds.right + buffer;
- const heightDifference = (height - anchorBounds.height) * 0.5;
- const top = anchorBounds.top - heightDifference;
+ const heightDifference = height - anchorBounds.height;
+ const top = anchorBounds.top - heightDifference * 0.5;
return { left, top, width, height };
};
const positionAtBottom = (anchorBounds, width, height, buffer) => {
const widthDifference = width - anchorBounds.width;
- const left = (anchorBounds.left - widthDifference) * 0.5;
+ const left = anchorBounds.left - widthDifference * 0.5;
const top = anchorBounds.bottom + buffer;
return { left, top, width, height };
};
const positionAtLeft = (anchorBounds, width, height, buffer) => {
const left = anchorBounds.left - width - buffer;
- const heightDifference = (height - anchorBounds.height) * 0.5;
- const top = anchorBounds.top - heightDifference;
+ const heightDifference = height - anchorBounds.height;
+ const top = anchorBounds.top - heightDifference * 0.5;
return { left, top, width, height };
};
@@ -50,23 +50,34 @@ export function calculatePopoverPosition(anchorBounds, popoverBounds, requestedP
const windowHeight = window.innerHeight;
const { width: popoverWidth, height: popoverHeight } = popoverBounds;
- // Calculate how much area of the popover is visible at each position.
- const positionToVisibleAreaMap = {
- top: getVisibleArea(positionAtTop(anchorBounds, popoverWidth, popoverHeight, buffer), windowWidth, windowHeight),
- right: getVisibleArea(positionAtRight(anchorBounds, popoverWidth, popoverHeight, buffer), windowWidth, windowHeight),
- bottom: getVisibleArea(positionAtBottom(anchorBounds, popoverWidth, popoverHeight, buffer), windowWidth, windowHeight),
- left: getVisibleArea(positionAtLeft(anchorBounds, popoverWidth, popoverHeight, buffer), windowWidth, windowHeight),
+ const positionToBoundsMap = {
+ top: positionAtTop(anchorBounds, popoverWidth, popoverHeight, buffer),
+ right: positionAtRight(anchorBounds, popoverWidth, popoverHeight, buffer),
+ bottom: positionAtBottom(anchorBounds, popoverWidth, popoverHeight, buffer),
+ left: positionAtLeft(anchorBounds, popoverWidth, popoverHeight, buffer),
};
+ const positions = Object.keys(positionToBoundsMap);
+
+ // Calculate how much area of the popover is visible at each position.
+ const positionToVisibleAreaMap = {};
+
+ positions.forEach((position) => {
+ positionToVisibleAreaMap[position] = getVisibleArea(positionToBoundsMap[position], windowWidth, windowHeight);
+ });
+
// Default to use the requested position.
let calculatedPopoverPosition = requestedPosition;
// If the requested position clips the popover, find the position which clips the popover the least.
- Object.keys(positionToVisibleAreaMap).forEach((position) => {
+ positions.forEach((position) => {
if (positionToVisibleAreaMap[position] > positionToVisibleAreaMap[calculatedPopoverPosition]) {
calculatedPopoverPosition = position;
}
});
- return calculatedPopoverPosition;
+ return {
+ position: calculatedPopoverPosition,
+ ...positionToBoundsMap[calculatedPopoverPosition],
+ };
}
diff --git a/src/services/popover/popover_calculate_styles.js b/src/services/popover/popover_calculate_styles.js
deleted file mode 100644
index 741d3e2c422..00000000000
--- a/src/services/popover/popover_calculate_styles.js
+++ /dev/null
@@ -1,19 +0,0 @@
-export function calculatePopoverStyles(wrapperNodeRect, popupNodeRect, position, buffer = 16) {
- const styles = {};
-
- if (position === 'top') {
- styles.top = wrapperNodeRect.top + window.scrollY - (popupNodeRect.height + buffer);
- styles.left = wrapperNodeRect.left + (wrapperNodeRect.width / 2) - (popupNodeRect.width / 2);
- } else if (position === 'bottom') {
- styles.top = wrapperNodeRect.top + window.scrollY + wrapperNodeRect.height + buffer;
- styles.left = wrapperNodeRect.left + (wrapperNodeRect.width / 2) - (popupNodeRect.width / 2);
- } else if (position === 'right') {
- styles.top = wrapperNodeRect.top + window.scrollY - ((popupNodeRect.height - wrapperNodeRect.height) / 2);
- styles.left = wrapperNodeRect.left + wrapperNodeRect.width + buffer;
- } else if (position === 'left') {
- styles.top = wrapperNodeRect.top + window.scrollY - ((popupNodeRect.height - wrapperNodeRect.height) / 2);
- styles.left = wrapperNodeRect.left - popupNodeRect.width - buffer;
- }
-
- return styles;
-}
From 36a890c86a286d653d3dc5f9c098f62315b4eddb Mon Sep 17 00:00:00 2001
From: CJ Cenizal
Date: Tue, 20 Mar 2018 20:19:42 -0700
Subject: [PATCH 3/6] Put comment back where it belongs. Fix EuiIconTip
example.
---
src-docs/src/views/tool_tip/icon_tip.js | 2 +-
.../popover/popover_calculate_position.js | 21 +++++++++----------
2 files changed, 11 insertions(+), 12 deletions(-)
diff --git a/src-docs/src/views/tool_tip/icon_tip.js b/src-docs/src/views/tool_tip/icon_tip.js
index e94c55bde76..1c40b4fbd10 100644
--- a/src-docs/src/views/tool_tip/icon_tip.js
+++ b/src-docs/src/views/tool_tip/icon_tip.js
@@ -10,7 +10,7 @@ import {
export default () => (
-
+
{
const { left, top, width, height } = bounds;
// This is a common algorithm for finding the intersected area among two rectangles.
@@ -45,6 +34,16 @@ const positionAtLeft = (anchorBounds, width, height, buffer) => {
return { left, top, width, height };
};
+/**
+ * Determine the best position for a popover that avoids clipping by the window view port.
+ *
+ * @param {native DOM Element} anchorBounds - getBoundingClientRect() of the node the popover is tethered to (e.g. a button).
+ * @param {native DOM Element} popoverBounds - getBoundingClientRect() of the popover node (e.g. the tooltip).
+ * @param {string} requestedPosition - Position the user wants. One of ["top", "right", "bottom", "left"]
+ * @param {number} buffer - The space between the wrapper and the popover. Also the minimum space between the popover and the window.
+ *
+ * @returns {string} One of ["top", "right", "bottom", "left"] that ensures the least amount of window overflow.
+ */
export function calculatePopoverPosition(anchorBounds, popoverBounds, requestedPosition, buffer = 16) {
const windowWidth = window.innerWidth;
const windowHeight = window.innerHeight;
From 2de8f3ee152e56f718acd432e2c50a2508f2d361 Mon Sep 17 00:00:00 2001
From: CJ Cenizal
Date: Tue, 20 Mar 2018 20:21:08 -0700
Subject: [PATCH 4/6] Rename popver_calculate_position to
calculate_popover_position.
---
...over_calculate_position.js => calculate_popover_position.js} | 0
src/services/popover/index.js | 2 +-
2 files changed, 1 insertion(+), 1 deletion(-)
rename src/services/popover/{popover_calculate_position.js => calculate_popover_position.js} (100%)
diff --git a/src/services/popover/popover_calculate_position.js b/src/services/popover/calculate_popover_position.js
similarity index 100%
rename from src/services/popover/popover_calculate_position.js
rename to src/services/popover/calculate_popover_position.js
diff --git a/src/services/popover/index.js b/src/services/popover/index.js
index 28fd6132873..5fc1aeb6ec1 100644
--- a/src/services/popover/index.js
+++ b/src/services/popover/index.js
@@ -1 +1 @@
-export { calculatePopoverPosition } from './popover_calculate_position';
+export { calculatePopoverPosition } from './calculate_popover_position';
From 18f56578c0e1b319bf2f70e5179bee0695277229 Mon Sep 17 00:00:00 2001
From: CJ Cenizal
Date: Tue, 20 Mar 2018 20:22:06 -0700
Subject: [PATCH 5/6] Update CHANGELOG.
---
CHANGELOG.md | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 658b1a768af..f3e1ee46211 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,10 @@
- Added `stop` and `stopFilled` icons ([#543](https://github.com/elastic/eui/pull/543))
+**Bug fixes**
+
+- Fix `EuiToolTip` smart positioning to prevent tooltip from being clipped by the window where possible ([#550]https://github.com/elastic/eui/pull/550)
+
# [`0.0.31`](https://github.com/elastic/eui/tree/v0.0.31)
- Made `` TypeScript types more specific ([#518](https://github.com/elastic/eui/pull/518))
From b72356fbf02392c560a0ecdeef14d2cae92c65d1 Mon Sep 17 00:00:00 2001
From: CJ Cenizal
Date: Tue, 20 Mar 2018 20:33:23 -0700
Subject: [PATCH 6/6] Clarify calculatePopoverPosition comments and use array
reduce() method.
---
.../popover/calculate_popover_position.js | 20 +++++++++----------
1 file changed, 9 insertions(+), 11 deletions(-)
diff --git a/src/services/popover/calculate_popover_position.js b/src/services/popover/calculate_popover_position.js
index bb60d0dcd39..00b824df525 100644
--- a/src/services/popover/calculate_popover_position.js
+++ b/src/services/popover/calculate_popover_position.js
@@ -37,12 +37,12 @@ const positionAtLeft = (anchorBounds, width, height, buffer) => {
/**
* Determine the best position for a popover that avoids clipping by the window view port.
*
- * @param {native DOM Element} anchorBounds - getBoundingClientRect() of the node the popover is tethered to (e.g. a button).
- * @param {native DOM Element} popoverBounds - getBoundingClientRect() of the popover node (e.g. the tooltip).
+ * @param {Object} anchorBounds - getBoundingClientRect() of the node the popover is tethered to (e.g. a button).
+ * @param {Object} popoverBounds - getBoundingClientRect() of the popover node (e.g. the tooltip).
* @param {string} requestedPosition - Position the user wants. One of ["top", "right", "bottom", "left"]
* @param {number} buffer - The space between the wrapper and the popover. Also the minimum space between the popover and the window.
*
- * @returns {string} One of ["top", "right", "bottom", "left"] that ensures the least amount of window overflow.
+ * @returns {Object} With properties position (one of ["top", "right", "bottom", "left"]), left, top, width, and height.
*/
export function calculatePopoverPosition(anchorBounds, popoverBounds, requestedPosition, buffer = 16) {
const windowWidth = window.innerWidth;
@@ -60,20 +60,18 @@ export function calculatePopoverPosition(anchorBounds, popoverBounds, requestedP
// Calculate how much area of the popover is visible at each position.
const positionToVisibleAreaMap = {};
-
positions.forEach((position) => {
positionToVisibleAreaMap[position] = getVisibleArea(positionToBoundsMap[position], windowWidth, windowHeight);
});
- // Default to use the requested position.
- let calculatedPopoverPosition = requestedPosition;
-
// If the requested position clips the popover, find the position which clips the popover the least.
- positions.forEach((position) => {
- if (positionToVisibleAreaMap[position] > positionToVisibleAreaMap[calculatedPopoverPosition]) {
- calculatedPopoverPosition = position;
+ // Default to use the requested position.
+ let calculatedPopoverPosition = positions.reduce((mostVisiblePosition, position) => {
+ if (positionToVisibleAreaMap[position] > positionToVisibleAreaMap[mostVisiblePosition]) {
+ return position;
}
- });
+ return mostVisiblePosition;
+ }, requestedPosition);
return {
position: calculatedPopoverPosition,