UNPKG

pragma-views2

Version:

282 lines (243 loc) 7.27 kB
import {BaseShortcuts} from "./base-shortcuts.js"; export class GridShortcuts extends BaseShortcuts { constructor(element) { super(); this._rowIndex = 0; this._columnIndex = 0; this._selectedItem = null; this._keyupHandler = this._keyup.bind(this); this._clickHandler = this._click.bind(this); this.element = element; this.element.addEventListener("keyup", this._keyupHandler); this.element.addEventListener("click", this._clickHandler); this.updateChildren(); } dispose() { super.dispose(); this.element.removeEventListener("click", this._clickHandler); this.element.removeEventListener("keyup", this._keyupHandler); this._clickHandler = null; this._keyupHandler = null; this.element = null; this._children = null; this._rowIndex = null; this._columnIndex = null; } /** * Click event handler * @param event * @private */ _click(event) { } /** * Ensures that the column and row index remain within bounds * @private */ _ensureBounds() { const nrOfRows = this._rows.length - 1; if (this._rowIndex < 0) { this._rowIndex = 0; } if (this._rowIndex > nrOfRows) { this._rowIndex = nrOfRows } const columns = this._getRowColumns(this._rowIndex); const nrOfColumns = columns.length - 1; if (this._columnIndex < 0) { this._columnIndex = 0; } if (this._columnIndex > nrOfColumns) { this._columnIndex = nrOfColumns; } } /** * Places focus on a given column within the grid * @private */ _focus() { const column = this._getColumn(this._rowIndex, this._columnIndex); if (column) { if (this._selectedItem != null) { this._blur(this._selectedItem); } column.classList.add("focus"); this.focus(column); this._selectedItem = column; } } /** * Removes focus from a column within the grid * @param element * @private */ _blur(element) { element.classList.remove("focus"); this.blur(element); } /** * Returns a column based on the row and column index * If the row is a grouped row, return the first column since there is only one * otherwise return the specific column index * @param rowIndex * @param columnIndex * @returns {*} * @private */ _getColumn(rowIndex, columnIndex) { const row = this._getRow(rowIndex); if (row != null) { const columns = this._getRowColumns(rowIndex); const grouped = this._isGroupedRow(row); if (grouped === true) { this._columnIndex = 0; return columns[0]; } else { return columns[columnIndex]; } } } /** * Returns the row at the specific index * @param index * @returns {*} * @private */ _getRow(index) { return this._rows[index]; } /** * Returns all the td elements for a row at a specific index * @param rowIndex * @returns {any[]} * @private */ _getRowColumns(rowIndex) { const row = this._getRow(rowIndex); if (row != null) { return Array.from(row.querySelectorAll("td")); } return []; } /** * Checks if a row is expanded * @param row * @returns {boolean} * @private */ _isExpanded(row) { return row.getAttribute("aria-expanded") === "true"; } /** * Checks if a row is a grouped row * @param row * @returns {*} * @private */ _isGroupedRow(row) { return row.classList.contains("grouped-row"); } /** * Keyup event handler * @param event * @private */ _keyup(event) { switch (event.keyCode) { case this.keyCodes.leftArrow: return this._leftArrowClicked(event); case this.keyCodes.rightArrow: return this._rightArrowClicked(event); case this.keyCodes.upArrow: this._rowIndex--; break; case this.keyCodes.downArrow: this._rowIndex++; break; case this.keyCodes.enter: this._enterClicked(); break; default: return; } this._ensureBounds(); this._focus(); } /** * Event handler for enter clicked * @private */ _enterClicked() { const row = this._getRow(this._rowIndex); if (row != null) { } } /** * If the row is grouped and expanded, collapse the group * If the row is not grouped, move to the previous column instead * @private */ _leftArrowClicked() { const row = this._getRow(this._rowIndex); if (row != null) { const grouped = this._isGroupedRow(row); const expanded = this._isExpanded(row); if (grouped === true) { if (expanded === true) { this._toggleRow(row); } } else { this._columnIndex--; this._ensureBounds(); this._focus(); } } } /** * If the row is grouped and not expanded, expand the row * Otherwise move to the next column * @private */ _rightArrowClicked() { const row = this._getRow(this._rowIndex); if (row != null) { const grouped = this._isGroupedRow(row); const expanded = this._isExpanded(row); if (grouped === true) { if (expanded === false) { this._toggleRow(row); } } else { this._columnIndex++; this._ensureBounds(); this._focus(); } } } /** * Invokes a click on the row item * @param row * @private */ _toggleRow(row) { const icon = row.querySelector("pragma-icon-button"); icon.click(); } /** * Sets focus to the first row and column */ initialise() { this._rowIndex = 0; this._columnIndex = 0; this._focus(); } /** * Update the visible children on the table */ updateChildren() { this._rows = Array.from(this.element.body.querySelectorAll("tr[aria-hidden='false']")); } }