Skip to content

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 ​

PropTypeDefaultDescription
headsIFTDataTableHead[]requiredColumn definitions used to render the header row.
itemsTItem[]requiredItems rendered through the row slot.
showEmptyboolean | nullnullOverrides derived empty-state visibility.
loadingbooleanfalseParticipates in empty-state display when showEmpty is not set.
rowKeykeyof TItem & stringundefinedStable key for rows and expandable-row behavior.
sortFn(items, sortKey, sortOrder) => TItem[]undefinedCustom sorting function.
scrollablebooleantrueEnables horizontal overflow scrolling.
iconPrefixstring'fas'Font Awesome prefix for internal icons.

IFTDataTableHead ​

PropertyTypeRequiredDescription
labelstringyesColumn header text.
fieldstringyesItem property key used to read cell values.
sortKeystringnoProperty key used for sorting. When omitted, the column is not sortable.
filterKeystringnoEnables the #filter slot for this column.
align'left' | 'right' | 'center'noHeader and cell text alignment. Defaults to 'left'.
tooltipstringnoTooltip text shown with an info icon next to the label.
classstringnoAdditional CSS class applied to the header cell.

Models ​

ModelTypeDefaultDescription
v-model:sortKeystring''Active sort column key.
v-model:sortOrder'asc' | 'desc''desc'Active sort direction.
v-model:expandedRows(string | number)[][]Expanded row identifiers, requires rowKey.

Events ​

EventDescription
sortChangeEmitted after a sortable header updates the active sort key or order.

Slots ​

SlotPropsDescription
selectAllnoneAdds a leading header cell, typically for bulk actions.
filterheadRenders a per-column filter trigger when filterKey is set.
rowitem, index, isExpanded, toggleExpandRequired row renderer.
expanded-rowitem, indexOptional detail row rendered below expanded rows.
emptynoneEmpty-state content.