Table

Table

Display data in a structured table format with automatic styling for headers, cells, and borders.

NameEmailRole
John Doejohn@example.comAdmin
Jane Smithjane@example.comUser
Bob Johnsonbob@example.comEditor
12345678910111213141516171819202122232425262728293031323334
package showcase import ( popui "github.com/invopop/popui/go" ) templ TableExample() { @popui.Table() { <thead> <tr> <th>Name</th> <th>Email</th> <th>Role</th> </tr> </thead> <tbody> <tr> <td>John Doe</td> <td>john@example.com</td> <td>Admin</td> </tr> <tr> <td>Jane Smith</td> <td>jane@example.com</td> <td>User</td> </tr> <tr> <td>Bob Johnson</td> <td>bob@example.com</td> <td>Editor</td> </tr> </tbody> } }

Variants

Tables support a card variant that adds an outer border. Default tables have no outer border.

Default (no border)

NameEmailRole
John Doejohn@example.comAdmin
Jane Smithjane@example.comUser

Card variant (with border)

NameEmailRole
John Doejohn@example.comAdmin
Jane Smithjane@example.comUser
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
package showcase import ( popui "github.com/invopop/popui/go" "github.com/invopop/popui/go/props" ) templ TableVariants() { <div class="flex flex-col gap-6"> <div> <h3 class="text-sm font-medium mb-2">Default (no border)</h3> @popui.Table() { <thead> <tr> <th>Name</th> <th>Email</th> <th>Role</th> </tr> </thead> <tbody> <tr> <td>John Doe</td> <td>john@example.com</td> <td>Admin</td> </tr> <tr> <td>Jane Smith</td> <td>jane@example.com</td> <td>User</td> </tr> </tbody> } </div> <div> <h3 class="text-sm font-medium mb-2">Card variant (with border)</h3> @popui.Table(props.Table{Variant: "card"}) { <thead> <tr> <th>Name</th> <th>Email</th> <th>Role</th> </tr> </thead> <tbody> <tr> <td>John Doe</td> <td>john@example.com</td> <td>Admin</td> </tr> <tr> <td>Jane Smith</td> <td>jane@example.com</td> <td>User</td> </tr> </tbody> } </div> </div> }

Clickable Rows

Add hover effects to table rows by passing additional classes via the Class prop.

ProductStatusPrice
Widget AAvailable$29.99
Widget BOut of Stock$39.99
Widget CAvailable$49.99
12345678910111213141516171819202122232425262728293031323334353637
package showcase import ( popui "github.com/invopop/popui/go" "github.com/invopop/popui/go/props" ) templ ClickableTableExample() { @popui.Table(props.Table{ Class: "[&_tr:hover_td]:bg-background-default-secondary [&_tr:hover_td]:cursor-pointer", }) { <thead> <tr> <th>Product</th> <th>Status</th> <th>Price</th> </tr> </thead> <tbody> <tr> <td>Widget A</td> <td>Available</td> <td>$29.99</td> </tr> <tr> <td>Widget B</td> <td>Out of Stock</td> <td>$39.99</td> </tr> <tr> <td>Widget C</td> <td>Available</td> <td>$49.99</td> </tr> </tbody> } }

Right-Aligned Cells

Right-align specific columns using the Class prop with arbitrary variants like [&_th:last-child]:text-right.

ItemQuantityAmount
Product A3$89.97
Product B1$39.99
Product C2$99.98
12345678910111213141516171819202122232425262728293031323334353637
package showcase import ( popui "github.com/invopop/popui/go" "github.com/invopop/popui/go/props" ) templ RightAlignTableExample() { @popui.Table(props.Table{ Class: "[&_th:last-child]:text-right [&_td:last-child]:text-right", }) { <thead> <tr> <th>Item</th> <th>Quantity</th> <th>Amount</th> </tr> </thead> <tbody> <tr> <td>Product A</td> <td>3</td> <td>$89.97</td> </tr> <tr> <td>Product B</td> <td>1</td> <td>$39.99</td> </tr> <tr> <td>Product C</td> <td>2</td> <td>$99.98</td> </tr> </tbody> } }

With Avatars

Tables can contain any components including avatars. Use the Avatar component for user initials or images.

