Table
TkTable is a component that allows you to display data in a tabular manner. It's generally called a datatable.
- React
- Vue
- Angular
import { TkTable } from '@takeoff-ui/react'
import { TkTable } from '@takeoff-ui/vue'
import { TkTable } from '@takeoff-ui/angular'
Basic​
The basic features of the TkTable component are demonstrated.
- React
- Vue
- Angular
const column: ITableColumn[] = [
{
field: "id",
header: "Id",
},
{
field: "name",
header: "Name",
},
{
field: "category",
header: "Category",
},
{
field: "quantity",
header: "Quantity",
},
];
return (
<div style={{ padding: "8px" }}>
<TkTable columns={column} data={basicData} />
</div>
);
<script setup>
import { TkTable } from '@takeoff-ui/vue'
const column = [
{
field: "id",
header: "Id",
},
{
field: "name",
header: "Name",
},
{
field: "category",
header: "Category",
},
{
field: "quantity",
header: "Quantity",
},
];
</script>
<template>
<div :style="{ padding: '8px' }">
<TkTable :columns.prop="column" :data.prop="basicData" />
</div>
</template>
<div style="padding: 8px">
<tk-table
[columns]="[
{ field: 'id', header: 'Id' },
{ field: 'name', header: 'Name' },
{ field: 'category', header: 'Category' },
{ field: 'quantity', header: 'Quantity' }
]"
[data]="[
{ id: 1, name: 'Product A', category: 'Electronics', quantity: 12 },
{ id: 2, name: 'Product B', category: 'Books', quantity: 8 },
{ id: 3, name: 'Product C', category: 'Groceries', quantity: 20 }
]"
/>
</div>
Striped​
To enable striped mode, set the striped prop to true. This feature displays rows with alternating background colors.
- React
- Vue
- Angular
<TkTable columns={column} data={basicData} striped />
<TkTable :columns.prop="column" :data.prop="basicData" striped />
<tk-table
[columns]="[
{ field: 'id', header: 'Id' },
{ field: 'name', header: 'Name' },
{ field: 'category', header: 'Category' },
{ field: 'quantity', header: 'Quantity' }
]"
[data]="[
{ id: 1, name: 'Product A', category: 'Electronics', quantity: 12 },
{ id: 2, name: 'Product B', category: 'Books', quantity: 8 },
{ id: 3, name: 'Product C', category: 'Groceries', quantity: 20 }
]"
striped
/>
Header Type​
The headerType prop is used to change the style of the table headers and allows you to customize the headers' style with values such as basic, primary, and dark.
headerType is basic
- React
- Vue
- Angular
<TkTable columns={column} data={headerTypeData} headerType="basic" />
<TkTable :columns.prop="column" :data.prop="headerTypeData" headerType="basic" />
<tk-table
[columns]="[
{ field: 'id', header: 'Id' },
{ field: 'name', header: 'Name' },
{ field: 'category', header: 'Category' },
{ field: 'quantity', header: 'Quantity' }
]"
[data]="[
{ id: 1, name: 'Product A', category: 'Electronics', quantity: 12 },
{ id: 2, name: 'Product B', category: 'Books', quantity: 8 },
{ id: 3, name: 'Product C', category: 'Groceries', quantity: 20 }
]"
headerType="basic"
/>
Selection​
This feature allows users to select rows in the table. The selected rows are visually highlighted and can be used for various actions.
- React
- Vue
- Angular
const column: ITableColumn[] = [
{
field: "id",
header: "Id",
},
{
field: "name",
header: "Name",
},
{
field: "category",
header: "Category",
},
{
field: "quantity",
header: "Quantity",
},
];
const [selectionList, setSelectionList] = useState();
const [mode, setMode] = useState();
return (
<div style={{ padding: "8px" }}>
<TkTable
columns={column}
data={basicData}
dataKey="id"
selectionMode={mode}
onTkSelectionChange={(e: CustomEvent) =>
setSelectionList({ ...e.detail })
}
/>
<p>{JSON.stringify(selectionList)}</p>
</div>
);
<script setup>
import { TkTable } from '@takeoff-ui/vue'
const column = [
{
field: "id",
header: "Id",
},
{
field: "name",
header: "Name",
},
{
field: "category",
header: "Category",
},
{
field: "quantity",
header: "Quantity",
},
];
</script>
<template>
<div :style="{ padding: '8px' }">
<TkTable
:columns.prop="column"
:data.prop="basicData"
dataKey="id"
selectionMode.prop="mode"
@tkSelectionChange="(e) => setSelectionList({ ...e.detail })"
/>
<p>{{ JSON.stringify(selectionList) }}</p>
</div>
</template>
Filter and Sorting​
The table supports three types of filtering:
- Text input filtering: Allows free text search in columns
- Checkbox filtering: Enables selecting multiple values from predefined options
- Radio filtering: Allows selecting a single value from predefined options
The filtering type can be configured using the filterType
property in column definition. For checkbox and radio filters, you need to provide filterOptions
with value-label pairs.
- React
- Vue
- Angular
const column: ITableColumn[] = [
{
field: 'id',
header: 'Id',
},
{
field: 'name',
header: 'Input Filter',
searchable: true,
sortable: true,
sorter: (a: any, b: any) => (a.name > b.name ? 1 : -1),
filter: (value: string, row: any) =>
row.name
.toString()
.toLowerCase()
.indexOf(value.toString().toLowerCase() as string) > -1,
},
{
field: 'status',
header: 'Checkbox Filter',
searchable: true,
filterType: 'checkbox',
filterOptions: [
{ value: 'active', label: 'Active' },
{ value: 'inactive', label: 'Inactive' },
{ value: 'pending', label: 'Pending' },
],
filterElements: {
icon: 'filter_list',
optionsSearchInput: { show: true, placeholder: 'Filter' },
},
},
{
field: 'group',
header: 'Radio Filter',
searchable: true,
filterType: 'radio',
filterOptions: [
{ value: 'group 1', label: 'Group 1' },
{ value: 'group 2', label: 'Group 2' },
{ value: 'group 3', label: 'Group 3' },
],
filterElements: {
optionsSearchInput: { show: true, placeholder: 'Filter' },
},
},
{
field: 'quantity',
header: 'Quantity',
sortable: true,
sorter: (a: any, b: any) =>
Number(a.quantity) > Number(b.quantity) ? 1 : -1,
},
];
const data = [
{
id: 'f230fh0g3',
name: 'Bamboo Watch',
status: 'active',
group: 'group 1',
quantity: 24,
},
{
id: 'nvklal433',
name: 'Black Watch',
status: 'inactive',
group: 'group 2',
quantity: 42,
},
{
id: 'zz21cz3c1',
name: 'Blue Band',
status: 'active',
group: 'group 3',
quantity: 87,
},
{
id: '244wgerg2',
name: 'Blue T-Shirt',
status: 'pending',
group: 'group 1',
quantity: 12,
},
{
id: 'h456wer53',
name: 'Bracelet',
status: 'inactive',
group: 'group 2',
quantity: 45,
},
];
return <TkTable columns={column} data={data} />;
<script setup>
import { TkTable } from '@takeoff-ui/vue';
const column = [
{
field: 'id',
header: 'Id',
},
{
field: 'name',
header: 'Input Filter',
searchable: true,
sortable: true,
sorter: (a, b) => (a.name > b.name ? 1 : -1),
filter: (value, row) =>
row.name
.toString()
.toLowerCase()
.indexOf(value.toString().toLowerCase()) > -1,
},
{
field: 'status',
header: 'Checkbox Filter',
searchable: true,
filterType: 'checkbox',
filterOptions: [
{ value: 'active', label: 'Active' },
{ value: 'inactive', label: 'Inactive' },
{ value: 'pending', label: 'Pending' },
],
filterElements: {
icon: 'filter_list',
optionsSearchInput: { show: true, placeholder: 'Filter' },
},
},
{
field: 'group',
header: 'Radio Filter',
searchable: true,
filterType: 'radio',
filterOptions: [
{ value: 'group 1', label: 'Group 1' },
{ value: 'group 2', label: 'Group 2' },
{ value: 'group 3', label: 'Group 3' },
],
filterElements: {
optionsSearchInput: { show: true, placeholder: 'Filter' },
},
},
{
field: 'quantity',
header: 'Quantity',
sortable: true,
sorter: (a, b) => (Number(a.quantity) > Number(b.quantity) ? 1 : -1),
},
];
const data = [
{
id: 'f230fh0g3',
name: 'Bamboo Watch',
status: 'active',
group: 'group 1',
quantity: 24,
},
{
id: 'nvklal433',
name: 'Black Watch',
status: 'inactive',
group: 'group 2',
quantity: 42,
},
{
id: 'zz21cz3c1',
name: 'Blue Band',
status: 'active',
group: 'group 3',
quantity: 87,
},
{
id: '244wgerg2',
name: 'Blue T-Shirt',
status: 'pending',
group: 'group 1',
quantity: 12,
},
{
id: 'h456wer53',
name: 'Bracelet',
status: 'inactive',
group: 'group 2',
quantity: 45,
},
];
</script>
<template>
<TkTable :columns.prop="column" :data.prop="data" />
</template>
Multi Sorting​
This feature allows users to sort the table by multiple columns simultaneously. Users can click on the column headers to apply sorting, and the order of sorting can be adjusted by clicking on the headers in the desired sequence.
- React
- Vue
- Angular
const column: ITableColumn[] = [
{
field: 'id',
header: 'Id',
},
{
field: 'name',
header: 'Name',
sortable: true,
sorter: (a: any, b: any) => {
if (a.name < b.name) return -1;
if (a.name > b.name) return 1;
return 0;
},
},
{
field: 'status',
header: 'Status',
sortable: true,
sorter: (a: any, b: any) => {
if (a.status < b.status) return -1;
if (a.status > b.status) return 1;
return 0;
},
},
{
field: 'group',
header: 'Group',
sortable: true,
sorter: (a: any, b: any) => {
if (a.group < b.group) return -1;
if (a.group > b.group) return 1;
return 0;
},
},
{
field: 'quantity',
header: 'Quantity',
sortable: true,
sorter: (a: any, b: any) => {
if (a.quantity < b.quantity) return -1;
if (a.quantity > b.quantity) return 1;
return 0;
},
},
];
const data = [
{
id: 'zz21cz3c1',
name: 'Blue Band',
status: 'active',
group: 'group 3',
quantity: 87,
},
{
id: 'h456wer53',
name: 'Bracelet',
status: 'inactive',
group: 'group 2',
quantity: 45,
},
{
id: 'a789def12',
name: 'Blue Band',
status: 'pending',
group: 'group 1',
quantity: 24,
},
{
id: 'b123ghi34',
name: 'Blue Band',
status: 'inactive',
group: 'group 2',
quantity: 12,
},
{
id: 'c456jkl56',
name: 'Smart Watch',
status: 'active',
group: 'group 3',
quantity: 24,
},
{
id: 'e012pqr90',
name: 'Bracelet',
status: 'active',
group: 'group 1',
quantity: 45,
},
];
return <TkTable columns={column} data={data} multiSort={true} />;
<script setup>
import { TkTable } from '@takeoff-ui/vue';
const column = [
{
field: 'id',
header: 'Id',
},
{
field: 'name',
header: 'Name',
sortable: true,
sorter: (a, b) => {
if (a.name < b.name) return -1;
if (a.name > b.name) return 1;
return 0;
},
},
{
field: 'status',
header: 'Status',
sortable: true,
sorter: (a, b) => {
if (a.status < b.status) return -1;
if (a.status > b.status) return 1;
return 0;
},
},
{
field: 'group',
header: 'Group',
sortable: true,
sorter: (a, b) => {
if (a.group < b.group) return -1;
if (a.group > b.group) return 1;
return 0;
},
},
{
field: 'quantity',
header: 'Quantity',
sortable: true,
sorter: (a, b) => {
if (a.quantity < b.quantity) return -1;
if (a.quantity > b.quantity) return 1;
return 0;
},
},
];
const data = [
{
id: 'zz21cz3c1',
name: 'Blue Band',
status: 'active',
group: 'group 3',
quantity: 87,
},
{
id: 'h456wer53',
name: 'Bracelet',
status: 'inactive',
group: 'group 2',
quantity: 45,
},
{
id: 'a789def12',
name: 'Blue Band',
status: 'pending',
group: 'group 1',
quantity: 24,
},
{
id: 'b123ghi34',
name: 'Blue Band',
status: 'inactive',
group: 'group 2',
quantity: 12,
},
{
id: 'c456jkl56',
name: 'Smart Watch',
status: 'active',
group: 'group 3',
quantity: 24,
},
{
id: 'e012pqr90',
name: 'Bracelet',
status: 'active',
group: 'group 1',
quantity: 45,
},
];
</script>
<template>
<TkTable :columns.prop="column" :data.prop="data" :multiSort.prop="true" />
</template>
Clear Filters and Sorting​
This example demonstrates how to clear all filters and sorting settings programmatically using the clearFilters
and clearSorting
methods.
- React
- Vue
- Angular
const Example = () => {
const tableRef = useRef(null);
const column: ITableColumn[] = [
{
field: "id",
header: "Id",
},
{
field: "name",
header: "Name",
searchable: true,
sortable: true,
sorter: (a: any, b: any) => (a.name > b.name ? 1 : -1),
filter: (value: string, row: any) =>
row.name.toString().toLowerCase().indexOf(value.toString().toLowerCase() as string) > -1,
},
{
field: "category",
header: "Category",
searchable: true,
filterType: 'checkbox',
filterOptions: [
{ value: 'Accessories', label: 'Accessories' },
{ value: 'Clothing', label: 'Clothing' },
{ value: 'Fitness', label: 'Fitness' },
],
},
{
field: "quantity",
header: "Quantity",
sortable: true,
sorter: (a: any, b: any) =>
Number(a.quantity) > Number(b.quantity) ? 1 : -1,
},
];
const handleClearFilters = () => {
tableRef.current?.clearFilters();
// For server-side pagination, after clearing filters,
// serverRequest method is called to trigger tkRequest event
// tableRef.current?.serverRequest();
};
const handleClearSorting = () => {
tableRef.current?.clearSorting();
// For server-side pagination, after clearing filters,
// serverRequest method is called to trigger tkRequest event
// tableRef.current?.serverRequest();
};
return (
<div>
<div style={{ marginBottom: '1rem', display: 'flex', gap: '0.5rem' }}>
<TkButton onClick={handleClearFilters} label="Clear Filters"></TkButton>
<TkButton onClick={handleClearSorting} label="Clear Sorting"></TkButton>
</div>
<TkTable ref={tableRef} columns={column} data={basicData}/>
</div>
);
};
<script setup>
import { TkTable, TkButton } from '@takeoff-ui/vue'
import { ref } from 'vue'
const tableRef = ref(null)
const column = [
{
field: "id",
header: "Id",
},
{
field: "name",
header: "Name",
searchable: true,
sortable: true,
sorter: (a, b) => (a.name > b.name ? 1 : -1),
filter: (value, row) =>
row.name.toString().toLowerCase().indexOf(value.toString().toLowerCase()) > -1,
},
{
field: "category",
header: "Category",
searchable: true,
filterType: 'checkbox',
filterOptions: [
{ value: 'Accessories', label: 'Accessories' },
{ value: 'Clothing', label: 'Clothing' },
{ value: 'Fitness', label: 'Fitness' },
],
},
{
field: "quantity",
header: "Quantity",
sortable: true,
sorter: (a, b) =>
Number(a.quantity) > Number(b.quantity) ? 1 : -1,
},
];
const handleClearFilters = () => {
tableRef.value?.$el.clearFilters();
// For server-side pagination, after clearing filters,
// serverRequest method is called to trigger tkRequest event
// tableRef.value?.$el.serverRequest();
};
const handleClearSorting = () => {
tableRef.value?.$el.clearSorting();
// For server-side pagination, after clearing filters,
// serverRequest method is called to trigger tkRequest event
// tableRef.value?.$el.serverRequest();
};
</script>
<template>
<div>
<div style="margin-bottom: 1rem; display: flex; gap: 0.5rem">
<TkButton @click="handleClearFilters" label="Clear Filters"></TkButton>
<TkButton @click="handleClearSorting" label="Clear Sorting"></TkButton>
</div>
<TkTable ref="tableRef" :columns.prop="column" :data.prop="basicData" />
</div>
</template>
Pagination​
Client side pagination
- React
- Vue
- Angular
const column: ITableColumn[] = [
{
field: "id",
header: "Id",
},
{
field: "name",
header: "Name",
searchable: true,
sortable: true,
sorter: (a: any, b: any) => (a.name > b.name ? 1 : -1),
filter: (value: string, row: any) =>
row.name
.toString()
.toLowerCase()
.indexOf(value.toString().toLowerCase() as string) > -1,
},
{
field: "category",
header: "Category",
searchable: true,
sortable: true,
sorter: (a: any, b: any) => (a.category > b.category ? 1 : -1),
filter: (value: string, row: any) =>
row.category
.toString()
.toLowerCase()
.indexOf(value.toString().toLowerCase() as string) > -1,
},
{
field: "quantity",
header: "Quantity",
sortable: true,
sorter: (a: any, b: any) =>
Number(a.quantity) > Number(b.quantity) ? 1 : -1,
},
];
return (
<TkTable
columns={column}
data={data}
paginationMethod="client"
rowsPerPage={5}
totalItems={data.length}
/>
);
<script setup>
import { TkTable } from '@takeoff-ui/vue'
const data = [
{
id: "f230fh0g3",
name: "Bamboo Watch",
category: "Accessories",
quantity: 24,
},
{
id: "nvklal433",
name: "Black Watch",
category: "Onyama",
quantity: 42,
},
{
id: "zz21cz3c1",
name: "Blue Band",
category: "Accessories",
quantity: 87,
},
{
id: "244wgerg2",
name: "Blue T-Shirt",
category: "Fitness",
quantity: 12,
},
{
id: "h456wer53",
name: "Bracelet",
category: "Clothing",
quantity: 45,
},
{
id: "344wgerg2",
name: "Art Venere",
category: "Accessories",
quantity: 23,
},
{
id: "144wgerg3",
name: "Simona Morasca",
category: "Clothing",
quantity: 56,
},
{
id: "444wgerg6",
name: "Leota Dilliard",
category: "Fitness",
quantity: 89,
},
{
id: "k14wgerj1",
name: "Sage Wieser",
category: "Accessories",
quantity: 77,
},
{
id: "fq4wgergq",
name: "Kris Marrier",
category: "Clothing",
quantity: 65,
},
{
id: "764wger11",
name: "Abel Maclead",
category: "Clothing",
quantity: 61,
},
{
id: "08ge885f",
name: "Mattie Poquette",
category: "Fitness",
quantity: 42,
},
{
id: "wg57erg2",
name: "Meaghan Garufi",
category: "Accessories",
quantity: 99,
},
{
id: "264w3erg2",
name: "Gladys Rim",
category: "Magalhaes",
quantity: 92,
},
];
const column = [
{
field: "id",
header: "Id",
},
{
field: "name",
header: "Name",
searchable: true,
sortable: true,
sorter: (a, b) => (a.name > b.name ? 1 : -1),
filter: (value, row) =>
row.name.toString().toLowerCase().indexOf(value.toString().toLowerCase()) > -1,
},
{
field: "category",
header: "Category",
searchable: true,
sortable: true,
sorter: (a, b) => (a.category > b.category ? 1 : -1),
filter: (value, row) =>
row.category.toString().toLowerCase().indexOf(value.toString().toLowerCase()) > -1,
},
{
field: "quantity",
header: "Quantity",
sortable: true,
sorter: (a, b) =>
Number(a.quantity) > Number(b.quantity) ? 1 : -1,
},
];
</script>
<template>
<TkTable
:columns.prop="column"
:data.prop="data"
paginationMethod="client"
:rowsPerPage="5"
:totalItems="data.length"
/>
</template>
Server Side​
Server side sorting, filter ang pagination example.
- React
- Vue
- Angular
const column: ITableColumn[] = [
{
field: "id",
header: "Id",
},
{
field: "name",
header: "Name",
searchable: true,
sortable: true,
},
{
field: "category",
header: "Category",
searchable: true,
sortable: true,
},
{
field: "quantity",
header: "Quantity",
sortable: true,
},
];
const tableRef = useRef<HTMLTkTableElement>(null);
const [data, setData] = useState();
const [totalItem, setTotalItem] = useState();
const [rowsPerPage, setRowsPerPage] = useState(5);
const [loading, setLoading] = useState(false);
const handleRequest = async (e: TkTableCustomEvent<ITableRequest>) => {
setLoading(true);
const result: any = await fetchFromServer(
e.detail.currentPage,
e.detail.rowsPerPage,
e.detail.filters,
e.detail.sortField,
e.detail.sortOrder
);
setTotalItem(result?.totalItem);
setRowsPerPage(e.detail.rowsPerPage);
setData(result?.data);
setLoading(false);
};
useEffect(() => {
tableRef.current.serverRequest();
}, []);
return (
<>
<TkButton
icon="refresh"
variant="neutral"
type="text"
onTkClick={async () => {
setLoading(true);
const result: any = await fetchFromServer(1, 5, [], null, null);
setTotalItem(result?.totalItem);
setData(result?.data);
setLoading(false);
tableRef.current!.setCurrentPage(1);
}}
/>
<TkTable
ref={tableRef}
columns={column}
data={data}
paginationMethod="server"
rowsPerPage={rowsPerPage}
totalItems={totalItem}
loading={loading}
onTkRequest={handleRequest}
/>
</>
);
<script setup>
import { TkTable, TkButton } from '@takeoff-ui/vue'
import { ref, onMounted } from 'vue';
const column = [
{
field: "id",
header: "Id",
},
{
field: "name",
header: "Name",
searchable: true,
sortable: true,
},
{
field: "category",
header: "Category",
searchable: true,
sortable: true,
},
{
field: "quantity",
header: "Quantity",
sortable: true,
},
];
const tableRef = ref(null);
const data = ref();
const totalItem = ref();
const rowsPerPage = ref(5);
const loading = ref(false);
const handleRequest = async (e) => {
loading.value = true;
const result = await fetchFromServer(
e.detail.currentPage,
e.detail.rowsPerPage,
e.detail.filters,
e.detail.sortField,
e.detail.sortOrder
);
totalItem.value = result?.totalItem;
rowsPerPage.value = e.detail.rowsPerPage;
data.value = result?.data;
loading.value = false;
};
onMounted(() => {
tableRef.value.serverRequest();
});
const refreshData = async () => {
loading.value = true;
const result = await fetchFromServer(1, 5, [], null, null);
totalItem.value = result?.totalItem;
data.value = result?.data;
loading.value = false;
tableRef.value.setCurrentPage(1);
};
</script>
<template>
<TkButton
icon="refresh"
variant="neutral"
type="text"
@tkClick="refreshData"
/>
<TkTable
ref="tableRef"
:columns.prop="column"
:data.prop="data"
paginationMethod="server"
:rowsPerPage="rowsPerPage"
:totalItems="totalItem"
:loading="loading"
@tkRequest="handleRequest"
/>
</template>
Custom Cell​
- React
- Vue
- Angular
const column: ITableColumn[] = [
{
field: "id",
header: "Id",
},
{
field: "name",
header: "Name",
searchable: true,
sortable: true,
},
{
field: "category",
header: "Category",
searchable: true,
sortable: true,
html: (row) => {
return `<tk-badge label="${row.category}" ></tk-badge>`;
},
},
{
field: "quantity",
header: "Quantity",
sortable: true,
},
{
field: "-",
header: "Actions",
html: (row) => {
const tkButton: HTMLTkButtonElement =
document.createElement("tk-button");
tkButton.label = "Detail";
tkButton.type = "text";
tkButton.variant = "info";
tkButton.addEventListener("tk-click", () => {
alert("clicked row: " + JSON.stringify(row));
});
return tkButton;
},
},
];
const [data, setData] = useState();
const [totalItem, setTotalItem] = useState();
const [loading, setLoading] = useState(false);
const handleRequest = async (e: TkTableCustomEvent<ITableRequest>) => {
setLoading(true);
const result: any = await fetchFromServer(
e.detail.currentPage,
e.detail.rowsPerPage,
e.detail.filters,
e.detail.sortField,
e.detail.sortOrder
);
setData(result?.data);
setTotalItem(result?.totalItem);
setLoading(false);
};
return (
<TkTable
columns={column}
data={data}
paginationMethod="server"
rowsPerPage={5}
totalItems={totalItem}
loading={loading}
onTkRequest={handleRequest}
/>
);
<script setup>
import { TkTable } from '@takeoff-ui/vue'
import { ref } from 'vue';
const column = [
{
field: "id",
header: "Id",
},
{
field: "name",
header: "Name",
searchable: true,
sortable: true,
},
{
field: "category",
header: "Category",
searchable: true,
sortable: true,
html: (row) => {
return `<tk-badge label="${row.category}" ></tk-badge>`;
},
},
{
field: "quantity",
header: "Quantity",
sortable: true,
},
{
field: "-",
header: "Actions",
html: (row) => {
const tkButton =
document.createElement("tk-button");
tkButton.label = "Detail";
tkButton.type = "text";
tkButton.variant = "info";
tkButton.addEventListener("tk-click", () => {
alert("clicked row: " + JSON.stringify(row));
});
return tkButton;
},
},
];
const data = ref([])
const totalItem = ref(0)
const loading = ref(false)
const handleRequest = async (e) => {
loading.value = true
const result = await fetchFromServer(
e.detail.currentPage,
e.detail.rowsPerPage,
e.detail.filters,
e.detail.sortField,
e.detail.sortOrder
);
data.value = result?.data
totalItem.value = result?.totalItem
loading.value = false
};
</script>
<template>
<TkTable :columns.prop="column" :data.prop="data" paginationMethod="server" :rowsPerPage="5" :totalItems="totalItem"
:loading="loading" @tkRequest="handleRequest" />
</template>
Custom Header​
- React
- Vue
- Angular
const column: ITableColumn[] = [
{
field: "id",
header: "Id",
},
{
field: "name",
header: "Name",
headerHtml: () => {
return '<div style="color: red;">Custom Header</div>';
},
},
{
field: "category",
header: "Category",
headerHtml: () => {
const checkbox = document.createElement('tk-checkbox');
checkbox.label = 'Checkbox';
checkbox.addEventListener('tk-change', (e) => {
console.log('checkbox status', e.detail);
});
return checkbox;
},
},
{
field: "quantity",
header: "Quantity",
},
];
return (
<div style={{ padding: "8px" }}>
<TkTable columns={column} data={basicData} />
</div>
);
<script setup>
import { TkTable } from '@takeoff-ui/vue'
const column = [
{
field: "id",
header: "Id",
},
{
field: "name",
header: "Name",
headerHtml: () => {
return '<div style="color: red;">Custom Header</div>';
},
},
{
field: "category",
header: "Category",
headerHtml: () => {
const checkbox = document.createElement('tk-checkbox');
checkbox.label = 'Checkbox';
checkbox.addEventListener('tk-change', (e) => {
console.log('checkbox status', e.detail);
});
return checkbox;
},
},
{
field: "quantity",
header: "Quantity",
},
];
</script>
<template>
<div :style="{ padding: '8px' }">
<TkTable :columns.prop="column" :data.prop="basicData" />
</div>
</template>
<div style="padding: 8px">
<tk-table
[columns]="[
{ field: 'id', header: 'Id' },
{
field: 'name',
header: 'Name',
headerHtml: () => {
return '<div style="color: red;">Custom Header</div>';
},
},
{
field: 'category',
header: 'Category',
headerHtml: () => {
const checkbox = document.createElement('tk-checkbox');
checkbox.label = 'Checkbox';
checkbox.addEventListener('tk-change', (e) => {
console.log('checkbox status', e.detail);
});
return checkbox;
},
},
{ field: 'quantity', header: 'Quantity' }
]"
[data]="[
{ id: 1, name: 'Product A', category: 'Electronics', quantity: 12 },
{ id: 2, name: 'Product B', category: 'Books', quantity: 8 },
{ id: 3, name: 'Product C', category: 'Groceries', quantity: 20 }
]"
/>
</div>
Header Style​
- React
- Vue
- Angular
const column: ITableColumn[] = [
{
field: "id",
header: "Id",
style: {
background: 'var(--primary-base)',
color: 'white',
},
},
{
field: "name",
header: "Name",
style: {
background: 'var(--primary-base)',
color: 'white',
},
},
{
field: "category",
header: "Category",
style: {
background: '#222530',
color: 'white',
},
},
{
field: "quantity",
header: "Quantity",
style: {
background: '#222530',
color: 'white',
},
},
];
return (
<div style={{ padding: "8px" }}>
<TkTable
columns={column}
data={basicData}
/>
</div>
);
<script setup>
import { TkTable } from '@takeoff-ui/vue'
const basicData = [
{
id: "f230fh0g3",
name: "Bamboo Watch",
category: "Accessories",
quantity: 24,
},
{
id: "nvklal433",
name: "Black Watch",
category: "Onyama",
quantity: 42,
},
{
id: "zz21cz3c1",
name: "Blue Band",
category: "Accessories",
quantity: 87,
},
{
id: "244wgerg2",
name: "Blue T-Shirt",
category: "Fitness",
quantity: 12,
},
{
id: "h456wer53",
name: "Bracelet",
category: "Clothing",
quantity: 45,
},
];
const column = [
{
field: "id",
header: "Id",
style: {
background: 'var(--primary-base)',
color: 'white',
},
},
{
field: "name",
header: "Name",
style: {
background: 'var(--primary-base)',
color: 'white',
},
},
{
field: "category",
header: "Category",
style: {
background: '#222530',
color: 'white',
},
},
{
field: "quantity",
header: "Quantity",
style: {
background: '#222530',
color: 'white',
},
];
</script>
<template>
<TkTable
:columns.prop="column"
:data.prop="basicData"
/>
</template>
Row/Cell Style​
- React
- Vue
- Angular
const column: ITableColumn[] = [
{
field: "id",
header: "Id",
},
{
field: "name",
header: "Name",
},
{
field: "category",
header: "Category",
},
{
field: "quantity",
header: "Quantity",
},
];
return (
<div style={{ padding: "8px" }}>
<TkTable
columns={column}
data={basicData}
cellStyle={(row, col) => {
if (col.field == "name" && row.name == "Blue Band") {
return { background: "var(--primary-base)", color: "white" };
}
}}
rowStyle={(row, index) => {
if (row.quantity > 50) {
return {
background: "var(--states-success-sub-base)",
color: "darkgreen",
};
}
if (index % 2 === 0) {
return {
background: "var(--states-info-sub-base)",
};
}
}}
/>
</div>
);
<script setup>
import { TkTable } from '@takeoff-ui/vue'
const basicData = [
{
id: "f230fh0g3",
name: "Bamboo Watch",
category: "Accessories",
quantity: 24,
},
{
id: "nvklal433",
name: "Black Watch",
category: "Onyama",
quantity: 42,
},
{
id: "zz21cz3c1",
name: "Blue Band",
category: "Accessories",
quantity: 87,
},
{
id: "244wgerg2",
name: "Blue T-Shirt",
category: "Fitness",
quantity: 12,
},
{
id: "h456wer53",
name: "Bracelet",
category: "Clothing",
quantity: 45,
},
];
const column = [
{
field: "id",
header: "Id",
},
{
field: "name",
header: "Name",
},
{
field: "category",
header: "Category",
},
{
field: "quantity",
header: "Quantity",
},
];
</script>
<template>
<TkTable
:columns.prop="column"
:data.prop="basicData"
:cellStyle.prop="(row, col) => {
if (col.field == 'name' && row.name == 'Blue Band') {
return { background: 'var(--primary-base)', color: 'white' };
}
}"
:rowStyle.prop="(row, index) => {
if (row.quantity > 50) {
return {
background: 'var(--states-success-sub-base)',
color: 'darkgreen',
};
}
if (index % 2 === 0) {
return {
background: 'var(--states-info-sub-base)',
};
}
}"
/>
</template>
Expanded Rows​
- React
- Vue
- Angular
const column: ITableColumn[] = [
{
expander: true,
field: "",
header: "",
},
{
field: "id",
header: "Id",
},
{
field: "name",
header: "Name",
},
{
field: "quantity",
header: "Quantity",
sortable: true,
sorter: (a: any, b: any) =>
Number(a.quantity) > Number(b.quantity) ? 1 : -1,
},
];
const [expandedRows, setExpandedRows] = useState<any[]>([]);
const handleExpandedRowsChange = (rows: any[]) => {
console.log(rows);
setExpandedRows([...rows]);
};
const renderExpandedRows = () => {
return expandedRows.map((item, index) => {
return (
<div slot={`expand-content-${item.id}`} key={"expanded-row-" + index}>
<div style={{ display: "flex", gap: "8px" }}>content</div>
</div>
);
});
};
return (
<TkTable
columns={column}
data={data}
dataKey="id"
paginationMethod="client"
rowsPerPage={5}
totalItems={data.length}
expandedRows={expandedRows}
onTkExpandedRowsChange={(e) => handleExpandedRowsChange(e.detail)}
>
{renderExpandedRows()}
</TkTable>
);
<script setup>
import { TkTable } from '@takeoff-ui/vue'
import { ref } from 'vue';
const data = [
{
id: "f230fh0g3",
name: "Bamboo Watch",
category: "Accessories",
quantity: 24,
},
{
id: "nvklal433",
name: "Black Watch",
category: "Onyama",
quantity: 42,
},
{
id: "zz21cz3c1",
name: "Blue Band",
category: "Accessories",
quantity: 87,
},
{
id: "244wgerg2",
name: "Blue T-Shirt",
category: "Fitness",
quantity: 12,
},
{
id: "h456wer53",
name: "Bracelet",
category: "Clothing",
quantity: 45,
},
{
id: "344wgerg2",
name: "Art Venere",
category: "Accessories",
quantity: 23,
},
{
id: "144wgerg3",
name: "Simona Morasca",
category: "Clothing",
quantity: 56,
},
{
id: "444wgerg6",
name: "Leota Dilliard",
category: "Fitness",
quantity: 89,
},
{
id: "k14wgerj1",
name: "Sage Wieser",
category: "Accessories",
quantity: 77,
},
{
id: "fq4wgergq",
name: "Kris Marrier",
category: "Clothing",
quantity: 65,
},
{
id: "764wger11",
name: "Abel Maclead",
category: "Clothing",
quantity: 61,
},
{
id: "08ge885f",
name: "Mattie Poquette",
category: "Fitness",
quantity: 42,
},
{
id: "wg57erg2",
name: "Meaghan Garufi",
category: "Accessories",
quantity: 99,
},
{
id: "264w3erg2",
name: "Gladys Rim",
category: "Magalhaes",
quantity: 92,
},
];
const column = [
{
expander: true,
field: "",
header: "",
},
{
field: "id",
header: "Id",
},
{
field: "name",
header: "Name",
},
{
field: "quantity",
header: "Quantity",
sortable: true,
sorter: (a, b) =>
Number(a.quantity) > Number(b.quantity) ? 1 : -1,
},
];
const expandedRows = ref([])
const handleExpandedRowsChange = (rows) => {
console.log(rows);
expandedRows.value = [...rows]
};
</script>
<template>
<TkTable
:columns.prop="column"
:data.prop="data"
dataKey="id"
paginationMethod="client"
:rowsPerPage="5"
:totalItems="data.length"
:expandedRows="expandedRows"
@tkExpandedRowsChange="(e) => handleExpandedRowsChange(e.detail)"
>
<div v-for="item, index in expandedRows" :slot="`expand-content-${item.id}`" :key="'expanded-row-' + index">
<div :style="{ display: 'flex', gap: '8px' }">content</div>
</div>
</TkTable>
</template>
Export File​
The basic features of the TkTable component are demonstrated.
- React
- Vue
- Angular
const tableRef = useRef<HTMLTkTableElement>(null);
const column: ITableColumn[] = [
{
field: "id",
header: "Id",
},
{
field: "name",
header: "Name",
},
{
field: "category",
header: "Category",
},
{
field: "quantity",
header: "Quantity",
},
];
const exportOptions = [
{
label: "Pdf",
value: "pdf",
},
{
label: "Excel",
value: "excel",
},
{
label: "Csv",
value: "csv",
},
];
const handleItemClick = (e) => {
tableRef.current?.exportFile({
type: e.detail.value,
fileName: "custom_file_name",
} as ITableExportOptions);
};
return (
<div style={{ padding: "8px" }}>
<TkTable ref={tableRef} columns={column} data={basicData}>
<div slot="header-right">
<TkDropdown
options={exportOptions}
position="bottom-end"
onTkItemClick={handleItemClick}
>
<TkButton
slot="trigger"
label="Export"
icon="keyboard_arrow_down"
iconPosition="right"
type="outlined"
/>
</TkDropdown>
</div>
</TkTable>
</div>
);
<script setup>
import { TkTable, TkDropdown, TkButton } from '@takeoff-ui/vue'
import { ref } from 'vue';
const basicData = [
{
id: "f230fh0g3",
name: "Bamboo Watch",
category: "Accessories",
quantity: 24,
},
{
id: "nvklal433",
name: "Black Watch",
category: "Onyama",
quantity: 42,
},
{
id: "zz21cz3c1",
name: "Blue Band",
category: "Accessories",
quantity: 87,
},
{
id: "244wgerg2",
name: "Blue T-Shirt",
category: "Fitness",
quantity: 12,
},
{
id: "h456wer53",
name: "Bracelet",
category: "Clothing",
quantity: 45,
},
];
const column = [
{
field: "id",
header: "Id",
},
{
field: "name",
header: "Name",
},
{
field: "category",
header: "Category",
},
{
field: "quantity",
header: "Quantity",
},
];
const exportOptions = [
{
label: "Pdf",
value: "pdf",
},
{
label: "Excel",
value: "excel",
},
{
label: "Csv",
value: "csv",
},
];
const tableRef = ref()
const handleItemClick = (e) => {
tableRef.value?.$el.exportFile({
type: e.detail.value,
fileName: "custom_file_name",
});
};
</script>
<template>
<div :style="{ padding: '8px' }">
<TkTable ref="tableRef" :columns.prop="column" :data.prop="basicData">
<div slot="header-right">
<TkDropdown
:options.prop="exportOptions"
position="bottom-end"
@tkItemClick="handleItemClick"
>
<TkButton
slot="trigger"
label="Export"
icon="keyboard_arrow_down"
iconPosition="right"
type="outlined"
/>
</TkDropdown>
</div>
</TkTable>
</div>
</template>
Sticky Column​
This feature allows the selected columns stay in their position in case of having multiple columns that extands the space.
- React
- Vue
- Angular
const tableRef = useRef<HTMLTkTableElement>(null);
const column: ITableColumn[] = [
{
field: "id",
header: "Id",
fixed: "left",
},
{
field: "name",
header: "Name",
},
{
field: "category",
header: "Category",
},
{
field: "quantity",
header: "Quantity",
},
{
field: "startDate",
header: "Start Date",
},
{
field: "endDate",
header: "End Date",
},
{
field: "duration",
header: "Dration",
},
{
field: "place",
header: "Place",
},
{
field: "status",
header: "Status",
fixed: "right",
},
];
return (
<div style={{ padding: "8px" }}>
<TkTable ref={tableRef} cardTitle="Sticky" columns={column} data={stickyData}>
</TkTable>
</div>
);
<script setup>
import { TkTable, TkDropdown, TkButton } from '@takeoff-ui/vue'
import { ref } from 'vue';
const stickyData=[
{
id: "f230fh0g3",
name: "Bamboo Watch",
category: "Accessories",
quantity: 24,
startDate:"12.20",
endDate:"13.20",
duration:"60 minutes",
place:"Ankara",
status:"Onboard"
},
{
id: "nvklal433",
name: "Black Watch",
category: "Onyama",
quantity: 42,
startDate:"11.40",
endDate:"15.20",
duration:"220 minutes",
place:"Istanbul",
status:"Boarding"
},
{
id: "zz21cz3c1",
name: "Blue Band",
category: "Accessories",
quantity: 87,
startDate:"09.00",
endDate:"15.00",
duration:"360 minutes",
place:"Paris",
status:"Departed"
},
{
id: "244wgerg2",
name: "Blue T-Shirt",
category: "Fitness",
quantity: 12,
startDate:"07.30",
endDate:"14.20",
duration:"410 minutes",
place:"London",
status:"Arrived"
},
{
id: "h456wer53",
name: "Bracelet",
category: "Clothing",
quantity: 45,
startDate:"18.20",
endDate:"06.20",
duration:"720 minutes",
place:"Tokyo",
status:"Checked-in"
},
]
const column = [
{
field: "id",
header: "Id",
fixed: "left",
},
{
field: "name",
header: "Name",
},
{
field: "category",
header: "Category",
},
{
field: "quantity",
header: "Quantity",
},
{
field: "startDate",
header: "Start Date",
},
{
field: "endDate",
header: "End Date",
},
{
field: "duration",
header: "Dration",
},
{
field: "place",
header: "Place",
},
{
field: "status",
header: "Status",
fixed: "right",
},
];
</script>
<template>
<div :style="{ padding: '8px' }">
<TkTable ref="tableRef" cardTitle="Sticky" :columns.prop="column" :data.prop="stickyData">
</TkTable>
</div>
</template>
Column Arrangement​
This feature allows the user to drag and drop the columns to the desired position.
- React
- Vue
- Angular
const [columns, setColumns] = useState<ITableColumn[]>([
{
field: 'id',
header: 'Id',
},
{
field: 'name',
header: 'Name',
},
{
field: 'category',
header: 'Category',
},
{
field: 'quantity',
header: 'Quantity',
},
]);
const [selectedColumns, setSelectedColumns] = useState<ITableColumn[]>(
columns.filter((item) => ['id', 'name'].includes(item.field)),
);
const handleDragStart = (e: React.DragEvent, index: number) => {
const parentElement = e.currentTarget.closest('div');
if (parentElement) {
e.dataTransfer.setData('text/plain', index.toString());
parentElement.classList.add('dragging');
e.dataTransfer.setDragImage(parentElement, 0, 0);
}
};
const handleDragOver = (e: React.DragEvent) => {
e.preventDefault();
};
const handleDragEnd = (e: React.DragEvent) => {
const parentElement = e.currentTarget.closest('div');
if (parentElement) {
parentElement.classList.remove('dragging');
}
};
const handleDrop = (e: React.DragEvent, targetIndex: number) => {
e.preventDefault();
const sourceIndex = parseInt(e.dataTransfer.getData('text/plain'));
const newColumns = [...columns];
const [movedItem] = newColumns.splice(sourceIndex, 1);
newColumns.splice(targetIndex, 0, movedItem);
setColumns(newColumns);
setSelectedColumns(
newColumns.filter((item) =>
selectedColumns
.map((selectedCol) => selectedCol.field)
.includes(item.field),
),
);
};
return (
<div className="flex flex-col gap-2">
<TkPopover className="flex justify-end" position="bottom" trigger="click">
<TkButton
variant="neutral"
type="outlined"
slot="trigger"
label="Arrange Columns"
/>
<div slot="content">
<div className="flex flex-col gap-2">
{columns.map((col, index) => (
<div
key={col.field}
className="flex justify-between gap-2 py-2 px-3 hover:bg-gray-100 transition-colors"
>
<TkCheckbox
label={col.header}
value={
selectedColumns.findIndex(
(item) => item.field == col.field,
) > -1
}
onTkChange={(e) => {
if (e.detail) {
setSelectedColumns([...selectedColumns, col]);
} else {
setSelectedColumns(
selectedColumns.filter(
(item) => item.field != col.field,
),
);
}
}}
/>
<TkIcon
icon="drag_indicator"
variant="neutral"
draggable
onDragStart={(e) => handleDragStart(e, index)}
onDragOver={handleDragOver}
onDragEnd={handleDragEnd}
onDrop={(e) => handleDrop(e, index)}
style={{ cursor: 'move' }}
/>
</div>
))}
</div>
</div>
</TkPopover>
<TkTable columns={selectedColumns} data={data} />
</div>
);
<script setup lang="ts">
import { ref } from 'vue';
import { ITableColumn } from '@takeoff-ui/core';
import {
TkTable,
TkCheckbox,
TkIcon,
TkPopover,
TkButton,
} from '@takeoff-ui/vue';
const columns = ref<ITableColumn[]>([
{ field: 'id', header: 'Id' },
{ field: 'name', header: 'Name' },
{ field: 'category', header: 'Category' },
{ field: 'quantity', header: 'Quantity' },
]);
const selectedColumns = ref<ITableColumn[]>(
columns.value.filter((item) => ['id', 'name'].includes(item.field)),
);
const handleDragStart = (e: DragEvent, index: number) => {
const parentElement = (e.currentTarget as HTMLElement).closest('div');
if (parentElement) {
e.dataTransfer?.setData('text/plain', index.toString());
parentElement.classList.add('dragging');
e.dataTransfer?.setDragImage(parentElement, 0, 0);
}
};
const handleDragOver = (e: DragEvent) => {
e.preventDefault();
};
const handleDragEnd = (e: DragEvent) => {
const parentElement = (e.currentTarget as HTMLElement).closest('div');
if (parentElement) {
parentElement.classList.remove('dragging');
}
};
const handleDrop = (e: DragEvent, targetIndex: number) => {
e.preventDefault();
const sourceIndex = parseInt(e.dataTransfer?.getData('text/plain') || '0');
const newColumns = [...columns.value];
const [movedItem] = newColumns.splice(sourceIndex, 1);
newColumns.splice(targetIndex, 0, movedItem);
columns.value = newColumns;
selectedColumns.value = newColumns.filter((item) =>
selectedColumns.value
.map((selectedCol) => selectedCol.field)
.includes(item.field),
);
};
const handleCheckboxChange = (e: any, col: ITableColumn) => {
if (e.detail) {
selectedColumns.value = [...selectedColumns.value, col];
} else {
selectedColumns.value = selectedColumns.value.filter(
(item) => item.field !== col.field,
);
}
};
</script>
<template>
<div class="flex flex-col gap-2">
<TkPopover
style="display: flex; justify-content: flex-end"
position="bottom"
trigger="click"
>
<TkButton
variant="neutral"
type="outlined"
slot="trigger"
label="Arrange Columns"
/>
<div slot="content">
<div
style="display: flex; flex-direction: column; gap: 8px; padding: 8px"
>
<div
v-for="(col, index) in columns"
:key="col.field"
style="
display: flex;
justify-content: space-between;
gap: 8px;
padding: 8px;
transition: background-color 0.3s ease;
"
>
<TkCheckbox
:label="col.header"
:value="
selectedColumns.findIndex((item) => item.field === col.field) >
-1
"
@tk-change="(e) => handleCheckboxChange(e, col)"
/>
<TkIcon
icon="drag_indicator"
variant="neutral"
draggable="true"
@dragstart="(e) => handleDragStart(e, index)"
@dragover="handleDragOver"
@dragend="handleDragEnd"
@drop="(e) => handleDrop(e, index)"
style="cursor: move"
/>
</div>
</div>
</div>
</TkPopover>
<TkTable :columns.prop="selectedColumns" :data.prop="data" />
</div>
</template>
Size​
This feature allows the user to use alternative sizes.
- React
- Vue
- Angular
const column: ITableColumn[] = [
{
field: "id",
header: "Id",
},
{
field: "name",
header: "Name",
},
{
field: "category",
header: "Category",
},
{
field: "quantity",
header: "Quantity",
},
];
return (
<div style={{ padding: "8px" }}>
<TkTable columns={column} data={basicData} size="small"/>
</div>
);
<script setup>
import { TkTable } from '@takeoff-ui/vue'
const column = [
{
field: "id",
header: "Id",
},
{
field: "name",
header: "Name",
},
{
field: "category",
header: "Category",
},
{
field: "quantity",
header: "Quantity",
},
];
</script>
<template>
<div :style="{ padding: '8px' }">
<TkTable :columns.prop="column" :data.prop="basicData" size="small" />
</div>
</template>
<div style="padding: 8px">
<tk-table
[columns]="[
{ field: 'id', header: 'Id' },
{ field: 'name', header: 'Name' },
{ field: 'category', header: 'Category' },
{ field: 'quantity', header: 'Quantity' }
]"
[data]="[
{ id: 1, name: 'Product A', category: 'Electronics', quantity: 12 },
{ id: 2, name: 'Product B', category: 'Books', quantity: 8 },
{ id: 3, name: 'Product C', category: 'Groceries', quantity: 20 }
]"
size="small"
/>
</div>
API​
Props​
Name | Type | Default | Description |
---|---|---|---|
string | '' | ||
(row: any, column: ITableColumn)=>any | null | Provides a function to customize cell styles. This function takes the row and column information and returns the style object for a specific cell. | |
ITableColumn[] | [] | The column definitions (Array of Objects) | |
any | null | The style attribute of container element | |
any[] | [] | Rows of data to display | |
string | null | Property of each row that defines the unique key of each row | |
any[] | [] | Specifies which rows are expanded to show additional content. | |
"basic", "dark", "primary" | 'basic' | Style to apply to header of table | |
boolean | null | Displays a loading indicator while data is being fetched or processed. | |
boolean | false | Enables multi-column sorting. | |
string | null | Defines whether pagination is handled on the client or server side. | |
"grouped", "outlined", "text" | 'outlined' | The type of the pagination | |
(row: any, index?: number)=>any | null | Provides a function to customize row styles. This function takes row information and row index, and returns the style object for a specific row. | |
number | 6 | Number of items per page. | |
number[] | null | Number of rows per page options | |
any | [] | List of the selected | |
"checkbox", "radio" | null | Determines how rows can be selected, either with radio buttons (single selection) or checkboxes (multiple selection). | |
Function | null | A function that returns true if the row should be disabled | |
"base", "small", "xsmall" | 'base' | Sets size for the component. | |
boolean | false | Enables or disables alternating row background colors for easier readability. | |
number | null | Number of total items. |
Events​
Name | Description |
---|---|
tk-cell-edit | Emitted when a cell is edited. |
tk-expanded-rows-change | Emitted when the expanded rows change. |
tk-request | Emitted when a request needs to be made to the server. |
tk-row-click | Emitted when a row is clicked. |
tk-selection-change |
Methods​
Name | Description |
---|---|
clearFilters | Clears all filters for server side pagination |
clearSorting | Clears all sorting for server side pagination |
exportFile | Exports the table data to a file |
getFilters | Returns the current filters |
getSorting | Returns the current sorting settings |
serverRequest | Allows tk-request event to be triggered manually |
setCurrentPage |
Slots​
Name | Description |
---|---|
empty-data | Set how the table will appear when there is no data |
Interfaces​
Defines the columns for the table
interface ITableColumn {
/** Defines the field for the column */
field: string;
/** Defines heading for the column */
header: string;
/** Defines sub heading for the column */
subHeader?: string;
/** Defines width for the column */
width?: string;
/** Indicates if the column supports sorting */
sortable?: boolean;
/** Custom sort function for the column, mandatory when using client-side sorting. */
sorter?: Function;
/** Custom filter function for the column, mandatory when using client-side filtering. */
filter?: Function;
/** Indicates if the column is searchable */
searchable?: boolean;
/** Indicates if the column is editable */
editable?: boolean;
/** Specifies the input type for editable columns */
inputType?: string;
/** Indicates if the column contains selection checkboxes */
selectColumn?: boolean;
/** Indicates if the column acts as an expander */
expander?: boolean;
/** Custom rendering function for HTML content in the column header */
headerHtml?: Function;
/** Custom rendering function for HTML content in the column cells */
html?: Function;
/** */
fixed?: 'left' | 'right';
/** Allows styling to be applied to the th element of the column */
style?: any;
/** When true, search and sort icons will only be displayed when hovering over the th element */
showIconsOnHover?: boolean;
/** Defines the filter type for this column (text, checkbox or radio) */
filterType?: 'text' | 'checkbox' | 'radio';
/** Defines options for checkbox or radio filter type */
filterOptions?: IFilterOption[];
/** Defines the label of the buttons */
filterButtons?: {
searchButton?: { label?: string };
cancelButton?: { label?: string };
selectAllCheckbox?: { label?: string };
};
filterElements?: {
icon?: string;
searchInput?: { placeholder?: string };
searchButton?: { label?: string };
cancelButton?: { label?: string };
selectAllCheckbox?: { label?: string };
optionsSearchInput?: { show?: boolean; placeholder?: string };
};
}
It is the return type of the tkRequest event.
interface ITableRequest {
/** The current page number */
currentPage: number;
/** The total number of pages */
totalPages: number;
/** The starting index of the items on the current page */
startItem: number;
/** The ending index of the items on the current page */
endItem: number;
/** The number of rows per page */
rowsPerPage: number;
/** The field by which the table is sorted */
sortField?: string;
/** The order of sorting: 'asc' or 'desc' */
sortOrder?: string;
/** Array of sort information for multi-sort functionality. When multiple sorts are applied, they are processed in priority order. */
sorts?: ITableSort[];
/** A list of filters applied to the table */
filters: ITableFilter[];
}
It is the return type of the tkCellEdit event.
interface ITableCellEdit {
/** The unique identifier of the row being edited. Contains the value of the dataKey prop in the edited row */
rowId: string;
/** The index of the row being edited */
rowIndex: number;
/** The field being edited */
field: string;
/** The new value for the field */
value: string;
}
interface ITableExportOptions {
/** only works when type is `pdf`. Default value is `vertical` */
orientation?: 'horizontal' | 'vertical';
/** */
fileName?: string;
/** */
type?: 'csv' | 'pdf' | 'excel';
/** `all` working only client side pagination. Default value is `current-page` */
scope?: 'current-page' | 'selected' | 'all';
/** Ignore Columns Fields array for only excel export */
ignoreColumnsFields?: string[];
/** Columns for only excel export */
columns?: ITableExportExcelColumn[];
/** */
externalData?: any[];
}
Represents a filter applied to a table
interface ITableFilter {
/** The value of the filter - string for text/radio filter, string array for checkbox filter */
value?: string | string[];
/** The field to which the filter is applied */
field: string;
/** The type of the filter (text, checkbox or radio) */
type?: 'text' | 'checkbox' | 'radio';
}
Defines options for checkbox filter
interface IFilterOption {
/** The value of the option */
value: string;
/** The display label of the option */
label?: string;
}
interface ITableSort {
/** The field name being sorted */
field: string;
/** The sort direction */
order: 'asc' | 'desc';
}
interface ICustomElement {
ref: HTMLElement;
element: HTMLElement;
}
interface ITableExportExcelColumn {
header: string;
field: string;
width: number;
}