UNPKG

@ackplus/react-tanstack-data-table

Version:

A powerful React data table component built with MUI and TanStack Table

120 lines (119 loc) 7.42 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.DataTableRow = DataTableRow; const jsx_runtime_1 = require("react/jsx-runtime"); /** * DataTableRow Component * * Renders individual table rows with support for: * - Column pinning * - Row expansion * - Hover effects * - Striped styling */ const material_1 = require("@mui/material"); const react_table_1 = require("@tanstack/react-table"); const utils_1 = require("../../utils"); const slot_helpers_1 = require("../../utils/slot-helpers"); const data_table_context_1 = require("../../contexts/data-table-context"); /** * Individual table row component with cell rendering and expansion support */ function DataTableRow(props) { var _a; const { row, enableHover = true, enableStripes = false, isOdd = false, renderSubComponent, disableStickyHeader = false, onRowClick, selectOnRowClick = false, cellProps, expandedRowProps, expandedCellProps, containerSx, expandedContainerSx, slots, slotProps, ...otherProps } = props; const { table } = (0, data_table_context_1.useDataTableContext)(); // Extract slot-specific props with enhanced merging const cellSlotProps = (0, slot_helpers_1.extractSlotProps)(slotProps, 'cell'); const expandedRowSlotProps = (0, slot_helpers_1.extractSlotProps)(slotProps, 'expandedRow'); const rowSlotProps = (0, slot_helpers_1.extractSlotProps)(slotProps, 'row'); const CellSlot = (0, slot_helpers_1.getSlotComponent)(slots, 'cell', material_1.TableCell); const ExpandedRowSlot = (0, slot_helpers_1.getSlotComponent)(slots, 'expandedRow', material_1.TableRow); const TableRowSlot = (0, slot_helpers_1.getSlotComponent)(slots, 'row', material_1.TableRow); // Handle row click const handleRowClick = (event) => { // Check if click target is a checkbox, button, or interactive element const target = event.target; // Check for various interactive elements const isCheckboxClick = target.closest('input[type="checkbox"]') !== null; const isButtonClick = target.closest('button') !== null; const isLinkClick = target.closest('a') !== null; // Check for elements with interactive roles (button, checkbox, switch, etc.) const isInteractiveRole = target.closest('[role="button"]') !== null || target.closest('[role="checkbox"]') !== null || target.closest('[role="switch"]') !== null || target.closest('[role="menuitem"]') !== null; // Determine if this is an interactive element click const isInteractiveClick = isCheckboxClick || isButtonClick || isLinkClick || isInteractiveRole; // If selectOnRowClick is enabled and it's not an interactive element click, toggle selection if (selectOnRowClick && !isInteractiveClick && (table === null || table === void 0 ? void 0 : table.toggleRowSelected)) { table.toggleRowSelected(row.id); } // Only call onRowClick if it's not an interactive element click if (onRowClick && !isInteractiveClick) { onRowClick(event, row); } }; // Merge all props for maximum flexibility const mergedRowProps = (0, slot_helpers_1.mergeSlotProps)({ hover: enableHover, selected: !!((_a = table === null || table === void 0 ? void 0 : table.getIsRowSelected) === null || _a === void 0 ? void 0 : _a.call(table, row.id)), onClick: (onRowClick || selectOnRowClick) ? handleRowClick : undefined, sx: (theme) => ({ // set the row background as a variable '--row-bg': enableStripes && isOdd ? theme.palette.action.hover : theme.palette.background.paper, backgroundColor: 'var(--row-bg)', // keep the variable in sync for hover/selected ...(enableHover && { '&:hover': { '--row-bg': theme.palette.action.hover }, }), [`&.${material_1.tableRowClasses.selected}`]: { '--row-bg': theme.palette.action.selected, backgroundColor: 'var(--row-bg)', }, // Add cursor pointer if row is clickable ...((onRowClick || selectOnRowClick) && { cursor: 'pointer', }), ...containerSx, }), }, rowSlotProps, otherProps); const mergedExpandedRowProps = (0, slot_helpers_1.mergeSlotProps)({ sx: expandedContainerSx, }, expandedRowSlotProps, expandedRowProps || {}); return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(TableRowSlot, { ...mergedRowProps, children: row.getVisibleCells().map(cell => { var _a, _b; const isPinned = cell.column.getIsPinned(); const pinnedPosition = isPinned ? cell.column.getStart('left') : undefined; const pinnedRightPosition = isPinned === 'right' ? cell.column.getAfter('right') : undefined; const alignment = (0, utils_1.getColumnAlignment)(cell.column.columnDef); // Get minSize and maxSize from column definition const minSize = (_a = cell.column.columnDef) === null || _a === void 0 ? void 0 : _a.minSize; const maxSize = cell.column.columnDef.maxSize; const wrapText = (_b = cell.column.columnDef.wrapText) !== null && _b !== void 0 ? _b : false; const mergedCellProps = (0, slot_helpers_1.mergeSlotProps)({ align: alignment, sx: { ...(0, utils_1.getPinnedColumnStyle)({ width: cell.column.getSize() || 'auto', minWidth: minSize !== undefined ? minSize : undefined, maxWidth: maxSize !== undefined ? maxSize : undefined, isPinned, pinnedPosition, pinnedRightPosition, zIndex: isPinned ? 9 : 1, disableStickyHeader, isLastLeftPinnedColumn: isPinned === 'left' && cell.column.getIsLastColumn('left'), isFirstRightPinnedColumn: isPinned === 'right' && cell.column.getIsFirstColumn('right'), wrapText, }), }, }, cellSlotProps, cellProps || {}); return ((0, jsx_runtime_1.jsx)(CellSlot, { ...mergedCellProps, children: (0, react_table_1.flexRender)(cell.column.columnDef.cell, cell.getContext()) }, cell.id)); }) }), row.getIsExpanded() && renderSubComponent ? ((0, jsx_runtime_1.jsx)(ExpandedRowSlot, { ...mergedExpandedRowProps, children: (0, jsx_runtime_1.jsx)(CellSlot, { colSpan: row.getVisibleCells().length, sx: { py: 0, ...expandedCellProps === null || expandedCellProps === void 0 ? void 0 : expandedCellProps.sx, }, ...(0, slot_helpers_1.mergeSlotProps)({}, cellSlotProps, expandedCellProps || {}), children: (0, jsx_runtime_1.jsx)(material_1.Collapse, { in: row.getIsExpanded(), timeout: "auto", unmountOnExit: true, children: renderSubComponent(row) }) }) })) : null] })); }