Создание кликабельных строк таблицы в виде ссылок с помощью tanstack-table и CSS
Хотите, чтобы вся строка таблицы была настоящей ссылкой с возможностью перехода? Здесь я предлагаю вам практичное и доступное решение.
Ссылка на codesandbox: Посмотрите!
Шаг 1: Создание таблицы
Используйте для этого любые технологии, которые вам нравятся: Я выбрал React и tanstack-table, потому что это то, что я сейчас использую на работе.
type Items = {
ranking: number;
url: string;
name: string;
};
const data: Items[] = [
{
ranking: 1,
url: "https://google.com",
name: "Google",
},
{
ranking: 2,
url: "https://bing.com",
name: "Bing",
},
{
ranking: 3,
url: "https://yahoo.com",
name: "Yahoo",
},
];
const columnHelper = createColumnHelper<Items>();
const columns = [
columnHelper.accessor("ranking", {
cell: (info) => info.getValue(),
}),
columnHelper.accessor("name", {
cell: (info) => info.getValue(),
}),
columnHelper.accessor("url", {
cell: (info) => info.getValue(),
}),
];
export function Table() {
const table = useReactTable({
data,
columns,
getCoreRowModel: getCoreRowModel(),
});
return (
<div>
<table>
<thead>
{table.getHeaderGroups().map((headerGroup) => (
<tr key={headerGroup.id}>
{headerGroup.headers.map((header) => (
<th key={header.id} className="table-head">
{header.isPlaceholder
? null
: flexRender(
header.column.columnDef.header,
header.getContext(),
)}
</th>
))}
</tr>
))}
</thead>
<tbody>
{table.getRowModel().rows.map((row) => (
<tr key={row.id} className="data-rows">
{row.getVisibleCells().map((cell) => (
<td key={cell.id} className="table-cell">
{flexRender(cell.column.columnDef.cell, cell.getContext())}
</td>
))}
</tr>
))}
</tbody>
</table>
</div>
);
}
Шаг 2: Добавление дополнительного столбца в таблицу
Я добавил его с левой стороны, но это не важно. Здесь он залит желтым цветом, поэтому его хорошо видно.
Шаг 3: Поместите свою ссылку в пустой столбец
В маленькую колонку поместите ссылку, на которую должна вести каждая строка, внутри тега-якоря.
...
<thead>
{table.getHeaderGroups().map((headerGroup) => (
<tr key={headerGroup.id}>
{/*⬇️ add an extra column here */}
<th key="extra-column" aria-label="Search Engine Links"></th>
{headerGroup.headers.map((header) => (
<th key={header.id} className="table-head">
...
<tbody>
{table.getRowModel().rows.map((row) => (
<tr key={row.id} className="data-rows">
{/*⬇️ add a cell with an empty link for every row
below the empty column header */}
<td>
<a
href={row.original.url}
aria-label={row.original.url}
className="row-link"
></a>
</td>
{row.getVisibleCells().map((cell) => (
...
Шаг 4: Расположите ссылку так, чтобы она охватывала всю строку
Теперь, когда ссылка является частью таблицы, давайте сделаем так, чтобы она перекрывала всю строку с помощью CSS:
tr {
border: 1px solid white;
position: relative;
height: 3rem;
}
.row-link {
position: absolute;
top: 0;
left: 0;
content: "";
width: 100%;
height: 3rem;
}
.data-rows:hover {
background-color: #a8a5a5;
}
Я добавил желтый фон и границы для каждого элемента, чтобы его было легче увидеть. Благодаря абсолютному позиционированию по отношению к строке таблицы тег-якорь охватывает всю строку и делает её кликабельной.
Благодаря добавлению соответствующего контура к тегу-якорю, в фокус попадает вся строка, что делает её удобной для просмотра на вкладке.
Замечания о доступности
- Пустой заголовок колонки и пустые теги-якори могут смущать людей, использующих программы чтения с экрана, поэтому я добавил к ним атрибут aria.
- Я настроил контур на
focus-visible
, чтобы ссылки были четко обозначены как нечто кликабельное и доступное с клавиатуры. - Разумеется, мой пример служит для того, чтобы показать концепцию - при выборе цветов всегда нужно проверять достаточную контрастность.
Мне нравится это решение - оно такое элегантное! Надеюсь, это помогло вам!