Appearance
Data Table
FTDataTable is a slot-driven table component for richer row layouts, sortable headers, column filter triggers, and expandable detail rows.
Usage
vue
<script setup lang="ts">
import { FTDataTable, FTTableFilter } from '@fasttrack-solutions/vue-components-lib';
import type { IFTDataTableHead } from '@fasttrack-solutions/vue-components-lib';
const heads: IFTDataTableHead[] = [
{ label: 'Name', field: 'name', sortKey: 'name' },
{ label: 'Role', field: 'role' },
];
</script><script setup lang="ts">
import { FTDataTable, FTTableFilter } from '@fasttrack-solutions/vue-components-lib';
import type { IFTDataTableHead } from '@fasttrack-solutions/vue-components-lib';
const heads: IFTDataTableHead[] = [
{ label: 'Name', field: 'name', sortKey: 'name' },
{ label: 'Role', field: 'role' },
];
</script>Sortable rows with filters and expansion
vue
<FTDataTable
v-model:sortKey="sortKey"
v-model:sortOrder="sortOrder"
v-model:expandedRows="expandedRows"
:heads="heads"
:items="items"
rowKey="id"
:sortFn="sortFn"
>
<template #filter="{ head }">
<FTTableFilter v-if="head.filterKey" @clear="statusFilter = 'all'">
<!-- filter controls -->
</FTTableFilter>
</template>
<template #row="{ item, isExpanded, toggleExpand }">
<tr>
<td>
<button type="button" @click="toggleExpand()">
{{ isExpanded ? 'Hide' : 'Show' }}
</button>
{{ item.name }}
</td>
<td>{{ item.email }}</td>
<td>{{ item.role }}</td>
<td>{{ item.department }}</td>
<td>{{ item.status }}</td>
</tr>
</template>
<template #expanded-row="{ item }">
<div>Detail row for {{ item.name }} — {{ item.department }}</div>
</template>
</FTDataTable><FTDataTable
v-model:sortKey="sortKey"
v-model:sortOrder="sortOrder"
v-model:expandedRows="expandedRows"
:heads="heads"
:items="items"
rowKey="id"
:sortFn="sortFn"
>
<template #filter="{ head }">
<FTTableFilter v-if="head.filterKey" @clear="statusFilter = 'all'">
<!-- filter controls -->
</FTTableFilter>
</template>
<template #row="{ item, isExpanded, toggleExpand }">
<tr>
<td>
<button type="button" @click="toggleExpand()">
{{ isExpanded ? 'Hide' : 'Show' }}
</button>
{{ item.name }}
</td>
<td>{{ item.email }}</td>
<td>{{ item.role }}</td>
<td>{{ item.department }}</td>
<td>{{ item.status }}</td>
</tr>
</template>
<template #expanded-row="{ item }">
<div>Detail row for {{ item.name }} — {{ item.department }}</div>
</template>
</FTDataTable>Empty state
vue
<FTDataTable :heads="heads" :items="[]" :showEmpty="true">
<template #empty>
<div>No rows found.</div>
</template>
</FTDataTable><FTDataTable :heads="heads" :items="[]" :showEmpty="true">
<template #empty>
<div>No rows found.</div>
</template>
</FTDataTable>Props
| Prop | Type | Default | Description |
|---|---|---|---|
heads | IFTDataTableHead[] | required | Column definitions used to render the header row. |
items | TItem[] | required | Items rendered through the row slot. |
showEmpty | boolean | null | null | Overrides derived empty-state visibility. |
loading | boolean | false | Participates in empty-state display when showEmpty is not set. |
rowKey | keyof TItem & string | undefined | Stable key for rows and expandable-row behavior. |
sortFn | (items, sortKey, sortOrder) => TItem[] | undefined | Custom sorting function. |
scrollable | boolean | true | Enables horizontal overflow scrolling. |
iconPrefix | string | 'fas' | Font Awesome prefix for internal icons. |
IFTDataTableHead
| Property | Type | Required | Description |
|---|---|---|---|
label | string | yes | Column header text. |
field | string | yes | Item property key used to read cell values. |
sortKey | string | no | Property key used for sorting. When omitted, the column is not sortable. |
filterKey | string | no | Enables the #filter slot for this column. |
align | 'left' | 'right' | 'center' | no | Header and cell text alignment. Defaults to 'left'. |
tooltip | string | no | Tooltip text shown with an info icon next to the label. |
class | string | no | Additional CSS class applied to the header cell. |
Models
| Model | Type | Default | Description |
|---|---|---|---|
v-model:sortKey | string | '' | Active sort column key. |
v-model:sortOrder | 'asc' | 'desc' | 'desc' | Active sort direction. |
v-model:expandedRows | (string | number)[] | [] | Expanded row identifiers, requires rowKey. |
Events
| Event | Description |
|---|---|
sortChange | Emitted after a sortable header updates the active sort key or order. |
Slots
| Slot | Props | Description |
|---|---|---|
selectAll | none | Adds a leading header cell, typically for bulk actions. |
filter | head | Renders a per-column filter trigger when filterKey is set. |
row | item, index, isExpanded, toggleExpand | Required row renderer. |
expanded-row | item, index | Optional detail row rendered below expanded rows. |
empty | none | Empty-state content. |