Skip to main content

Table Basic

The Table Basic component provides a comprehensive set of HTML table variations with modern styling, responsive design, and advanced features like pagination. It offers multiple styling options and layouts for different use cases.

Overview​

The Table Basic component is designed to provide flexible table functionality with:

  • Multiple styling variants (bordered, striped, hover effects)
  • Responsive design with horizontal scrolling
  • Custom header and border colors
  • Caption support (top and bottom)
  • Table nesting capabilities
  • Built-in pagination integration
  • Status badges and custom cell content
  • Dark mode support

Basic Usage​

import { Table } from '@/components/atoms'

function MyComponent() {
return (
<Table responsive>
<thead>
<tr>
<th>Name</th>
<th>Email</th>
<th>Status</th>
</tr>
</thead>
<tbody>
<tr>
<td>John Doe</td>
<td>john@example.com</td>
<td>Active</td>
</tr>
<tr>
<td>Jane Smith</td>
<td>jane@example.com</td>
<td>Inactive</td>
</tr>
</tbody>
</Table>
)
}

Props​

PropTypeDefaultDescription
childrenReactNode-Table content (thead, tbody, tfoot)
responsivebooleanfalseEnable responsive horizontal scrolling
borderedbooleanfalseAdd borders to all table cells
stripedRowsbooleanfalseAdd zebra striping to table rows
stripedColsbooleanfalseAdd zebra striping to table columns
hoverbooleanfalseEnable hover effects on table rows
headPrimarybooleanfalseApply primary color to table header
borderColorstring-Custom border color (primary, secondary, etc.)
captionstring-Table caption text
captionTopbooleanfalsePosition caption at the top
classNamestring''Additional CSS classes

Table Variants​

Basic Table​

Simple table with minimal styling:

<Table responsive>
<thead>
<tr>
<th>Name</th>
<th>Created</th>
<th>Service</th>
<th>Status</th>
<th>Doctor</th>
</tr>
</thead>
<tbody>
<tr>
<td>Lukas MΓΌller</td>
<td>2024-06-01</td>
<td>Cardiology</td>
<td>In Treatment</td>
<td>Dr. Anna Schmidt</td>
</tr>
</tbody>
</Table>

Bordered Table​

Table with borders around all cells:

<Table bordered responsive>
<thead>
<tr>
<th>Name</th>
<th>Service</th>
<th>Status</th>
</tr>
</thead>
<tbody>
<tr>
<td>Sophie Dubois</td>
<td>Dermatology</td>
<td>Completed</td>
</tr>
</tbody>
</Table>

Striped Rows​

Table with alternating row colors:

<Table stripedRows responsive>
<thead>
<tr>
<th>Name</th>
<th>Service</th>
<th>Status</th>
</tr>
</thead>
<tbody>
<tr>
<td>Marek Nowak</td>
<td>Orthopedics</td>
<td>Waiting</td>
</tr>
<tr>
<td>Giulia Rossi</td>
<td>Pediatrics</td>
<td>In Queue</td>
</tr>
</tbody>
</Table>

Striped Columns​

Table with alternating column colors:

<Table stripedCols responsive>
<thead>
<tr>
<th>Name</th>
<th>Service</th>
<th>Status</th>
<th>Doctor</th>
</tr>
</thead>
<tbody>
<tr>
<td>Emma Johansson</td>
<td>Neurology</td>
<td>Under Examination</td>
<td>Dr. Erik Larsson</td>
</tr>
</tbody>
</Table>

Hover Effects​

Table with hover effects on rows:

<Table hover responsive bordered>
<thead>
<tr>
<th>Name</th>
<th>Service</th>
<th>Status</th>
</tr>
</thead>
<tbody>
<tr>
<td>Carlos Rodriguez</td>
<td>Oncology</td>
<td>In Treatment</td>
</tr>
</tbody>
</Table>

Header Styling​

Primary Header​

Table with primary colored header:

<Table headPrimary responsive bordered>
<thead>
<tr>
<th>Name</th>
<th>Service</th>
<th>Status</th>
<th>Doctor</th>
</tr>
</thead>
<tbody>
<tr>
<td>Yuki Tanaka</td>
<td>Radiology</td>
<td>Completed</td>
<td>Dr. Hiroshi Yamamoto</td>
</tr>
</tbody>
</Table>

Border Colors​

