Skip to content

Commit 687ead4

Browse files
committed
Moves the onClick handling to the table row rather than the cell
1 parent a1c37d6 commit 687ead4

File tree

1 file changed

+44
-28
lines changed
  • apps/webapp/app/components/primitives

1 file changed

+44
-28
lines changed

apps/webapp/app/components/primitives/Table.tsx

Lines changed: 44 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { ChevronRightIcon } from "@heroicons/react/24/solid";
2-
import { Link } from "@remix-run/react";
3-
import { ReactNode, forwardRef, useState } from "react";
2+
import { useNavigate } from "@remix-run/react";
3+
import React, { ReactNode, forwardRef, useState } from "react";
44
import { cn } from "~/utils/cn";
55
import { Popover, PopoverContent, PopoverVerticalEllipseTrigger } from "./Popover";
66
import { InfoIconTooltip } from "./Tooltip";
@@ -44,6 +44,7 @@ export const TableHeader = forwardRef<HTMLTableSectionElement, TableHeaderProps>
4444
"sticky top-0 z-10 bg-background-dimmed after:absolute after:bottom-0 after:left-0 after:right-0 after:h-px after:bg-grid-bright",
4545
className
4646
)}
47+
tabIndex={-1}
4748
>
4849
{children}
4950
</thead>
@@ -71,16 +72,49 @@ type TableRowProps = {
7172
children: ReactNode;
7273
disabled?: boolean;
7374
isSelected?: boolean;
75+
to?: string;
76+
onClick?: (event: React.KeyboardEvent | React.MouseEvent) => void;
7477
};
7578

7679
export const TableRow = forwardRef<HTMLTableRowElement, TableRowProps>(
77-
({ className, disabled, isSelected, children }, ref) => {
80+
({ className, disabled, isSelected, children, to, onClick }, ref) => {
81+
const navigate = useNavigate();
82+
83+
const handleInteraction = (event: React.KeyboardEvent | React.MouseEvent) => {
84+
if ((event.target as HTMLElement).closest('button, a, [role="button"]')) {
85+
return;
86+
}
87+
88+
const firstCellWithTo = React.Children.toArray(children).find((child) => {
89+
if (React.isValidElement(child) && child.type === TableCell) {
90+
return child.props.to;
91+
}
92+
return false;
93+
}) as React.ReactElement | undefined;
94+
95+
if (firstCellWithTo?.props.to) {
96+
navigate(firstCellWithTo.props.to);
97+
} else if (onClick) {
98+
onClick(event);
99+
}
100+
};
101+
102+
const handleKeyDown = (event: React.KeyboardEvent) => {
103+
if (event.key === "Enter") {
104+
event.preventDefault();
105+
event.stopPropagation();
106+
handleInteraction(event);
107+
}
108+
};
109+
78110
return (
79111
<tr
80112
ref={ref}
81-
tabIndex={0}
113+
tabIndex={disabled ? -1 : 0}
114+
onClick={handleInteraction}
115+
onKeyDown={handleKeyDown}
82116
className={cn(
83-
"group/table-row relative w-full outline-none after:absolute after:bottom-0 after:left-3 after:right-0 after:h-px after:bg-grid-dimmed focus:focus-custom",
117+
"group/table-row relative w-full cursor-pointer outline-none after:absolute after:bottom-0 after:left-3 after:right-0 after:h-px after:bg-grid-dimmed focus-visible:bg-background-bright",
84118
disabled && "opacity-50",
85119
isSelected && isSelectedStyle,
86120
className
@@ -126,6 +160,7 @@ export const TableHeaderCell = forwardRef<HTMLTableCellElement, TableHeaderCellP
126160
className
127161
)}
128162
colSpan={colSpan}
163+
tabIndex={-1}
129164
>
130165
{hiddenLabel ? (
131166
<span className="sr-only">{children}</span>
@@ -154,7 +189,7 @@ type TableCellProps = TableCellBasicProps & {
154189

155190
const rowHoverStyles = {
156191
default:
157-
"group-hover/table-row:bg-charcoal-800 group-hover/table-row:before:absolute group-hover/table-row:before:bg-charcoal-750 group-hover/table-row:before:top-[-1px] group-hover/table-row:before:left-0 group-hover/table-row:before:h-px group-hover/table-row:before:w-3 group-hover/table-row:after:absolute group-hover/table-row:after:bg-charcoal-750 group-hover/table-row:after:bottom-0 group-hover/table-row:after:left-0 group-hover/table-row:after:h-px group-hover/table-row:after:w-3",
192+
"group-hover/table-row:bg-charcoal-800 group-focus-visible/table-row:bg-background-bright group-hover/table-row:before:absolute group-hover/table-row:before:bg-charcoal-750 group-hover/table-row:before:top-[-1px] group-hover/table-row:before:left-0 group-hover/table-row:before:h-px group-hover/table-row:before:w-3 group-hover/table-row:after:absolute group-hover/table-row:after:bg-charcoal-750 group-hover/table-row:after:bottom-0 group-hover/table-row:after:left-0 group-hover/table-row:after:h-px group-hover/table-row:after:w-3",
158193
dimmed:
159194
"group-hover/table-row:bg-charcoal-850 group-hover/table-row:before:absolute group-hover/table-row:before:bg-charcoal-800 group-hover/table-row:before:top-[-1px] group-hover/table-row:before:left-0 group-hover/table-row:before:h-px group-hover/table-row:before:w-3 group-hover/table-row:after:absolute group-hover/table-row:after:bg-charcoal-800 group-hover/table-row:after:bottom-0 group-hover/table-row:after:left-0 group-hover/table-row:after:h-px group-hover/table-row:after:w-3",
160195
bright:
@@ -193,40 +228,21 @@ export const TableCell = forwardRef<HTMLTableCellElement, TableCellProps>(
193228
break;
194229
}
195230

196-
const flexClasses = cn(
197-
"flex w-full whitespace-nowrap px-3 py-3 text-xs text-text-dimmed",
198-
alignment === "left"
199-
? "justify-start text-left"
200-
: alignment === "center"
201-
? "justify-center text-center"
202-
: "justify-end text-right"
203-
);
204-
205231
return (
206232
<td
207233
ref={ref}
208234
className={cn(
209235
"text-xs text-charcoal-400",
210-
to || onClick || hasAction ? "cursor-pointer" : "px-3 py-3 align-middle",
211-
!to && !onClick && alignmentClassName,
236+
hasAction ? "cursor-pointer" : "px-3 py-3 align-middle",
237+
alignmentClassName,
212238
isSticky && stickyStyles,
213239
isSelected && isSelectedStyle,
214240
!isSelected && rowHoverStyles[rowHoverStyle],
215241
className
216242
)}
217243
colSpan={colSpan}
218244
>
219-
{to ? (
220-
<Link to={to} tabIndex={-1} className={cn(flexClasses, actionClassName)}>
221-
{children}
222-
</Link>
223-
) : onClick ? (
224-
<button onClick={onClick} tabIndex={-1} className={cn(flexClasses, actionClassName)}>
225-
{children}
226-
</button>
227-
) : (
228-
<>{children}</>
229-
)}
245+
{children}
230246
</td>
231247
);
232248
}

0 commit comments

Comments
 (0)