Table
Introduction
The Table component is a robust layout element used to render complex tabular dataset structures clearly on client pages. Built with full support for zero-JS responsive templates and data-driven CMS configuration schemas, it supports clean vertical scroll wrapping, dynamic column alignment presets, and hover highlights.
Usage
You can easily map data and style tables directly from their dashboard.
1. Basic Plain Table with Custom Alignment
A standard text inventory list using the plain variant and featuring end-aligned prices for easy reading.
{
"type": "table",
"variant": "plain",
"columns": [
{ "header": "Name", "key": "name" },
{ "header": "Category", "key": "category" },
{ "header": "Price", "key": "price", "align": "end" }
],
"rows": "[{\"name\": \"Laptop\", \"category\": \"Electronics\", \"price\": \"$999.00\"}, {\"name\": \"Coffee Mug\", \"category\": \"Home & Kitchen\", \"price\": \"$15.00\"}]"
}
| Name | Category | Price |
|---|---|---|
| Laptop | Electronics | $999.00 |
| Coffee Mug | Home & Kitchen | $15.00 |
2. Zebra-Striped Interactive Table (Surface Variant)
Features shaded alternating row colors with zebra-striping, interactive hover highlighting, and structural borders.
{
"type": "table",
"variant": "surface",
"striped": true,
"interactive": true,
"columnBorder": true,
"columns": [
{ "header": "System Service", "key": "service" },
{ "header": "Server Node", "key": "node", "align": "center" },
{ "header": "Status", "key": "status", "align": "end" }
],
"rows": "[{\"service\": \"Auth Endpoint\", \"node\": \"EU-West\", \"status\": \"Online\"}, {\"service\": \"Payment API\", \"node\": \"US-East\", \"status\": \"Degraded\"}, {\"service\": \"File Storage\", \"node\": \"APAC-South\", \"status\": \"Online\"}]"
}
| System Service | Server Node | Status |
|---|---|---|
| Auth Endpoint | EU-West | Online |
| Payment API | US-East | Degraded |
| File Storage | APAC-South | Online |
3. Row Hover Actions
Pass hoverActions to render extra controls (e.g. a "View Details" button) into a zero-width trailing cell that stays hidden until its row is hovered or one of its controls receives keyboard focus. It's absolutely positioned over the row's end, so it never widens the table — it may visually cover the last column(s) while revealed.
| Name | Category | |
|---|---|---|
| Laptop | Electronics | View Details |
| Coffee Mug | Home & Kitchen | View Details |
hoverActions is a render function (like column.render), not a CMS-serializable field — it isn't exposed in the Sveltia CMS table block schema.
Hydration and Interactive Limitations of hoverActions
When using hoverActions on a table that is fully or partially interactive (for example, when headers are sortable or the table hydrates via a parent island wrapper), there are some important architectural considerations regarding client-side state:
- Static Markup Rendering: The
hoverActionsfunction is executed during server-side rendering (SSR). If the table has sorting enabled or undergoes client-side hydration, any interactive event listeners (likeonClickor stateful island components) nested directly insidehoverActionsmay be dropped during DOM cloning and hydration. - Recommended Click-Delegation Pattern: Instead of embedding complex client islands or active event hooks directly inside the
hoverActionscallback:- Render static triggers or standard HTML elements with descriptive data attributes (e.g.,
<button type="button" data-action="delete" data-id={row.id}>Delete</button>). - Mount a single stateful controller island outside of the
Tablecomponent. - Listen to events globally (or delegate them on the parent element) to capture clicks on those data attributes and trigger appropriate modals, drawers, or API calls.
- Render static triggers or standard HTML elements with descriptive data attributes (e.g.,
Props
| Property | CMS Field Type | Default | Description / Supported Options |
|---|---|---|---|
Columns (columns) | list | - | An ordered list of column configurations (see Column item details below). |
Rows Data (rows) | text | - | A raw JSON-serialised array string representing table rows. (E.g. "[{\"item\": \"Laptop\"}]"). Parsed automatically at server render-time. |
Variant (variant) | select | "plain" | The general design layout style of the table container. • Options: "plain", "surface". |
Zebra Striping (striped) | boolean | false | When true, renders alternating rows with subtle shaded backgrounds for enhanced data legibility. |
Row Highlights (interactive) | boolean | false | Enables full mouse-hover background animations across active cells on desktop machines. |
Column Borders (columnBorder) | boolean | false | Renders a dividing vertical border line between table columns. |
Sticky Header (stickyHeader) | boolean | false | Pins the main header row to the top of the table scroll viewport during scrolling. |
Hover Actions (hoverActions) | code-only | - | (row, rowIndex) => JSX.Element. Renders into a zero-width trailing cell, absolutely positioned over the row's end (may cover the last column(s)), hidden until the row is hovered (or a rendered control gains keyboard focus). Not exposed as a CMS field. |
Column List Properties (columns)
Each entry in the columns list parameter accepts the following fields:
| Sub-Property | Type | Required | Description / Supported Options |
|---|---|---|---|
Header Text (header) | string | Yes | Column header title rendered inside the table header row. |
Item Key (key) | string | Yes | Property key in the rows data object that maps directly to this cell. |
Text Alignment (align) | select | "start" | Alignment of cell values. Useful for aligning numeric values to the right side of columns. • Options: "start", "center", "end". |
Architecture Notes
- Optimized JSON String Coercions: Because raw row structures vary dynamically per table block, Sveltia CMS delivers row items as an escaped JSON array string under the
rowsfield. This string is safely parsed at render-time, guaranteeing optimal bundle sizes without heavy payload serialization. - Pure CSS Layout Hygiene: Headers, column outlines, and zebra striping rely on lightweight, highly robust Panda CSS utility variables. This eliminates layout shifts while keeping table rendering instantaneous on mobile touchscreens.
- Scroll pinning: Pinning column headers with
stickyHeaderutilises standardposition: stickyon headers inside an overflow wrap, bypassing expensive scroll event listeners in client-side script contexts.