Skip to content

Table

Data table built on TanStack Table v8. Aurora wraps TanStack with sensible aurora-flavored defaults: sorting indicators, pagination, column visibility, row selection, and persistence via the DS_TABLE_SETTINGS adapter.

ID
First Name
Last Name
Age
Status
1
John
Doe
25
Active
2
Jane
Doe
23
Inactive
3
Michael
Smith
32
Active
4
Emily
Johnson
28
Pending
5
David
Williams
35
Active
6
David1
Williams
35
Active
7
David2
Williams
35
Active
8
David3
Williams
35
Active
9
David4
Williams
35
Active
10
David5
Williams
35
Active
11
David6
Williams
35
Active
Showing 1 - 11 of 11

The column schema uses TanStack's createColumnHelper<T>() — pass your row type for cell-typed safety.

When to reach for a table

  • Structured datasets with multiple comparable attributes per row — the user wants to scan, sort, or compare across columns
  • ESG data — buildings, meters, certifications, surveys, audits
  • Admin views and audit logs — long lists where filtering and bulk action matter
  • Sortable, filterable, or bulk-actionable content — selection + the floating action bar live here

When not to use a table

  • Small datasets (handful of items, few attributes) — cards or a plain list read better
  • Single-column content — that's a list, not a table
  • Deeply nested hierarchies — use a tree view
  • A form layout — fields belong in Input / Combobox / etc., laid out as a form. Tables are for displaying rows of data.

Basic example (everything enabled)

vue
<script setup lang="ts">
import { ref } from 'vue'
import { Table } from '@scaler-tech/aurora/table'
import { createColumnHelper } from '@tanstack/vue-table'

type Person = { id: number; firstName: string; lastName: string; age: number; status: string }

const columnHelper = createColumnHelper<Person>()

const columns = [
    columnHelper.accessor('id', { header: 'ID', cell: info => info.getValue() }),
    columnHelper.accessor('firstName', { header: 'First Name', cell: info => info.getValue() }),
    columnHelper.accessor('lastName', { header: 'Last Name', cell: info => info.getValue() }),
    columnHelper.accessor('age', { header: 'Age', cell: info => info.getValue() }),
    columnHelper.accessor('status', { header: 'Status', cell: info => info.getValue() }),
]

const data = ref<Person[]>([
    { id: 1, firstName: 'John', lastName: 'Doe', age: 25, status: 'Active' },
    /* … */
])
</script>

<Table
  :data="data"
  :columns="columns"
  :enable-sorting
  :enable-column-resizing
  :enable-pagination
  :enable-column-visibility
  :enable-row-selection
/>

Minimal — no extra features

Pagination, sorting, and the rest are off by default-ish; pass exactly what you want.

ID
First Name
Last Name
Age
Status
1
Aurora
Borealis
0
Active
2
Inter
Manrope
0
Active
html
<Table :data="rows" :columns="columns" :enable-pagination="false" />

Loading

Showing 1 - 3 of 3
html
<Table :data="data" :columns="columns" :loading="true" />

Props (subset — most-used)

PropTypeDefaultDescription
dataT[]requiredRow data array.
columnsColumnDef<T>[]requiredColumn definitions from createColumnHelper<T>().
enableSortingbooleantrueShow sort indicators in headers; clicking toggles sort.
enableColumnResizingbooleantrueDrag the column edge to resize.
enablePaginationbooleantrueRender pagination footer.
enableColumnVisibilitybooleanfalseShow the column-toggle menu in the header.
enableRowSelectionbooleanfalseRender checkbox column.
enableRowReorderingbooleanfalseDrag rows to reorder.
enableColumnReorderingbooleanfalseDrag columns to reorder.
enableColumnFiltersbooleanfalsePer-column filter UI.
enableGlobalFilterbooleanfalseGlobal search input.
loadingbooleanfalseShow loading skeletons.
pagination{ pageIndex?: number; pageSize?: number; pageSizeOptions?: number[]; serverSide?: boolean }{ pageSize: 25, pageSizeOptions: [10, 25, 50, 100] }Pagination configuration.
columnPinning{ left?: string[]; right?: string[] }{ left: [], right: [] }Pin columns to the start/end.
defaultColumnSizing{ minSize?: number; maxSize?: number; size?: number }{ size: 0, minSize: 0 }Default sizing applied to all columns.
showInternalBordersbooleantrueRender borders between cells.
hideInternalVerticalBordersbooleanfalseHide vertical cell borders only.
roundedCornersbooleanRound the outer corners.
stickyScrollbarbooleanPin the horizontal scrollbar to the viewport bottom.

The data and columns props are TanStack-shaped — refer to TanStack Table docs for advanced column features (filter functions, sort functions, sub-rows, expanding, custom cell renderers).

Custom cell rendering

Use a slot named after the column id to override that column's cell rendering — no need to provide a cell function in the column definition.

html
<Table :data="data" :columns="columns">
  <template #status="{ value }">
    <Tag :variant="value === 'Active' ? 'success' : 'neutral'">{{ value }}</Tag>
  </template>
</Table>

The slot props give you { cell, row, original, value, index }value is typed as the column's cell value when you use createColumnHelper<T>().

Persistence (DS_TABLE_SETTINGS)

Column order, row order, column visibility, and saved views all persist through the DS_TABLE_SETTINGS adapter. Aurora ships a no-op default — Table renders without persistence out of the box. Provide a real adapter at the app root via provideTableSettings(app) to enable saving.