Hi everyone! 👋 I wanted to share a story about my quest to find an open-source table component with Google Sheets–style functionality. My requirements were quite advanced:
- Grouping rows
- Showing totals
- Validating cells in real-time (e.g., for financial data)
- Dynamically enabling/disabling rows and columns
- Supporting an intuitive, spreadsheet-like editing experience
After an extensive search, I couldn’t find an existing library or code snippet that perfectly fit my use case. I needed something powerful enough to handle complex financial work in a CMS, yet still easy to customize. So, I decided to build my own component leveraging these tools:
- TanStack Table for the core table logic
- Zod for robust, schema-based validation
- ShadCN/UI for elegant UI components and styling
I’m calling this component FlexiSheet. Here’s an overview of what it offers and how it can help you create spreadsheet-like tables in your React application.
Why FlexiSheet?
Editable Cells with Validation
Each cell can be edited directly in the table. If you need validation (e.g., ensuring the value is a non-negative number), you can define a Zod schema. If the new value doesn’t pass validation, FlexiSheet can highlight the cell and prevent submission until it’s valid.Row and Column Disabling
Certain rows/columns can be disabled for editing. This is perfect for locking down areas meant for static values, or for read-only columns that compute total/aggregated data.Grouping Rows
By assigning a simpleheaderKey
to each row, the component automatically groups rows by category. This is handy if you have multiple items belonging to the same group, like “Budget Items” or “Expense Items.”Footer Rows and Custom Footers
You can display a totals row at the bottom of the table and even attach a fully customizable footer element. For example, a row summing up monthly expenses or a quick note on invoice terms.Column Resizing
Enable column resizing out of the box by toggling a single prop and definingsize
,minSize
, andmaxSize
in the column definitions.
Example Usage
Here’s a short example demonstrating how to define your data and columns, including validation with Zod:
import { z } from "zod";
// Define Zod schemas
const materialNameSchema = z.string().min(1, "Material name is required");
const quantitySchema = z.number().nonnegative().optional();
const costSchema = z.number().min(0, "Cost must be >= 0");
// Define your columns
const columns = [
{
accessorKey: "materialName",
header: "Material Name",
validationSchema: materialNameSchema,
},
{
accessorKey: "quantity",
header: "Quantity",
validationSchema: quantitySchema,
},
{
accessorKey: "cost",
header: "Cost",
validationSchema: costSchema,
},
];
// Your data
const initialData = [
{ headerKey: "Expenses", materialName: "Wood", quantity: 5, cost: 100 },
{ headerKey: "Expenses", materialName: "Paint", quantity: 3, cost: 50 },
];
// Render the table
function App() {
const [data, setData] = useState(initialData);
const handleEdit = (rowIndex, columnId, value) => {
// Update state if validation passes
const newData = [...data];
newData[rowIndex] = { ...newData[rowIndex], [columnId]: value };
setData(newData);
};
return (
<SheetTable
columns={columns}
data={data}
onEdit={handleEdit}
// Example: disable "materialName" column for editing
disabledColumns={["materialName"]}
// Example: group rows by headerKey
showHeader
/>
);
}
And that’s it! You’ll have a table that behaves like a spreadsheet—rows can be grouped by category (headerKey
), columns can be validated (validationSchema
), and totals can be displayed in the footer. It’s a flexible foundation for building powerful, spreadsheet-like features in any React app.
Want to Learn More?
I’ve created a detailed README.md with full installation instructions and additional examples. I’m also open to feature requests—if there’s something you’d like to see added (conditional formatting, advanced filtering, etc.), please let me know!
If you find this project helpful, feel free to star it ⭐on GitHub. I appreciate the support, and it helps me continue adding new features.
Thanks for reading to the end, and happy coding! 😊
Top comments (2)
Lord tanstack, the quality of package he have written is just unreal
😅Yes, ❤️ tanstack