UNPKG

eventx-design-system

Version:
195 lines (184 loc) 7.92 kB
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; import styled from 'styled-components'; import { colors, typography, spacing, borderRadius, shadows } from '../../tokens/design-tokens'; const TableContainer = styled.div ` width: 100%; overflow-x: auto; border-radius: ${borderRadius.lg}; box-shadow: ${shadows.base}; background-color: ${colors.neutral[50]}; `; const StyledTable = styled.table ` width: 100%; border-collapse: separate; border-spacing: 0; font-family: ${typography.fontFamily.primary}; ${({ variant }) => { if (variant === 'bordered') { return ` border: 1px solid ${colors.neutral[300]}; border-radius: ${borderRadius.lg}; `; } return ''; }} `; const TableHeader = styled.thead ` background-color: ${colors.neutral[100]}; `; const TableHeaderCell = styled.th ` padding: ${spacing[4]}; text-align: ${({ align }) => align || 'left'}; font-family: ${typography.fontFamily.primary}; font-size: ${typography.fontSize.sm}; font-weight: ${typography.fontWeight.semibold}; color: ${colors.neutral[700]}; border-bottom: 1px solid ${colors.neutral[300]}; cursor: ${({ sortable }) => sortable ? 'pointer' : 'default'}; user-select: none; position: relative; width: ${({ width }) => width || 'auto'}; min-width: ${({ width }) => width || 'auto'}; ${({ sortable }) => sortable && ` &:hover { background-color: ${colors.neutral[200]}; } `} ${({ sorted }) => sorted && ` color: ${colors.brand.primary[600]}; &::after { content: '${sorted === 'asc' ? '↑' : '↓'}'; position: absolute; right: ${spacing[2]}; color: ${colors.brand.primary[500]}; } `} &:first-child { border-top-left-radius: ${borderRadius.lg}; } &:last-child { border-top-right-radius: ${borderRadius.lg}; } `; const TableBody = styled.tbody ` ${({ variant }) => { if (variant === 'striped') { return ` tr:nth-child(even) { background-color: ${colors.neutral[50]}; } tr:nth-child(odd) { background-color: ${colors.neutral[100]}; } `; } return ''; }} `; const TableRow = styled.tr ` transition: all 0.2s ease-in-out; border-bottom: 1px solid ${colors.neutral[200]}; ${({ hoverable }) => hoverable && ` &:hover { background-color: ${colors.brand.primary[50]} !important; transform: translateY(-1px); box-shadow: ${shadows.md}; } `} ${({ selected }) => selected && ` background-color: ${colors.brand.primary[100]} !important; border-left: 3px solid ${colors.brand.primary[500]}; `} &:last-child { border-bottom: none; } `; const TableCell = styled.td ` padding: ${spacing[4]}; text-align: ${({ align }) => align || 'left'}; font-family: ${typography.fontFamily.primary}; font-size: ${typography.fontSize.sm}; color: ${colors.neutral[700]}; border-bottom: 1px solid ${colors.neutral[200]}; width: ${({ width }) => width || 'auto'}; min-width: ${({ width }) => width || 'auto'}; vertical-align: middle; &:last-child { border-right: none; } `; const EmptyState = styled.div ` padding: ${spacing[12]}; text-align: center; color: ${colors.neutral[500]}; font-family: ${typography.fontFamily.primary}; font-size: ${typography.fontSize.base}; `; const LoadingState = styled.div ` padding: ${spacing[12]}; text-align: center; color: ${colors.neutral[500]}; font-family: ${typography.fontFamily.primary}; font-size: ${typography.fontSize.base}; `; const SortIcon = styled.span ` margin-left: ${spacing[1]}; color: ${colors.neutral[400]}; font-size: ${typography.fontSize.xs}; `; export const Table = ({ columns, dataSource, loading = false, variant = 'default', hoverable = true, selectable = false, selectedRowKeys = [], onRowSelect, onRowClick, sortConfig, onSort, rowKey = 'id', emptyText = 'Nenhum dado encontrado', className, }) => { const getRowKey = (record, index) => { if (typeof rowKey === 'function') { return rowKey(record); } return record[rowKey] || index.toString(); }; const handleSort = (column) => { if (!column.sortable || !onSort) return; const currentDirection = sortConfig?.key === column.key ? sortConfig.direction : null; const newDirection = currentDirection === 'asc' ? 'desc' : 'asc'; onSort(column.key, newDirection); }; const handleRowClick = (record, index) => { onRowClick?.(record, index); }; const handleRowSelect = (record, checked) => { if (!selectable || !onRowSelect) return; const key = getRowKey(record, 0); const newSelectedKeys = checked ? [...selectedRowKeys, key] : selectedRowKeys.filter(k => k !== key); const newSelectedRows = dataSource.filter(item => newSelectedKeys.includes(getRowKey(item, 0))); onRowSelect(newSelectedKeys, newSelectedRows); }; const renderCell = (column, record, index) => { if (column.render) { return column.render(record[column.dataIndex], record, index); } const value = column.dataIndex ? record[column.dataIndex] : record[column.key]; return value; }; if (loading) { return (_jsx(TableContainer, { variant: variant, className: className, children: _jsx(LoadingState, { children: "Carregando..." }) })); } if (!dataSource || dataSource.length === 0) { return (_jsx(TableContainer, { variant: variant, className: className, children: _jsx(EmptyState, { children: emptyText }) })); } return (_jsx(TableContainer, { variant: variant, className: className, children: _jsxs(StyledTable, { variant: variant, children: [_jsx(TableHeader, { children: _jsxs("tr", { children: [selectable && (_jsx(TableHeaderCell, { width: "40px", children: _jsx("input", { type: "checkbox", checked: selectedRowKeys.length === dataSource.length, onChange: (e) => { if (e.target.checked) { const allKeys = dataSource.map((record, index) => getRowKey(record, index)); onRowSelect?.(allKeys, dataSource); } else { onRowSelect?.([], []); } } }) })), columns.map((column) => (_jsxs(TableHeaderCell, { sortable: column.sortable, sorted: sortConfig?.key === column.key ? sortConfig.direction : null, align: column.align, width: column.width, onClick: () => handleSort(column), children: [column.title, column.sortable && (_jsx(SortIcon, { direction: sortConfig?.key === column.key ? sortConfig.direction : null, children: sortConfig?.key === column.key ? (sortConfig.direction === 'asc' ? '↑' : '↓') : '↕' }))] }, column.key)))] }) }), _jsx(TableBody, { variant: variant, children: dataSource.map((record, index) => { const key = getRowKey(record, index); const isSelected = selectedRowKeys.includes(key); return (_jsxs(TableRow, { variant: variant, hoverable: hoverable, selected: isSelected, onClick: () => handleRowClick(record, index), children: [selectable && (_jsx(TableCell, { width: "40px", children: _jsx("input", { type: "checkbox", checked: isSelected, onChange: (e) => handleRowSelect(record, e.target.checked), onClick: (e) => e.stopPropagation() }) })), columns.map((column) => (_jsx(TableCell, { align: column.align, width: column.width, children: renderCell(column, record, index) }, column.key)))] }, key)); }) })] }) })); };