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 |
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' \| '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 |
headerTooltip |
string |
undefined |
Tooltip text displayed when hovering header |
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}) |
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.
Checkbox Column
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 clickedIcon Column
type: 'icon' in the column definitionListIconProps object with:
icon: string - Font Awesome icon namecolor: string (optional) - custom color for the iconEmail Column
type: 'email' in the column definitionname field exists, creates mailto:name <email> formatmailto:email formatAction Column
type: '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 |
When 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).
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:
<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>