A highly configurable data table module for Nuxt 3 with advanced features like pre-formatting, relation handling, and more.
- ✨ Release Notes
- 📊 Column Configuration
- 🔍 Filtering System
- 📤 Data Export
- 🎨 Theming
- 📚 API Reference
- 🧩 Reusable Components
- 📊 Highly configurable data tables with TypeScript support
- 🔄 Client and server-side pagination, sorting, and filtering
- 🔍 Built-in search functionality (configurable to trigger on Enter)
- 🎨 Customizable themes with CSS variables
- 🔗 Support for complex data relations and Hasura-like APIs
- 📱 Responsive design with table and card views
- 🧩 Slot system for custom cell rendering
- 📝 Pre-formatting system for data display (status, boolean, date, etc.)
- 📊 Reusable components (ProgressBar, TagsList)
- 🌐 Internationalization (i18n) support compatible with @nuxtjs/i18n
- 📤 Data export capabilities (CSV, Excel, PDF)
- 💾 State persistence (filtering, search, pagination, sorting) - Coming soon
- 🔍 Advanced filtering system with multiple operators
- 🎛️ Configurable row density (normal, compact)
- 🐞 Debug mode for development
Install the module to your Nuxt application:
# Using Nuxt CLI (recommended)
npx nuxi module add nuxt-arpix-data-table
# Or using npm/yarn
npm install nuxt-arpix-data-table
# or
yarn add nuxt-arpix-data-tableAdd the module to your nuxt.config.ts:
export default defineNuxtConfig({
modules: [
'nuxt-arpix-data-table'
],
arpixDataTable: {
// Module options
perPage: 10,
paginationType: 'client',
searchable: true,
theme: 'default',
i18n: {
enabled: true,
defaultLocale: 'en'
}
}
})That's it! You can now use Arpix Data Table in your Nuxt app ✨
Local development
# Install dependencies
npm install
# Generate type stubs
npm run dev:prepare
# Develop with the playground
npm run dev
# Build the playground
npm run dev:build
# Run ESLint
npm run lint
# Run Vitest
npm run test
npm run test:watch
# Release new version
npm run release<template>
<ArpixDataTable
:columns="columns"
:data-source="data"
/>
</template>
<script setup>
import { ref } from 'vue'
const columns = [
{ key: 'id', label: 'ID', sortable: true },
{ key: 'name', label: 'Name', sortable: true, filterable: true },
{ key: 'email', label: 'Email' },
{ key: 'status', label: 'Status' }
]
const data = [
{ id: 1, name: 'John Doe', email: 'john@example.com', status: 'Active' },
{ id: 2, name: 'Jane Smith', email: 'jane@example.com', status: 'Inactive' },
// More data...
]
</script><template>
<ArpixDataTable
:columns="columns"
data-source="/api/users"
pagination="server"
:per-page="10"
/>
</template><script setup>
const columns = [
// ...
{
key: 'price',
label: 'Price',
sortable: true,
format: (value) => `$${value.toFixed(2)}`
},
{
key: 'status',
label: 'Status',
format: (value) => {
const classes = {
active: 'status-active',
inactive: 'status-inactive',
pending: 'status-pending'
}
return `<span class="status-badge ${classes[value]}">${value}</span>`
}
}
]
</script>
<style>
.status-badge {
display: inline-block;
padding: 0.25rem 0.5rem;
border-radius: 9999px;
font-size: 0.75rem;
font-weight: 500;
}
.status-active {
background-color: #d1fae5;
color: #065f46;
}
.status-inactive {
background-color: #fee2e2;
color: #b91c1c;
}
.status-pending {
background-color: #fef3c7;
color: #92400e;
}
</style><template>
<ArpixDataTable :columns="columns" :data-source="data">
<template #cell(actions)="{ row }">
<button @click="editItem(row)">Edit</button>
<button @click="deleteItem(row)">Delete</button>
</template>
</ArpixDataTable>
</template>The module includes reusable components that can be used in your tables or anywhere in your application:
<template>
<ArpixDataTable :columns="columns" :data-source="data">
<!-- Progress bar for percentage values -->
<template #cell(progress)="{ value }">
<ProgressBar :value="value" :show-label="true" suffix="%" />
</template>
<!-- Tags list for array values -->
<template #cell(tags)="{ value }">
<TagsList
:tags="value"
:color-map="tagColors"
:clickable="true"
@tag-click="handleTagClick"
/>
</template>
</ArpixDataTable>
</template>
<script setup>
const tagColors = {
'Frontend': '#ede9fe',
'Backend': '#f3e8ff',
'API': '#fae8ff'
}
const handleTagClick = (tag) => {
// Handle tag click event
}
</script>See the Components Documentation for more details.
The data table provides a powerful filtering system with support for different column types:
<template>
<ArpixDataTable
:columns="columns"
:data-source="data"
/>
</template>
<script setup>
const columns = [
// Text column with filtering
{
key: 'name',
label: 'Name',
sortable: true,
filterable: true,
type: 'text' // Default type
},
// Number column with filtering
{
key: 'age',
label: 'Age',
sortable: true,
filterable: true,
type: 'number'
},
// Date column with filtering
{
key: 'birthdate',
label: 'Birth Date',
sortable: true,
filterable: true,
type: 'date'
},
// Boolean column with filtering
{
key: 'active',
label: 'Active',
sortable: true,
filterable: true,
type: 'boolean'
},
// Enum/Status column with predefined values
{
key: 'status',
label: 'Status',
sortable: true,
filterable: true,
type: 'custom',
format: 'status-format',
enumValues: ['Active', 'Inactive', 'Pending'],
statusColors: {
'Active': { background: '#dcfce7', text: '#166534', border: '#166534' },
'Inactive': { background: '#f3f4f6', text: '#4b5563', border: '#4b5563' },
'Pending': { background: '#fef9c3', text: '#854d0e', border: '#854d0e' }
}
},
// Relation column with filtering
{
key: 'department_id',
label: 'Department',
sortable: true,
filterable: true,
type: 'relation',
relation: {
table: 'department',
displayField: 'name',
foreignKey: 'department_id',
apiEndpoint: '/api/departments/options'
}
}
]
</script>Each column type has specific filter operators:
- Text: Contains, Equals, Starts with, Ends with
- Number: Equals, Not equals, Greater than, Less than, etc.
- Date: After, Before, Between
- Boolean: True/False selection
- Relation: Selection from available options
The data table includes a debug mode that shows additional information in the UI and console logs, which is helpful during development:
<template>
<ArpixDataTable
:columns="columns"
:data-source="data"
:debug="true"
/>
</template>You can also enable debug mode globally in your nuxt.config.ts:
// nuxt.config.ts
export default defineNuxtConfig({
modules: ['nuxt-arpix-data-table'],
arpixDataTable: {
// ... other options
debug: true
}
})When debug mode is enabled, you'll see:
- Console logs for data loading, filtering, sorting, etc.
- Debug information in the table UI
- Error messages with more details
The data table supports internationalization and is compatible with @nuxtjs/i18n:
<template>
<ArpixDataTable
:columns="columns"
:data-source="data"
/>
</template>You can configure i18n in your nuxt.config.ts:
// nuxt.config.ts
export default defineNuxtConfig({
modules: [
'nuxt-arpix-data-table',
'@nuxtjs/i18n'
],
arpixDataTable: {
i18n: {
enabled: true,
defaultLocale: 'en',
messages: {
// Custom translations
pt: {
// Portuguese translations
'pagination.itemsPerPage': '{count} por página',
'pagination.of': 'de',
'pagination.nextPage': 'Próxima página',
'pagination.previousPage': 'Página anterior',
'pagination.firstPage': 'Primeira página',
'pagination.lastPage': 'Última página',
'search.placeholder': 'Pesquisar...',
'search.clear': 'Limpar pesquisa',
'filters.title': 'Filtros ativos:',
'filters.clearAll': 'Limpar tudo',
'filters.apply': 'Aplicar',
// ... more translations
}
}
}
},
i18n: {
// @nuxtjs/i18n configuration
locales: ['en', 'es', 'fr', 'pt'],
defaultLocale: 'en'
}
})The module will use translations from @nuxtjs/i18n if available, otherwise it will use its own translations.
// nuxt.config.ts
export default defineNuxtConfig({
modules: ['nuxt-arpix-data-table'],
arpixDataTable: {
// Pagination options
perPage: 10, // Default items per page
paginationType: 'client', // 'client' or 'server'
// Feature flags
searchable: true, // Enable search functionality by default
debug: false, // Enable debug mode (shows debug info in console and UI)
// Appearance
theme: 'default', // Default theme ('default' or 'dark')
themeVars: { // Custom CSS variables for theming
// Table appearance
// 'primary-color': '#8b5cf6', // Purple instead of default blue
// 'header-background': '#f5f3ff', // Light purple background for header
// 'header-text-color': '#6d28d9', // Dark purple text for header
// 'border-color': '#e9d5ff', // Light purple border
// 'hover-color': '#faf5ff', // Very light purple for row hover
// Component appearance
// 'progress-bg': '#f0f0f0', // Custom progress bar background
// 'tag-bg': '#e5e7eb', // Custom tag background
// Note: For filter window styling, use global CSS with !important:
// :root {
// --arpix-filter-menu-bg: #f8f5ff !important; // Background for filter menu
// --arpix-filter-apply-bg: #8b5cf6 !important; // Background for Apply button
// --arpix-filter-apply-hover-bg: #7c3aed !important; // Apply button hover
// --arpix-input-bg: #f5f3ff !important; // Background for input fields
// }
},
// Internationalization
i18n: {
enabled: true, // Enable i18n support
defaultLocale: 'en', // Default locale
messages: { // Custom translations
// Example of how to add translations:
// pt: {
// 'pagination.itemsPerPage': '{count} por página',
// 'pagination.of': 'de',
// 'pagination.nextPage': 'Próxima página',
// // ... more translations
// }
}
},
// State persistence (cookies) - Coming soon
// statePersistence: {
// enabled: true, // Enable state persistence
// cookiePrefix: 'arpix-dt', // Prefix for cookie names
// persist: ['filters', 'search', 'pagination', 'sort'] // State to persist
// }
}
})| Prop | Type | Default | Description |
|---|---|---|---|
columns |
Array<TableColumn> |
[] |
Table column definitions |
dataSource |
Array/String/Object |
[] |
Data source for the table (array, API endpoint, or object) |
perPage |
Number |
10 |
Items per page |
pagination |
String |
'client' |
Pagination type ('client' or 'server') |
searchable |
Boolean |
true |
Enable search functionality |
selectable |
Boolean |
false |
Enable row selection |
theme |
String |
'default' |
Theme name ('default' or 'dark') |
density |
String |
'normal' |
Row density ('normal' or 'compact') |
tableClass |
String |
'' |
Additional CSS class for the table |
themeVars |
Object |
{} |
Custom CSS variables for theming |
showHeader |
Boolean |
true |
Show table header |
showFooter |
Boolean |
true |
Show table footer |
showPagination |
Boolean |
true |
Show pagination controls |
showSearch |
Boolean |
true |
Show search input |
loading |
Boolean |
false |
Show loading state |
error |
String |
'' |
Error message to display |
noDataText |
String |
'No data available' |
Text to display when there are no results |
debug |
Boolean |
false |
Enable debug mode |
initialSort |
Object |
null |
Initial sort configuration |
initialFilters |
Object |
{} |
Initial filters configuration |
initialPage |
Number |
1 |
Initial page number |
relations |
Array |
[] |
Relations configuration for Hasura-like APIs |
Each column in the columns array can have the following properties:
| Property | Type | Default | Description |
|---|---|---|---|
key |
String |
- | Unique identifier for the column (required) |
label |
String |
- | Display label for the column header (required) |
sortable |
Boolean |
false |
Whether the column is sortable |
filterable |
Boolean |
false |
Whether the column is filterable |
type |
String |
'text' |
Data type ('text', 'number', 'date', 'boolean', 'relation', 'custom') |
format |
Function/String |
- | Formatter function or predefined format name |
width |
String |
- | Column width (CSS value, e.g., '200px', '20%') |
align |
String |
'left' |
Text alignment ('left', 'center', 'right') |
visible |
Boolean |
true |
Whether the column is visible |
enumValues |
Array |
- | Possible values for enum/status fields (used for filtering) |
statusColors |
Object |
- | Custom colors for status values |
relation |
Object |
- | Configuration for relation columns |
See the Column Configuration Documentation for more details.
The data table supports exporting data in various formats:
<template>
<div>
<ArpixDataTable
ref="dataTable"
:columns="columns"
:data-source="data"
/>
<div class="export-buttons">
<button @click="exportToCsv">Export to CSV</button>
<button @click="exportToExcel">Export to Excel</button>
<button @click="exportToPdf">Export to PDF</button>
</div>
</div>
</template>
<script setup>
import { ref } from 'vue'
const dataTable = ref(null)
const exportToCsv = async () => {
if (!dataTable.value) return
try {
const result = await dataTable.value.exportData('csv', {
fileName: 'my-data-export',
// Apply current filters and search
applyFilters: true,
applySearch: true
})
console.log('Export successful:', result)
} catch (error) {
console.error('Export failed:', error)
}
}
const exportToExcel = async () => {
if (!dataTable.value) return
try {
const result = await dataTable.value.exportData('excel', {
fileName: 'my-data-export',
excel: {
sheetName: 'My Data',
styleHeaders: true,
autoSize: true
}
})
console.log('Export successful:', result)
} catch (error) {
console.error('Export failed:', error)
}
}
const exportToPdf = async () => {
if (!dataTable.value) return
try {
const result = await dataTable.value.exportData('pdf', {
fileName: 'my-data-export',
pdf: {
orientation: 'landscape',
title: 'My Data Export',
includeDate: true
}
})
console.log('Export successful:', result)
} catch (error) {
console.error('Export failed:', error)
}
}
</script>Note: Excel export requires the
exceljslibrary, and PDF export requires thejspdflibrary. You can install them withnpm install exceljs jspdforyarn add exceljs jspdf.
The data table will soon support saving the state of filtering, search, pagination, and sorting in cookies, allowing users to return to the same view when they revisit the page:
// nuxt.config.ts (Coming soon)
export default defineNuxtConfig({
modules: ['nuxt-arpix-data-table'],
arpixDataTable: {
// ... other options
statePersistence: {
enabled: true,
cookiePrefix: 'my-app-dt', // Customize cookie names
persist: ['filters', 'search', 'pagination', 'sort'] // State to persist
}
}
})You will also be able to control state persistence at the component level:
<!-- Coming soon -->
<template>
<ArpixDataTable
:columns="columns"
:data-source="data"
:persist-state="true"
persist-key="users-table" // Unique key for this table
/>
</template>Note: This feature is currently under development and will be available in a future release.