Table

#Overview

Show data in a list / table.

Product Quantity
1 Apple
2 Banana
3 Tomato
4 Salad
5 Carrot
6 Onion
7 Pasta
8 Cheese
9 Chocolate
<x-table class="w-max" columns="auto minmax(10rem, auto) minmax(auto, 8rem)" row-separator="border-base-300">
  <x-slot:header>
	<x-row class="font-semibold">
	  <span></span>
	  <span>Product</span>
	  <span>Quantity</span>
	</x-row>
  </x-slot:header>
  @foreach ($groceries as $index => $product)
	<x-row>
	  <span class="font-semibold">{{ $index + 1 }}</span>
	  <span>{{ $product['name'] }}</span>
	  <x-input type="number" min="0" value="{{ $product['value'] ?? 0 }}" :label="$product['unit'] ?? '×'"/>
	</x-row>
  @endforeach
</x-table>
groceries = [ 
	[ 'name' => 'Apple'    , 'unit' => null, 'value' => 6],
	[ 'name' => 'Banana'   , 'unit' => null, 'value' => 4],
	[ 'name' => 'Tomato'   , 'unit' => null],
	[ 'name' => 'Salad'    , 'unit' => null],
	[ 'name' => 'Carrot'   , 'unit' => null],
	[ 'name' => 'Onion'    , 'unit' => null],
	[ 'name' => 'Pasta'    , 'unit' => 'g.', 'value' => 250],
	[ 'name' => 'Cheese'   , 'unit' => 'g.'],
	[ 'name' => 'Chocolate', 'unit' => null],
];

An <x-table> requires the following to be displayed properly:

#Borders

#Around the table

Borders are added around the table with the regular border classes.

Picture Name Position
1
Unknown user
John Hammond CEO
2
Unknown user
Nathalie Simmons CFO
3
Unknown user
Geoff Moore Accountant
4
Unknown user
Severine Waters HR
5
Unknown user
Abhishek Singh Developer
6
Unknown user
Fred Davis Developer
7
Unknown user
Liz Yeung IT manager
<x-table class="w-max border-1 border-info rounded-box" columns="auto auto 1fr auto">
  <x-slot:header>
	<x-row class="font-semibold">
	  <span></span>
	  <span>Picture</span>
	  <span>Name</span>
	  <span>Position</span>
	</x-row>
  </x-slot:header>
  @foreach ($list as $index => $person)
	<x-row>
	  <span class="font-semibold">{{ $index + 1 }}</span>
	  <x-avatar class="size-12 bg-base-300" :picture="$person['picture']"/>
	  <span>{{ $person['name'] }}</span>
	  <span>{{ $person['position'] }}</span>
	</x-row>
  @endforeach
</x-table>
list = [
  ['name' => 'John Hammond', 'picture' => '/people/fake/john-hammond.webp', 'position'=> 'CEO'],
  ['name' => 'Nathalie Simmons', 'picture' => '/people/fake/nathalie-simmons.webp', 'position'=> 'CFO'],
  ['name' => 'Geoff Moore', 'picture' => '/people/fake/geoff-moore.webp', 'position'=> 'Accountant'],
  ['name' => 'Severine Waters', 'picture' => '/people/fake/severine-walter.webp', 'position'=> 'HR'],
  ['name' => 'Abhishek Singh', 'picture' => '/people/fake/abhishek-singh.webp', 'position'=> 'Developer'],
  ['name' => 'Fred Davis', 'picture' => '/people/fake/fred-davis.webp', 'position'=> 'Developer'],
  ['name' => 'Liz Yeung', 'picture' => '/people/fake/liz-yeung.webp', 'position'=> 'IT manager'],
];

#Between rows and columns

Just add a class in the row-separator attribute to add lines between rows.
Similarly, add a class in the column-separator attribute to add lines between columns.

If you put a class for both, unless you use a z-index class the vertical separators will appear behind the horizontal separators.

Picture Name Position
1
Unknown user
John Hammond CEO
2
Unknown user
Nathalie Simmons CFO
3
Unknown user
Geoff Moore Accountant
Picture Name Position
1
Unknown user
John Hammond CEO
2
Unknown user
Nathalie Simmons CFO
3
Unknown user
Geoff Moore Accountant
Picture Name Position
1
Unknown user
John Hammond CEO
2
Unknown user
Nathalie Simmons CFO
3
Unknown user
Geoff Moore Accountant
<x-table class="w-max" columns="auto 4rem fit-content(20rem) auto" row-separator="border-base-300">
  <x-slot:header>
	<x-row class="font-semibold">
	  <span></span>
	  <span>Picture</span>
	  <span>Name</span>
	  <span>Position</span>
	</x-row>
  </x-slot:header>
  @foreach ($list as $index => $person)
	<x-row>
	  <span class="font-semibold">{{ $index + 1 }}</span>
	  <x-avatar class="size-12 bg-base-300" :picture="$person['picture']"/>
	  <span>{{ $person['name'] }}</span>
	  <span>{{ $person['position'] }}</span>
	</x-row>
  @endforeach
