@cloudscape-design/components 3.0.562 → 3.0.564

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
1
  export var PACKAGE_SOURCE = "components";
2
- export var PACKAGE_VERSION = "3.0.0 (b78509b5)";
2
+ export var PACKAGE_VERSION = "3.0.0 (70058014)";
3
3
  export var THEME = "open-source-visual-refresh";
4
4
  export var ALWAYS_VISUAL_REFRESH = true;
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "PACKAGE_SOURCE": "components",
3
- "PACKAGE_VERSION": "3.0.0 (b78509b5)",
3
+ "PACKAGE_VERSION": "3.0.0 (70058014)",
4
4
  "THEME": "default",
5
5
  "ALWAYS_VISUAL_REFRESH": false
6
6
  }
@@ -1,3 +1,3 @@
1
1
  {
2
- "commit": "b78509b5300294516d90d344afc6f654d61159b9"
2
+ "commit": "70058014b0c2f4fe95a6cb98b93fc94581478825"
3
3
  }
package/package.json CHANGED
@@ -116,7 +116,7 @@
116
116
  "./internal/base-component/index.js",
117
117
  "./internal/base-component/styles.css.js"
118
118
  ],
119
- "version": "3.0.562",
119
+ "version": "3.0.564",
120
120
  "repository": {
121
121
  "type": "git",
122
122
  "url": "https://github.com/cloudscape-design/components.git"
@@ -51,6 +51,7 @@ class GridNavigationProcessor {
51
51
  this._table = null;
52
52
  // State
53
53
  this.focusedCell = null;
54
+ this.keepUserIndex = false;
54
55
  this.focusables = new Set();
55
56
  this.focusHandlers = new Map();
56
57
  this.focusablesState = new WeakMap();
@@ -72,7 +73,6 @@ class GridNavigationProcessor {
72
73
  this.focusHandlers.delete(focusable);
73
74
  };
74
75
  this.onFocusin = (event) => {
75
- var _a;
76
76
  if (!(event.target instanceof HTMLElement)) {
77
77
  return;
78
78
  }
@@ -84,8 +84,12 @@ class GridNavigationProcessor {
84
84
  // Focusing on cell is not eligible when it contains focusable elements in the content.
85
85
  // If content focusables are available - move the focus to the first one.
86
86
  const cellElement = getClosestCell(this.focusedCell.element);
87
- if (this.focusedCell.element === cellElement) {
88
- (_a = this.getFocusablesFrom(cellElement)[0]) === null || _a === void 0 ? void 0 : _a.focus();
87
+ const nextTarget = this.focusedCell.element === cellElement ? this.getFocusablesFrom(cellElement)[0] : null;
88
+ if (nextTarget) {
89
+ nextTarget.focus();
90
+ }
91
+ else {
92
+ this.keepUserIndex = false;
89
93
  }
90
94
  };
91
95
  this.onFocusout = () => {
@@ -194,6 +198,11 @@ class GridNavigationProcessor {
194
198
  }
195
199
  moveFocusBy(cell, delta) {
196
200
  var _a;
201
+ // For vertical moves preserve column- and element indices set by user.
202
+ // It allows keeping indices while moving over disabled actions or cells with colspan > 1.
203
+ if (delta.y !== 0 && delta.x === 0) {
204
+ this.keepUserIndex = true;
205
+ }
197
206
  (_a = this.getNextFocusable(cell, delta)) === null || _a === void 0 ? void 0 : _a.focus();
198
207
  }
199
208
  updateFocusTarget() {
@@ -219,7 +228,7 @@ class GridNavigationProcessor {
219
228
  return !element || this.focusables.has(element);
220
229
  }
221
230
  updateFocusedCell(focusedElement) {
222
- var _a, _b;
231
+ var _a, _b, _c, _d, _e, _f;
223
232
  if (!focusedElement) {
224
233
  return;
225
234
  }
@@ -235,7 +244,14 @@ class GridNavigationProcessor {
235
244
  }
236
245
  const cellFocusables = this.getFocusablesFrom(cellElement);
237
246
  const elementIndex = cellFocusables.indexOf(focusedElement);
238
- this.focusedCell = { rowIndex, colIndex, element: focusedElement, elementIndex };
247
+ const prevColIndex = (_d = (_c = this.focusedCell) === null || _c === void 0 ? void 0 : _c.colIndex) !== null && _d !== void 0 ? _d : -1;
248
+ const prevElementIndex = (_f = (_e = this.focusedCell) === null || _e === void 0 ? void 0 : _e.elementIndex) !== null && _f !== void 0 ? _f : -1;
249
+ this.focusedCell = {
250
+ rowIndex,
251
+ colIndex: this.keepUserIndex && prevColIndex !== -1 ? prevColIndex : colIndex,
252
+ elementIndex: this.keepUserIndex && prevElementIndex !== -1 ? prevElementIndex : elementIndex,
253
+ element: focusedElement,
254
+ };
239
255
  }
240
256
  getNextFocusable(from, delta) {
241
257
  var _a;
@@ -1 +1 @@
1
- {"version":3,"file":"grid-navigation.js","sourceRoot":"","sources":["../../../../src/table/table-role/grid-navigation.tsx"],"names":[],"mappings":"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","sourcesContent":["// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport React from 'react';\nimport { useEffect, useMemo } from 'react';\nimport {\n defaultIsSuppressed,\n findTableRowByAriaRowIndex,\n findTableRowCellByAriaColIndex,\n getClosestCell,\n isElementDisabled,\n} from './utils';\nimport { FocusedCell, GridNavigationProps } from './interfaces';\nimport { KeyCode } from '../../internal/keycode';\nimport { useStableCallback } from '@cloudscape-design/component-toolkit/internal';\nimport { nodeBelongs } from '../../internal/utils/node-belongs';\nimport { getAllFocusables } from '../../internal/components/focus-lock/utils';\nimport {\n SingleTabStopNavigationContext,\n FocusableChangeHandler,\n} from '../../internal/context/single-tab-stop-navigation-context';\n\n/**\n * Makes table navigable with keyboard commands.\n * See grid-navigation.md\n */\nexport function GridNavigationProvider({ keyboardNavigation, pageSize, getTable, children }: GridNavigationProps) {\n const gridNavigation = useMemo(() => new GridNavigationProcessor(), []);\n\n const getTableStable = useStableCallback(getTable);\n\n // Initialize the processor with the table container assuming it is mounted synchronously and only once.\n useEffect(() => {\n if (keyboardNavigation) {\n const table = getTableStable();\n table && gridNavigation.init(table);\n }\n return () => gridNavigation.cleanup();\n }, [keyboardNavigation, gridNavigation, getTableStable]);\n\n // Notify the processor of the props change.\n useEffect(() => {\n gridNavigation.update({ pageSize });\n }, [gridNavigation, pageSize]);\n\n // Notify the processor of the new render.\n useEffect(() => {\n if (keyboardNavigation) {\n gridNavigation.refresh();\n }\n });\n\n return (\n <SingleTabStopNavigationContext.Provider\n value={{\n navigationActive: keyboardNavigation,\n registerFocusable: gridNavigation.registerFocusable,\n }}\n >\n {children}\n </SingleTabStopNavigationContext.Provider>\n );\n}\n\n/**\n * This helper encapsulates the grid navigation behaviors which are:\n * 1. Responding to keyboard commands and moving the focus accordingly;\n * 2. Muting table interactive elements for only one to be user-focusable at a time;\n * 3. Suppressing the above behaviors when focusing an element inside a dialog or when instructed explicitly.\n */\nclass GridNavigationProcessor {\n // Props\n private _pageSize = 0;\n private _table: null | HTMLTableElement = null;\n\n // State\n private focusedCell: null | FocusedCell = null;\n private focusables = new Set<Element>();\n private focusHandlers = new Map<Element, FocusableChangeHandler>();\n private focusablesState = new WeakMap<Element, boolean>();\n private focusTarget: null | Element = null;\n\n public init(table: HTMLTableElement) {\n this._table = table;\n\n this.table.addEventListener('focusin', this.onFocusin);\n this.table.addEventListener('focusout', this.onFocusout);\n this.table.addEventListener('keydown', this.onKeydown);\n\n this.updateFocusTarget();\n\n this.cleanup = () => {\n this.table.removeEventListener('focusin', this.onFocusin);\n this.table.removeEventListener('focusout', this.onFocusout);\n this.table.removeEventListener('keydown', this.onKeydown);\n this.focusables.forEach(this.unregisterFocusable);\n };\n }\n\n public cleanup() {\n // Do nothing before initialized.\n }\n\n public update({ pageSize }: { pageSize: number }) {\n this._pageSize = pageSize;\n }\n\n public refresh() {\n // Timeout ensures the newly rendered content elements are registered.\n setTimeout(() => {\n if (this._table) {\n // Update focused cell indices in case table rows, columns, or firstIndex change.\n this.updateFocusedCell(this.focusedCell?.element);\n this.updateFocusTarget();\n }\n }, 0);\n }\n\n public registerFocusable = (focusableElement: Element, changeHandler: FocusableChangeHandler) => {\n this.focusables.add(focusableElement);\n this.focusHandlers.set(focusableElement, changeHandler);\n const isFocusable = this.focusablesState.get(focusableElement) ?? false;\n const newIsFocusable = this.focusTarget === focusableElement || this.isSuppressed(focusableElement);\n if (newIsFocusable !== isFocusable) {\n this.focusablesState.set(focusableElement, newIsFocusable);\n changeHandler(newIsFocusable);\n }\n return () => this.unregisterFocusable(focusableElement);\n };\n\n public unregisterFocusable = (focusable: Element) => {\n this.focusables.delete(focusable);\n this.focusHandlers.delete(focusable);\n };\n\n private get pageSize() {\n return this._pageSize;\n }\n\n private get table(): HTMLTableElement {\n if (!this._table) {\n throw new Error('Invariant violation: GridNavigationProcessor is used before initialization.');\n }\n return this._table;\n }\n\n private onFocusin = (event: FocusEvent) => {\n if (!(event.target instanceof HTMLElement)) {\n return;\n }\n\n this.updateFocusedCell(event.target);\n if (!this.focusedCell) {\n return;\n }\n\n this.updateFocusTarget();\n\n // Focusing on cell is not eligible when it contains focusable elements in the content.\n // If content focusables are available - move the focus to the first one.\n const cellElement = getClosestCell(this.focusedCell.element);\n if (this.focusedCell.element === cellElement) {\n this.getFocusablesFrom(cellElement)[0]?.focus();\n }\n };\n\n private onFocusout = () => {\n // When focus leaves the cell and the cell no longer belong to the table it indicates the focused element has been unmounted.\n // In that case the focus needs to be restored on the same coordinates.\n setTimeout(() => {\n if (this.focusedCell && !nodeBelongs(this.table, this.focusedCell.element)) {\n this.moveFocusBy(this.focusedCell, { x: 0, y: 0 });\n }\n }, 0);\n };\n\n private onKeydown = (event: KeyboardEvent) => {\n if (!this.focusedCell) {\n return;\n }\n\n const ctrlKey = event.ctrlKey ? 1 : 0;\n const altKey = event.altKey ? 1 : 0;\n const shiftKey = event.shiftKey ? 1 : 0;\n const metaKey = event.metaKey ? 1 : 0;\n const numModifiersPressed = ctrlKey + altKey + shiftKey + metaKey;\n\n let key = event.keyCode;\n if (numModifiersPressed === 1 && event.ctrlKey) {\n key = -key;\n } else if (numModifiersPressed) {\n return;\n }\n\n const from = this.focusedCell;\n\n if (this.isSuppressed(document.activeElement) || !this.isRegistered(document.activeElement)) {\n return;\n }\n\n switch (key) {\n case KeyCode.up:\n event.preventDefault();\n return this.moveFocusBy(from, { y: -1, x: 0 });\n\n case KeyCode.down:\n event.preventDefault();\n return this.moveFocusBy(from, { y: 1, x: 0 });\n\n case KeyCode.left:\n event.preventDefault();\n return this.moveFocusBy(from, { y: 0, x: -1 });\n\n case KeyCode.right:\n event.preventDefault();\n return this.moveFocusBy(from, { y: 0, x: 1 });\n\n case KeyCode.pageUp:\n event.preventDefault();\n return this.moveFocusBy(from, { y: -this.pageSize, x: 0 });\n\n case KeyCode.pageDown:\n event.preventDefault();\n return this.moveFocusBy(from, { y: this.pageSize, x: 0 });\n\n case KeyCode.home:\n event.preventDefault();\n return this.moveFocusBy(from, { y: 0, x: -Infinity });\n\n case KeyCode.end:\n event.preventDefault();\n return this.moveFocusBy(from, { y: 0, x: Infinity });\n\n case -KeyCode.home:\n event.preventDefault();\n return this.moveFocusBy(from, { y: -Infinity, x: -Infinity });\n\n case -KeyCode.end:\n event.preventDefault();\n return this.moveFocusBy(from, { y: Infinity, x: Infinity });\n\n default:\n return;\n }\n };\n\n private moveFocusBy(cell: FocusedCell, delta: { x: number; y: number }) {\n this.getNextFocusable(cell, delta)?.focus();\n }\n\n private updateFocusTarget() {\n this.focusTarget = this.getSingleFocusable();\n for (const focusableElement of this.focusables) {\n const isFocusable = this.focusablesState.get(focusableElement) ?? false;\n const newIsFocusable = this.focusTarget === focusableElement || this.isSuppressed(focusableElement);\n if (newIsFocusable !== isFocusable) {\n this.focusablesState.set(focusableElement, newIsFocusable);\n this.focusHandlers.get(focusableElement)!(newIsFocusable);\n }\n }\n }\n\n private isSuppressed(element: null | Element) {\n // Omit calculation as irrelevant until the table receives focus.\n if (!this.focusedCell) {\n return false;\n }\n return !element || defaultIsSuppressed(element);\n }\n\n private isRegistered(element: null | Element) {\n return !element || this.focusables.has(element);\n }\n\n private updateFocusedCell(focusedElement?: HTMLElement): void {\n if (!focusedElement) {\n return;\n }\n\n const cellElement = getClosestCell(focusedElement);\n const rowElement = cellElement?.closest('tr');\n if (!cellElement || !rowElement) {\n return;\n }\n\n const colIndex = parseInt(cellElement.getAttribute('aria-colindex') ?? '');\n const rowIndex = parseInt(rowElement.getAttribute('aria-rowindex') ?? '');\n if (isNaN(colIndex) || isNaN(rowIndex)) {\n return;\n }\n\n const cellFocusables = this.getFocusablesFrom(cellElement);\n const elementIndex = cellFocusables.indexOf(focusedElement);\n this.focusedCell = { rowIndex, colIndex, element: focusedElement, elementIndex };\n }\n\n private getNextFocusable(from: FocusedCell, delta: { y: number; x: number }) {\n // Find next row to move focus into (can be null if the top/bottom is reached).\n const targetAriaRowIndex = from.rowIndex + delta.y;\n const targetRow = findTableRowByAriaRowIndex(this.table, targetAriaRowIndex, delta.y);\n if (!targetRow) {\n return null;\n }\n\n // Return next interactive cell content element if available.\n const cellElement = getClosestCell(from.element);\n const cellFocusables = cellElement ? this.getFocusablesFrom(cellElement) : [];\n const nextElementIndex = from.elementIndex + delta.x;\n if (delta.x && from.elementIndex !== -1 && 0 <= nextElementIndex && nextElementIndex < cellFocusables.length) {\n return cellFocusables[nextElementIndex];\n }\n\n // Find next cell to focus or move focus into (can be null if the left/right edge is reached).\n const targetAriaColIndex = from.colIndex + delta.x;\n const targetCell = findTableRowCellByAriaColIndex(targetRow, targetAriaColIndex, delta.x);\n if (!targetCell) {\n return null;\n }\n\n // When target cell matches the current cell it means we reached the left or right boundary.\n if (targetCell === cellElement && delta.x !== 0) {\n return null;\n }\n\n const targetCellFocusables = this.getFocusablesFrom(targetCell);\n\n // When delta.x = 0 keep element index if possible.\n let focusIndex = from.elementIndex;\n // Use first element index when moving to the right or to extreme left.\n if ((isFinite(delta.x) && delta.x > 0) || delta.x === -Infinity) {\n focusIndex = 0;\n }\n // Use last element index when moving to the left or to extreme right.\n if ((isFinite(delta.x) && delta.x < 0) || delta.x === Infinity) {\n focusIndex = targetCellFocusables.length - 1;\n }\n\n return targetCellFocusables[focusIndex] ?? targetCell;\n }\n\n private getSingleFocusable() {\n const cell = this.focusedCell;\n const firstTableCell = this.table.querySelector('td,th') as null | HTMLTableCellElement;\n\n // A single element of the table is made user-focusable.\n // It defaults to the first interactive element of the first cell or the first cell itself otherwise.\n let focusTarget: null | HTMLElement =\n (firstTableCell && this.getFocusablesFrom(firstTableCell)[0]) ?? firstTableCell;\n\n // When a navigation-focused element is present in the table it is used for user-navigation instead.\n if (cell) {\n focusTarget = this.getNextFocusable(cell, { x: 0, y: 0 });\n }\n\n return focusTarget;\n }\n\n private getFocusablesFrom(target: HTMLElement) {\n return getAllFocusables(target).filter(el => this.focusables.has(el) && !isElementDisabled(el));\n }\n}\n"]}
1
+ {"version":3,"file":"grid-navigation.js","sourceRoot":"","sources":["../../../../src/table/table-role/grid-navigation.tsx"],"names":[],"mappings":"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","sourcesContent":["// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport React from 'react';\nimport { useEffect, useMemo } from 'react';\nimport {\n defaultIsSuppressed,\n findTableRowByAriaRowIndex,\n findTableRowCellByAriaColIndex,\n getClosestCell,\n isElementDisabled,\n} from './utils';\nimport { FocusedCell, GridNavigationProps } from './interfaces';\nimport { KeyCode } from '../../internal/keycode';\nimport { useStableCallback } from '@cloudscape-design/component-toolkit/internal';\nimport { nodeBelongs } from '../../internal/utils/node-belongs';\nimport { getAllFocusables } from '../../internal/components/focus-lock/utils';\nimport {\n SingleTabStopNavigationContext,\n FocusableChangeHandler,\n} from '../../internal/context/single-tab-stop-navigation-context';\n\n/**\n * Makes table navigable with keyboard commands.\n * See grid-navigation.md\n */\nexport function GridNavigationProvider({ keyboardNavigation, pageSize, getTable, children }: GridNavigationProps) {\n const gridNavigation = useMemo(() => new GridNavigationProcessor(), []);\n\n const getTableStable = useStableCallback(getTable);\n\n // Initialize the processor with the table container assuming it is mounted synchronously and only once.\n useEffect(() => {\n if (keyboardNavigation) {\n const table = getTableStable();\n table && gridNavigation.init(table);\n }\n return () => gridNavigation.cleanup();\n }, [keyboardNavigation, gridNavigation, getTableStable]);\n\n // Notify the processor of the props change.\n useEffect(() => {\n gridNavigation.update({ pageSize });\n }, [gridNavigation, pageSize]);\n\n // Notify the processor of the new render.\n useEffect(() => {\n if (keyboardNavigation) {\n gridNavigation.refresh();\n }\n });\n\n return (\n <SingleTabStopNavigationContext.Provider\n value={{\n navigationActive: keyboardNavigation,\n registerFocusable: gridNavigation.registerFocusable,\n }}\n >\n {children}\n </SingleTabStopNavigationContext.Provider>\n );\n}\n\n/**\n * This helper encapsulates the grid navigation behaviors which are:\n * 1. Responding to keyboard commands and moving the focus accordingly;\n * 2. Muting table interactive elements for only one to be user-focusable at a time;\n * 3. Suppressing the above behaviors when focusing an element inside a dialog or when instructed explicitly.\n */\nclass GridNavigationProcessor {\n // Props\n private _pageSize = 0;\n private _table: null | HTMLTableElement = null;\n\n // State\n private focusedCell: null | FocusedCell = null;\n private keepUserIndex = false;\n private focusables = new Set<Element>();\n private focusHandlers = new Map<Element, FocusableChangeHandler>();\n private focusablesState = new WeakMap<Element, boolean>();\n private focusTarget: null | Element = null;\n\n public init(table: HTMLTableElement) {\n this._table = table;\n\n this.table.addEventListener('focusin', this.onFocusin);\n this.table.addEventListener('focusout', this.onFocusout);\n this.table.addEventListener('keydown', this.onKeydown);\n\n this.updateFocusTarget();\n\n this.cleanup = () => {\n this.table.removeEventListener('focusin', this.onFocusin);\n this.table.removeEventListener('focusout', this.onFocusout);\n this.table.removeEventListener('keydown', this.onKeydown);\n this.focusables.forEach(this.unregisterFocusable);\n };\n }\n\n public cleanup() {\n // Do nothing before initialized.\n }\n\n public update({ pageSize }: { pageSize: number }) {\n this._pageSize = pageSize;\n }\n\n public refresh() {\n // Timeout ensures the newly rendered content elements are registered.\n setTimeout(() => {\n if (this._table) {\n // Update focused cell indices in case table rows, columns, or firstIndex change.\n this.updateFocusedCell(this.focusedCell?.element);\n this.updateFocusTarget();\n }\n }, 0);\n }\n\n public registerFocusable = (focusableElement: Element, changeHandler: FocusableChangeHandler) => {\n this.focusables.add(focusableElement);\n this.focusHandlers.set(focusableElement, changeHandler);\n const isFocusable = this.focusablesState.get(focusableElement) ?? false;\n const newIsFocusable = this.focusTarget === focusableElement || this.isSuppressed(focusableElement);\n if (newIsFocusable !== isFocusable) {\n this.focusablesState.set(focusableElement, newIsFocusable);\n changeHandler(newIsFocusable);\n }\n return () => this.unregisterFocusable(focusableElement);\n };\n\n public unregisterFocusable = (focusable: Element) => {\n this.focusables.delete(focusable);\n this.focusHandlers.delete(focusable);\n };\n\n private get pageSize() {\n return this._pageSize;\n }\n\n private get table(): HTMLTableElement {\n if (!this._table) {\n throw new Error('Invariant violation: GridNavigationProcessor is used before initialization.');\n }\n return this._table;\n }\n\n private onFocusin = (event: FocusEvent) => {\n if (!(event.target instanceof HTMLElement)) {\n return;\n }\n\n this.updateFocusedCell(event.target);\n if (!this.focusedCell) {\n return;\n }\n\n this.updateFocusTarget();\n\n // Focusing on cell is not eligible when it contains focusable elements in the content.\n // If content focusables are available - move the focus to the first one.\n const cellElement = getClosestCell(this.focusedCell.element);\n const nextTarget = this.focusedCell.element === cellElement ? this.getFocusablesFrom(cellElement)[0] : null;\n if (nextTarget) {\n nextTarget.focus();\n } else {\n this.keepUserIndex = false;\n }\n };\n\n private onFocusout = () => {\n // When focus leaves the cell and the cell no longer belong to the table it indicates the focused element has been unmounted.\n // In that case the focus needs to be restored on the same coordinates.\n setTimeout(() => {\n if (this.focusedCell && !nodeBelongs(this.table, this.focusedCell.element)) {\n this.moveFocusBy(this.focusedCell, { x: 0, y: 0 });\n }\n }, 0);\n };\n\n private onKeydown = (event: KeyboardEvent) => {\n if (!this.focusedCell) {\n return;\n }\n\n const ctrlKey = event.ctrlKey ? 1 : 0;\n const altKey = event.altKey ? 1 : 0;\n const shiftKey = event.shiftKey ? 1 : 0;\n const metaKey = event.metaKey ? 1 : 0;\n const numModifiersPressed = ctrlKey + altKey + shiftKey + metaKey;\n\n let key = event.keyCode;\n if (numModifiersPressed === 1 && event.ctrlKey) {\n key = -key;\n } else if (numModifiersPressed) {\n return;\n }\n\n const from = this.focusedCell;\n\n if (this.isSuppressed(document.activeElement) || !this.isRegistered(document.activeElement)) {\n return;\n }\n\n switch (key) {\n case KeyCode.up:\n event.preventDefault();\n return this.moveFocusBy(from, { y: -1, x: 0 });\n\n case KeyCode.down:\n event.preventDefault();\n return this.moveFocusBy(from, { y: 1, x: 0 });\n\n case KeyCode.left:\n event.preventDefault();\n return this.moveFocusBy(from, { y: 0, x: -1 });\n\n case KeyCode.right:\n event.preventDefault();\n return this.moveFocusBy(from, { y: 0, x: 1 });\n\n case KeyCode.pageUp:\n event.preventDefault();\n return this.moveFocusBy(from, { y: -this.pageSize, x: 0 });\n\n case KeyCode.pageDown:\n event.preventDefault();\n return this.moveFocusBy(from, { y: this.pageSize, x: 0 });\n\n case KeyCode.home:\n event.preventDefault();\n return this.moveFocusBy(from, { y: 0, x: -Infinity });\n\n case KeyCode.end:\n event.preventDefault();\n return this.moveFocusBy(from, { y: 0, x: Infinity });\n\n case -KeyCode.home:\n event.preventDefault();\n return this.moveFocusBy(from, { y: -Infinity, x: -Infinity });\n\n case -KeyCode.end:\n event.preventDefault();\n return this.moveFocusBy(from, { y: Infinity, x: Infinity });\n\n default:\n return;\n }\n };\n\n private moveFocusBy(cell: FocusedCell, delta: { x: number; y: number }) {\n // For vertical moves preserve column- and element indices set by user.\n // It allows keeping indices while moving over disabled actions or cells with colspan > 1.\n if (delta.y !== 0 && delta.x === 0) {\n this.keepUserIndex = true;\n }\n this.getNextFocusable(cell, delta)?.focus();\n }\n\n private updateFocusTarget() {\n this.focusTarget = this.getSingleFocusable();\n for (const focusableElement of this.focusables) {\n const isFocusable = this.focusablesState.get(focusableElement) ?? false;\n const newIsFocusable = this.focusTarget === focusableElement || this.isSuppressed(focusableElement);\n if (newIsFocusable !== isFocusable) {\n this.focusablesState.set(focusableElement, newIsFocusable);\n this.focusHandlers.get(focusableElement)!(newIsFocusable);\n }\n }\n }\n\n private isSuppressed(element: null | Element) {\n // Omit calculation as irrelevant until the table receives focus.\n if (!this.focusedCell) {\n return false;\n }\n return !element || defaultIsSuppressed(element);\n }\n\n private isRegistered(element: null | Element) {\n return !element || this.focusables.has(element);\n }\n\n private updateFocusedCell(focusedElement?: HTMLElement): void {\n if (!focusedElement) {\n return;\n }\n\n const cellElement = getClosestCell(focusedElement);\n const rowElement = cellElement?.closest('tr');\n if (!cellElement || !rowElement) {\n return;\n }\n\n const colIndex = parseInt(cellElement.getAttribute('aria-colindex') ?? '');\n const rowIndex = parseInt(rowElement.getAttribute('aria-rowindex') ?? '');\n if (isNaN(colIndex) || isNaN(rowIndex)) {\n return;\n }\n\n const cellFocusables = this.getFocusablesFrom(cellElement);\n const elementIndex = cellFocusables.indexOf(focusedElement);\n\n const prevColIndex = this.focusedCell?.colIndex ?? -1;\n const prevElementIndex = this.focusedCell?.elementIndex ?? -1;\n this.focusedCell = {\n rowIndex,\n colIndex: this.keepUserIndex && prevColIndex !== -1 ? prevColIndex : colIndex,\n elementIndex: this.keepUserIndex && prevElementIndex !== -1 ? prevElementIndex : elementIndex,\n element: focusedElement,\n };\n }\n\n private getNextFocusable(from: FocusedCell, delta: { y: number; x: number }) {\n // Find next row to move focus into (can be null if the top/bottom is reached).\n const targetAriaRowIndex = from.rowIndex + delta.y;\n const targetRow = findTableRowByAriaRowIndex(this.table, targetAriaRowIndex, delta.y);\n if (!targetRow) {\n return null;\n }\n\n // Return next interactive cell content element if available.\n const cellElement = getClosestCell(from.element);\n const cellFocusables = cellElement ? this.getFocusablesFrom(cellElement) : [];\n const nextElementIndex = from.elementIndex + delta.x;\n if (delta.x && from.elementIndex !== -1 && 0 <= nextElementIndex && nextElementIndex < cellFocusables.length) {\n return cellFocusables[nextElementIndex];\n }\n\n // Find next cell to focus or move focus into (can be null if the left/right edge is reached).\n const targetAriaColIndex = from.colIndex + delta.x;\n const targetCell = findTableRowCellByAriaColIndex(targetRow, targetAriaColIndex, delta.x);\n if (!targetCell) {\n return null;\n }\n\n // When target cell matches the current cell it means we reached the left or right boundary.\n if (targetCell === cellElement && delta.x !== 0) {\n return null;\n }\n\n const targetCellFocusables = this.getFocusablesFrom(targetCell);\n\n // When delta.x = 0 keep element index if possible.\n let focusIndex = from.elementIndex;\n // Use first element index when moving to the right or to extreme left.\n if ((isFinite(delta.x) && delta.x > 0) || delta.x === -Infinity) {\n focusIndex = 0;\n }\n // Use last element index when moving to the left or to extreme right.\n if ((isFinite(delta.x) && delta.x < 0) || delta.x === Infinity) {\n focusIndex = targetCellFocusables.length - 1;\n }\n\n return targetCellFocusables[focusIndex] ?? targetCell;\n }\n\n private getSingleFocusable() {\n const cell = this.focusedCell;\n const firstTableCell = this.table.querySelector('td,th') as null | HTMLTableCellElement;\n\n // A single element of the table is made user-focusable.\n // It defaults to the first interactive element of the first cell or the first cell itself otherwise.\n let focusTarget: null | HTMLElement =\n (firstTableCell && this.getFocusablesFrom(firstTableCell)[0]) ?? firstTableCell;\n\n // When a navigation-focused element is present in the table it is used for user-navigation instead.\n if (cell) {\n focusTarget = this.getNextFocusable(cell, { x: 0, y: 0 });\n }\n\n return focusTarget;\n }\n\n private getFocusablesFrom(target: HTMLElement) {\n return getAllFocusables(target).filter(el => this.focusables.has(el) && !isElementDisabled(el));\n }\n}\n"]}