mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
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:
@@ -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">
|
||||
|
||||
Reference in New Issue
Block a user