Skip to content

Instantly share code, notes, and snippets.

@CarmeloRicarte
Last active February 23, 2023 12:02
Show Gist options
  • Save CarmeloRicarte/7377daaec7e05081a0aeebb6b0fddf19 to your computer and use it in GitHub Desktop.
Save CarmeloRicarte/7377daaec7e05081a0aeebb6b0fddf19 to your computer and use it in GitHub Desktop.
Custom table witn React, Typescript, CSS without libraries
.table-container {
display: flex;
flex-direction: column;
align-items: center;
margin-top: 20px;
}
.table {
width: 100%;
max-width: 90vw;
margin-bottom: 20px;
border-collapse: collapse;
background-color: #363636;
box-shadow: 0 0 10px rgba(255, 255, 255, 0.15);
}
.table-div-action-buttons {
display: flex;
justify-content: end;
margin-bottom: 0.5rem;
}
.table th,
.table td {
padding: 12px;
}
.table th {
font-weight: 600;
background-color: var(--header-background-color);
color: #fff;
border-bottom: 2px solid #ddd;
}
.table tr:hover {
background-color: #f5f5f5;
color: var(--background-color);
}
.table-action-button {
margin-right: 5px;
color: #fff;
background-color: var(--primary-color);
border: none;
padding: 8px 16px;
border-radius: 4px;
cursor: pointer;
transition: background-color 0.3s ease;
}
.table-action-button:hover {
background-color: #f57c00;
}
.pagination {
display: flex;
justify-content: center;
margin-top: 20px;
}
.pagination-button {
margin: 0 5px;
padding: 8px 16px;
border: none;
border-radius: 4px;
background-color: var(--background-color);
color: var(--primary-color);
cursor: pointer;
transition: background-color 0.3s ease;
}
.pagination-button:hover {
background-color: var(--secondary-color);
color: #fff;
}
.pagination-button:disabled {
color: #999;
cursor: not-allowed;
}
import './CustomTable.css';
import { useState } from 'react';
import { ObjetoGenerico } from '../../@types/app';
interface CustomTableProps {
data: Array<ObjetoGenerico<any>>;
columns: CustomTableColumn[];
perPage?: number;
actions?: CustomTableAction[];
}
interface CustomTableColumn {
key: string;
header: string;
render?: (value: any) => React.ReactNode;
}
interface CustomTableAction {
label: string;
onClick: () => void;
}
export function CustomTable({
data,
columns,
perPage = 10,
actions,
}: CustomTableProps) {
const [page, setPage] = useState(1);
const startIndex = (page - 1) * perPage;
const endIndex = startIndex + perPage;
const paginatedData = data.slice(startIndex, endIndex);
return (
<div className='table-container'>
<table className='table'>
<caption>
{actions != null && (
<div className='table-div-action-buttons'>
{actions.map((action, actionIndex) => (
<button
key={actionIndex}
onClick={() => {
action.onClick();
}}
className='table-action-button'
>
{action.label}
</button>
))}
</div>
)}
</caption>
<thead>
<tr>
{columns.map((column) => (
<th key={column.key}>{column.header}</th>
))}
</tr>
</thead>
<tbody>
{paginatedData.map((row, rowIndex) => (
<tr key={rowIndex}>
{columns.map((column, columnIndex) => (
<td key={columnIndex}>
{column.render != null
? column.render(row[column.key])
: row[column.key]}
</td>
))}
</tr>
))}
</tbody>
</table>
<div className='pagination'>
<button
onClick={() => {
setPage((prevPage) => prevPage - 1);
}}
disabled={page === 1}
className='pagination-button'
>
Anterior
</button>
<button
onClick={() => {
setPage((prevPage) => prevPage + 1);
}}
disabled={endIndex >= data.length}
className='pagination-button'
>
Siguiente
</button>
</div>
</div>
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment