Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 46 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,26 +129,61 @@ function App() {

The MultiLevelTable component accepts the following props:

#### Data and Configuration Props
| Prop | Type | Required | Default | Description |
|------|------|----------|---------|-------------|
| data | array | Yes | - | Array of data objects to display in the table |
| columns | array | Yes | - | Array of column configurations |
| data | DataItem[] | Yes | - | Array of data objects to display in the table |
| columns | Column[] | Yes | - | Array of column configurations |
| pageSize | number | No | 10 | Number of rows to display per page |
| theme | object | No | - | Custom theme object for styling the table |
| theme | ThemeProps | No | - | Custom theme object for styling the table |
| renderCustomPagination | function | No | null | Custom pagination component render function |
| sortable | boolean | No | false | Enable/disable sorting functionality |
| ascendingIcon | ReactNode | No | - | Custom icon for ascending sort |
| descendingIcon | ReactNode | No | - | Custom icon for descending sort |
| expandIcon | ReactNode | No | - | Custom icon for expanding rows |
| selectable | boolean | No | false | Enable/disable row selection |
| onSelectionChange | function | No | - | Callback function when selection changes |
| onRowClick | function | No | - | Callback function when a parent row is clicked |
| onDelete | function | No | - | Callback function for row deletion |
| searchable | boolean | No | true | Enable/disable global search functionality |
| filterable | boolean | No | true | Enable/disable column filtering |
| exportable | boolean | No | false | Enable/disable data export functionality |
| exportFormats | array | No | ['csv', 'excel'] | Available export formats |
| onExport | function | No | - | Custom export handler function |

#### State Props
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| selectionState | SelectionState | Yes | Current selection state with selected rows and all selected flag |
| searchTerm | string | Yes | Current search term for filtering data |
| selectedFilterValues | Set<string \| number> | Yes | Currently selected filter values |
| deletePopup | object | Yes | Delete confirmation popup state (isOpen, itemId, itemName) |
| bulkDeletePopup | object | Yes | Bulk delete confirmation popup state (isOpen, selectedCount) |
| openDropdowns | Set<string> | Yes | Set of currently open dropdown IDs |
| expandedRows | Set<string \| number> | Yes | Set of currently expanded row IDs |

#### Handler Props
| Prop | Type | Description |
|------|------|-------------|
| onSearchChange | (searchTerm: string) => void | Updates the search term for filtering data |
| onFilterChange | (values: Set<string \| number>) => void | Updates the selected filter values |
| onDeleteClick | (itemId: string \| number, itemName: string) => void | Handles delete button click for a specific row |
| onDeleteConfirm | () => void | Confirms the delete action for the selected row |
| onDeleteCancel | () => void | Cancels the delete action and closes popup |
| onBulkDeleteClick | () => void | Handles bulk delete button click for selected rows |
| onBulkDeleteConfirm | () => void | Confirms the bulk delete action for selected rows |
| onBulkDeleteCancel | () => void | Cancels the bulk delete action and closes popup |
| onDropdownToggle | (buttonId: string, isOpen: boolean) => void | Toggles dropdown open/close state for action buttons |
| onDropdownClose | (buttonId: string) => void | Closes a specific dropdown by ID |
| onButtonClick | (button: ButtonConfig) => void | Handles click events for action buttons (export, filter, etc.) |
| onSelectAll | () => void | Handles select all checkbox click to select/deselect all rows |
| onRowSelect | (rowId: string \| number) => void | Handles individual row selection checkbox click |
| onRowToggle | (rowId: string \| number) => void | Handles row expand/collapse toggle for nested rows |

#### Additional Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| onRowClick | (row: DataItem) => void | - | Callback function when a parent row is clicked |
| searchableColumns | string[] | - | Array of column keys to search in |
| showSearchBar | boolean | true | Whether to show the search bar |
| filterColumn | string | - | The column to filter by |
| tableTitle | string | - | Title displayed above the table |
| tableSubtitle | string | - | Subtitle displayed below the table title |
| showDarkMode | boolean | false | Whether to show dark mode toggle button |
| isDarkMode | boolean | false | Current dark mode state |
| onToggleTheme | () => void | - | Callback function to toggle between light/dark themes |

## 3. Customization

Expand Down
35 changes: 19 additions & 16 deletions src/components/MultiLevelTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -438,22 +438,25 @@ export const MultiLevelTable: React.FC<MultiLevelTableProps> = ({
if (!children || !expandedRows.has(parentId)) return null;

return children.map((child) => (
<TableRow
key={child.id}
row={child}
columns={columns}
hasChildren={!!child.children && child.children.length > 0}
isExpanded={expandedRows.has(child.id)}
onToggle={() => onRowToggle(child.id)}
level={level}
theme={mergedTheme}
selectable={selectable}
isRowSelected={selectionState.selectedRows.has(child.id)}
onRowSelect={() => onRowSelect(child.id)}
onRowClick={onRowClick}
onDelete={handleDeleteClick}
expandIcon={expandIcon}
/>
<React.Fragment key={child.id}>
<TableRow
row={child}
columns={columns}
hasChildren={!!child.children && child.children.length > 0}
isExpanded={expandedRows.has(child.id)}
onToggle={() => onRowToggle(child.id)}
level={level}
theme={mergedTheme}
selectable={selectable}
isRowSelected={selectionState.selectedRows.has(child.id)}
onRowSelect={() => onRowSelect(child.id)}
onRowClick={onRowClick}
onDelete={handleDeleteClick}
expandIcon={expandIcon}
/>
{/* Recursively render nested children */}
{child.children && child.children.length > 0 && renderNestedRows(child.id, level + 1)}
</React.Fragment>
));
};

Expand Down
7 changes: 5 additions & 2 deletions src/components/TableCell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -108,14 +108,17 @@ export const TableCell: React.FC<TableCellProps> = ({
cell.render('Cell')
) : (
<>
{hasChildren ? (
{/* Only show expand button in the first column when row has children */}
{index === 0 && hasChildren ? (
<div
onClick={handleExpandClick}
className="expand-button"
>
{expandIcon || <ExpandIcon isExpanded={isExpanded} theme={theme} mode="expand" />}
</div>
) : <div className="expand-button" />}
) : index === 0 ? (
<div className="expand-button" />
) : null}
{cell.render('Cell')}
</>
)}
Expand Down
21 changes: 13 additions & 8 deletions src/components/TableRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -141,14 +141,19 @@ export const TableRow: React.FC<TableRowProps> = ({
<div className="placeholder-spacer" />
)}

<div
onClick={handleExpandClick}
className={`expand-button ${isParentRow || index !== 0 ? 'parent-row-expand-button' : 'nested-row-expand-button'} ${hasChildren && index === 0 ? 'expand-button-visible' : 'expand-button-hidden'}`}
>
{expandIcon || (
<ExpandIcon isExpanded={isExpanded} theme={theme} mode="expand" />
)}
</div>
{/* Only show expand button in the first column when row has children */}
{index === 0 && (
<div
onClick={handleExpandClick}
className={`expand-button ${isParentRow || index !== 0 ? 'parent-row-expand-button' : 'nested-row-expand-button'} ${hasChildren ? 'expand-button-visible' : 'expand-button-hidden'}`}
>
{hasChildren ? (
expandIcon || (
<ExpandIcon isExpanded={isExpanded} theme={theme} mode="expand" />
)
) : null}
</div>
)}

{column.render
? column.render(displayValue, dataItem)
Expand Down
8 changes: 4 additions & 4 deletions src/styles/Pagination.css
Original file line number Diff line number Diff line change
Expand Up @@ -92,14 +92,14 @@
.pagination-total-items {
display: block;
}
}

}
/* Hide total items text on screens smaller than 798px */
@media (max-width: 797px) {
.pagination-total-items {
display: none;
}
}

.pagination-container {
min-width: 1200px; /* Maintain minimum width */
overflow-x: auto; /* Enable horizontal scroll */
Expand Down
Loading