vue-input-components

List Component

A flexible and customizable list component that supports sorting, filtering, and different presentation styles.

Props

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

Column Definition

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

Data Definition

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.

Example data array with different column types:

const users = [
  {
    id: 1,
    class: 'specialrow', // set the rowclass `list__row--${class}` which can be used for special row indications
    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),
      },
    ],
  },
]

// 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',
  },
  {
    key: 'name',
    label: 'Name',
    type: 'text',
    sortable: true,
    filterable: true,
  },
  {
    key: 'email',
    label: 'Email',
    type: 'email',
    sortable: true,
    filterable: true,
  },
  {
    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.

Column Type Examples

  1. Checkbox Column

    • Use type: 'checkbox' in the column definition
    • Data should include a ListCheckboxProps object with:
      • modelValue: string string[] boolean - current checkbox state
      • disabled: boolean - whether the checkbox is disabled
      • autosave: function - called when checkbox state changes
      • onCheckboxClick: function - called when checkbox is clicked
    • Useful for row selection and bulk actions
  2. Icon Column

    • Use type: 'icon' in the column definition
    • Data should include a ListIconProps object with:
      • icon: string - Font Awesome icon name
      • color: string (optional) - custom color for the icon
    • Icons are displayed using Font Awesome classes
    • Useful for status indicators and visual cues
  3. Email Column

    • Use type: 'email' in the column definition
    • Data should include an email string
    • Automatically creates clickable mailto links
    • If a name field exists, creates mailto:name <email> format
    • Otherwise creates simple mailto:email format
  4. Action Column

    • Use type: 'action' in the column definition
    • Data should include a ListActionProps object with:
      • id: string - unique identifier for the action
      • label: string - display text for the action
      • icon: string - Font Awesome icon name
      • type: ‘button’ ‘submit’ ‘reset’ - button type
      • disabled: boolean - whether the action is disabled
      • color: string - custom color for the action
      • size: ‘small’ ‘regular’ ‘large’ - size of the action
      • variant: ‘solid’ ‘transparent’ - style variant
      • presentation: ‘default’ ‘minimal’ - visual presentation
      • onActionClick: function - handler for click events

Slots

Slot Name Description
header_extras Custom content to display in the header area

Events

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

Exposed Methods

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

Features

CSV Download

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).

Filtering

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:

Usage Example

<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>