Компонент таблицы DataTable в
библиотеке Carbon Components Svelte предоставляет мощный и гибкий
инструмент для отображения данных с возможностью сортировки по различным
колонкам. Основной принцип работы сортировки основан на передаче функции
sortRow и использовании состояния
sortHeader.
Для включения сортировки необходимо:
DataTable и его дочерние
элементы:<script>
import { DataTable, Table, TableHead, TableBody, TableRow, TableHeader, TableCell } from "carbon-components-svelte";
import { writable } from "svelte/store";
const headers = [
{ key: "name", header: "Имя" },
{ key: "age", header: "Возраст" },
{ key: "department", header: "Отдел" }
];
const rows = writable([
{ id: "1", name: "Иван", age: 28, department: "Разработка" },
{ id: "2", name: "Мария", age: 34, department: "Маркетинг" },
{ id: "3", name: "Сергей", age: 22, department: "Дизайн" }
]);
let sortHeader = null;
let sortDirection = "ASC";
function sortRows(headerKey) {
rows.update(currentRows => {
const direction = sortHeader === headerKey && sortDirection === "ASC" ? "DESC" : "ASC";
sortHeader = headerKey;
sortDirection = direction;
return [...currentRows].sort((a, b) => {
if (a[headerKey] < b[headerKey]) return direction === "ASC" ? -1 : 1;
if (a[headerKey] > b[headerKey]) return direction === "ASC" ? 1 : -1;
return 0;
});
});
}
</script>
<DataTable {rows} {headers}>
<Table>
<TableHead>
<TableRow>
{#each headers as header}
<TableHeader
on:click={() => sortRows(header.key)}
sortDirection={sortHeader === header.key ? sortDirection.toLowerCase() : null}
>
{header.header}
</TableHeader>
{/each}
</TableRow>
</TableHead>
<TableBody>
{#each $rows as row}
<TableRow>
{#each headers as header}
<TableCell>{row[header.key]}</TableCell>
{/each}
</TableRow>
{/each}
</TableBody>
</Table>
</DataTable>
Ключевые моменты:
sortDirection принимает значения "ASC" или
"DESC" и используется для визуального указания направления
сортировки в заголовке колонки.sortRows проверяет текущий сортированный
столбец и меняет направление сортировки при повторном клике на тот же
заголовок.[...] гарантирует, что
состояние rows будет обновлено корректно и сработают
реактивные обновления Svelte.Для сложных данных можно передавать собственную функцию сортировки. Например, для строк с учетом регистра или для числовых значений:
function customSort(headerKey, type = "string") {
rows.update(currentRows => {
const direction = sortHeader === headerKey && sortDirection === "ASC" ? "DESC" : "ASC";
sortHeader = headerKey;
sortDirection = direction;
return [...currentRows].sort((a, b) => {
let valA = a[headerKey];
let valB = b[headerKey];
if (type === "string") {
valA = valA.toLowerCase();
valB = valB.toLowerCase();
}
if (valA < valB) return direction === "ASC" ? -1 : 1;
if (valA > valB) return direction === "ASC" ? 1 : -1;
return 0;
});
});
}
Для реализации многоуровневой сортировки
(secondary sort) можно хранить массив сортировок:
let multiSort = [];
function sortMultiple(headerKey) {
const existing = multiSort.findIndex(s => s.key === headerKey);
if (existing >= 0) {
multiSort[existing].direction = multiSort[existing].direction === "ASC" ? "DESC" : "ASC";
} else {
multiSort.push({ key: headerKey, direction: "ASC" });
}
rows.update(currentRows => {
return [...currentRows].sort((a, b) => {
for (let sort of multiSort) {
if (a[sort.key] < b[sort.key]) return sort.direction === "ASC" ? -1 : 1;
if (a[sort.key] > b[sort.key]) return sort.direction === "ASC" ? 1 : -1;
}
return 0;
});
});
}
Такой подход позволяет, например, сначала сортировать по отделу, а внутри отдела — по возрасту.
Для отображения стрелки направления сортировки в заголовке таблицы:
<TableHeader
on:click={() => sortRows(header.key)}
sortDirection={sortHeader === header.key ? sortDirection.toLowerCase() : null}
>
{header.header}
{#if sortHeader === header.key}
<span>{sortDirection === "ASC" ? "↑" : "↓"}</span>
{/if}
</TableHeader>
Это позволяет пользователю мгновенно увидеть, по какому столбцу и в каком направлении происходит сортировка.
Для таблиц с большим количеством строк рекомендуется:
DataTable.Сортировка в Carbon Components Svelte строится на комбинации реактивного состояния, функций сортировки и визуальных индикаторов, что позволяет создавать гибкие и масштабируемые таблицы для сложных интерфейсов.