import { Checkbox } from '@mantine/core'; import { type Cell, flexRender } from '@tanstack/react-table'; import { getGriddyColumn } from '../core/columnMapper'; import { CSS, SELECTION_COLUMN_ID } from '../core/constants'; import { useGriddyStore } from '../core/GriddyStore'; import { TreeExpandButton } from '../features/tree/TreeExpandButton'; import styles from '../styles/griddy.module.css'; import { EditableCell } from './EditableCell'; interface TableCellProps { cell: Cell; showGrouping?: boolean; } export function TableCell({ cell, showGrouping }: TableCellProps) { const isSelectionCol = cell.column.id === SELECTION_COLUMN_ID; const isEditing = useGriddyStore((s) => s.isEditing); const focusedRowIndex = useGriddyStore((s) => s.focusedRowIndex); const focusedColumnId = useGriddyStore((s) => s.focusedColumnId); const setEditing = useGriddyStore((s) => s.setEditing); const setFocusedColumn = useGriddyStore((s) => s.setFocusedColumn); const onEditCommit = useGriddyStore((s) => s.onEditCommit); const tree = useGriddyStore((s) => s.tree); const treeLoadingNodes = useGriddyStore((s) => s.treeLoadingNodes); const selection = useGriddyStore((s) => s.selection); if (isSelectionCol) { return ; } const griddyColumn = getGriddyColumn(cell.column); const rowIndex = cell.row.index; const columnId = cell.column.id; const isEditable = (griddyColumn as any)?.editable ?? false; const isFocusedCell = isEditing && focusedRowIndex === rowIndex && focusedColumnId === columnId; const handleCommit = async (value: unknown) => { if (onEditCommit) { await onEditCommit(cell.row.id, columnId, value); } setEditing(false); setFocusedColumn(null); }; const handleCancel = () => { setEditing(false); setFocusedColumn(null); }; const handleDoubleClick = () => { if (isEditable) { setEditing(true); setFocusedColumn(columnId); } }; const isPinned = cell.column.getIsPinned(); const leftOffset = isPinned === 'left' ? cell.column.getStart('left') : undefined; const rightOffset = isPinned === 'right' ? cell.column.getAfter('right') : undefined; const isGrouped = cell.getIsGrouped(); const isAggregated = cell.getIsAggregated(); const isPlaceholder = cell.getIsPlaceholder(); // Tree support const depth = cell.row.depth; const canExpand = cell.row.getCanExpand(); const isExpanded = cell.row.getIsExpanded(); const hasSelection = selection?.mode !== 'none'; const columnIndex = cell.column.getIndex(); // First content column is index 0 if no selection, or index 1 if selection enabled const isFirstColumn = hasSelection ? columnIndex === 1 : columnIndex === 0; const indentSize = tree?.indentSize ?? 20; const showTreeButton = tree?.enabled && isFirstColumn && tree?.showExpandIcon !== false; return (
{showTreeButton && ( cell.row.toggleExpanded()} /> )} {showGrouping && isGrouped && ( )} {isFocusedCell && isEditable ? ( ) : isGrouped ? ( <> {flexRender(cell.column.columnDef.cell, cell.getContext())} ({cell.row.subRows.length}) ) : isAggregated ? ( flexRender( cell.column.columnDef.aggregatedCell ?? cell.column.columnDef.cell, cell.getContext() ) ) : isPlaceholder ? null : ( flexRender(cell.column.columnDef.cell, cell.getContext()) )}
); } function RowCheckbox({ cell }: TableCellProps) { const row = cell.row; const isPinned = cell.column.getIsPinned(); const leftOffset = isPinned === 'left' ? cell.column.getStart('left') : undefined; const rightOffset = isPinned === 'right' ? cell.column.getAfter('right') : undefined; return (
e.stopPropagation()} size="xs" />
); }