UserEmailRole
J
John Doe
john@example.comAdmin
S
Jane Smith
jane@example.comEditor
12345678910111213141516171819202122232425262728293031323334353637383940
package showcase import ( popui "github.com/invopop/popui/go" "github.com/invopop/popui/go/props" ) templ TableWithAvatarsExample() { @popui.Table() { <thead> <tr> <th>User</th> <th>Email</th> <th>Role</th> </tr> </thead> <tbody> <tr> <td> <div class="flex items-center gap-2"> @popui.Avatar(props.Avatar{Initial: "J"}) <span>John Doe</span> </div> </td> <td>john@example.com</td> <td>Admin</td> </tr> <tr> <td> <div class="flex items-center gap-2"> @popui.Avatar(props.Avatar{Initial: "S"}) <span>Jane Smith</span> </div> </td> <td>jane@example.com</td> <td>Editor</td> </tr> </tbody> } }

Table Pagination

Add pagination controls to your table with TablePagination component. Uses AnchorButton with URLs for navigation and supports custom action buttons via children slot.

Invoice IDCustomerAmountStatus
INV-001Acme Corp$1,234.56Paid
INV-002Tech Solutions$987.65Pending
INV-003Global Inc$2,345.67Paid
/ 260
25,991 invoices
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
package showcase import ( popui "github.com/invopop/popui/go" "github.com/invopop/popui/go/props" ) templ TablePaginationExample() { <div class="border border-border rounded-lg overflow-hidden"> @popui.Table() { <thead> <tr> <th>Invoice ID</th> <th>Customer</th> <th>Amount</th> <th>Status</th> </tr> </thead> <tbody> <tr> <td>INV-001</td> <td>Acme Corp</td> <td>$1,234.56</td> <td>Paid</td> </tr> <tr> <td>INV-002</td> <td>Tech Solutions</td> <td>$987.65</td> <td>Pending</td> </tr> <tr> <td>INV-003</td> <td>Global Inc</td> <td>$2,345.67</td> <td>Paid</td> </tr> </tbody> } @popui.TablePagination(props.TablePagination{ CurrentPage: 1, TotalPages: 260, TotalItems: 25991, RowsPerPage: 100, RowsPerPageOptions: []int{10, 25, 50, 100, 250}, ShowRowsPerPage: true, ItemsLabel: "invoices", FirstPageURL: "?page=1", PrevPageURL: "?page=0", NextPageURL: "?page=2", LastPageURL: "?page=260", }) { <div class="flex items-center gap-2"> @popui.Button(props.Button{ Type: "button", Size: "sm", Variant: "secondary", }) { Export } @popui.Button(props.Button{ Type: "button", Size: "sm", Variant: "primary", }) { Create Invoice } </div> } </div> }

API Reference

Table

A table component with automatic styling for borders, spacing, and typography. The table wrapper provides rounded corners and overflow handling.

NameTypeDefaultDescription
ID string-Unique identifier for the table element
Class string-Additional CSS classes to merge with base styles. Use Tailwind's arbitrary variants like [&_tr:hover_td]:bg-gray-100 for advanced styling
Attributes templ.Attributes-Additional HTML attributes to apply to the table element
Variant string-Visual style: 'card' adds outer border and rounded corners

TablePagination

Pagination controls for tables with page navigation, rows per page selector, and total count display. Uses AnchorButton for URL-based navigation. Supports a children slot for custom action buttons.

NameTypeDefaultDescription
ID string-Unique identifier for the pagination container
Class string-Additional CSS classes to merge with base styles
Attributes templ.Attributes-Additional HTML attributes for the container
CurrentPage int1Current active page number (1-indexed)
TotalPages int1Total number of pages available
TotalItems int0Total count of items across all pages
RowsPerPage int100Number of rows displayed per page
RowsPerPageOptions []int[10, 25, 50, 100]Available options for rows per page dropdown
ShowRowsPerPage boolfalseWhether to show the rows per page dropdown
ItemsLabel stringitemsLabel for the total count (e.g., 'invoices', 'users')
FirstPageURL templ.SafeURL-URL for the first page navigation button
PrevPageURL templ.SafeURL-URL for the previous page navigation button
NextPageURL templ.SafeURL-URL for the next page navigation button
LastPageURL templ.SafeURL-URL for the last page navigation button
PageInputAttributes templ.Attributes-Additional attributes for the page number input field