From 716060cca9a61f7f0ba5b10c70ed257e53ac21ba Mon Sep 17 00:00:00 2001 From: Ben Gelsey Date: Mon, 20 Mar 2017 19:09:00 +0800 Subject: [PATCH] Don't autofocus if the entire react-data-grid is offscreen --- packages/react-data-grid/src/Cell.js | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/packages/react-data-grid/src/Cell.js b/packages/react-data-grid/src/Cell.js index cd4a5fa21a..57d9df9cf0 100644 --- a/packages/react-data-grid/src/Cell.js +++ b/packages/react-data-grid/src/Cell.js @@ -348,7 +348,17 @@ const Cell = React.createClass({ return !this.isSelected() && this.isDraggedOver() && this.props.rowIdx > dragged.rowIdx; }, - isFocusedOnBody() { + isFocusedOnBody(dataGridDOMNode) { + // Make sure the table is on-screen + // http://stackoverflow.com/a/11193613 + const docViewTop = (window.pageYOffset !== undefined) ? window.pageYOffset : (document.documentElement || document.body.parentNode || document.body).scrollTop; + // http://stackoverflow.com/a/28241682 + const docViewBottom = docViewTop + (window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight); + + const elemTop = dataGridDOMNode.offsetTop; + const elemBottom = elemTop + dataGridDOMNode.offsetHeight; + + if (!((elemTop >= docViewTop && elemTop <= docViewBottom) || (elemBottom >= docViewTop && elemBottom <= docViewBottom))) return false; return document.activeElement == null || (document.activeElement.nodeName && typeof document.activeElement.nodeName === 'string' && document.activeElement.nodeName.toLowerCase() === 'body'); }, @@ -364,7 +374,7 @@ const Cell = React.createClass({ // Only focus to the current cell if the currently active node in the document is within the data grid. // Meaning focus should not be stolen from elements that the grid doesnt control. let dataGridDOMNode = this.props.cellMetaData && this.props.cellMetaData.getDataGridDOMNode ? this.props.cellMetaData.getDataGridDOMNode() : null; - if (this.isFocusedOnCell() || this.isFocusedOnBody() || (dataGridDOMNode && dataGridDOMNode.contains(document.activeElement))) { + if (this.isFocusedOnCell() || this.isFocusedOnBody(dataGridDOMNode) || (dataGridDOMNode && dataGridDOMNode.contains(document.activeElement))) { let cellDOMNode = ReactDOM.findDOMNode(this); if (cellDOMNode) { cellDOMNode.focus();