From f4616d82babba896199f1a8a5aa7c007febb1026 Mon Sep 17 00:00:00 2001 From: Anton Platonov Date: Fri, 25 Aug 2017 17:56:31 +0300 Subject: [PATCH] Keyboard navigation: fix horizontal scrolling --- vaadin-grid-keyboard-navigation-mixin.html | 54 +++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) diff --git a/vaadin-grid-keyboard-navigation-mixin.html b/vaadin-grid-keyboard-navigation-mixin.html index 88f83fce2..e35814573 100644 --- a/vaadin-grid-keyboard-navigation-mixin.html +++ b/vaadin-grid-keyboard-navigation-mixin.html @@ -41,6 +41,13 @@ this.addEventListener('focusin', this._onFocusIn); this.addEventListener('focusout', this._onFocusOut); this.addEventListener('cell-focus', this._onCellFocus); + + // Ensure horizontal scrolling when cell is focused, e.g., on tab key + this.$.table.addEventListener('focusin', (e) => { + if (e.composedPath().indexOf(this.$.table) === 3) { + this._scrollHorizontallyToCell(e.composedPath()[0]); + } + }); } _focusableChanged(focusable, oldFocusable) { @@ -211,13 +218,14 @@ dstRowIndex === rowIndex && dstIsRowDetails === isRowDetails) { // Navigation resulted in the same place, no action. + this._scrollHorizontallyToCell(activeCell); return; } else if (dstOrderedColumnIndex !== orderedColumnIndex) { // Horizontal movement invalidates stored _focusedColumnOrder this._focusedColumnOrder = undefined; } - // Ensure correct scroll position, destination row is visible + // Ensure correct vertical scroll position, destination row is visible if (activeRowGroup === this.$.items) { if (dstRowIndex <= this.firstVisibleIndex) { // Scroll up @@ -242,6 +250,7 @@ Array.from(dstRow.children) .filter(el => el.matches('[part~="details-cell"]'))[0] : dstRow.children[dstColumnIndex]; + this._scrollHorizontallyToCell(dstCell); this._focusCell(dstCell, activeRowGroup); } @@ -403,5 +412,48 @@ } cell.focus(); } + + _scrollHorizontallyToCell(dstCell) { + if (dstCell.hasAttribute('frozen') || dstCell.matches('[part~="details-cell"]')) { + // These cells are, by design, always visible, no need to scroll. + return; + } + + const dstCellRect = dstCell.getBoundingClientRect(); + const dstRow = dstCell.parentNode; + const dstCellIndex = Array.from(dstRow.children).indexOf(dstCell); + const tableRect = this.$.table.getBoundingClientRect(); + let leftBoundary = tableRect.left, + rightBoundary = tableRect.right; + for (let i = dstCellIndex - 1; i >= 0; i--) { + const cell = dstRow.children[i]; + if (cell.hasAttribute('hidden') || + cell.matches('[part~="details-cell"]')) { + continue; + } + if (cell.hasAttribute('frozen')) { + leftBoundary = cell.getBoundingClientRect().right; + break; + } + } + for (let i = dstCellIndex + 1; i < dstRow.children.length; i++) { + const cell = dstRow.children[i]; + if (cell.hasAttribute('hidden') || + cell.matches('[part~="details-cell"]')) { + continue; + } + if (cell.hasAttribute('frozen')) { + rightBoundary = cell.getBoundingClientRect().left; + break; + } + } + + if (dstCellRect.left < leftBoundary) { + this.$.table.scrollLeft += Math.round(dstCellRect.left - leftBoundary); + } + if (dstCellRect.right > rightBoundary) { + this.$.table.scrollLeft += Math.round(dstCellRect.right - rightBoundary); + } + } };