Skip to content

Commit b728a6b

Browse files
Fix: table row style
1 parent 0c83f71 commit b728a6b

File tree

5 files changed

+87
-41
lines changed

5 files changed

+87
-41
lines changed

README.md

Lines changed: 46 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -129,26 +129,61 @@ function App() {
129129

130130
The MultiLevelTable component accepts the following props:
131131

132+
#### Data and Configuration Props
132133
| Prop | Type | Required | Default | Description |
133134
|------|------|----------|---------|-------------|
134-
| data | array | Yes | - | Array of data objects to display in the table |
135-
| columns | array | Yes | - | Array of column configurations |
135+
| data | DataItem[] | Yes | - | Array of data objects to display in the table |
136+
| columns | Column[] | Yes | - | Array of column configurations |
136137
| pageSize | number | No | 10 | Number of rows to display per page |
137-
| theme | object | No | - | Custom theme object for styling the table |
138+
| theme | ThemeProps | No | - | Custom theme object for styling the table |
138139
| renderCustomPagination | function | No | null | Custom pagination component render function |
139140
| sortable | boolean | No | false | Enable/disable sorting functionality |
140141
| ascendingIcon | ReactNode | No | - | Custom icon for ascending sort |
141142
| descendingIcon | ReactNode | No | - | Custom icon for descending sort |
142143
| expandIcon | ReactNode | No | - | Custom icon for expanding rows |
143144
| selectable | boolean | No | false | Enable/disable row selection |
144-
| onSelectionChange | function | No | - | Callback function when selection changes |
145-
| onRowClick | function | No | - | Callback function when a parent row is clicked |
146-
| onDelete | function | No | - | Callback function for row deletion |
147-
| searchable | boolean | No | true | Enable/disable global search functionality |
148-
| filterable | boolean | No | true | Enable/disable column filtering |
149-
| exportable | boolean | No | false | Enable/disable data export functionality |
150-
| exportFormats | array | No | ['csv', 'excel'] | Available export formats |
151-
| onExport | function | No | - | Custom export handler function |
145+
146+
#### State Props
147+
| Prop | Type | Required | Description |
148+
|------|------|----------|-------------|
149+
| selectionState | SelectionState | Yes | Current selection state with selected rows and all selected flag |
150+
| searchTerm | string | Yes | Current search term for filtering data |
151+
| selectedFilterValues | Set<string \| number> | Yes | Currently selected filter values |
152+
| deletePopup | object | Yes | Delete confirmation popup state (isOpen, itemId, itemName) |
153+
| bulkDeletePopup | object | Yes | Bulk delete confirmation popup state (isOpen, selectedCount) |
154+
| openDropdowns | Set<string> | Yes | Set of currently open dropdown IDs |
155+
| expandedRows | Set<string \| number> | Yes | Set of currently expanded row IDs |
156+
157+
#### Handler Props
158+
| Prop | Type | Description |
159+
|------|------|-------------|
160+
| onSearchChange | (searchTerm: string) => void | Updates the search term for filtering data |
161+
| onFilterChange | (values: Set<string \| number>) => void | Updates the selected filter values |
162+
| onDeleteClick | (itemId: string \| number, itemName: string) => void | Handles delete button click for a specific row |
163+
| onDeleteConfirm | () => void | Confirms the delete action for the selected row |
164+
| onDeleteCancel | () => void | Cancels the delete action and closes popup |
165+
| onBulkDeleteClick | () => void | Handles bulk delete button click for selected rows |
166+
| onBulkDeleteConfirm | () => void | Confirms the bulk delete action for selected rows |
167+
| onBulkDeleteCancel | () => void | Cancels the bulk delete action and closes popup |
168+
| onDropdownToggle | (buttonId: string, isOpen: boolean) => void | Toggles dropdown open/close state for action buttons |
169+
| onDropdownClose | (buttonId: string) => void | Closes a specific dropdown by ID |
170+
| onButtonClick | (button: ButtonConfig) => void | Handles click events for action buttons (export, filter, etc.) |
171+
| onSelectAll | () => void | Handles select all checkbox click to select/deselect all rows |
172+
| onRowSelect | (rowId: string \| number) => void | Handles individual row selection checkbox click |
173+
| onRowToggle | (rowId: string \| number) => void | Handles row expand/collapse toggle for nested rows |
174+
175+
#### Additional Props
176+
| Prop | Type | Default | Description |
177+
|------|------|---------|-------------|
178+
| onRowClick | (row: DataItem) => void | - | Callback function when a parent row is clicked |
179+
| searchableColumns | string[] | - | Array of column keys to search in |
180+
| showSearchBar | boolean | true | Whether to show the search bar |
181+
| filterColumn | string | - | The column to filter by |
182+
| tableTitle | string | - | Title displayed above the table |
183+
| tableSubtitle | string | - | Subtitle displayed below the table title |
184+
| showDarkMode | boolean | false | Whether to show dark mode toggle button |
185+
| isDarkMode | boolean | false | Current dark mode state |
186+
| onToggleTheme | () => void | - | Callback function to toggle between light/dark themes |
152187

153188
## 3. Customization
154189

src/components/MultiLevelTable.tsx

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -438,22 +438,25 @@ export const MultiLevelTable: React.FC<MultiLevelTableProps> = ({
438438
if (!children || !expandedRows.has(parentId)) return null;
439439

440440
return children.map((child) => (
441-
<TableRow
442-
key={child.id}
443-
row={child}
444-
columns={columns}
445-
hasChildren={!!child.children && child.children.length > 0}
446-
isExpanded={expandedRows.has(child.id)}
447-
onToggle={() => onRowToggle(child.id)}
448-
level={level}
449-
theme={mergedTheme}
450-
selectable={selectable}
451-
isRowSelected={selectionState.selectedRows.has(child.id)}
452-
onRowSelect={() => onRowSelect(child.id)}
453-
onRowClick={onRowClick}
454-
onDelete={handleDeleteClick}
455-
expandIcon={expandIcon}
456-
/>
441+
<React.Fragment key={child.id}>
442+
<TableRow
443+
row={child}
444+
columns={columns}
445+
hasChildren={!!child.children && child.children.length > 0}
446+
isExpanded={expandedRows.has(child.id)}
447+
onToggle={() => onRowToggle(child.id)}
448+
level={level}
449+
theme={mergedTheme}
450+
selectable={selectable}
451+
isRowSelected={selectionState.selectedRows.has(child.id)}
452+
onRowSelect={() => onRowSelect(child.id)}
453+
onRowClick={onRowClick}
454+
onDelete={handleDeleteClick}
455+
expandIcon={expandIcon}
456+
/>
457+
{/* Recursively render nested children */}
458+
{child.children && child.children.length > 0 && renderNestedRows(child.id, level + 1)}
459+
</React.Fragment>
457460
));
458461
};
459462

src/components/TableCell.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,14 +108,17 @@ export const TableCell: React.FC<TableCellProps> = ({
108108
cell.render('Cell')
109109
) : (
110110
<>
111-
{hasChildren ? (
111+
{/* Only show expand button in the first column when row has children */}
112+
{index === 0 && hasChildren ? (
112113
<div
113114
onClick={handleExpandClick}
114115
className="expand-button"
115116
>
116117
{expandIcon || <ExpandIcon isExpanded={isExpanded} theme={theme} mode="expand" />}
117118
</div>
118-
) : <div className="expand-button" />}
119+
) : index === 0 ? (
120+
<div className="expand-button" />
121+
) : null}
119122
{cell.render('Cell')}
120123
</>
121124
)}

src/components/TableRow.tsx

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -141,14 +141,19 @@ export const TableRow: React.FC<TableRowProps> = ({
141141
<div className="placeholder-spacer" />
142142
)}
143143

144-
<div
145-
onClick={handleExpandClick}
146-
className={`expand-button ${isParentRow || index !== 0 ? 'parent-row-expand-button' : 'nested-row-expand-button'} ${hasChildren && index === 0 ? 'expand-button-visible' : 'expand-button-hidden'}`}
147-
>
148-
{expandIcon || (
149-
<ExpandIcon isExpanded={isExpanded} theme={theme} mode="expand" />
150-
)}
151-
</div>
144+
{/* Only show expand button in the first column when row has children */}
145+
{index === 0 && (
146+
<div
147+
onClick={handleExpandClick}
148+
className={`expand-button ${isParentRow || index !== 0 ? 'parent-row-expand-button' : 'nested-row-expand-button'} ${hasChildren ? 'expand-button-visible' : 'expand-button-hidden'}`}
149+
>
150+
{hasChildren ? (
151+
expandIcon || (
152+
<ExpandIcon isExpanded={isExpanded} theme={theme} mode="expand" />
153+
)
154+
) : null}
155+
</div>
156+
)}
152157

153158
{column.render
154159
? column.render(displayValue, dataItem)

src/styles/Pagination.css

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -92,14 +92,14 @@
9292
.pagination-total-items {
9393
display: block;
9494
}
95-
}
96-
95+
}
96+
9797
/* Hide total items text on screens smaller than 798px */
9898
@media (max-width: 797px) {
9999
.pagination-total-items {
100100
display: none;
101-
}
102-
101+
}
102+
103103
.pagination-container {
104104
min-width: 1200px; /* Maintain minimum width */
105105
overflow-x: auto; /* Enable horizontal scroll */

0 commit comments

Comments
 (0)