</x-table>

<x-table class="w-max" columns="auto 4rem fit-content(20rem) auto" column-separator="border-dashed">
  <x-slot:header>
	<x-row class="font-semibold">
	  <span></span>
	  <span>Picture</span>
	  <span>Name</span>
	  <span>Position</span>
	</x-row>
  </x-slot:header>
  @foreach ($list as $index => $person)
	<x-row>
	  <span  class="pe-4 font-semibold">{{ $index + 1 }}</span>
	  <x-avatar class="size-12 bg-base-300" :picture="$person['picture']"/>
	  <span class="pe-4">{{ $person['name'] }}</span>
	  <span class="pe-4">{{ $person['position'] }}</span>
	</x-row>
  @endforeach
</x-table>

<x-table class="w-max border-1 border-info rounded-box" columns="auto 4rem fit-content(20rem) auto" row_separator="border-3 border-success" column-separator="border-4 border-error border-double">
  <x-slot:header>
	<x-row class="font-semibold">
	  <span></span>
	  <span>Picture</span>
	  <span>Name</span>
	  <span>Position</span>
	</x-row>
  </x-slot:header>
  @foreach ($list as $index => $person)
	<x-row>
	  <span  class="pe-4 font-semibold">{{ $index + 1 }}</span>
	  <x-avatar class="size-12 bg-base-300" :picture="$person['picture']"/>
	  <span class="pe-4">{{ $person['name'] }}</span>
	  <span class="pe-4">{{ $person['position'] }}</span>
	</x-row>
  @endforeach
</x-table>
list = [
  ['name' => 'John Hammond', 'picture' => '/people/fake/john-hammond.webp', 'position'=> 'CEO'],
  ['name' => 'Nathalie Simmons', 'picture' => '/people/fake/nathalie-simmons.webp', 'position'=> 'CFO'],
  ['name' => 'Geoff Moore', 'picture' => '/people/fake/geoff-moore.webp', 'position'=> 'Accountant'],
];

#Zebra

The zebra attribute creates alternately-colored rows.

Product Quantity
1 Apple
2 Banana
3 Tomato
4 Salad
5 Carrot
6 Onion
7 Pasta
8 Cheese
9 Chocolate
<x-table zebra class="w-max border-1 border-base-300 rounded-box" columns="auto minmax(10rem, auto) minmax(auto, 8rem)" row-separator="border-base-300">
  <x-slot:header>
	<x-row class="font-semibold">
	  <span></span>
	  <span>Product</span>
	  <span>Quantity</span>
	</x-row>
  </x-slot:header>
  @foreach ($groceries as $index => $product)
	<x-row>
	  <span class="font-semibold">{{ $index + 1 }}</span>
	  <span>{{ $product['name'] }}</span>
	  <x-input type="number" min="0" value="{{ $product['value'] ?? 0 }}" :label="$product['unit'] ?? '×'"/>
	</x-row>
  @endforeach
</x-table>
groceries = [ 
	[ 'name' => 'Apple'    , 'unit' => null, 'value' => 6],
	[ 'name' => 'Banana'   , 'unit' => null, 'value' => 4],
	[ 'name' => 'Tomato'   , 'unit' => null],
	[ 'name' => 'Salad'    , 'unit' => null],
	[ 'name' => 'Carrot'   , 'unit' => null],
	[ 'name' => 'Onion'    , 'unit' => null],
	[ 'name' => 'Pasta'    , 'unit' => 'g.', 'value' => 250],
	[ 'name' => 'Cheese'   , 'unit' => 'g.'],
	[ 'name' => 'Chocolate', 'unit' => null],
];

#Collapsible rows

#As sub-rows

As <x-table> internally uses a grid layout, it is possible to make collapsible rows. A row with its collapsible attribute set behaves just like a collapse component.
For instance, the below example creates collapsible rows with the keep-open attribute set.

