--- description: 'Display data in a table.' links: - label: GitHub icon: i-simple-icons-github to: https://github.com/nuxt/ui/blob/dev/src/runtime/components/data/Table.vue --- ## Usage Use the `rows` prop to set the data to display in the table. By default, the table will display all the fields of the rows. ::component-example{class="grid"} --- padding: false overflowClass: 'overflow-x-auto' --- #default :table-example-basic{class="flex-1"} #code ```vue ``` :: ### Columns Use the `columns` prop to configure which columns to display. It's an array of objects with the following properties: - `label` - The label to display in the table header. Can be changed through the `column-attribute` prop. - `key` - The field to display from the row data. - `sortable` - Whether the column is sortable. Defaults to `false`. - `direction` - The sort direction to use on first click. Defaults to `asc`. - `class` - The class to apply to the column cells. ::component-example{class="grid"} --- padding: false overflowClass: 'overflow-x-auto' --- #default :table-example-columns{class="flex-1"} #code ```vue ``` :: You can easily use the [SelectMenu](/forms/select-menu) component to change the columns to display. ::component-example{class="grid"} --- padding: false overflowClass: 'overflow-x-auto' --- #default :table-example-columns-selectable{class="flex-1"} #code ```vue ``` :: ### Sortable You can make the columns sortable by setting the `sortable` property to `true` in the column configuration. ::component-example{class="grid"} --- padding: false overflowClass: 'overflow-x-auto' --- #default :table-example-columns-sortable{class="flex-1"} #code ```vue ``` :: You can specify the default direction of each column through the `direction` property. It can be either `asc` or `desc` and defaults to `asc`. You can specify a default sort for the table through the `sort` prop. It's an object with the following properties: - `column` - The column to sort by. - `direction` - The sort direction. Can be either `asc` or `desc` and defaults to `asc`. ::callout{icon="i-heroicons-light-bulb"} This will set the default sort and will work even if no column is set as `sortable`. :: Use the `sort-button` prop to customize the sort button in the header. You can pass all the props of the [Button](/elements/button) component to customize it through this prop or globally through `ui.table.default.sortButton`. Its icon defaults to `i-heroicons-arrows-up-down-20-solid`. ::component-card{class="grid"} --- padding: false overflowClass: 'overflow-x-auto' baseProps: class: 'w-full' columns: - key: 'id' label: 'ID' - key: 'name' label: 'Name' sortable: true - key: 'title' label: 'Title' sortable: true - key: 'email' label: 'Email' sortable: true - key: 'role' label: 'Role' rows: - id: 1 name: 'Lindsay Walton' title: 'Front-end Developer' email: 'lindsay.walton@example.com' role: 'Member' - id: 2 name: 'Courtney Henry' title: 'Designer' email: 'courtney.henry@example.com' role: 'Admin' - id: 3 name: 'Tom Cook' title: 'Director of Product' email: 'tom.cook@example.com' role: 'Member' - id: 4 name: 'Whitney Francis' title: 'Copywriter' email: 'whitney.francis@example.com' role: 'Admin' - id: 5 name: 'Leonard Krasner' title: 'Senior Designer' email: 'leonard.krasner@example.com' role: 'Owner' - id: 6 name: 'Floyd Miles' title: 'Principal Designer' email: 'floyd.miles@example.com' role: 'Member' props: sortAscIcon: 'i-heroicons-arrow-up-20-solid' sortDescIcon: 'i-heroicons-arrow-down-20-solid' sortButton: icon: 'i-heroicons-sparkles-20-solid' color: 'primary' variant: 'outline' size: '2xs' square: false ui: rounded: 'rounded-full' excludedProps: - sortButton - sortAscIcon - sortDescIcon --- :: Use the `sort-asc-icon` prop to set a different icon or change it globally in `ui.table.default.sortAscIcon`. Defaults to `i-heroicons-bars-arrow-up-20-solid`. Use the `sort-desc-icon` prop to set a different icon or change it globally in `ui.table.default.sortDescIcon`. Defaults to `i-heroicons-bars-arrow-down-20-solid`. ::callout{icon="i-heroicons-light-bulb"} You can also customize the entire header cell, read more in the [Slots](#slots) section. :: ### Selectable Use a `v-model` to make the table selectable. The `v-model` will be an array of the selected rows. ::component-example{class="grid"} --- padding: false overflowClass: 'overflow-x-auto' --- #default :table-example-selectable{class="flex-1"} #code ```vue ``` :: ::callout{icon="i-heroicons-light-bulb"} You can use the `by` prop to compare objects by a field instead of comparing object instances. We've replicated the behavior of Headless UI [Combobox](https://headlessui.com/vue/combobox#binding-objects-as-values). :: You can also add a `select` listener on your Table to make the rows clickable. The function will receive the row as the first argument. You can use this to navigate to a page, open a modal or even to select the row manually. ::component-example{class="grid"} --- padding: false overflowClass: 'overflow-x-auto' --- #default :table-example-clickable{class="flex-1"} #code ```vue ``` :: ### Searchable You can easily use the [Input](/forms/input) component to filter the rows. ::component-example{class="grid"} --- padding: false overflowClass: 'overflow-x-auto' --- #default :table-example-searchable{class="flex-1"} #code ```vue ``` :: ### Paginable You can easily use the [Pagination](/navigation/pagination) component to paginate the rows. ::component-example --- padding: false --- #default :table-example-paginable{class="w-full"} #code ```vue ``` :: ### Loading Use the `loading` prop to display a loading state. Use the `loading-state` prop to customize the `icon` and `label` or change them globally in `ui.table.default.loadingState`. You can also set it to `null` to hide the loading state. ::component-card --- padding: false overflowClass: 'overflow-x-auto' baseProps: class: 'w-full' columns: - key: 'id' label: 'ID' - key: 'name' label: 'Name' - key: 'title' label: 'Title' - key: 'email' label: 'Email' - key: 'role' label: 'Role' props: loading: true loadingState: icon: 'i-heroicons-arrow-path-20-solid' label: "Loading..." excludedProps: - loadingState --- :: This can be easily used with Nuxt `useAsyncData` composable. ```vue ``` ### Empty An empty state will be displayed when there are no results. Use the `empty-state` prop to customize the `icon` and `label` or change them globally in `ui.table.default.emptyState`. You can also set it to `null` to hide the empty state. ::component-card --- padding: false overflowClass: 'overflow-x-auto' baseProps: class: 'w-full' columns: - key: 'id' label: 'ID' - key: 'name' label: 'Name' - key: 'title' label: 'Title' - key: 'email' label: 'Email' - key: 'role' label: 'Role' props: emptyState: icon: 'i-heroicons-circle-stack-20-solid' label: "No items." excludedProps: - emptyState --- :: ## Slots You can use slots to customize the header and data cells of the table. ### `-header` Use the `#-header` slot to customize the header cell of a column. You will have access to the `column`, `sort` and `on-sort` properties in the slot scope. The `sort` property is an object with the following properties: - `field` - The field to sort by. - `direction` - The direction to sort by. Can be `asc` or `desc`. The `on-sort` property is a function that you can call to sort the table and accepts the column as parameter. ::callout{icon="i-heroicons-light-bulb"} Even though you can customize the sort button as mentioned in the [Sortable](#sortable) section, you can use this slot to completely override its behavior, with a custom dropdown for example. :: ### `-data` Use the `#-data` slot to customize the data cell of a column. You will have access to the `row`, `column` and `getRowData` properties in the slot scope. You can for example create an extra column for actions with a [Dropdown](/elements/dropdown) component inside or change the color of the rows based on a selection. ::component-example{class="grid"} --- padding: false overflowClass: 'overflow-x-auto' --- #default :table-example-slots{class="flex-1"} #code ```vue ``` :: ### `loading-state` Use the `#loading-state` slot to customize the loading state. ::component-example{class="grid"} --- padding: false overflowClass: 'overflow-x-auto' --- #default :table-example-loading-slot{class="flex-1"} #code ```vue ``` :: ### `empty-state` Use the `#empty-state` slot to customize the empty state. ::component-example{class="grid"} --- padding: false overflowClass: 'overflow-x-auto' --- #default :table-example-empty-slot{class="flex-1"} #code ```vue ``` :: ## Props :component-props ## Preset :component-preset