fix: keep multi-selection when clicking beside a table row checkbox (#14576)

This commit is contained in:
ktx-vaidehi
2026-09-22 06:32:10 +00:00
committed by GitHub
parent c518688e42
commit ccc14f098a
3 changed files with 72 additions and 6 deletions
+48 -3
View File
@@ -779,11 +779,56 @@ describe("OTable", () => {
data: makeRows(5),
columns: makeColumns(),
selection: "multiple",
onRowClick: vi.fn(),
},
});
// The checkbox might be a nested component; trigger the row click
const row = wrapper.find('[data-test="o2-table-row-0"]');
await row.trigger("click");
await wrapper.find('[data-test="o2-table-select-0"] button').trigger("click");
expect(wrapper.emitted("update:selectedIds")?.[0][0]).toEqual(["1"]);
expect(wrapper.emitted("row-click")).toBeFalsy();
});
it("toggles selection without a row-click when the select cell padding is clicked", async () => {
wrapper = mount(OTable, {
props: {
data: makeRows(5),
columns: makeColumns(),
selection: "multiple",
onRowClick: vi.fn(),
},
});
const cell = wrapper.findAll('[data-test="o2-table-select-cell"]')[1];
await cell.trigger("click");
expect(wrapper.emitted("update:selectedIds")?.[0][0]).toEqual(["2"]);
await cell.trigger("click");
expect(wrapper.emitted("update:selectedIds")?.[1][0]).toEqual([]);
expect(wrapper.emitted("row-click")).toBeFalsy();
});
it("ignores select cell clicks on rows that are not selectable", async () => {
wrapper = mount(OTable, {
props: {
data: makeRows(3),
columns: makeColumns(),
selection: "multiple",
isRowSelectable: (row: TestRow) => row.id !== 1,
onRowClick: vi.fn(),
},
});
await wrapper.findAll('[data-test="o2-table-select-cell"]')[0].trigger("click");
expect(wrapper.emitted("update:selectedIds")).toBeFalsy();
expect(wrapper.emitted("row-click")).toBeFalsy();
});
it("toggles all rows when the header select cell padding is clicked", async () => {
wrapper = mount(OTable, {
props: {
data: makeRows(3),
columns: makeColumns(),
selection: "multiple",
},
});
await wrapper.find('[data-test="o2-table-th-select"]').trigger("click");
expect(wrapper.emitted("update:selectedIds")?.[0][0]).toEqual(["1", "2", "3"]);
});
});
@@ -148,6 +148,12 @@ function onClick(event: MouseEvent) {
emit("row-click", props.row.original, event);
}
// Clicks on the checkbox itself are stopped by OCheckbox, so this only sees misses on the cell padding.
function onSelectCellClick() {
if (props.isRowSelectable && !props.isRowSelectable(props.row.original)) return;
emit("toggle-selection", props.row.original);
}
function onDblclick(event: MouseEvent) {
emit("row-dblclick", props.row.original, event);
}
@@ -216,7 +222,7 @@ function onRowMouseleave() {
:class="[
'text-left align-middle',
bordered ? 'border-table-row-divider border-b' : '',
isRowSelectable && !isRowSelectable(row.original) ? 'cursor-not-allowed' : '',
isRowSelectable && !isRowSelectable(row.original) ? 'cursor-not-allowed' : 'cursor-pointer',
]"
:style="{
width: TABLE_CHECKBOX_COL_WIDTH + 'px',
@@ -225,6 +231,7 @@ function onRowMouseleave() {
paddingLeft: 'var(--spacing-table-edge)',
}"
data-test="o2-table-select-cell"
@click.stop="onSelectCellClick"
>
<div class="flex items-center justify-start">
<OTableSelectCheckbox
@@ -144,6 +144,12 @@ function handleSort(columnId: string, toggleHandler?: (event: Event) => void, ev
if (event) toggleHandler?.(event);
}
// Clicks on the checkbox itself are stopped by OCheckbox, so this only sees misses on the cell padding.
function onSelectAllCellClick() {
if (props.showSelectAll === false) return;
emit("toggle-all-rows");
}
function handleDragStart(event: any) {
emit("drag-start", event);
}
@@ -485,7 +491,10 @@ function getStandardStickyTotalStyle(header: any): Record<string, any> {
<!-- Selection checkbox header -->
<th
v-if="selectionMultiple"
class="border-table-header-border border-b text-left"
:class="[
'border-table-header-border border-b text-left',
showSelectAll !== false ? 'cursor-pointer' : '',
]"
:style="{
width: TABLE_CHECKBOX_COL_WIDTH + 'px',
minWidth: TABLE_CHECKBOX_COL_WIDTH + 'px',
@@ -493,6 +502,7 @@ function getStandardStickyTotalStyle(header: any): Record<string, any> {
paddingLeft: 'var(--spacing-table-edge)',
}"
data-test="o2-table-th-select"
@click="onSelectAllCellClick"
>
<OTableSelectCheckbox
v-if="showSelectAll !== false"
@@ -826,7 +836,10 @@ function getStandardStickyTotalStyle(header: any): Record<string, any> {
<th
v-if="selectionMultiple"
class="border-table-header-border border-b text-left"
:class="[
'border-table-header-border border-b text-left',
showSelectAll !== false ? 'cursor-pointer' : '',
]"
:style="{
width: TABLE_CHECKBOX_COL_WIDTH + 'px',
minWidth: TABLE_CHECKBOX_COL_WIDTH + 'px',
@@ -834,6 +847,7 @@ function getStandardStickyTotalStyle(header: any): Record<string, any> {
paddingLeft: 'var(--spacing-table-edge)',
}"
data-test="o2-table-th-select"
@click="onSelectAllCellClick"
>
<OTableSelectCheckbox
v-if="showSelectAll !== false"