fix(grid): restore keyboard focus after tab switches
This commit is contained in:
1 parent
ae87353a28
commit
8228c2af17
3 files changed
+142
-1
No files matched your search
@@ -214,6 +214,7 @@ import { useConnectionStore } from "@/stores/connectionStore";
|
||||
import { useQueryStore } from "@/stores/queryStore";
|
||||
import { useSettingsStore } from "@/stores/settingsStore";
|
||||
import { simpleDataGridOrderByMatchesSort, simpleDataGridOrderByReferencesMissingColumn, type DataGridSortDirection, type DataGridSortMode } from "@/lib/dataGrid/dataGridSort";
|
||||
import { resolveGridFocusRestoreTarget } from "@/lib/dataGrid/dataGridFocusRestore";
|
||||
import { buildOrderedGridRows, type GridInsertRowPosition, type GridNewRowPlacement } from "@/lib/dataGrid/gridNewRowPlacement";
|
||||
import {
|
||||
DATA_GRID_CONDITION_TOOLBAR_MIN_WIDTH,
|
||||
@@ -5414,6 +5415,8 @@ watch(
|
||||
function pauseCanvasGridWork() {
|
||||
dataGridIsActive = false;
|
||||
stopLoadingElapsedTimer();
|
||||
gridFocusActivationToken += 1;
|
||||
gridRef.value?.setAttribute("data-grid-active", "false");
|
||||
if (gridSurfaceBusy.value) finishDataGridNativeSelectionBlock(dataGridNativeSelectionBlockOwner);
|
||||
canvasRuntime.pause();
|
||||
gridScrollbarsRuntime.pause();
|
||||
@@ -5428,6 +5431,7 @@ function pauseCanvasGridWork() {
|
||||
function resumeCanvasGridWork() {
|
||||
dataGridIsActive = true;
|
||||
startLoadingElapsedTimer();
|
||||
gridRef.value?.setAttribute("data-grid-active", "true");
|
||||
if (gridSurfaceBusy.value) beginDataGridNativeSelectionBlock(dataGridNativeSelectionBlockOwner);
|
||||
canvasRuntime.resume();
|
||||
gridScrollbarsRuntime.resume();
|
||||
@@ -5443,6 +5447,30 @@ function clearInternalClipboardCopy() {
|
||||
clearDataGridClipboardCopy();
|
||||
}
|
||||
|
||||
// Remember the last element that held focus inside the grid. Switching to
|
||||
// another tab moves focus onto the tab strip (or body) and the kept-alive
|
||||
// grid never gets it back on its own, which breaks arrow-key cell navigation
|
||||
// after returning to the tab.
|
||||
let lastFocusedWithinGrid: HTMLElement | null = null;
|
||||
let gridFocusActivationToken = 0;
|
||||
|
||||
function onGridFocusIn(event: FocusEvent) {
|
||||
if (event.target instanceof HTMLElement) lastFocusedWithinGrid = event.target;
|
||||
}
|
||||
|
||||
function restoreGridFocusAfterActivation() {
|
||||
if (!lastFocusedWithinGrid) return;
|
||||
const activationToken = ++gridFocusActivationToken;
|
||||
nextTick(() => {
|
||||
if (!dataGridIsActive || activationToken !== gridFocusActivationToken) return;
|
||||
if (editingCell.value) return; // the cell editor restores its own input focus
|
||||
const target = resolveGridFocusRestoreTarget(gridRef.value, lastFocusedWithinGrid, document.activeElement);
|
||||
target?.focus({ preventScroll: true });
|
||||
});
|
||||
}
|
||||
|
||||
onActivated(restoreGridFocusAfterActivation);
|
||||
|
||||
onMounted(resumeCanvasGridWork);
|
||||
onActivated(resumeCanvasGridWork);
|
||||
onMounted(() => {
|
||||
@@ -8426,7 +8454,18 @@ const gridContextMenuItems = computed<ContextMenuItem[]>(() => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div ref="gridRef" data-grid-root class="h-full flex flex-col overflow-hidden outline-none" :class="{ 'data-grid--editing-cell': !!editingCell, 'data-grid--dark': isDark }" :style="gridStyle" tabindex="0" @keydown="onGridKeydown" @paste="onGridPaste">
|
||||
<div
|
||||
ref="gridRef"
|
||||
data-grid-root
|
||||
data-grid-active="true"
|
||||
class="h-full flex flex-col overflow-hidden outline-none"
|
||||
:class="{ 'data-grid--editing-cell': !!editingCell, 'data-grid--dark': isDark }"
|
||||
:style="gridStyle"
|
||||
tabindex="0"
|
||||
@keydown="onGridKeydown"
|
||||
@paste="onGridPaste"
|
||||
@focusin="onGridFocusIn"
|
||||
>
|
||||
<CustomContextMenu :items="gridContextMenuItems" v-slot="{ onContextMenu }">
|
||||
<div v-if="hasData || canShowWhereSearch" class="flex-1 flex flex-col overflow-hidden" @contextmenu="onContextMenu">
|
||||
<!-- Search bar -->
|
||||
|
||||
Reference in new issue
Block a user