From 3f64e830f8d39d5b3e04a990bfb716e692e5d9a3 Mon Sep 17 00:00:00 2001 From: t8y2 <1156263951@qq.com> Date: Thu, 28 May 2026 19:03:21 +0800 Subject: [PATCH] fix(grid): show cell highlight for row multi-select --- apps/desktop/src/components/grid/DataGrid.vue | 22 +++++++++++++++++++ .../dataGridSelectionShortcuts.test.ts | 9 ++++++++ 2 files changed, 31 insertions(+) diff --git a/apps/desktop/src/components/grid/DataGrid.vue b/apps/desktop/src/components/grid/DataGrid.vue index 4f4bc9cf0a..72a928a742 100644 --- a/apps/desktop/src/components/grid/DataGrid.vue +++ b/apps/desktop/src/components/grid/DataGrid.vue @@ -2572,6 +2572,10 @@ function rowNumberStatusClass(item: RowItem): string { return "text-muted-foreground"; } +function rowCellsUseSelectionVisual(rowId: number): boolean { + return hasRowSelection.value && isRowSelected(rowId) && !hasCellSelection.value; +} + function setRowStatusFilter(value: string) { rowStatusFilter.value = value as RowStatusFilter; } @@ -5037,6 +5041,14 @@ const gridContextMenuItems = computed(() => { cellIsSelected(item.displayIndex, visibleColIdx) && !item.isDirtyCol[actualColIdx], 'cell-selected-dirty': cellIsSelected(item.displayIndex, visibleColIdx) && item.isDirtyCol[actualColIdx], + 'row-cell-selected': + rowCellsUseSelectionVisual(item.id) && + !cellIsSelected(item.displayIndex, visibleColIdx) && + !item.isDirtyCol[actualColIdx], + 'row-cell-selected-dirty': + rowCellsUseSelectionVisual(item.id) && + !cellIsSelected(item.displayIndex, visibleColIdx) && + item.isDirtyCol[actualColIdx], 'bg-yellow-200/60 dark:bg-yellow-500/20': cellIsSearchMatch(item.displayIndex, actualColIdx), 'ring-2 ring-inset ring-yellow-500 bg-yellow-300/60 dark:bg-yellow-500/40': cellIsCurrentMatch( item.displayIndex, @@ -5734,11 +5746,21 @@ const gridContextMenuItems = computed(() => { box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--primary) 70%, transparent); } +.row-cell-selected { + background-color: color-mix(in oklab, var(--primary) 25%, transparent); + box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--primary) 70%, transparent); +} + .cell-selected-dirty { background-color: color-mix(in oklab, oklch(0.8 0.15 85) 30%, color-mix(in oklab, var(--primary) 18%, transparent)); box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--primary) 70%, transparent); } +.row-cell-selected-dirty { + background-color: color-mix(in oklab, oklch(0.8 0.15 85) 30%, color-mix(in oklab, var(--primary) 18%, transparent)); + box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--primary) 70%, transparent); +} + .active-row > div:not(.cell-dirty) { background-color: color-mix(in oklab, var(--primary) 15%, transparent); } diff --git a/packages/app-tests/dataGridSelectionShortcuts.test.ts b/packages/app-tests/dataGridSelectionShortcuts.test.ts index 87e9cab9f4..757d813a83 100644 --- a/packages/app-tests/dataGridSelectionShortcuts.test.ts +++ b/packages/app-tests/dataGridSelectionShortcuts.test.ts @@ -26,6 +26,15 @@ test("data grid intercepts copy and select-all shortcuts for grid selections", ( assert.match(source, /copySelectedRowsTsv\(\)/); }); +test("row number multi-selection reuses cell selection visuals", () => { + assert.match(source, /function rowCellsUseSelectionVisual\(rowId: number\): boolean/); + assert.match(source, /hasRowSelection\.value && isRowSelected\(rowId\) && !hasCellSelection\.value/); + assert.match(source, /'row-cell-selected':/); + assert.match(source, /'row-cell-selected-dirty':/); + assert.match(source, /\.row-cell-selected \{/); + assert.match(source, /\.row-cell-selected-dirty \{/); +}); + test("transpose cells reuse grid cell selection and details", () => { assert.match(source, /function selectTransposeCell\(rowIndex: number, actualColIdx: number, event: MouseEvent\)/); assert.match(source, /transposeCellIsSelected\(cell\.recordIndex, cell\.valueIndex\)/);