Tables with too many columns can be frustrating to navigate. Scrolling back and forth just to find relevant information isn’t just annoying — it’s a bad user experience (UX). That’s where Tab-Table comes in. It helps break large tables into manageable sections using tabs, allowing users to focus on relevant data without endless scrolling.
In this post, I’ll introduce you to the Tab-Table approach, show you how it works, and provide a reusable React component that simplifies large tables.
The Problem: Large Tables with Too Many Columns
Imagine a table with 20+ columns. Whether you’re working with order data, customer details, or financial reports, too many columns make the table:
✅ Hard to read — Users struggle to focus on the right data.
✅ Difficult to navigate — Scrolling left and right constantly breaks the flow.
✅ Bad for mobile users — Wide tables don’t fit well on small screens.
Instead of cramming everything into a single massive table, a tabbed interface can help.
The Solution: Tab-Table for a Better UX
What is Tab-Table?
Tab-Table organizes columns into logical groups, and users can switch between them using tabs. Instead of displaying everything at once, it only shows relevant columns based on the selected tab.
For example, in an order management table, columns can be grouped like this:
By default, only the Basic tab is active. When users switch to another tab, the previous columns are hidden, and the relevant columns are displayed.
Building the Tab-Table Component in React
Here’s how to implement a generic Tab-Table component that works with any table structure.
Step 1: Create the Tab-Table Component
import React from "react";
const TabTable = ({ groups, data }) => {
const [selected, setSelected] = React.useState(groups.find(tab => tab.key)?.key || null);
return (
<div className="container">
<div className="row">
<div className="col-md-2"></div>
<div className="col-md-8">
{/* Tabs Navigation */}
<ul className="nav nav-tabs">
{groups
.filter(tab => tab.title) // Exclude empty titles
.map(tab => (
<li className="nav-item" key={tab.key}>
<button
className={`nav-link ${selected === tab.key ? 'active' : ''}`}
type="button"
onClick={() => setSelected(tab.key)}
>
{tab.title}
</button>
</li>
))}
</ul>
{/* Table */}
<table className="table table-bordered mt-3">
<thead>
<tr>
{groups.flatMap(group =>
group.columns.map((col, idx) => (
<th
key={col + idx}
className={group.key === null || group.key === selected ? '' : 'd-none' }
>
{col}
</th>
))
)}
</tr>
</thead>
<tbody>
{data.map((row, rowIndex) => (
<tr key={rowIndex}>
{groups.flatMap(group =>
group.columns.map((col, idx) => (
<td
key={col + idx}
className={group.key === null || group.key === selected ? '' : 'd-none' }
>
{row[col] || "-"}
</td>
))
)}
</tr>
))}
</tbody>
</table>
</div>
<div className="col-md-2"></div>
</div>
</div>
);
}
export default TabTable;
Step 2: Use the Component with Your Data
Now, let’s use TabTable in an app with some sample data
import TabTable from "./TabTable";
const groups = [
{ title: '', key: null, columns: ['Serial', 'OrderNumber'] },
{ title: 'Basic', key: 'basic', columns: ['Placed On', 'Status'] },
{ title: 'Customer', key: 'customer', columns: ['Name', 'Email', 'Phone', 'Billing Address'] },
{ title: 'Payment', key: 'payment', columns: ['Payment', 'Payment Status', 'Payment Reference'] },
{ title: 'Shipping', key: 'shipping', columns: ['Shipping Method', 'Shipping Address', 'Tracking ID', 'View Address'] },
{ title: 'Summary', key: 'summary', columns: ['Subtotal', 'Discount', 'Shipping', 'Total', 'Balance', 'Payment'] },
{ title: '', key: null, columns: ['Actions'] },
];
const data = [
{ Serial: 1, OrderNumber: "ORD123", "Placed On": "2024-01-01", Status: "Pending", Name: "John Doe", Email: "john@example.com", Phone: "1234567890", "Billing Address": "New York", Payment: "Card", "Payment Status": "Paid", "Payment Reference": "REF123", "Shipping Method": "DHL", "Shipping Address": "USA", "Tracking ID": "TRACK123", "View Address": "NY", Subtotal: "$100", Discount: "$10", Shipping: "$5", Total: "$95", Balance: "$0", Actions: "View" },
{ Serial: 2, OrderNumber: "ORD456", "Placed On": "2024-01-05", Status: "Shipped", Name: "Jane Smith", Email: "jane@example.com", Phone: "9876543210", "Billing Address": "California", Payment: "PayPal", "Payment Status": "Pending", "Payment Reference": "REF456", "Shipping Method": "FedEx", "Shipping Address": "Canada", "Tracking ID": "TRACK456", "View Address": "LA", Subtotal: "$150", Discount: "$15", Shipping: "$7", Total: "$142", Balance: "$0", Actions: "Track" }
];
function App() {
return (
<div className="App">
<TabTable groups={groups} data={data} />
</div>
);
}
export default App;
Why Use Tab-Table?
✔ Improved UX — No more horizontal scrolling, only relevant data is shown.
✔ Responsive Design — Works better on mobile screens.
✔ Reusable Component — Can be used for any table with many columns.
✔ Easy Integration — Just pass groups and data, and it works!
Final Thoughts
If you’re dealing with wide tables that require endless scrolling, Tab-Table is an easy solution to provide a better UX. By grouping columns into tabs, users can quickly navigate relevant data without overwhelming the interface. Take a look at the visual interface.
Check out demo.
Try it out and let me know how it works for your project! 🚀
Would you add any improvements to Tab-Table? Let’s discuss in the comments! 👇
Top comments (0)