Name Position
Management
1
John Hammond
John Hammond
CEO
2
Nathalie Simmons
Nathalie Simmons
CFO
Business stakeholders
1
Geoff Moore
Geoff Moore
Accountant
2
Severine Walter
Severine Walter
HR
Development
1
Abhishek Singh
Abhishek Singh
Developer
2
Fred Davis
Fred Davis
Developer
3
Liz Yeung
Liz Yeung
IT manager
<x-table zebra class="w-max border-1 rounded-box" columns="3rem minmax(max-content,15rem) minmax(max-content,10rem) minmax(max-content,7rem)" column-separator="border-base-300">
  <x-slot:header>
	<x-row class="col-span-full grid grid-cols-subgrid font-semibold border-b-1">
	  <span></span>
	  <span>Name</span>
	  <span class="bg-base-100 col-span-2">Position</span>
	</x-row>
  </x-slot:header>
  @foreach ($teams as $team => $teammates)
	<x-row class="not-last:border-b-1" collapsible keep-open left arrow>
	  <x-slot:label>
		<span class="col-start-2 font-semibold">{{ $team }}</span>
	  </x-slot:label>
	  @foreach ($teammates as $index => $teammate)
		<x-row>
		  <span class="font-semibold justify-self-center">{{ $index + 1 }}</span>
		  <x-avatar class="size-12 rounded-full bg-base-300" :picture="$teammate['picture']" name="{{ $teammate['name'] }}"/>
		  <span>{{ $teammate['position'] }}</span>
		  <x-button color="primary" variant="ghost" label="Contact"/>
		</x-row>
	  @endforeach
	</x-row>
  @endforeach
</x-table>
teams = [
	'Management' => [
        ['name' => 'John Hammond', 'picture' => '/people/fake/john-hammond.webp', 'position'=> 'CEO'],
        ['name' => 'Nathalie Simmons', 'picture' => '/people/fake/nathalie-simmons.webp', 'position'=> 'CFO'],
    ], 'Business stakeholders' => [
        ['name' => 'Geoff Moore', 'picture' => '/people/fake/geoff-moore.webp', 'position'=> 'Accountant'],
        ['name' => 'Severine Walter', 'picture' => '/people/fake/severine-walter.webp', 'position'=> 'HR'],
    ], 'Development' => [
		['name' => 'Abhishek Singh', 'picture' => '/people/fake/abhishek-singh.webp', 'position'=> 'Developer'],
        ['name' => 'Fred Davis', 'picture' => '/people/fake/fred-davis.webp', 'position'=> 'Developer'],
        ['name' => 'Liz Yeung', 'picture' => '/people/fake/liz-yeung.webp', 'position'=> 'IT manager'],
    ]
];

#Insert different components

It is possible for the content of collapsible rows to be full-fledged components instead of sub-rows.

Country CTA
China
France
Italy
Japan
Spain
<x-table class="w-max border-1 border-base-300 rounded-box" columns="1fr max-content">
  <x-row class="col-span-full grid grid-cols-subgrid font-semibold border-b-1 border-base-300">
	<span class="min-w-60">Country</span>
	<span class="min-w-60">CTA</span>
  </x-row>
  @foreach($countries as $country => $pictures)
	<x-row class="col-span-full not-last:border-b-1" collapsible left arrow>
	  <x-slot:label class="font-light">
		<span class="bg-base-[inherit]">{{ $country }}</span>
		<x-button size="sm" class="self-center justify-self-center my-1" label="Book a flight now"/>
	  </x-slot:label>
	  <x-skewed-gallery class="col-span-full mx-4 rounded-box gap-[3px] h-60 *:hover:w-40 *:duration-500" :pictures="$pictures"/>
	</x-row>
  @endforeach
</x-table>
countries = [
  'China' => [
	'/assets/sightseeing/china/emei.webp',
	'/assets/sightseeing/china/fanjing.webp',
	'/assets/sightseeing/china/great-wall.webp',
	'/assets/sightseeing/china/heng.webp',
	'/assets/sightseeing/china/shanghai.webp',
	'/assets/sightseeing/china/shangri-la.webp',
  ],
  'France' => [
	'/assets/sightseeing/france/gros-horloge.webp',
	'/assets/sightseeing/france/carcassone.webp',
	'/assets/sightseeing/france/beaune.jpg',
	'/assets/sightseeing/france/grand-palais.webp',
	'/assets/sightseeing/france/arles.jpg',
	'/assets/sightseeing/france/lavande.webp',
	'/assets/sightseeing/france/rocamadour.jpg',
	'/assets/sightseeing/france/chenonceau.webp',
	'/assets/sightseeing/france/mont-saint-michel.webp',
  ],
  'Italy' => [
	'/assets/sightseeing/italy/florence.webp',
	'/assets/sightseeing/italy/pompeii.webp',
	'/assets/sightseeing/italy/venice.webp',
  ],
  'Japan' => [
	'/assets/sightseeing/japan/fuji.webp',
	'/assets/sightseeing/japan/kyoto.webp',
	'/assets/sightseeing/japan/miyajima.webp',
	'/assets/sightseeing/japan/nara.webp',
	'/assets/sightseeing/japan/tokyo.webp',
  ],
  'Spain' => [
	'/assets/sightseeing/spain/alhambra.webp',
	'/assets/sightseeing/spain/sagrada-familia.webp',
  ],
];

#Examples

#Highlight row on hover

A simple hover:bg-{color} class takes care of that. You may want to add cursor-pointer for added effect.

