Documentation Index Fetch the complete documentation index at: https://mintlify.com/ephraimduncan/blocks/llms.txt
Use this file to discover all available pages before exploring further.
Overview
Table blocks provide powerful components for displaying and managing tabular data. From simple data tables to complex interfaces with accordion rows, filters, and inline actions, these components help you build comprehensive data management interfaces.
Available Blocks
Table with Accordion Expandable table rows revealing additional details
Table with Actions Data table with row-level action menus
Table with Filters Filterable table with search and column filters
Table with Grouped Rows Table with grouped or categorized rows
Data Table Comprehensive data table with sorting and pagination
Table Features
Sorting : Click column headers to sort data
Filtering : Search and filter table contents
Pagination : Navigate large datasets efficiently
Row Actions : Contextual actions for each row
Selection : Select single or multiple rows
Expandable Rows : Show/hide additional details
Responsive : Adapt to different screen sizes
Use Cases
Display user lists with actions like edit, delete, or change permissions. Use row selection for bulk operations.
Show orders with expandable rows revealing order items, status history, and customer details.
Present product listings with filters for category, price, availability, and other attributes.
Display audit logs or transaction histories with date filters, search, and detailed row expansion.
Create data-rich reports with grouping, sorting, and export capabilities.
Implementation Example
import { DataTable } from '@/components/blocks/table-05'
import { useState } from 'react'
interface User {
id : string
name : string
email : string
role : string
status : 'active' | 'inactive'
createdAt : Date
}
export default function UsersTable () {
const [ users , setUsers ] = useState < User []>([])
const [ sorting , setSorting ] = useState ({ column: 'name' , direction: 'asc' })
const [ currentPage , setCurrentPage ] = useState ( 1 )
const pageSize = 10
const columns = [
{
key: 'name' ,
label: 'Name' ,
sortable: true
},
{
key: 'email' ,
label: 'Email' ,
sortable: true
},
{
key: 'role' ,
label: 'Role' ,
sortable: true
},
{
key: 'status' ,
label: 'Status' ,
render : ( value : string ) => (
< span className = { `
px-2 py-1 rounded-full text-xs
${ value === 'active' ? 'bg-green-100 text-green-800' : 'bg-gray-100 text-gray-800' }
` } >
{ value }
</ span >
)
},
{
key: 'actions' ,
label: '' ,
render : ( _ , row : User ) => (
< DropdownMenu >
< DropdownMenuItem onClick = { () => editUser ( row . id ) } > Edit </ DropdownMenuItem >
< DropdownMenuItem onClick = { () => deleteUser ( row . id ) } > Delete </ DropdownMenuItem >
</ DropdownMenu >
)
}
]
return (
< DataTable
columns = { columns }
data = { users }
sorting = { sorting }
onSortChange = { setSorting }
currentPage = { currentPage }
pageSize = { pageSize }
totalItems = { users . length }
onPageChange = { setCurrentPage }
/>
)
}
Sorting Implementation
function sortData < T >( data : T [], column : keyof T , direction : 'asc' | 'desc' ) : T [] {
return [ ... data ]. sort (( a , b ) => {
const aValue = a [ column ]
const bValue = b [ column ]
if ( aValue < bValue ) return direction === 'asc' ? - 1 : 1
if ( aValue > bValue ) return direction === 'asc' ? 1 : - 1
return 0
})
}
const handleSort = ( column : string ) => {
setSorting ( prev => ({
column ,
direction: prev . column === column && prev . direction === 'asc' ? 'desc' : 'asc'
}))
}
For large datasets (>1000 rows), implement server-side sorting, filtering, and pagination to maintain good performance. Client-side operations should only be used for smaller datasets.
Filtering & Search
Implement table filtering:
import { TableWithFilters } from '@/components/blocks/table-03'
import { useState } from 'react'
function FilterableTable () {
const [ searchQuery , setSearchQuery ] = useState ( '' )
const [ filters , setFilters ] = useState ({
role: 'all' ,
status: 'all'
})
const filteredData = data . filter ( row => {
// Text search
const matchesSearch =
row . name . toLowerCase (). includes ( searchQuery . toLowerCase ()) ||
row . email . toLowerCase (). includes ( searchQuery . toLowerCase ())
// Role filter
const matchesRole = filters . role === 'all' || row . role === filters . role
// Status filter
const matchesStatus = filters . status === 'all' || row . status === filters . status
return matchesSearch && matchesRole && matchesStatus
})
return (
< div >
< div className = "mb-4 flex gap-4" >
< input
type = "search"
placeholder = "Search users..."
value = { searchQuery }
onChange = { ( e ) => setSearchQuery ( e . target . value ) }
className = "flex-1"
/>
< select
value = { filters . role }
onChange = { ( e ) => setFilters ({ ... filters , role: e . target . value }) }
>
< option value = "all" > All Roles </ option >
< option value = "admin" > Admin </ option >
< option value = "user" > User </ option >
</ select >
< select
value = { filters . status }
onChange = { ( e ) => setFilters ({ ... filters , status: e . target . value }) }
>
< option value = "all" > All Status </ option >
< option value = "active" > Active </ option >
< option value = "inactive" > Inactive </ option >
</ select >
</ div >
< TableWithFilters data = { filteredData } />
</ div >
)
}
Best Practices
Table Design
Column Width : Set appropriate widths for different content types
Text Alignment : Left-align text, right-align numbers
Row Height : Ensure adequate padding for readability
Zebra Striping : Use alternating row colors for easier scanning
Sticky Headers : Keep headers visible when scrolling
Responsive : Consider card view for mobile devices
Data Handling
Loading States : Show skeleton rows while data loads
Empty States : Provide helpful messages when no data exists
Error Handling : Display errors gracefully
Optimistic Updates : Update UI immediately, sync in background
Debounce Search : Don’t filter on every keystroke
User Experience
Clear Actions : Make row actions discoverable but not cluttered
Bulk Operations : Allow multi-select for batch actions
Keyboard Navigation : Support arrow keys and shortcuts
Export Options : Provide CSV or Excel export when appropriate
Customize Columns : Let users show/hide columns
Implement pagination:
function Pagination ({
currentPage ,
totalPages ,
onPageChange
} : {
currentPage : number
totalPages : number
onPageChange : ( page : number ) => void
}) {
return (
< div className = "flex items-center justify-between mt-4" >
< div className = "text-sm text-gray-600" >
Page { currentPage } of { totalPages }
</ div >
< div className = "flex gap-2" >
< button
onClick = { () => onPageChange ( currentPage - 1 ) }
disabled = { currentPage === 1 }
>
Previous
</ button >
{ Array . from ({ length: totalPages }, ( _ , i ) => i + 1 ). map ( page => (
< button
key = { page }
onClick = { () => onPageChange ( page ) }
className = { currentPage === page ? 'font-bold' : '' }
>
{ page }
</ button >
)) }
< button
onClick = { () => onPageChange ( currentPage + 1 ) }
disabled = { currentPage === totalPages }
>
Next
</ button >
</ div >
</ div >
)
}
Expandable Rows
Implement accordion-style rows:
import { TableWithAccordion } from '@/components/blocks/table-01'
import { useState } from 'react'
function ExpandableTable () {
const [ expandedRows , setExpandedRows ] = useState < Set < string >>( new Set ())
const toggleRow = ( id : string ) => {
setExpandedRows ( prev => {
const next = new Set ( prev )
if ( next . has ( id )) {
next . delete ( id )
} else {
next . add ( id )
}
return next
})
}
return (
< table >
< tbody >
{ data . map ( row => (
< React.Fragment key = { row . id } >
< tr onClick = { () => toggleRow ( row . id ) } >
< td >
< ChevronIcon
className = { expandedRows . has ( row . id ) ? 'rotate-90' : '' }
/>
</ td >
< td > { row . name } </ td >
< td > { row . email } </ td >
</ tr >
{ expandedRows . has ( row . id ) && (
< tr >
< td colSpan = { 3 } >
< div className = "p-4 bg-gray-50" >
{ /* Expanded content */ }
< h4 > Additional Details </ h4 >
< p > Created: { row . createdAt } </ p >
< p > Last login: { row . lastLogin } </ p >
</ div >
</ td >
</ tr >
) }
</ React.Fragment >
)) }
</ tbody >
</ table >
)
}
Row Selection
Implement row selection:
function SelectableTable () {
const [ selectedRows , setSelectedRows ] = useState < Set < string >>( new Set ())
const toggleRow = ( id : string ) => {
setSelectedRows ( prev => {
const next = new Set ( prev )
if ( next . has ( id )) next . delete ( id )
else next . add ( id )
return next
})
}
const toggleAll = () => {
if ( selectedRows . size === data . length ) {
setSelectedRows ( new Set ())
} else {
setSelectedRows ( new Set ( data . map ( row => row . id )))
}
}
return (
<>
{ selectedRows . size > 0 && (
< div className = "mb-4" >
{ selectedRows . size } rows selected
< button onClick = { () => bulkDelete ( Array . from ( selectedRows )) } >
Delete Selected
</ button >
</ div >
) }
< table >
< thead >
< tr >
< th >
< input
type = "checkbox"
checked = { selectedRows . size === data . length }
onChange = { toggleAll }
/>
</ th >
< th > Name </ th >
< th > Email </ th >
</ tr >
</ thead >
< tbody >
{ data . map ( row => (
< tr key = { row . id } >
< td >
< input
type = "checkbox"
checked = { selectedRows . has ( row . id ) }
onChange = { () => toggleRow ( row . id ) }
/>
</ td >
< td > { row . name } </ td >
< td > { row . email } </ td >
</ tr >
)) }
</ tbody >
</ table >
</>
)
}
Responsive Tables
Handle mobile responsiveness:
// Card view for mobile
function ResponsiveTable ({ data } : { data : any [] }) {
const isMobile = useMediaQuery ( '(max-width: 768px)' )
if ( isMobile ) {
return (
< div className = "space-y-4" >
{ data . map ( row => (
< div key = { row . id } className = "border rounded-lg p-4" >
< div className = "font-semibold" > { row . name } </ div >
< div className = "text-sm text-gray-600" > { row . email } </ div >
< div className = "mt-2" >
< span className = "text-xs bg-gray-100 px-2 py-1 rounded" >
{ row . role }
</ span >
</ div >
</ div >
)) }
</ div >
)
}
return < Table data = { data } /> // Desktop table
}
Accessibility
Use semantic <table> elements
Include <caption> for table description
Use <thead>, <tbody>, <tfoot> properly
Add scope attributes to headers
Ensure keyboard navigation works
Provide sort direction indicators
Make action buttons keyboard accessible
Announce dynamic updates to screen readers
Grid List - Alternative grid layout
Stats - Metric summaries above tables
Dialogs - Modal forms for row editing