Table
A feature-rich data table component for displaying structured data with sorting, filtering, and pagination.
Features
- Column sorting (ascending/descending)
- Search and filtering
- Pagination
- Row selection (single/multiple)
- Expandable rows
- Sticky headers
- Responsive (mobile card view)
- Export functionality
- Custom cell renderers
- Loading states
Usage
Web (React)
import { Table, TableColumn } from '@cuppa/ui'
function MyComponent() {
const columns: TableColumn[] = [
{ key: 'id', label: 'ID', sortable: true },
{ key: 'name', label: 'Name', sortable: true },
{ key: 'email', label: 'Email' },
{ key: 'status', label: 'Status', render: (row) => (
<Badge variant={row.status === 'active' ? 'success' : 'default'}>
{row.status}
</Badge>
)},
{ key: 'actions', label: 'Actions', render: (row) => (
<Button size="sm" onClick={() => handleEdit(row)}>Edit</Button>
)},
]
const data = [
{ id: 1, name: 'John Doe', email: 'john@example.com', status: 'active' },
{ id: 2, name: 'Jane Smith', email: 'jane@example.com', status: 'inactive' },
]
return (
<Table
columns={columns}
data={data}
sortable
searchable
pagination
pageSize={10}
/>
)
}
iOS (SwiftUI)
import CuppaUI
struct MyView: View {
let columns = [
TableColumn(key: "id", label: "ID", sortable: true),
TableColumn(key: "name", label: "Name", sortable: true),
TableColumn(key: "email", label: "Email"),
TableColumn(key: "status", label: "Status"),
]
let data = [
["id": "1", "name": "John Doe", "email": "john@example.com", "status": "active"],
["id": "2", "name": "Jane Smith", "email": "jane@example.com", "status": "inactive"],
]
var body: some View {
CuppaTable(
columns: columns,
data: data,
sortable: true,
searchable: true
)
}
}
Android (Jetpack Compose)
import com.cuppa.ui.components.CuppaTable
import androidx.compose.runtime.*
@Composable
fun MyScreen() {
val columns = listOf(
TableColumn("id", "ID", sortable = true),
TableColumn("name", "Name", sortable = true),
TableColumn("email", "Email"),
TableColumn("status", "Status")
)
val data = listOf(
mapOf("id" to "1", "name" to "John Doe", "email" to "john@example.com", "status" to "active"),
mapOf("id" to "2", "name" to "Jane Smith", "email" to "jane@example.com", "status" to "inactive")
)
CuppaTable(
columns = columns,
data = data,
sortable = true,
searchable = true,
pagination = true,
pageSize = 10
)
}
Props
| Prop | Type | Default | Description | |------|------|---------|-------------| | columns | array | [] | Column definitions | | data | array | [] | Table data | | sortable | boolean | false | Enable sorting | | searchable | boolean | false | Enable search | | pagination | boolean | false | Enable pagination | | pageSize | number | 10 | Items per page | | selectable | boolean | false | Enable row selection | | loading | boolean | false | Show loading state | | emptyMessage | string | - | Message when no data |
Column Options
{
key: string, // Data key
label: string, // Column header
sortable?: boolean, // Enable sorting
width?: string, // Column width
align?: 'left' | 'center' | 'right',
render?: (row) => ReactNode, // Custom renderer
hide?: boolean, // Hide column
}
Examples
With Row Selection
<Table
columns={columns}
data={data}
selectable
onSelectionChange={(selected) => console.log(selected)}
/>
With Expandable Rows
<Table
columns={columns}
data={data}
expandable
renderExpanded={(row) => (
<div className="p-4">
<h4>Details for {row.name}</h4>
<p>{row.details}</p>
</div>
)}
/>
With Custom Empty State
<Table
columns={columns}
data={[]}
emptyMessage="No users found"
emptyAction={
<Button onClick={handleAdd}>Add User</Button>
}
/>
Accessibility
- Keyboard navigation (arrow keys, tab)
- Screen reader support
- Sortable column headers announced
- Row selection accessible
- Proper ARIA labels
Best Practices
- Keep columns to 5-7 for readability
- Use custom renderers for complex cells
- Implement server-side pagination for large datasets
- Provide clear empty states
- Use sticky headers for long tables
- Consider mobile-responsive card view