Picture Name Position
1
Unknown user
John Hammond CEO
2
Unknown user
Nathalie Simmons CFO
3
Unknown user
Geoff Moore Accountant
4
Unknown user
Severine Waters HR
5
Unknown user
Abhishek Singh Developer
6
Unknown user
Fred Davis Developer
7
Unknown user
Liz Yeung IT manager
<x-table class="w-max" columns="auto 4rem fit-content(20rem) auto" row-separator="border-base-300">
  <x-slot:header>
	<x-row class="font-semibold">
	  <span></span>
	  <span>Picture</span>
	  <span>Name</span>
	  <span>Position</span>
	</x-row>
  </x-slot:header>
  @foreach ($list as $index => $person)
	<x-row class="cursor-pointer hover:bg-base-300/50">
	  <span class="font-semibold">{{ $index + 1 }}</span>
	  <x-avatar class="size-12 bg-base-300" :picture="$person['picture']"/>
	  <span>{{ $person['name'] }}</span>
	  <span>{{ $person['position'] }}</span>
	</x-row>
  @endforeach
</x-table>
list = [
  ['name' => 'John Hammond', 'picture' => '/people/fake/john-hammond.webp', 'position'=> 'CEO'],
  ['name' => 'Nathalie Simmons', 'picture' => '/people/fake/nathalie-simmons.webp', 'position'=> 'CFO'],
  ['name' => 'Geoff Moore', 'picture' => '/people/fake/geoff-moore.webp', 'position'=> 'Accountant'],
  ['name' => 'Severine Waters', 'picture' => '/people/fake/severine-walter.webp', 'position'=> 'HR'],
  ['name' => 'Abhishek Singh', 'picture' => '/people/fake/abhishek-singh.webp', 'position'=> 'Developer'],
  ['name' => 'Fred Davis', 'picture' => '/people/fake/fred-davis.webp', 'position'=> 'Developer'],
  ['name' => 'Liz Yeung', 'picture' => '/people/fake/liz-yeung.webp', 'position'=> 'IT manager'],
];

#Reducing the row height

The default row height is mainly due to the default padding being applied to rows (class py-3). This is usually fine if the table does not contain too many rows and if each row only contains no more than 1 line of text.
If you believe that is too high, you can reduce it by adding a py-{number|length} class to each row.

Because each row contains an input that increases the row height, the grocery shopping list is a good candidate for reduction; here is a before/after comparison.

Product Quantity
1 Apple
2 Banana
3 Tomato
4 Salad
5 Carrot
6 Onion
7 Pasta
8 Cheese
9 Chocolate
Product Quantity
1 Apple
2 Banana
3 Tomato
4 Salad
5 Carrot
6 Onion
7 Pasta
8 Cheese
9 Chocolate
<x-table zebra class="w-max border-1 border-base-300 rounded-box" columns="auto minmax(10rem, auto) minmax(auto, 8rem)" row-separator="border-base-300">
  <x-slot:header>
	<x-row class="font-semibold">
	  <span></span>
	  <span>Product</span>
	  <span>Quantity</span>
	</x-row>
  </x-slot:header>
  @foreach ($groceries as $index => $product)
	<x-row>
	  <span class="font-semibold">{{ $index + 1 }}</span>
	  <span>{{ $product['name'] }}</span>
	  <x-input type="number" min="0" value="{{ $product['value'] ?? 0 }}" :label="$product['unit'] ?? '×'"/>
	</x-row>
  @endforeach
</x-table>

<x-table zebra class="w-max border-1 border-base-300 rounded-box" columns="auto minmax(10rem, auto) minmax(auto, 8rem)" row-separator="border-base-300">
  <x-slot:header>
	<x-row class="font-semibold">
	  <span></span>
	  <span>Product</span>
	  <span>Quantity</span>
	</x-row>
  </x-slot:header>
  @foreach ($groceries as $index => $product)
	<x-row class="py-1">
	  <span class="font-semibold">{{ $index + 1 }}</span>
	  <span>{{ $product['name'] }}</span>
	  <x-input type="number" min="0" value="{{ $product['value'] ?? 0 }}" :label="$product['unit'] ?? '×'"/>
	</x-row>
  @endforeach
</x-table>
groceries = [ 
	[ 'name' => 'Apple'    , 'unit' => null, 'value' => 6],
	[ 'name' => 'Banana'   , 'unit' => null, 'value' => 4],
	[ 'name' => 'Tomato'   , 'unit' => null],
	[ 'name' => 'Salad'    , 'unit' => null],
	[ 'name' => 'Carrot'   , 'unit' => null],
	[ 'name' => 'Onion'    , 'unit' => null],
	[ 'name' => 'Pasta'    , 'unit' => 'g.', 'value' => 250],
	[ 'name' => 'Cheese'   , 'unit' => 'g.'],
	[ 'name' => 'Chocolate', 'unit' => null],
];