Last active
February 23, 2023 12:02
-
-
Save CarmeloRicarte/7377daaec7e05081a0aeebb6b0fddf19 to your computer and use it in GitHub Desktop.
Custom table witn React, Typescript, CSS without libraries
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.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; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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