Skip to content

Instantly share code, notes, and snippets.

@Saar25
Last active July 4, 2023 07:10
Show Gist options
  • Save Saar25/4321ebd576d25b65edbdaddb842954d5 to your computer and use it in GitHub Desktop.
Save Saar25/4321ebd576d25b65edbdaddb842954d5 to your computer and use it in GitHub Desktop.
React Generic Table Component
import styles from './generic-table.module.css';
export type TableElement = {
};
export type TableColumn<T extends TableElement> = {
title: string;
html: (e: T) => JSX.Element;
width?: number;
};
export type TableModel<T extends TableElement> = {
columns: TableColumn<T>[];
};
export type Props<T extends TableElement> = {
model: TableModel<T>;
elements: T[];
};
export const GenericTable = <T extends TableElement>({ model, elements }: Props<T>) => {
const sumWidth = model.columns.reduce((sum, column) => sum + (column.width || 1), 0);
const widthOf = (c: TableColumn<T>) => ((c.width || 1) / sumWidth) * 100;
return (
<div className={styles.genericTableContainer}>
<div className={styles.genericTableHeader}>
<div className={styles.genericTableRow}>
{model.columns.map(c =>
<div className={styles.genericTableCell} style={{ width: `${widthOf(c)}%` }}>
<span className={styles.genericTableCellText}>{c.title}</span>
</div>
)}
</div>
</div>
<div className={styles.genericTableBody}>
{elements.map(e =>
<div className={styles.genericTableRow}>
{model.columns.map(c =>
<div className={styles.genericTableCell} style={{ width: `${widthOf(c)}%` }}>
{c.html(e)}
</div>
)}
</div>
)}
</div>
</div>
);
};
.genericTableContainer {
margin: 30px 10%;
display: flex;
flex-direction: column;
font-size: 20px;
}
.genericTableBody {
flex-grow: 1;
}
.genericTableRow {
display: flex;
flex-direction: row;
border-bottom: 1px solid #555;
}
.genericTableRow:last-child {
border-bottom: 0;
}
.genericTableHeader > .genericTableRow {
border-bottom: 1px solid #555;
}
.genericTableCell {
padding: 10px;
text-align: center;
transition: 500ms background-color;
}
.genericTableCell:hover {
background-color: #333;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment