/
TableCheckbox.tsx
150 lines (139 loc) · 3.72 KB
/
TableCheckbox.tsx
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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
import type { CSSProperties, Ref, TdHTMLAttributes } from "react";
import { forwardRef } from "react";
import cn from "classnames";
import type { CheckboxProps } from "@react-md/form";
import { Checkbox } from "@react-md/form";
import type { TableCellProps } from "./TableCell";
import { TableCell } from "./TableCell";
type WantedCheckboxProps =
| "name"
| "value"
| "icon"
| "iconStyle"
| "iconClassName"
| "toggleStyle"
| "toggleClassName"
| "disableIconOverlay"
| "checked"
| "onChange"
| "defaultChecked"
| "indeterminate"
| "aria-controls";
export interface TableCheckboxProps
extends Omit<
TdHTMLAttributes<HTMLTableCellElement>,
"onChange" | "scope" | "aria-sort"
>,
Pick<CheckboxProps, WantedCheckboxProps>,
Pick<TableCellProps, "sticky"> {
/**
* The id for the checkbox. This is required for a11y.
*/
id: string;
/**
* An optional id to provide to the `<td>` element. The base `id` prop is
* passed to the checkbox input instead.
*/
cellId?: string;
/**
* An screen reader label to use for the checkbox. Either this or the
* `aria-labelledby` prop are required for a11y.
*
* Note: This is defaulted automatically to "Toggle Row Selection".
*/
"aria-label"?: string;
/**
* An optional id or space-delimited list of ids that describe the checkbox.
* Either this or the `aria-label` props are required for a11y.
*/
"aria-labelledby"?: string;
/**
* An optional `ref` to apply to the checkbox element. The base `ref` is
* passed to the `<td>` element.
*/
checkboxRef?: Ref<HTMLInputElement>;
/**
* An optional style to apply to the checkbox. The base `style` is passed to
* the `<td>`.
*/
checkboxStyle?: CSSProperties;
/**
* An optional className to apply to the checkbox. The base `className` is
* passed to the `<td>`.
*/
checkboxClassName?: string;
}
const DEFAULT_ARIA_LABEL = "Toggle Row Selection";
/**
* This is a simple wrapper for the `Checkbox` component that allows you to
* render a nicely styled `Checkbox` within a `TableCell` element. This will
* mostly just remove the additional padding applied and default an `aria-label`
* since you normally don't want a checkbox with a label within a table since
* it's more for selection.
*/
export const TableCheckbox = forwardRef<
HTMLTableCellElement,
TableCheckboxProps
>(function TableCheckbox(
{
cellId,
className,
id,
"aria-label": ariaLabel,
"aria-labelledby": ariaLabelledBy,
"aria-checked": ariaChecked,
"aria-controls": ariaControls,
checkboxRef,
checkboxStyle,
checkboxClassName,
icon,
iconStyle,
iconClassName,
toggleStyle,
toggleClassName,
disableIconOverlay,
name,
value,
checked,
onChange,
defaultChecked,
indeterminate,
...props
},
ref
) {
return (
<TableCell
{...props}
ref={ref}
id={cellId}
header={false}
className={cn("rmd-table-cell--checkbox", className)}
>
<Checkbox
id={id}
aria-label={
ariaLabel ?? ariaLabelledBy ? undefined : DEFAULT_ARIA_LABEL
}
aria-labelledby={ariaLabelledBy}
aria-checked={ariaChecked}
aria-controls={ariaControls}
ref={checkboxRef}
style={checkboxStyle}
indeterminate={indeterminate}
className={checkboxClassName}
icon={icon}
iconStyle={iconStyle}
iconClassName={iconClassName}
toggleStyle={toggleStyle}
toggleClassName={toggleClassName}
disableIconOverlay={disableIconOverlay}
name={name}
value={value}
checked={checked}
onChange={onChange}
defaultChecked={defaultChecked}
/>
</TableCell>
);
});