Фильтрация строк таблицы

Фильтрация данных в таблицах является важным инструментом для управления большими наборами информации и повышения удобства взаимодействия с интерфейсом. В библиотеке Carbon Components Svelte реализованы компоненты и паттерны, которые позволяют эффективно организовать фильтрацию строк таблицы с минимальной ручной работой и высокой кастомизацией.


Основные концепции

  1. Компонент DataTable Основной контейнер для работы с таблицами в Carbon Svelte — это <DataTable>. Он принимает набор колонок и строк, а также предоставляет вспомогательные свойства и методы для управления состоянием таблицы.

    <DataTable {rows} {headers}>
      <Table>
        <TableHead />
        <TableBody />
      </Table>
    </DataTable>
    • rows — массив объектов, каждый объект представляет строку таблицы.
    • headers — массив объектов с ключами key и header, определяющими название и идентификатор колонки.
  2. Ключевые свойства для фильтрации

    • rows может быть динамически изменяемым массивом, что позволяет фильтровать строки на лету.
    • selectedRows хранит выделенные строки, что удобно для интеграции фильтров с выбором элементов.

Фильтрация через текстовое поле

Для фильтрации часто используется компонент <TextInput> из Carbon, связанный с фильтруемыми строками таблицы:

<script>
  import { DataTable, Table, TableHead, TableBody, TableRow, TableCell, TextInput } from 'carbon-components-svelte';
  
  let filterText = '';
  
  let rows = [
    { id: '1', name: 'Alice', role: 'Developer' },
    { id: '2', name: 'Bob', role: 'Designer' },
    { id: '3', name: 'Charlie', role: 'Manager' }
  ];
  
  const headers = [
    { key: 'name', header: 'Имя' },
    { key: 'role', header: 'Должность' }
  ];
  
  $: filteredRows = rows.filter(row =>
    Object.values(row).some(value =>
      String(value).toLowerCase().includes(filterText.toLowerCase())
    )
  );
</script>

<TextInput bind:value={filterText} labelText="Фильтр по таблице" />

<DataTable {headers} rows={filteredRows}>
  <Table>
    <TableHead />
    <TableBody let:row>
      <TableRow>
        <TableCell>{row.name}</TableCell>
        <TableCell>{row.role}</TableCell>
      </TableRow>
    </TableBody>
  </Table>
</DataTable>

Ключевые моменты:

  • Использование реактивной переменной $: filteredRows позволяет динамически обновлять содержимое таблицы при изменении текста фильтра.
  • Метод Object.values(row).some(...) обеспечивает универсальную фильтрацию по всем колонкам строки.

Фильтрация по отдельной колонке

Если требуется фильтровать конкретное поле, логика упрощается:

$: filteredRows = rows.filter(row =>
  row.role.toLowerCase().includes(filterText.toLowerCase())
);
  • Такой подход удобен для создания отдельных фильтров для каждой колонки, например через несколько <TextInput> или выпадающих списков <Dropdown>.

Интеграция с компонентом TableToolbar

Carbon Components Svelte предоставляет TableToolbar, который объединяет элементы управления таблицей:

<TableToolbar>
  <TableToolbarContent>
    <TextInput bind:value={filterText} labelText="Фильтр по имени" />
  </TableToolbarContent>
</TableToolbar>
  • Фильтр, встроенный в TableToolbar, визуально и функционально соответствует рекомендациям IBM Carbon Design.
  • Использование TableToolbarSearch упрощает фильтрацию и автоматически обеспечивает доступность (a11y).

Оптимизация производительности при больших наборах данных

Для таблиц с сотнями и тысячами строк фильтрация на стороне клиента может быть медленной. Рекомендации по оптимизации:

  1. Дебаунсинг ввода Использовать setTimeout или svelte-use для задержки фильтрации после ввода текста.

    let filterText = '';
    let debouncedText = '';
    let timeout;
    
    $: {
      clearTimeout(timeout);
      timeout = setTimeout(() => debouncedText = filterText, 300);
    }
    
    $: filteredRows = rows.filter(row =>
      row.name.toLowerCase().includes(debouncedText.toLowerCase())
    );
  2. Виртуализация строк Для рендеринга тысяч элементов использовать сторонние библиотеки виртуализации, например svelte-virtual-list, чтобы рендерить только видимые строки.


Расширенные сценарии фильтрации

  1. Множественные фильтры При необходимости фильтровать одновременно по нескольким колонкам:

    $: filteredRows = rows.filter(row =>
      row.name.toLowerCase().includes(nameFilter.toLowerCase()) &&
      row.role.toLowerCase().includes(roleFilter.toLowerCase())
    );
  2. Фильтрация с регулярными выражениями Позволяет гибко находить совпадения:

    $: regex = new RegExp(filterText, 'i');
    $: filteredRows = rows.filter(row => regex.test(row.name));
  3. Фильтрация через коллбэк Полезно, если данные приходят с сервера и фильтр должен быть сложным:

    function filterRows(row) {
      return row.active && row.role.startsWith('D');
    }
    
    $: filteredRows = rows.filter(filterRows);

Важные аспекты интеграции с Carbon Svelte

  • Состояние таблицы (DataTable): при фильтрации строки остаются частью состояния таблицы, что важно для правильной работы сортировки и выделения.
  • Совместимость с сортировкой и пагинацией: фильтры всегда должны применяться до отображения пагинации и сортировки, чтобы избежать несоответствия данных на экране.
  • Доступность (a11y): все фильтрующие компоненты должны быть связаны с таблицей через aria-label и aria-controls.

Эти подходы обеспечивают мощную, гибкую и масштабируемую фильтрацию строк в таблицах Carbon Components Svelte, позволяя создавать интерактивные и удобные интерфейсы с минимальным количеством кастомного кода.