-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Expand file tree
/
Copy pathuseClickableTableRow.ts
More file actions
76 lines (70 loc) · 2.36 KB
/
Copy pathuseClickableTableRow.ts
File metadata and controls
76 lines (70 loc) · 2.36 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
/**
* @file 2024-02-19 - MES - Sadly, even though this hook aims to make elements
* more accessible, it's doing the opposite right now. Per axe audits, the
* current implementation will create a bunch of critical-level accessibility
* violations:
*
* 1. Nesting interactive elements (e.g., workspace table rows having checkboxes
* inside them)
* 2. Overriding the native element's role (in this case, turning a native table
* row into a button, which means that screen readers lose the ability to
* announce the row's data as part of a larger table)
*
* It might not make sense to test this hook until the underlying design
* problems are fixed.
*/
import { cn } from "cn";
import type { HTMLAttributes, MouseEventHandler } from "react";
import {
type ClickableAriaRole,
type UseClickableResult,
useClickable,
} from "./useClickable";
type TableRowClickHandlers = Pick<
HTMLAttributes<HTMLTableRowElement>,
"onClick" | "onDoubleClick" | "onAuxClick"
>;
type UseClickableTableRowResult<
TRole extends ClickableAriaRole = ClickableAriaRole,
> = UseClickableResult<HTMLTableRowElement, TRole> &
TableRowClickHandlers & {
className: string;
hover: true;
onAuxClick: MouseEventHandler<HTMLTableRowElement>;
};
type UseClickableTableRowConfig<TRole extends ClickableAriaRole> =
TableRowClickHandlers & {
role?: TRole;
onClick: MouseEventHandler<HTMLTableRowElement>;
onMiddleClick?: MouseEventHandler<HTMLTableRowElement>;
};
export const useClickableTableRow = <
TRole extends ClickableAriaRole = ClickableAriaRole,
>({
role,
onClick,
onDoubleClick,
onMiddleClick,
onAuxClick: externalOnAuxClick,
}: UseClickableTableRowConfig<TRole>): UseClickableTableRowResult<TRole> => {
const clickableProps = useClickable(onClick, (role ?? "button") as TRole);
return {
...clickableProps,
className: cn([
"cursor-pointer outline-none hover:outline-solid hover:outline-1 focus-visible:outline-solid focus-visible:outline-1 -outline-offset-1 outline-border-secondary",
"first:rounded-t-md last:rounded-b-md",
]),
hover: true,
onDoubleClick,
onAuxClick: (event) => {
// Regardless of which callback gets called, the hook won't stop the event
// from bubbling further up the DOM
const isMiddleMouseButton = event.button === 1;
if (isMiddleMouseButton) {
onMiddleClick?.(event);
} else {
externalOnAuxClick?.(event);
}
},
};
};