diff --git a/src/App.tsx b/src/App.tsx index 6b62e8f..f13ea66 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -421,6 +421,11 @@ const App: React.FC = () => { return
Custom Pagination
; }; + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const renderCustomExpandButton = () => { + return
; + }; + return (
= ({ sortable = false, ascendingIcon, descendingIcon, + expandIcon, }) => { const mergedTheme = mergeThemeProps(defaultThemeProps, theme); const [filterInput, setFilterInput] = useState(""); @@ -184,6 +186,7 @@ export const MultiLevelTable: React.FC = ({ onToggle={() => hasChildren && toggleRow(child.id)} level={level} theme={mergedTheme} + expandIcon={expandIcon} /> {renderNestedRows(child.id, level + 1)} @@ -216,6 +219,7 @@ export const MultiLevelTable: React.FC = ({ isExpanded={expandedRows.has(parentId)} onToggle={() => hasChildren && toggleRow(parentId)} theme={mergedTheme} + expandIcon={expandIcon} /> {renderNestedRows(parentId)} diff --git a/src/components/TableCell.tsx b/src/components/TableCell.tsx index 0a70e51..58acd14 100644 --- a/src/components/TableCell.tsx +++ b/src/components/TableCell.tsx @@ -18,6 +18,7 @@ import '../styles/TableCell.css'; * @property {() => void} onToggle - Function to toggle row expansion * @property {number} [paddingLeft=0] - Left padding for nested cells * @property {ThemeProps} theme - Theme properties + * @property {React.ReactNode} [expandIcon] - Custom expand icon */ interface TableCellProps { cell: Cell; @@ -26,6 +27,7 @@ interface TableCellProps { onToggle: () => void; paddingLeft?: number; theme: ThemeProps; + expandIcon?: React.ReactNode; } /** @@ -40,7 +42,8 @@ export const TableCell: React.FC = ({ isExpanded, onToggle, paddingLeft = 0, - theme + theme, + expandIcon, }) => { const { key, ...cellProps } = cell.getCellProps(); @@ -67,7 +70,7 @@ export const TableCell: React.FC = ({ onClick={handleExpandClick} className="expand-button" > - + {expandIcon || } ) :
} {cell.render('Cell')} diff --git a/src/components/TableHeader.tsx b/src/components/TableHeader.tsx index be8c97b..3fe2b86 100644 --- a/src/components/TableHeader.tsx +++ b/src/components/TableHeader.tsx @@ -100,8 +100,9 @@ export const TableHeader: React.FC = ({ onChange={(e) => column.setFilter?.(e.target.value)} placeholder={`Filter ${column.title || column.id}...`} style={{ - color: theme.table?.header?.textColor, - borderColor: theme.table?.header?.textColor, + color: theme.table?.filter?.textColor, + borderColor: theme.table?.filter?.borderColor, + backgroundColor: theme.table?.filter?.background, }} />
diff --git a/src/components/TableRow.tsx b/src/components/TableRow.tsx index f4208e7..5b474e7 100644 --- a/src/components/TableRow.tsx +++ b/src/components/TableRow.tsx @@ -19,6 +19,7 @@ import "../styles/TableRow.css"; * @property {() => void} onToggle - Function to toggle row expansion * @property {number} [level=0] - Nesting level of the row * @property {ThemeProps} theme - Theme properties + * @property {React.ReactNode} [expandIcon] - Custom expand icon */ interface TableRowProps { row: Row | DataItem; @@ -28,6 +29,7 @@ interface TableRowProps { onToggle: () => void; level?: number; theme: ThemeProps; + expandIcon?: React.ReactNode; } /** @@ -44,6 +46,7 @@ export const TableRow: React.FC = ({ onToggle, level = 0, theme, + expandIcon, }) => { const getRowClassName = () => { const classes = ["table-row"]; @@ -91,16 +94,15 @@ export const TableRow: React.FC = ({ >
{hasChildren && index === 0 ? ( - ) : (
)} - {column.render + {column.render ? column.render(displayValue, dataItem) : String(displayValue)}
@@ -131,6 +133,7 @@ export const TableRow: React.FC = ({ onToggle={onToggle} paddingLeft={level > 0 ? 32 + level * 16 : 0} theme={theme} + expandIcon={expandIcon} /> ))} diff --git a/src/defaultThemeProps.ts b/src/defaultThemeProps.ts index a7a753d..b07195d 100644 --- a/src/defaultThemeProps.ts +++ b/src/defaultThemeProps.ts @@ -2,27 +2,30 @@ import type { ThemeProps } from './types/theme'; export const defaultThemeProps: ThemeProps = { colors: { - primaryColor: '#007bff', - textColor: '#212529', - borderColor: '#dee2e6', background: '#ffffff', + primaryColor: '#3498db', + borderColor: '#e0e0e0', }, table: { header: { - background: '#e9ecef', - textColor: '#495057', - borderColor: '#dee2e6', + background: '#2c3e50', + textColor: '#ffffff', }, row: { mainBackground: '#ffffff', nestedBackground: '#f8f9fa', - expandedBackground: '#e9ecef', - hoverBackground: '#f8f9fa', + expandedBackground: '#f1f3f5', }, cell: { - textColor: '#212529', - borderColor: '#dee2e6', - nestedPadding: '1rem', + textColor: '#333333', + borderColor: '#e0e0e0', + }, + filter: { + background: 'transparent', + textColor: '#ffffff', + borderColor: '#ffffff', + focusBorderColor: '#3498db', + placeholderColor: 'rgba(255, 255, 255, 0.7)', }, }, pagination: { diff --git a/src/themes.ts b/src/themes.ts index 4e1495d..96f58b3 100644 --- a/src/themes.ts +++ b/src/themes.ts @@ -2,27 +2,30 @@ import type { ThemeProps } from './types/theme'; export const lightTheme: ThemeProps = { colors: { + background: '#ffffff', primaryColor: '#007bff', - textColor: '#212529', borderColor: '#dee2e6', - background: '#ffffff', }, table: { header: { background: '#e9ecef', textColor: '#495057', + }, + cell: { + textColor: '#212529', borderColor: '#dee2e6', }, row: { mainBackground: '#ffffff', nestedBackground: '#f8f9fa', expandedBackground: '#e9ecef', - hoverBackground: '#f8f9fa', }, - cell: { - textColor: '#212529', - borderColor: '#dee2e6', - nestedPadding: '1rem', + filter: { + background: 'transparent', + textColor: '#495057', + borderColor: '#495057', + focusBorderColor: '#007bff', + placeholderColor: 'rgba(73, 80, 87, 0.7)', }, }, pagination: { @@ -47,27 +50,30 @@ export const lightTheme: ThemeProps = { export const darkTheme: ThemeProps = { colors: { + background: '#212529', primaryColor: '#0d6efd', - textColor: '#ffffff', borderColor: '#495057', - background: '#212529', }, table: { header: { background: '#2b3035', textColor: '#e9ecef', + }, + cell: { + textColor: '#e9ecef', borderColor: '#495057', }, row: { mainBackground: '#343a40', nestedBackground: '#2b3035', expandedBackground: '#212529', - hoverBackground: '#2b3035', }, - cell: { + filter: { + background: 'transparent', textColor: '#e9ecef', - borderColor: '#495057', - nestedPadding: '1rem', + borderColor: '#e9ecef', + focusBorderColor: '#0d6efd', + placeholderColor: 'rgba(233, 236, 239, 0.7)', }, }, pagination: { diff --git a/src/types/theme.ts b/src/types/theme.ts index 1857952..7c1e681 100644 --- a/src/types/theme.ts +++ b/src/types/theme.ts @@ -3,29 +3,32 @@ export type Theme = { light: ThemeProps; }; -export type ThemeProps = { +export interface ThemeProps { colors?: { + background?: string; primaryColor?: string; - textColor?: string; borderColor?: string; - background?: string; }; table?: { header?: { background?: string; textColor?: string; + }; + cell?: { + textColor?: string; borderColor?: string; }; row?: { mainBackground?: string; nestedBackground?: string; expandedBackground?: string; - hoverBackground?: string; }; - cell?: { + filter?: { + background?: string; textColor?: string; borderColor?: string; - nestedPadding?: string; + focusBorderColor?: string; + placeholderColor?: string; }; }; pagination?: { @@ -46,4 +49,4 @@ export type ThemeProps = { expandIcon?: { color?: string; }; -}; \ No newline at end of file +} \ No newline at end of file