A flexible and customizable list component that supports sorting, filtering, and different presentation styles.
| Prop | Type | Default | Description |
|---|---|---|---|
columns |
ListColumn[] |
required | Array of column definitions |
data |
any[] |
required | Array of data items to display |
actions |
ListActionProps[] |
[] |
Array of actions to display in the header |
CSVDownload |
string |
undefined |
Enables CSV download with optional filename |
XLSXDownload |
string |
undefined |
Enables XLSX download with optional filename |
filter |
{ placeholder?: string } |
undefined |
Filter configuration |
loading |
boolean |
false |
Whether the list is in loading state |
emptyMessage |
string |
'No data available' |
Message to display when data is empty |
presentation |
'default' \| 'minimal' |
'default' |
Visual presentation style |
width |
string |
'100%' |
Width of the list component |
Each column in the columns array should have the following properties:
| Prop | Type | Default | Description |
|---|---|---|---|
key |
string |
required | Unique identifier for the column |
label |
string |
required | Display label for the column |
type |
'text' \| 'number' \| 'date' \| 'datetime' \| 'time' \| 'action' \| 'checkbox' \| 'icon' \| 'email' |
'text' |
Type of data in the column |
align |
'left' \| 'center' \| 'right' |
'left' |
Text alignment |
sortable |
boolean |
false |
Whether the column can be sorted |
filterable |
boolean |
false |
Whether the column can be filtered |
width |
string |
undefined |
Fixed width of the column |
minWidth |
string |
undefined |
Minimum width of the column |
maxWidth |
string |
undefined |
Maximum width of the column |
cellClasses |
Record<string, (value: any) => boolean> |
undefined |
Conditional classes applied to cell content |
headerTooltip |
string |
undefined |
Tooltip text displayed when hovering header |
cellTooltip |
boolean |
false |
Enables automatic tooltip content per cell |
The data prop expects an array of objects where each object represents a row in the list. The properties of each object should match the key values defined in the columns configuration.
Each row object can include the following special properties for controlling behavior:
| Property | Type | Description |
|---|---|---|
excludeFromSort |
boolean |
Excludes the row from sorting operations |
excludeFromFilter |
boolean |
Excludes the row from filtering operations |
fixed |
'top' \| 'bottom' |
Fixes the row at the top or bottom of the list |
selected |
boolean |
Marks the row as selected (for styling) |
class |
string |
Adds a custom CSS class to the row (as list__row--${class}) |
When using type: 'checkbox', the value for that column key should be a checkbox props object (for example { modelValue, disabled, autosave, onCheckboxClick }).
Example data array with different column types:
const users = [
{
id: 1,
class: 'specialrow', // Adds CSS class: list__row--specialrow
excludeFromSort: true, // Row won't be affected by sorting
fixed: 'top', // Row stays at the top
name: 'John Doe',
email: 'john@example.com',
role: 'Admin',
status: 'active',
lastLogin: '2024-03-15T10:30:00Z',
// Checkbox column
selected: <ListCheckboxProps>{
modelValue: false,
disabled: false,
autosave: (info) => console.log('Checkbox changed:', info),
onCheckboxClick: (row, itemKey) => console.log('Checkbox clicked:', row.id, itemKey),
},
// Icon column
status: <ListIconProps>{
icon: 'fa-check-circle',
color: 'var(--success-color)',
},
// Action column
actions: <ListActionProps[]>[
{
id: 'edit',
label: 'Edit',
icon: 'fa-edit',
onActionClick: (row, action) => console.log('Action clicked:', action.id),
},
{
id: 'delete',
label: 'Delete',
icon: 'fa-trash',
onActionClick: (row, action) => console.log('Action clicked:', action.id),
},
],
},
{
id: 2,
name: 'Jane Smith',
email: 'jane@example.com',
role: 'User',
status: 'inactive',
lastLogin: '2024-03-14T15:45:00Z',
// Checkbox column
selected: <ListCheckboxProps>{
modelValue: true,
disabled: true,
autosave: (info) => console.log('Checkbox changed:', info),
onCheckboxClick: (row, itemKey) => console.log('Checkbox clicked:', row.id, itemKey),
},
// Icon column
status: <ListIconProps>{
icon: 'fa-times-circle',
color: 'var(--danger-color)',
},
// Action column
actions: <ListActionProps[]>[
{
id: 'edit',
label: 'Edit',
icon: 'fa-edit',
onActionClick: (row, action) => console.log('Action clicked:', action.id),
},
{
id: 'delete',
label: 'Delete',
icon: 'fa-trash',
onActionClick: (row, action) => console.log('Action clicked:', action.id),
},
],
},
{
id: 3,
excludeFromFilter: true, // Row won't be affected by filtering
fixed: 'bottom', // Row stays at the bottom
name: 'System Message',
email: 'system@example.com',
role: 'System',
status: 'active',
lastLogin: '2024-01-01T00:00:00Z',
},
]
// Example columns configuration for the above data
const columns: ListColumn[] = [
{
key: 'selected',
label: '',
type: 'checkbox',
width: '50px',
align: 'center',
},
{
key: 'status',
label: 'Status',
type: 'icon',
align: 'center',
width: '80px',
headerTooltip: 'User status indicator',
},
{
key: 'name',
label: 'Name',
type: 'text',
sortable: true,
filterable: true,
headerTooltip: 'The full name of the user',
},
{
key: 'email',
label: 'Email',
type: 'email',
sortable: true,
filterable: true,
headerTooltip: 'Contact email address',
},
{
key: 'role',
label: 'Role',
type: 'text',
sortable: true,
},
{
key: 'actions',
label: 'Actions',
type: 'action',
align: 'center',
width: '120px',
},
]
The data can include any properties, but only those defined in the columns configuration will be displayed. Each row can also include additional metadata that can be used in actions or custom rendering.
type: 'checkbox' in the column definitionListCheckboxProps object with:
modelValue: string |
string[] | boolean - current checkbox state |
disabled: boolean - whether the checkbox is disabledautosave: function - called when checkbox state changesonCheckboxClick: function - called when checkbox is clickedtype: 'icon' in the column definitionListIconProps object with:
icon: string - Font Awesome icon namecolor: string (optional) - custom color for the icontype: 'email' in the column definitionname field exists, creates mailto:name <email> formatmailto:email formattype: 'action' in the column definitionListActionProps object with:
id: string - unique identifier for the actionlabel: string - display text for the actionicon: string - Font Awesome icon nametype: ‘button’ |
‘submit’ | ‘reset’ - button type |
disabled: boolean - whether the action is disabledcolor: string - custom color for the actionsize: ‘small’ |
‘regular’ | ‘large’ - size of the action |
variant: ‘solid’ |
‘transparent’ - style variant |
presentation: ‘default’ |
‘minimal’ - visual presentation |
onActionClick: function - handler for click events| Slot Name | Description |
|---|---|
header_extras |
Custom content to display in the header area |
| Event | Parameters | Description |
|---|---|---|
row-click |
(row: any, index: number) |
Emitted when a row is clicked |
row-dblclick |
(row: any, index: number) |
Emitted when a row is double-clicked |
The component exposes the following methods for external control:
| Method | Description |
|---|---|
focus() |
Focuses the filter input field |
blur() |
Removes focus from the filter input field |
clearFilter() |
Clears the current filter value |
cellTooltipWhen the CSVDownload prop is provided, a download button is automatically added to the actions area. The CSV will include all non-object columns (text, number, date) and will be named according to the prop value (with .csv extension if not already present).
When the XLSXDownload prop is provided, a download button is automatically added to the actions area. The generated workbook includes non-interactive columns (all except checkbox, icon, and action) and is named according to the prop value (with .xlsx extension if not already present).
The filter input supports debounced searching with a 3-character minimum. Only columns marked as filterable: true are included in the search. The filter supports:
Note: filtering becomes active after at least 3 characters, with a 250ms debounce.
<template>
<List
:columns="columns"
:data="users"
:actions="listActions"
:filter="{ placeholder: 'Search users...' }"
:CSVDownload="'users'"
@row-click="handleRowClick"
@row-dblclick="handleRowDblClick"
width="500px"
>
<template #header_extras>
<div class="custom-header-content">
<span>Total Users: </span>
</div>
</template>
</List>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import List from '@/components/List.vue'
import type { ListColumn, ListActionProps, ListCheckboxProps, ListIconProps } from '@/types'
const columns: ListColumn[] = [
{
key: 'name',
label: 'Name',
type: 'text',
sortable: true,
filterable: true,
},
{
key: 'email',
label: 'Email',
type: 'email',
sortable: true,
filterable: true,
},
]
const users = [
{
id: 1,
name: 'John Doe',
email: 'john@example.com',
role: 'Admin',
status: 'active',
lastLogin: '2024-03-15T10:30:00Z',
},
{
id: 2,
name: 'Jane Smith',
email: 'jane@example.com',
role: 'User',
status: 'inactive',
lastLogin: '2024-03-14T15:45:00Z',
},
]
const listActions: ListActionProps[] = [
{
id: 'new-user',
label: 'New User',
icon: 'add',
onActionClick: (event, action) => console.log('New user clicked'),
},
]
const handleRowClick = (row: any, index: number) => {
console.log('Row clicked:', row, index)
}
const handleRowDblClick = (row: any, index: number) => {
console.log('Row double-clicked:', row, index)
}
</script>