fix(site): enlarge checkbox click target in workspace and task tables (#24739)

Fixes a UX issue where clicking near (but not exactly on) the
bulk-action
checkbox in the Workspaces or Tasks table would navigate to the
workspace/task page instead of toggling the checkbox. Clicking back then
clears all previous selections.

## Changes

Wraps each row checkbox in a `div` that:
- Calls `e.stopPropagation()` on `click` and `keydown` so near-miss
  clicks toggle the checkbox instead of navigating.
- Uses `h-[72px]` to fill the full row height for vertical coverage.
- Uses `pr-4 -mr-4` to extend the safe zone to the right without
  shifting layout.
- Sets `cursor-default` so the pointer hand does not appear in the
  safe zone.

Applied to both:
- `WorkspacesTable.tsx` (workspaces page)
- `TasksTable.tsx` (tasks page)

> This PR was authored by Coder Agents.
This commit is contained in:
TJ
2026-05-11 16:37:00 +00:00
committed by GitHub
parent 0a17660691
commit c2dfaa406a
2 changed files with 48 additions and 28 deletions
+20 -10
View File
@@ -221,17 +221,27 @@ const TaskRow: FC<TaskRowProps> = ({ task, checked, onCheckChange }) => {
>
<TableCell>
<div className="flex items-center gap-5">
<Checkbox
data-testid={`checkbox-${task.id}`}
checked={checked}
onClick={(e) => {
e.stopPropagation();
{/* Wrap the checkbox in a click-absorbing container
* so that near-miss clicks do not bubble up to the
* row's navigation handler. */}
<div
className="flex items-center cursor-default h-[72px] pr-4 -mr-4"
onClick={(e) => e.stopPropagation()}
onKeyDown={(e) => {
if (e.key === "Enter" || e.key === " ") {
e.stopPropagation();
}
}}
onCheckedChange={(checked) => {
onCheckChange(task.id, Boolean(checked));
}}
aria-label={`Select task ${task.initial_prompt}`}
/>
>
<Checkbox
data-testid={`checkbox-${task.id}`}
checked={checked}
onCheckedChange={(checked) => {
onCheckChange(task.id, Boolean(checked));
}}
aria-label={`Select task ${task.initial_prompt}`}
/>
</div>
<AvatarData
title={
<span className="block max-w-[520px] truncate">
@@ -185,26 +185,36 @@ export const WorkspacesTable: FC<WorkspacesTableProps> = ({
>
<TableCell>
<div className="flex items-center gap-5">
<Checkbox
data-testid={`checkbox-${workspace.id}`}
disabled={cantBeChecked(workspace)}
checked={checked}
onClick={(e) => {
e.stopPropagation();
}}
onCheckedChange={(checked) => {
if (checked) {
onCheckChange([...checkedWorkspaces, workspace]);
} else {
onCheckChange(
checkedWorkspaces.filter(
(w) => w.id !== workspace.id,
),
);
{/* Wrap the checkbox in a click-absorbing container
* so that near-miss clicks do not bubble up to the
* row's navigation handler. */}
<div
className="flex items-center cursor-default h-[72px] pr-4 -mr-4"
onClick={(e) => e.stopPropagation()}
onKeyDown={(e) => {
if (e.key === "Enter" || e.key === " ") {
e.stopPropagation();
}
}}
aria-label={`Select workspace ${workspace.name}`}
/>
>
<Checkbox
data-testid={`checkbox-${workspace.id}`}
disabled={cantBeChecked(workspace)}
checked={checked}
onCheckedChange={(checked) => {
if (checked) {
onCheckChange([...checkedWorkspaces, workspace]);
} else {
onCheckChange(
checkedWorkspaces.filter(
(w) => w.id !== workspace.id,
),
);
}
}}
aria-label={`Select workspace ${workspace.name}`}
/>
</div>
<AvatarData
title={
<div className="flex items-center gap-1">