Custom Border Colors​

Table with custom border colors:

<Table bordered borderColor="primary" responsive>
<thead>
<tr>
<th>Name</th>
<th>Service</th>
<th>Status</th>
</tr>
</thead>
<tbody>
<tr>
<td>Aisha Patel</td>
<td>Gynecology</td>
<td>Waiting</td>
</tr>
</tbody>
</Table>

Available border colors:

  • primary - Blue border
  • secondary - Gray border
  • success - Green border
  • danger - Red border
  • warning - Yellow border
  • info - Cyan border

Table including footer section:

<Table bordered responsive>
<thead>
<tr>
<th>Name</th>
<th>Service</th>
<th>Status</th>
<th>Doctor</th>
</tr>
</thead>
<tbody>
<tr>
<td>Hans Weber</td>
<td>Urology</td>
<td>In Queue</td>
<td>Dr. Klaus Mueller</td>
</tr>
</tbody>
<tfoot>
<tr>
<th>Total Patients</th>
<th>-</th>
<th>1</th>
<th>-</th>
</tr>
</tfoot>
</Table>

Table with Caption​

Bottom Caption​

<Table bordered responsive>
<thead>
<tr>
<th>Name</th>
<th>Service</th>
<th>Status</th>
</tr>
</thead>
<tbody>
<tr>
<td>Isabella Silva</td>
<td>Endocrinology</td>
<td>Under Examination</td>
</tr>
</tbody>
</Table>
<div className="text-center text-gray-500 text-xs">Patient Data Table</div>

Top Caption​

<Table bordered caption="Patient Data Table (Top)" captionTop responsive>
<thead>
<tr>
<th>Name</th>
<th>Service</th>
<th>Status</th>
</tr>
</thead>
<tbody>
<tr>
<td>Ole Hansen</td>
<td>Cardiology</td>
<td>In Treatment</td>
</tr>
</tbody>
</Table>

Nested Tables​

Tables can be nested within other tables:

<Table bordered responsive>
<thead>
<tr>
<th>Department</th>
<th>Details</th>
</tr>
</thead>
<tbody>
<tr>
<td>Cardiology</td>
<td>
<Table bordered responsive>
<thead>
<tr>
<th>Doctor</th>
<th>Patients</th>
<th>Status</th>
</tr>
</thead>
<tbody>
<tr>
<td>Dr. Anna Schmidt</td>
<td>5</td>
<td>Available</td>
</tr>
</tbody>
</Table>
</td>
</tr>
</tbody>
</Table>

Status Badges​

Integrate status badges for enhanced data presentation:

import { Table, Badges } from '@/components/atoms'

const StatusBadge = ({ status }) => {
const getStatusClass = (status) => {
switch (status) {
case 'In Treatment':
return 'badges-info'
case 'Completed':
return 'badges-success'
case 'Waiting':
return 'badges-warning'
case 'In Queue':
return 'badges-secondary'
case 'Under Examination':
return 'badges-primary'
default:
return 'badges-dark'
}
}

const getShortStatus = (status) => {
switch (status) {
case 'In Treatment':
return 'Treatment'
case 'Completed':
return 'Done'
case 'Under Examination':
return 'Exam'
default:
return status
}
}

return (
<Badges className={getStatusClass(status)}>
{getShortStatus(status)}
</Badges>
)
}

// Usage in table
<Table responsive>
<tbody>
<tr>
<td>Fatima Al-Zahra</td>
<td>Dermatology</td>
<td>
<StatusBadge status="Completed" />
</td>
</tr>
</tbody>
</Table>

Pagination Integration​

Combine tables with pagination for large datasets:

import React, { useState } from 'react'
import { Table } from '@/components/atoms'
import { Card, Pagination } from '@/components/molecules'

