import React from 'react'; import { IconArrowUp, IconArrowDown, IconEdit, IconTrash, IconCopy, IconCheck, IconX } from '@tabler/icons-react'; import TableSkeleton, { TableEmpty } from './TableSkeleton.jsx'; import EmptyState from './EmptyState.jsx'; import Pagination from './Pagination.jsx'; import Tooltip from './Tooltip.jsx'; /** * Универсальный компонент таблицы данных * * @param {Object} props * @param {Array} props.columns - Массив описаний колонок * - { key: string, title: string, sortable?: boolean, icon?: Component, render?: (value, item) => ReactNode } * @param {Array} props.items - Массив данных для отображения * @param {string} props.itemKey - Ключ уникального идентификатора элемента * @param {boolean} props.loading - Состояние загрузки * @param {string} props.sortField - Текущее поле сортировки * @param {string} props.sortOrder - Направление сортировки ('asc' | 'desc') * @param {function} props.onSort - Обработчик изменения сортировки * @param {Set} props.selectedItems - Набор выбранных элементов * @param {function} props.onSelectItem - Обработчик выбора элемента * @param {function} props.onSelectAll - Обработчик выбора всех * @param {function} props.onDeselectAll - Обработчик снятия выбора * @param {function} props.onEdit - Обработчик редактирования (item) => void * @param {function} props.onDelete - Обработчик удаления (item) => void * @param {function} props.onCopy - Обработчик копирования (item) => void * @param {Object} props.inlineEdit - Настройки инлайн-редактирования * - { editingKey: string, editingValue: string, onSave: () => void, onCancel: () => void, onChange: (value) => void, renderEditor?: () => ReactNode } * @param {Object} props.pagination - Настройки пагинации * - { currentPage, totalPages, totalItems, pageSize, onPageChange } * @param {Object} props.emptyState - Настройки пустого состояния * - { title, description, action, secondaryAction } * @param {Array} props.actions - Дополнительные действия в строке * - [{ icon: Component, label: string, onClick: (item) => void, variant?: string }] * @param {boolean} props.selectable - Включить чекбоксы выбора (default: true) * @param {number} props.skeletonRows - Количество строк скелетона (default: 10) * @param {boolean} props.striped - Чередование фона строк (Tabler UX, default: true) * @param {boolean} props.compact - Уменьшенные отступы ячеек (default: false) * @param {boolean} props.flat - Таблица без карточной подложки: только горизонтальные разделители (default: false) */ function DataTable({ columns = [], items = [], itemKey = 'id', loading = false, sortField, sortOrder = 'asc', onSort, selectedItems = new Set(), onSelectItem, onSelectAll, onDeselectAll, onEdit, onDelete, onCopy, inlineEdit, pagination, emptyState, actions = [], selectable = true, skeletonRows = 10, striped = true, compact = false, flat = false, }) { const hasActions = onEdit || onDelete || onCopy || actions.length > 0; const isEditing = (item) => inlineEdit && item[itemKey] === inlineEdit.editingKey; // Рендер заголовка колонки (col.title — подпись, col.tooltip — подсказка для UX) const renderColumnHeader = (col) => { const isSortable = col.sortable !== false && onSort; const isActive = sortField === col.key; const content = (
| e.target.checked ? onSelectAll?.() : onDeselectAll?.()} title="Выбрать все на странице" /> | )} {columns.map(renderColumnHeader)} {hasActions &&Действия | }|
|---|---|---|
| onSelectItem?.(id)} onClick={(e) => e.stopPropagation()} /> | )} {columns.map((col) => ({renderCell(col, item)} | ))} {hasActions && ({renderActions(item)} | )}