Table
Use the table component to show text, images, links, and other elements inside a structured set of data made up of rows and columns of table cells
Loading...
{%- set products = [
{name: 'Apple MacBook Pro 17"', color: 'Silver', category: 'Laptop', price: '$2999', stock: 231},
{name: 'Microsoft Surface Pro', color: 'White', category: 'Laptop PC', price: '$1999', stock: 423},
{name: 'Magic Mouse 2', color: 'Black', category: 'Accessories', price: '$99', stock: 121},
] -%}
<div class="w-full relative overflow-x-auto bg-neutral-primary-soft shadow-xs rounded-base border border-default">
<twig:Table>
<twig:Table:Caption>
Our products
<p class="mt-1.5 text-sm font-normal text-body">Browse a list of Flowbite products designed to help you work and play, stay organized, get answers, keep in touch, grow your business, and more.</p>
</twig:Table:Caption>
<twig:Table:Header class="border-t">
<twig:Table:Row>
<twig:Table:Head>Product name</twig:Table:Head>
<twig:Table:Head>Color</twig:Table:Head>
<twig:Table:Head>Category</twig:Table:Head>
<twig:Table:Head>Price</twig:Table:Head>
<twig:Table:Head>Stock</twig:Table:Head>
</twig:Table:Row>
</twig:Table:Header>
<twig:Table:Body>
{% for product in products %}
<twig:Table:Row>
<twig:Table:Head scope="row" class="font-medium text-heading whitespace-nowrap">{{ product.name }}</twig:Table:Head>
<twig:Table:Cell>{{ product.color }}</twig:Table:Cell>
<twig:Table:Cell>{{ product.category }}</twig:Table:Cell>
<twig:Table:Cell>{{ product.price }}</twig:Table:Cell>
<twig:Table:Cell>{{ product.stock }}</twig:Table:Cell>
</twig:Table:Row>
{% endfor %}
</twig:Table:Body>
<twig:Table:Footer>
<twig:Table:Row>
<twig:Table:Head scope="row" class="text-base" colspan="3">Total</twig:Table:Head>
<twig:Table:Cell>$5997</twig:Table:Cell>
<twig:Table:Cell>775</twig:Table:Cell>
</twig:Table:Row>
</twig:Table:Footer>
</twig:Table>
</div>
Installation
bin/console ux:install table --kit flowbite-4
That's it!
Install the following Composer dependencies:
composer require tales-from-a-dev/twig-tailwind-extra:^1.0.0
Copy the following file(s) into your Symfony app:
templates/components/Table.html.twig
{# @block content The table structure, typically includes `Table:Header`, `Table:Body`, and optionally `Table:Footer` #}
{# @prop borderless boolean Whether to hide the table borders. Defaults to `false` #}
{%- props borderless = false -%}
<table
data-border="{{ borderless ? 'borderless' : 'bordered' }}"
class="{{ ('w-full text-sm text-left rtl:text-right text-body group/table ' ~ attributes.render('class'))|tailwind_merge }}"
{{ attributes }}
>
{%- block content %}{% endblock -%}
</table>
templates/components/Table/Body.html.twig
{# @prop highlight 'none'|'hover'|'striped' The visual row style highlight. Defaults to `hover` #}
{# @block content The table body rows, typically `Table:Row` components #}
{% props highlight = 'hover' %}
{%- set style = html_cva(
base: '[&>tr]:bg-neutral-primary-soft group-data-[border=bordered]/table:[&>tr]:border-b group-data-[border=bordered]/table:[&>tr]:border-default [&>tr]:transition-colors',
variants: {
highlight: {
none: '',
hover: '[&>tr]:hover:bg-neutral-secondary-medium',
striped: '[&>tr]:odd:bg-neutral-primary [&>tr]:even:bg-neutral-secondary-soft',
},
},
) -%}
<tbody
class="{{ style.apply({highlight: highlight}, attributes.render('class'))|tailwind_merge }}"
{{ attributes }}
>
{%- block content %}{% endblock -%}
</tbody>
templates/components/Table/Caption.html.twig
{# @block content The table caption text #}
<caption
class="{{ ('p-5 text-lg font-medium text-left rtl:text-right text-heading ' ~ attributes.render('class'))|tailwind_merge }}"
{{ attributes }}
>
{%- block content %}{% endblock -%}
</caption>
templates/components/Table/Cell.html.twig
{# @block content The cell content #}
<td
class="{{ ('px-6 py-4 ' ~ attributes.render('class'))|tailwind_merge }}"
{{ attributes }}
>
{%- block content %}{% endblock -%}
</td>
templates/components/Table/Footer.html.twig
{# @block content The table footer rows, typically `Table:Row` components #}
<tfoot
class="{{ ('font-semibold text-heading ' ~ attributes.render('class'))|tailwind_merge }}"
{{ attributes }}
>
{%- block content %}{% endblock -%}
</tfoot>
templates/components/Table/Head.html.twig
{# @block content The header cell content #}
<th
class="{{ ('px-6 py-3 font-medium ' ~ attributes.render('class'))|tailwind_merge }}"
{{ attributes }}
>
{%- block content %}{% endblock -%}
</th>
templates/components/Table/Header.html.twig
{# @block content The header row(s), typically a `Table:Row` with `Table:Head` cells #}
<thead
class="{{ ('text-sm text-body rounded-base group-data-[border=bordered]/table:bg-neutral-secondary-soft group-data-[border=bordered]/table:border-b group-data-[border=bordered]/table:border-default ' ~ attributes.render('class'))|tailwind_merge }}"
{{ attributes }}
>
{%- block content %}{% endblock -%}
</thead>
templates/components/Table/Row.html.twig
{# @block content The row cells, typically `Table:Cell` or `Table:Head` components #}
<tr
{{ attributes }}
>
{%- block content %}{% endblock -%}
</tr>
Happy coding!
Usage
<twig:Table>
<twig:Table:Caption>A list of your recent invoices.</twig:Table:Caption>
<twig:Table:Header>
<twig:Table:Row>
<twig:Table:Head>Invoice</twig:Table:Head>
<twig:Table:Head>Status</twig:Table:Head>
<twig:Table:Head>Method</twig:Table:Head>
<twig:Table:Head class="text-right">Amount</twig:Table:Head>
</twig:Table:Row>
</twig:Table:Header>
<twig:Table:Body>
<twig:Table:Row>
<twig:Table:Cell class="font-medium">INV001</twig:Table:Cell>
<twig:Table:Cell>Paid</twig:Table:Cell>
<twig:Table:Cell>Credit Card</twig:Table:Cell>
<twig:Table:Cell class="text-right">$250.00</twig:Table:Cell>
</twig:Table:Row>
</twig:Table:Body>
</twig:Table>
Examples
Highlight striped
Use this example to increase the readability of the data sets by alternating the background color of every second table row.
Loading...
{%- set products = [
{name: 'Apple MacBook Pro 17"', color: 'Silver', category: 'Laptop', price: '$2999', stock: 231},
{name: 'Microsoft Surface Pro', color: 'White', category: 'Laptop PC', price: '$1999', stock: 423},
{name: 'Magic Mouse 2', color: 'Black', category: 'Accessories', price: '$99', stock: 121},
] -%}
<div class="w-full relative overflow-x-auto bg-neutral-primary-soft shadow-xs rounded-base border border-default">
<twig:Table>
<twig:Table:Header>
<twig:Table:Row>
<twig:Table:Head>Product name</twig:Table:Head>
<twig:Table:Head>Color</twig:Table:Head>
<twig:Table:Head>Category</twig:Table:Head>
<twig:Table:Head>Price</twig:Table:Head>
<twig:Table:Head>Stock</twig:Table:Head>
</twig:Table:Row>
</twig:Table:Header>
<twig:Table:Body highlight="striped">
{% for product in products %}
<twig:Table:Row>
<twig:Table:Head scope="row" class="font-medium text-heading whitespace-nowrap">{{ product.name }}</twig:Table:Head>
<twig:Table:Cell>{{ product.color }}</twig:Table:Cell>
<twig:Table:Cell>{{ product.category }}</twig:Table:Cell>
<twig:Table:Cell>{{ product.price }}</twig:Table:Cell>
<twig:Table:Cell>{{ product.stock }}</twig:Table:Cell>
</twig:Table:Row>
{% endfor %}
</twig:Table:Body>
<twig:Table:Footer>
<twig:Table:Row>
<twig:Table:Head scope="row" class="text-base" colspan="3">Total</twig:Table:Head>
<twig:Table:Cell>$5997</twig:Table:Cell>
<twig:Table:Cell>775</twig:Table:Cell>
</twig:Table:Row>
</twig:Table:Footer>
</twig:Table>
</div>
Without border
Use this example of a table component without any border between the table cells.
Loading...
{%- set products = [
{name: 'Apple MacBook Pro 17"', color: 'Silver', category: 'Laptop', price: '$2999', stock: 231},
{name: 'Microsoft Surface Pro', color: 'White', category: 'Laptop PC', price: '$1999', stock: 423},
{name: 'Magic Mouse 2', color: 'Black', category: 'Accessories', price: '$99', stock: 121},
] -%}
<twig:Table borderless>
<twig:Table:Header>
<twig:Table:Row>
<twig:Table:Head>Product name</twig:Table:Head>
<twig:Table:Head>Color</twig:Table:Head>
<twig:Table:Head>Category</twig:Table:Head>
<twig:Table:Head>Price</twig:Table:Head>
<twig:Table:Head>Stock</twig:Table:Head>
</twig:Table:Row>
</twig:Table:Header>
<twig:Table:Body>
{% for product in products %}
<twig:Table:Row>
<twig:Table:Head scope="row" class="font-medium text-heading whitespace-nowrap">{{ product.name }}</twig:Table:Head>
<twig:Table:Cell>{{ product.color }}</twig:Table:Cell>
<twig:Table:Cell>{{ product.category }}</twig:Table:Cell>
<twig:Table:Cell>{{ product.price }}</twig:Table:Cell>
<twig:Table:Cell>{{ product.stock }}</twig:Table:Cell>
</twig:Table:Row>
{% endfor %}
</twig:Table:Body>
<twig:Table:Footer>
<twig:Table:Row>
<twig:Table:Head scope="row" class="text-base" colspan="3">Total</twig:Table:Head>
<twig:Table:Cell>$5997</twig:Table:Cell>
<twig:Table:Cell>775</twig:Table:Cell>
</twig:Table:Row>
</twig:Table:Footer>
</twig:Table>
API Reference
Table
| Prop | Type | Description |
|---|---|---|
borderless |
boolean |
Whether to hide the table borders. Defaults to false |
| Block | Description |
|---|---|
content |
The table structure, typically includes Table:Header, Table:Body, and optionally Table:Footer |
Table:Body
| Prop | Type | Description |
|---|---|---|
highlight |
'none'|'hover'|'striped' |
The visual row style highlight. Defaults to hover |
| Block | Description |
|---|---|
content |
The table body rows, typically Table:Row components |
Table:Caption
| Block | Description |
|---|---|
content |
The table caption text |
Table:Cell
| Block | Description |
|---|---|
content |
The cell content |
Table:Footer
| Block | Description |
|---|---|
content |
The table footer rows, typically Table:Row components |
Table:Head
| Block | Description |
|---|---|
content |
The header cell content |
Table:Header
| Block | Description |
|---|---|
content |
The header row(s), typically a Table:Row with Table:Head cells |
Table:Row
| Block | Description |
|---|---|
content |
The row cells, typically Table:Cell or Table:Head components |