const PaginatedTable = ({ data }) => {
const [currentPage, setCurrentPage] = useState(1)
const [pageSize, setPageSize] = useState(5)

const totalItems = data.length
const totalPages = Math.ceil(totalItems / pageSize)
const startIndex = (currentPage - 1) * pageSize
const endIndex = startIndex + pageSize
const currentData = data.slice(startIndex, endIndex)

const handlePageChange = (page) => {
setCurrentPage(page)
}

const handlePageSizeChange = (newPageSize) => {
setPageSize(newPageSize)
setCurrentPage(1)
}

return (
<Card>
<h4>Table with Pagination</h4>
<Table bordered responsive>
<thead>
<tr>
<th>Name</th>
<th>Created</th>
<th>Service</th>
<th>Status</th>
<th>Doctor</th>
</tr>
</thead>
<tbody>
{currentData.map((row, idx) => (
<tr key={idx}>
<td>{row.name}</td>
<td>{row.created}</td>
<td>{row.service}</td>
<td>
<StatusBadge status={row.status} />
</td>
<td>{row.doctor}</td>
</tr>
))}
</tbody>
</Table>

<div className="flex items-center justify-between mt-4">
<div className="flex items-center gap-4">
<div className="text-sm text-gray-600 dark:text-gray-400">
Showing {startIndex + 1} to {Math.min(endIndex, totalItems)} of {totalItems} results
</div>

<div className="flex items-center gap-2">
<span className="text-sm text-gray-600 dark:text-gray-400">Show</span>
<select
value={pageSize}
onChange={(e) => handlePageSizeChange(parseInt(e.target.value))}
className="px-2 py-1 text-sm border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
>
{[5, 10, 25, 50].map((size) => (
<option key={size} value={size}>
{size}
</option>
))}
</select>
<span className="text-sm text-gray-600 dark:text-gray-400">entries</span>
</div>

<div className="flex items-center gap-2">
<span className="text-sm text-gray-600 dark:text-gray-400">Go to</span>
<input
type="number"
min="1"
max={totalPages}
className="w-16 px-2 py-1 text-sm border border-gray-300 dark:border-gray-600 rounded-md bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100 text-center focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
onKeyPress={(e) => {
if (e.key === 'Enter') {
const page = parseInt(e.target.value)
if (page >= 1 && page <= totalPages) {
handlePageChange(page)
}
}
}}
/>
<span className="text-sm text-gray-600 dark:text-gray-400">page</span>
</div>
</div>

<Pagination
currentPage={currentPage}
totalPages={totalPages}
onPageChange={handlePageChange}
position="right"
/>
</div>
</Card>
)
}

Responsive Design​

The table component provides several responsive options:

Always Responsive​

<Table responsive>
{/* Table content */}
</Table>

Responsive with Breakpoints​

<Table responsive="sm">  {/* Responsive on small screens and up */}
<Table responsive="md"> {/* Responsive on medium screens and up */}
<Table responsive="lg"> {/* Responsive on large screens and up */}

Styling​

The component supports comprehensive styling options:

  • Base styles: Clean, modern table appearance
  • Dark mode: Automatic dark theme support
  • Responsive: Horizontal scrolling on smaller screens
  • Hover effects: Subtle row highlighting
  • Color variants: Multiple border and header color options

Best Practices​

  1. Responsive Design: Always use responsive prop for mobile compatibility
  2. Data Consistency: Ensure consistent data types across columns
  3. Status Indicators: Use badges for status and categorical data
  4. Pagination: Implement pagination for large datasets (>50 rows)
  5. Accessibility: Include proper table headers and ARIA labels
  6. Performance: Use key props for dynamic table rows

Examples​

Patient Management Table​

import React from 'react'
import { Table, Badges } from '@/components/atoms'
import { Card } from '@/components/molecules'

const PatientTable = ({ patients }) => {
return (
<Card>
<h4>Patient Management</h4>
<Table bordered responsive hover>
<thead>
<tr>
<th>Name</th>
<th>Created</th>
<th>Service</th>
<th>Status</th>
<th>Doctor</th>
</tr>
</thead>
<tbody>
{patients.map((patient, idx) => (
<tr key={idx}>
<td>{patient.name}</td>
<td>{patient.created}</td>
<td>{patient.service}</td>
<td>
<StatusBadge status={patient.status} />
</td>
<td>{patient.doctor}</td>
</tr>
))}
</tbody>
</Table>
</Card>
)
}

Troubleshooting​

Common Issues​

Table not responsive on mobile

  • Ensure responsive prop is set
  • Check for fixed width containers

Styling conflicts

  • Verify CSS class specificity
  • Check for conflicting table styles

Performance with large datasets

  • Implement pagination or virtualization
  • Consider using AG Grid for complex data tables

Accessibility issues

  • Include proper <th> elements in <thead>
  • Add scope attributes for complex tables
  • Ensure sufficient color contrast for status badges