@veristone/nuxt-v-app 0.2.2 → 0.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,26 +1,28 @@
1
1
  <script setup lang="ts">
2
+ import type { TableColumn } from '@nuxt/ui'
3
+
2
4
  definePageMeta({
3
5
  title: 'Table Components'
4
6
  })
5
7
 
6
8
  // Sample data
7
9
  const users = ref([
8
- { id: 1, name: 'John Doe', email: 'john@example.com', role: 'Admin', status: 'active', department: 'Engineering', salary: 95000 },
9
- { id: 2, name: 'Jane Smith', email: 'jane@example.com', role: 'Editor', status: 'active', department: 'Marketing', salary: 72000 },
10
- { id: 3, name: 'Bob Wilson', email: 'bob@example.com', role: 'Viewer', status: 'pending', department: 'Sales', salary: 68000 },
11
- { id: 4, name: 'Alice Brown', email: 'alice@example.com', role: 'Admin', status: 'active', department: 'Engineering', salary: 105000 },
12
- { id: 5, name: 'Charlie Davis', email: 'charlie@example.com', role: 'Editor', status: 'inactive', department: 'Design', salary: 78000 },
13
- { id: 6, name: 'Diana Miller', email: 'diana@example.com', role: 'Viewer', status: 'active', department: 'HR', salary: 62000 },
14
- { id: 7, name: 'Edward Lee', email: 'edward@example.com', role: 'Admin', status: 'active', department: 'Engineering', salary: 112000 },
15
- { id: 8, name: 'Fiona Garcia', email: 'fiona@example.com', role: 'Editor', status: 'pending', department: 'Marketing', salary: 75000 },
16
- { id: 9, name: 'George Martinez', email: 'george@example.com', role: 'Viewer', status: 'active', department: 'Sales', salary: 71000 },
17
- { id: 10, name: 'Hannah Robinson', email: 'hannah@example.com', role: 'Editor', status: 'active', department: 'Design', salary: 82000 },
18
- { id: 11, name: 'Ivan Thompson', email: 'ivan@example.com', role: 'Admin', status: 'inactive', department: 'Engineering', salary: 98000 },
19
- { id: 12, name: 'Julia White', email: 'julia@example.com', role: 'Viewer', status: 'active', department: 'HR', salary: 58000 }
10
+ { id: 1, name: 'John Doe', email: 'john@example.com', role: 'Admin', status: 'active', department: 'Engineering', salary: 95000, createdAt: '2024-01-15T10:30:00Z' },
11
+ { id: 2, name: 'Jane Smith', email: 'jane@example.com', role: 'Editor', status: 'active', department: 'Marketing', salary: 72000, createdAt: '2024-02-20T14:00:00Z' },
12
+ { id: 3, name: 'Bob Wilson', email: 'bob@example.com', role: 'Viewer', status: 'pending', department: 'Sales', salary: 68000, createdAt: '2024-03-10T09:15:00Z' },
13
+ { id: 4, name: 'Alice Brown', email: 'alice@example.com', role: 'Admin', status: 'active', department: 'Engineering', salary: 105000, createdAt: '2024-04-05T11:45:00Z' },
14
+ { id: 5, name: 'Charlie Davis', email: 'charlie@example.com', role: 'Editor', status: 'inactive', department: 'Design', salary: 78000, createdAt: '2024-05-01T16:20:00Z' },
15
+ { id: 6, name: 'Diana Miller', email: 'diana@example.com', role: 'Viewer', status: 'active', department: 'HR', salary: 62000, createdAt: '2024-06-12T08:00:00Z' },
16
+ { id: 7, name: 'Edward Lee', email: 'edward@example.com', role: 'Admin', status: 'active', department: 'Engineering', salary: 112000, createdAt: '2024-07-18T13:30:00Z' },
17
+ { id: 8, name: 'Fiona Garcia', email: 'fiona@example.com', role: 'Editor', status: 'pending', department: 'Marketing', salary: 75000, createdAt: '2024-08-22T10:00:00Z' },
18
+ { id: 9, name: 'George Martinez', email: 'george@example.com', role: 'Viewer', status: 'active', department: 'Sales', salary: 71000, createdAt: '2024-09-03T15:45:00Z' },
19
+ { id: 10, name: 'Hannah Robinson', email: 'hannah@example.com', role: 'Editor', status: 'active', department: 'Design', salary: 82000, createdAt: '2024-10-14T12:10:00Z' },
20
+ { id: 11, name: 'Ivan Thompson', email: 'ivan@example.com', role: 'Admin', status: 'inactive', department: 'Engineering', salary: 98000, createdAt: '2024-11-25T09:30:00Z' },
21
+ { id: 12, name: 'Julia White', email: 'julia@example.com', role: 'Viewer', status: 'active', department: 'HR', salary: 58000, createdAt: '2024-12-01T17:00:00Z' }
20
22
  ])
21
23
 
22
- // Basic columns
23
- const basicColumns = [
24
+ // Basic columns using the new Nuxt UI TableColumn format
25
+ const basicColumns: TableColumn<typeof users.value[0]>[] = [
24
26
  { accessorKey: 'name', header: 'Name' },
25
27
  { accessorKey: 'email', header: 'Email' },
26
28
  { accessorKey: 'role', header: 'Role' },
@@ -28,22 +30,27 @@ const basicColumns = [
28
30
  ]
29
31
 
30
32
  // Full columns with more fields
31
- const fullColumns = [
33
+ const fullColumns: TableColumn<typeof users.value[0]>[] = [
32
34
  { accessorKey: 'name', header: 'Name' },
33
35
  { accessorKey: 'email', header: 'Email' },
34
36
  { accessorKey: 'role', header: 'Role' },
35
37
  { accessorKey: 'department', header: 'Department' },
36
38
  { accessorKey: 'salary', header: 'Salary' },
37
- { accessorKey: 'status', header: 'Status' }
39
+ { accessorKey: 'status', header: 'Status' },
40
+ { accessorKey: 'createdAt', header: 'Created' }
38
41
  ]
39
42
 
40
- // Columns with custom cells
41
- const customCellColumns = [
42
- { accessorKey: 'name', header: 'Name' },
43
- { accessorKey: 'email', header: 'Email' },
44
- { accessorKey: 'role', header: 'Role' },
45
- { accessorKey: 'status', header: 'Status' },
46
- { accessorKey: 'salary', header: 'Salary' }
43
+ // Columns using presets
44
+ const { presets } = useXATableColumns()
45
+
46
+ const presetColumns: TableColumn<typeof users.value[0]>[] = [
47
+ presets.text('name', 'Name'),
48
+ presets.email('email', 'Email'),
49
+ presets.badge('status', 'Status', {
50
+ colorMap: { active: 'success', pending: 'warning', inactive: 'neutral' }
51
+ }),
52
+ presets.currency('salary', 'Salary'),
53
+ presets.date('createdAt', 'Joined', { format: 'relative' })
47
54
  ]
48
55
 
49
56
  // Products data for variety
@@ -56,7 +63,7 @@ const products = ref([
56
63
  { id: 6, name: 'Mac Mini M2', category: 'Desktops', price: 699, stock: 60, rating: 4.5 }
57
64
  ])
58
65
 
59
- const productColumns = [
66
+ const productColumns: TableColumn<typeof products.value[0]>[] = [
60
67
  { accessorKey: 'name', header: 'Product' },
61
68
  { accessorKey: 'category', header: 'Category' },
62
69
  { accessorKey: 'price', header: 'Price' },
@@ -64,56 +71,23 @@ const productColumns = [
64
71
  { accessorKey: 'rating', header: 'Rating' }
65
72
  ]
66
73
 
67
- // Event handlers
68
- const handleSearch = (query: string) => {
69
- console.log('Search:', query)
70
- }
71
-
72
- const handleSelect = (rows: any[]) => {
73
- console.log('Selected:', rows)
74
- }
75
-
76
- const handleView = (row: any) => {
77
- console.log('View:', row)
78
- }
79
-
80
- const handleEdit = (row: any) => {
81
- console.log('Edit:', row)
82
- }
83
-
84
- const handleDelete = (row: any) => {
85
- console.log('Delete:', row)
86
- }
87
-
88
- const handleExport = (format: string, data: any[]) => {
89
- console.log(`Exported ${data.length} rows as ${format}`)
90
- }
91
-
92
- // Status badge color helper
93
- const getStatusColor = (status: string) => {
94
- switch (status) {
95
- case 'active': return 'green'
96
- case 'pending': return 'yellow'
97
- case 'inactive': return 'red'
98
- default: return 'gray'
99
- }
100
- }
101
-
102
- // VADataTable handlers
103
- const handleDataTableSelect = (row: any) => {
104
- console.log('DataTable selected:', row)
105
- }
106
-
107
- const handleDataTablePrev = () => {
108
- console.log('DataTable prev')
109
- }
110
-
111
- const handleDataTableNext = () => {
112
- console.log('DataTable next')
113
- }
74
+ // Filter definitions
75
+ const statusFilters = [
76
+ { label: 'Status', key: 'status', options: [
77
+ { label: 'Active', value: 'active' },
78
+ { label: 'Pending', value: 'pending' },
79
+ { label: 'Inactive', value: 'inactive' }
80
+ ]},
81
+ { label: 'Role', key: 'role', options: [
82
+ { label: 'Admin', value: 'Admin' },
83
+ { label: 'Editor', value: 'Editor' },
84
+ { label: 'Viewer', value: 'Viewer' }
85
+ ]}
86
+ ]
114
87
 
115
- const handleDataTableNew = () => {
116
- console.log('DataTable new')
88
+ // Event handlers
89
+ const handleRowClick = (row: any) => {
90
+ console.log('Row clicked:', row)
117
91
  }
118
92
  </script>
119
93
 
@@ -124,494 +98,149 @@ const handleDataTableNew = () => {
124
98
  <div>
125
99
  <h1 class="text-3xl font-bold mb-4">VATable Components Showcase</h1>
126
100
  <p class="text-gray-600 dark:text-gray-400">
127
- Full-featured data tables with search, sort, filter, export, selection, and pagination capabilities.
101
+ TanStack-powered data tables with search, sort, filter, export, selection, and pagination.
128
102
  </p>
129
103
  </div>
130
104
 
131
105
  <!-- Basic Table -->
132
- <h2 class="text-2xl font-semibold mb-4 mt-8">Basic Table</h2>
133
- <p class="text-gray-600 dark:text-gray-400 mb-4">Simple table with minimal configuration.</p>
134
- <div class="mb-8">
135
- <UCard>
136
- <template #header>
137
- <h3 class="font-semibold">Basic Table Example</h3>
138
- </template>
139
- <ClientOnly>
140
- <VATable
141
- :data="users.slice(0, 5)"
142
- :columns="basicColumns"
143
- :paginated="false"
144
- card
145
- />
146
- </ClientOnly>
147
- </UCard>
148
- </div>
149
-
150
- <!-- Searchable Table -->
151
- <h2 class="text-2xl font-semibold mb-4 mt-8">Searchable Table</h2>
152
- <p class="text-gray-600 dark:text-gray-400 mb-4">Table with search functionality to filter rows.</p>
153
- <div class="mb-8">
154
- <UCard>
155
- <template #header>
156
- <h3 class="font-semibold">Search Example</h3>
157
- </template>
158
- <ClientOnly>
159
- <VATable
160
- :data="users"
161
- :columns="basicColumns"
162
- searchable
163
- search-placeholder="Search users..."
164
- card
165
- name="Users"
166
- @search="handleSearch"
167
- />
168
- </ClientOnly>
169
- </UCard>
170
- </div>
171
-
172
- <!-- Sortable Table -->
173
- <h2 class="text-2xl font-semibold mb-4 mt-8">Sortable Table</h2>
174
- <p class="text-gray-600 dark:text-gray-400 mb-4">Click column headers to sort. Click again to reverse, third click to clear.</p>
175
- <div class="mb-8">
176
- <UCard>
177
- <template #header>
178
- <h3 class="font-semibold">Sort Example</h3>
179
- </template>
180
- <ClientOnly>
181
- <VATable
182
- :data="products"
183
- :columns="productColumns"
184
- sortable
185
- card
186
- name="Products"
187
- />
188
- </ClientOnly>
189
- </UCard>
190
- </div>
191
-
192
- <!-- Row Selection -->
193
- <h2 class="text-2xl font-semibold mb-4 mt-8">Row Selection</h2>
194
- <p class="text-gray-600 dark:text-gray-400 mb-4">Multi-select with checkbox column and select all functionality.</p>
195
- <div class="mb-8">
196
- <UCard>
197
- <template #header>
198
- <h3 class="font-semibold">Multi-Select Example</h3>
199
- </template>
200
- <ClientOnly>
201
- <VATable
202
- :data="users.slice(0, 6)"
203
- :columns="basicColumns"
204
- selectable="multi"
205
- card
206
- name="Select Users"
207
- @select="handleSelect"
208
- />
209
- </ClientOnly>
210
- </UCard>
211
- </div>
212
-
213
- <!-- Single Selection -->
214
- <h2 class="text-2xl font-semibold mb-4 mt-8">Single Selection</h2>
215
- <p class="text-gray-600 dark:text-gray-400 mb-4">Single row selection mode - only one row can be selected at a time.</p>
216
- <div class="mb-8">
217
- <UCard>
218
- <template #header>
219
- <h3 class="font-semibold">Single-Select Example</h3>
220
- </template>
221
- <ClientOnly>
222
- <VATable
223
- :data="products"
224
- :columns="productColumns"
225
- selectable="single"
226
- card
227
- name="Select Product"
228
- :paginated="false"
229
- @select="handleSelect"
230
- />
231
- </ClientOnly>
232
- </UCard>
233
- </div>
234
-
235
- <!-- Row Actions -->
236
- <h2 class="text-2xl font-semibold mb-4 mt-8">Row Actions</h2>
237
- <p class="text-gray-600 dark:text-gray-400 mb-4">Table with view, edit, and delete action buttons per row.</p>
238
- <div class="mb-8">
239
- <UCard>
240
- <template #header>
241
- <h3 class="font-semibold">Actions Example</h3>
242
- </template>
243
- <ClientOnly>
244
- <VATable
245
- :data="users.slice(0, 5)"
246
- :columns="basicColumns"
247
- show-view
248
- show-edit
249
- show-delete
250
- card
251
- name="Users with Actions"
252
- :paginated="false"
253
- @view="handleView"
254
- @edit="handleEdit"
255
- @delete="handleDelete"
256
- />
257
- </ClientOnly>
258
- </UCard>
259
- </div>
260
-
261
- <!-- Export Functionality -->
262
- <h2 class="text-2xl font-semibold mb-4 mt-8">Export Functionality</h2>
263
- <p class="text-gray-600 dark:text-gray-400 mb-4">Export data to CSV or JSON format.</p>
264
- <div class="mb-8">
265
- <UCard>
266
- <template #header>
267
- <h3 class="font-semibold">Export Example</h3>
268
- </template>
269
- <ClientOnly>
270
- <VATable
271
- :data="products"
272
- :columns="productColumns"
273
- exportable
274
- :export-formats="['csv', 'json']"
275
- card
276
- name="Products Export"
277
- @export="handleExport"
278
- />
279
- </ClientOnly>
280
- </UCard>
281
- </div>
282
-
283
- <!-- Column Toggle -->
284
- <h2 class="text-2xl font-semibold mb-4 mt-8">Column Toggle</h2>
285
- <p class="text-gray-600 dark:text-gray-400 mb-4">Show/hide columns using the column toggle dropdown.</p>
286
- <div class="mb-8">
287
- <UCard>
288
- <template #header>
289
- <h3 class="font-semibold">Column Toggle Example</h3>
290
- </template>
291
- <ClientOnly>
292
- <VATable
293
- :data="users.slice(0, 6)"
294
- :columns="fullColumns"
295
- show-column-toggle
296
- card
297
- name="Toggle Columns"
298
- />
299
- </ClientOnly>
300
- </UCard>
301
- </div>
302
-
303
- <!-- Custom Cell Rendering -->
304
- <h2 class="text-2xl font-semibold mb-4 mt-8">Custom Cell Rendering</h2>
305
- <p class="text-gray-600 dark:text-gray-400 mb-4">Custom cell templates for status badges and formatted currency.</p>
306
- <div class="mb-8">
307
- <UCard>
308
- <template #header>
309
- <h3 class="font-semibold">Custom Cells Example</h3>
310
- </template>
311
- <ClientOnly>
312
- <VATable
313
- :data="users.slice(0, 6)"
314
- :columns="customCellColumns"
315
- card
316
- name="Custom Cells"
317
- :paginated="false"
318
- >
319
- <template #status-data="{ value }">
320
- <UBadge :color="getStatusColor(value)" size="sm" variant="subtle">
321
- {{ value }}
322
- </UBadge>
323
- </template>
324
- <template #salary-data="{ value }">
325
- <span class="font-medium text-gray-900 dark:text-white">
326
- ${{ value.toLocaleString() }}
327
- </span>
328
- </template>
329
- </VATable>
330
- </ClientOnly>
331
- </UCard>
332
- </div>
333
-
334
- <!-- Striped Table -->
335
- <h2 class="text-2xl font-semibold mb-4 mt-8">Striped Table</h2>
336
- <p class="text-gray-600 dark:text-gray-400 mb-4">Alternating row colors for improved readability.</p>
337
- <div class="mb-8">
338
- <UCard>
339
- <template #header>
340
- <h3 class="font-semibold">Striped Example</h3>
341
- </template>
342
- <ClientOnly>
343
- <VATable
344
- :data="users.slice(0, 8)"
345
- :columns="basicColumns"
346
- striped
347
- card
348
- name="Striped Table"
349
- />
350
- </ClientOnly>
351
- </UCard>
352
- </div>
353
-
354
- <!-- Compact Table -->
355
- <h2 class="text-2xl font-semibold mb-4 mt-8">Compact Table</h2>
356
- <p class="text-gray-600 dark:text-gray-400 mb-4">Reduced padding for denser data display.</p>
357
- <div class="mb-8">
358
- <UCard>
359
- <template #header>
360
- <h3 class="font-semibold">Compact Example</h3>
361
- </template>
362
- <ClientOnly>
363
- <VATable
364
- :data="users.slice(0, 8)"
365
- :columns="basicColumns"
366
- compact
367
- card
368
- name="Compact Table"
369
- />
370
- </ClientOnly>
371
- </UCard>
372
- </div>
373
-
374
- <!-- Sticky Header -->
375
- <h2 class="text-2xl font-semibold mb-4 mt-8">Sticky Header</h2>
376
- <p class="text-gray-600 dark:text-gray-400 mb-4">Header stays visible when scrolling through large datasets.</p>
377
- <div class="mb-8">
378
- <UCard>
379
- <template #header>
380
- <h3 class="font-semibold">Sticky Header Example</h3>
381
- </template>
382
- <div class="max-h-64 overflow-auto">
383
- <ClientOnly>
384
- <VATable
385
- :data="users"
386
- :columns="basicColumns"
387
- sticky-header
388
- :paginated="false"
389
- card
390
- name="Sticky Header"
391
- />
392
- </ClientOnly>
393
- </div>
394
- </UCard>
395
- </div>
396
-
397
- <!-- Full Featured Table -->
398
- <h2 class="text-2xl font-semibold mb-4 mt-8">Full Featured Table</h2>
399
- <p class="text-gray-600 dark:text-gray-400 mb-4">All features combined: search, sort, select, export, pagination, and actions.</p>
400
- <div class="mb-8">
401
- <UCard>
402
- <template #header>
403
- <h3 class="font-semibold">Full Featured Example</h3>
404
- </template>
405
- <ClientOnly>
406
- <VATable
407
- :data="users"
408
- :columns="fullColumns"
409
- searchable
410
- search-placeholder="Search users..."
411
- sortable
412
- selectable="multi"
413
- show-column-toggle
414
- exportable
415
- show-view
416
- show-edit
417
- show-delete
418
- striped
419
- card
420
- name="Full Featured Users"
421
- :page-size="5"
422
- :page-sizes="[5, 10, 20]"
423
- @search="handleSearch"
424
- @select="handleSelect"
425
- @view="handleView"
426
- @edit="handleEdit"
427
- @delete="handleDelete"
428
- @export="handleExport"
429
- >
430
- <template #status-data="{ value }">
431
- <UBadge :color="getStatusColor(value)" size="sm" variant="subtle">
432
- {{ value }}
433
- </UBadge>
434
- </template>
435
- <template #salary-data="{ value }">
436
- <span class="font-medium">${{ value.toLocaleString() }}</span>
437
- </template>
438
- </VATable>
439
- </ClientOnly>
440
- </UCard>
441
- </div>
106
+ <section>
107
+ <h2 class="text-2xl font-semibold mb-4">Basic Table</h2>
108
+ <p class="text-gray-600 dark:text-gray-400 mb-4">Simple table with minimal configuration.</p>
109
+ <ClientOnly>
110
+ <VATable
111
+ name="Basic Users"
112
+ :data="users.slice(0, 5)"
113
+ :columns="basicColumns"
114
+ />
115
+ </ClientOnly>
116
+ </section>
117
+
118
+ <!-- Preset-Based Columns -->
119
+ <section>
120
+ <h2 class="text-2xl font-semibold mb-4">Preset-Based Columns</h2>
121
+ <p class="text-gray-600 dark:text-gray-400 mb-4">Using useXATableColumns presets for automatic cell rendering (badge, currency, date).</p>
122
+ <ClientOnly>
123
+ <VATable
124
+ name="Users with Presets"
125
+ :data="users"
126
+ :columns="presetColumns"
127
+ />
128
+ </ClientOnly>
129
+ </section>
130
+
131
+ <!-- Table with Filters -->
132
+ <section>
133
+ <h2 class="text-2xl font-semibold mb-4">Table with Filters</h2>
134
+ <p class="text-gray-600 dark:text-gray-400 mb-4">Inline filter dropdowns with active filter chips.</p>
135
+ <ClientOnly>
136
+ <VATable
137
+ name="Filtered Users"
138
+ :data="users"
139
+ :columns="basicColumns"
140
+ :filters="statusFilters"
141
+ />
142
+ </ClientOnly>
143
+ </section>
144
+
145
+ <!-- Selectable Table -->
146
+ <section>
147
+ <h2 class="text-2xl font-semibold mb-4">Selectable Table</h2>
148
+ <p class="text-gray-600 dark:text-gray-400 mb-4">Multi-select with checkbox column and bulk action support.</p>
149
+ <ClientOnly>
150
+ <VATable
151
+ name="Select Users"
152
+ :data="users.slice(0, 6)"
153
+ :columns="basicColumns"
154
+ selectable
155
+ >
156
+ <template #bulk-actions="{ count, clear }">
157
+ <span class="text-sm text-muted">{{ count }} selected</span>
158
+ <UButton size="xs" color="neutral" variant="outline" label="Clear" @click="clear" />
159
+ <UButton size="xs" color="error" variant="soft" label="Delete Selected" />
160
+ </template>
161
+ </VATable>
162
+ </ClientOnly>
163
+ </section>
164
+
165
+ <!-- Table with Row Actions -->
166
+ <section>
167
+ <h2 class="text-2xl font-semibold mb-4">Table with Row Actions</h2>
168
+ <p class="text-gray-600 dark:text-gray-400 mb-4">Custom actions column via slot.</p>
169
+ <ClientOnly>
170
+ <VATable
171
+ name="Users with Actions"
172
+ :data="users.slice(0, 5)"
173
+ :columns="basicColumns"
174
+ :on-row-click="handleRowClick"
175
+ >
176
+ <template #actions-cell="{ row }">
177
+ <div class="flex items-center justify-end gap-1">
178
+ <UButton icon="i-lucide-eye" color="neutral" variant="ghost" size="xs" @click.stop="() => console.log('View', row.original)" />
179
+ <UButton icon="i-lucide-pencil" color="neutral" variant="ghost" size="xs" @click.stop="() => console.log('Edit', row.original)" />
180
+ <UButton icon="i-lucide-trash-2" color="error" variant="ghost" size="xs" @click.stop="() => console.log('Delete', row.original)" />
181
+ </div>
182
+ </template>
183
+ </VATable>
184
+ </ClientOnly>
185
+ </section>
186
+
187
+ <!-- Table with Refresh -->
188
+ <section>
189
+ <h2 class="text-2xl font-semibold mb-4">Table with Refresh</h2>
190
+ <p class="text-gray-600 dark:text-gray-400 mb-4">Refresh button with loading state.</p>
191
+ <ClientOnly>
192
+ <VATable
193
+ name="Products"
194
+ :data="products"
195
+ :columns="productColumns"
196
+ :on-refresh="async () => { await new Promise(r => setTimeout(r, 1000)) }"
197
+ />
198
+ </ClientOnly>
199
+ </section>
200
+
201
+ <!-- Default Sort -->
202
+ <section>
203
+ <h2 class="text-2xl font-semibold mb-4">Default Sort</h2>
204
+ <p class="text-gray-600 dark:text-gray-400 mb-4">Table pre-sorted by salary descending.</p>
205
+ <ClientOnly>
206
+ <VATable
207
+ name="Sorted Users"
208
+ :data="users"
209
+ :columns="fullColumns"
210
+ default-sort="salary"
211
+ :default-sort-desc="true"
212
+ />
213
+ </ClientOnly>
214
+ </section>
442
215
 
443
216
  <!-- Loading State -->
444
- <h2 class="text-2xl font-semibold mb-4 mt-8">Loading State</h2>
445
- <p class="text-gray-600 dark:text-gray-400 mb-4">Skeleton loading state while data is being fetched.</p>
446
- <div class="mb-8">
447
- <UCard>
448
- <template #header>
449
- <h3 class="font-semibold">Loading Example</h3>
450
- </template>
451
- <ClientOnly>
452
- <VATable
453
- :data="[]"
454
- :columns="basicColumns"
455
- loading
456
- card
457
- name="Loading Table"
458
- />
459
- </ClientOnly>
460
- </UCard>
461
- </div>
462
-
463
- <!-- Empty State -->
464
- <h2 class="text-2xl font-semibold mb-4 mt-8">Empty State</h2>
465
- <p class="text-gray-600 dark:text-gray-400 mb-4">Custom empty state when no data is available.</p>
466
- <div class="mb-8">
467
- <UCard>
468
- <template #header>
469
- <h3 class="font-semibold">Empty State Example</h3>
470
- </template>
471
- <ClientOnly>
472
- <VATable
473
- :data="[]"
474
- :columns="basicColumns"
475
- empty-title="No users found"
476
- empty-description="There are no users matching your criteria. Try adjusting your filters or add new users."
477
- empty-icon="i-lucide-users"
478
- card
479
- name="Empty Table"
480
- />
481
- </ClientOnly>
482
- </UCard>
483
- </div>
484
-
485
- <!-- Custom Pagination -->
486
- <h2 class="text-2xl font-semibold mb-4 mt-8">Custom Pagination</h2>
487
- <p class="text-gray-600 dark:text-gray-400 mb-4">Configurable page sizes and pagination controls.</p>
488
- <div class="mb-8">
489
- <UCard>
490
- <template #header>
491
- <h3 class="font-semibold">Pagination Example</h3>
492
- </template>
493
- <ClientOnly>
494
- <VATable
495
- :data="users"
496
- :columns="basicColumns"
497
- :page-size="3"
498
- :page-sizes="[3, 5, 10, 20]"
499
- show-page-size
500
- card
501
- name="Paginated Table"
502
- />
503
- </ClientOnly>
504
- </UCard>
505
- </div>
217
+ <section>
218
+ <h2 class="text-2xl font-semibold mb-4">Loading State</h2>
219
+ <p class="text-gray-600 dark:text-gray-400 mb-4">Full-screen loading state for initial data fetch.</p>
220
+ <ClientOnly>
221
+ <VATable
222
+ name="Loading Table"
223
+ :data="[]"
224
+ :columns="basicColumns"
225
+ :loading="true"
226
+ />
227
+ </ClientOnly>
228
+ </section>
506
229
 
507
230
  <!-- VADataTable Section -->
508
- <h2 class="text-2xl font-semibold mb-4 mt-8">VADataTable</h2>
509
- <p class="text-gray-600 dark:text-gray-400 mb-4">Simpler table component with basic search, pagination, and loading states. Ideal for list pages with minimal configuration.</p>
510
-
511
- <!-- Basic DataTable -->
512
- <div class="mb-8">
513
- <UCard>
514
- <template #header>
515
- <h3 class="font-semibold">Basic DataTable</h3>
516
- </template>
517
- <ClientOnly>
518
- <VADataTable
519
- title="Users"
520
- :rows="users.slice(0, 5)"
521
- :columns="basicColumns"
522
- :show-search="false"
523
- :show-pagination="false"
524
- @select="handleDataTableSelect"
525
- />
526
- </ClientOnly>
527
- </UCard>
528
- </div>
529
-
530
- <!-- DataTable with Search -->
531
- <div class="mb-8">
532
- <UCard>
533
- <template #header>
534
- <h3 class="font-semibold">DataTable with Search</h3>
535
- </template>
536
- <ClientOnly>
537
- <VADataTable
538
- title="Users"
539
- :rows="users"
540
- :columns="basicColumns"
541
- search-placeholder="Search users..."
542
- :show-search="true"
543
- :show-pagination="false"
544
- @select="handleDataTableSelect"
545
- />
546
- </ClientOnly>
547
- </UCard>
548
- </div>
549
-
550
- <!-- DataTable with Pagination -->
551
- <div class="mb-8">
552
- <UCard>
553
- <template #header>
554
- <h3 class="font-semibold">DataTable with Pagination</h3>
555
- </template>
556
- <ClientOnly>
557
- <VADataTable
558
- title="Products"
559
- :rows="products.slice(0, 3)"
560
- :columns="productColumns"
561
- :total-count="products.length"
562
- :has-prev="false"
563
- :has-next="true"
564
- :show-search="true"
565
- :show-pagination="true"
566
- search-placeholder="Search products..."
567
- @select="handleDataTableSelect"
568
- @prev="handleDataTablePrev"
569
- @next="handleDataTableNext"
570
- />
571
- </ClientOnly>
572
- </UCard>
573
- </div>
574
-
575
- <!-- DataTable with New Button -->
576
- <div class="mb-8">
577
- <UCard>
578
- <template #header>
579
- <h3 class="font-semibold">DataTable with New Button</h3>
580
- </template>
581
- <ClientOnly>
582
- <VADataTable
583
- title="Users"
584
- :rows="users.slice(0, 4)"
585
- :columns="basicColumns"
586
- :show-search="true"
587
- :show-pagination="false"
588
- :show-new-button="true"
589
- new-button-label="Add User"
590
- @select="handleDataTableSelect"
591
- @new="handleDataTableNew"
592
- />
593
- </ClientOnly>
594
- </UCard>
595
- </div>
596
-
597
- <!-- DataTable Loading State -->
598
- <div class="mb-8">
599
- <UCard>
600
- <template #header>
601
- <h3 class="font-semibold">DataTable Loading State</h3>
602
- </template>
603
- <ClientOnly>
604
- <VADataTable
605
- title="Loading Data"
606
- :rows="[]"
607
- :columns="basicColumns"
608
- :loading="true"
609
- :show-search="true"
610
- :show-pagination="false"
611
- />
612
- </ClientOnly>
613
- </UCard>
614
- </div>
231
+ <section>
232
+ <h2 class="text-2xl font-semibold mb-4">VADataTable</h2>
233
+ <p class="text-gray-600 dark:text-gray-400 mb-4">Dashboard-integrated table with UDashboardPanel wrapper.</p>
234
+ <ClientOnly>
235
+ <VADataTable
236
+ title="Users (DataTable)"
237
+ :rows="users.slice(0, 5)"
238
+ :columns="basicColumns"
239
+ :show-search="false"
240
+ :show-pagination="false"
241
+ />
242
+ </ClientOnly>
243
+ </section>
615
244
  </div>
616
245
  </UContainer>
617
246
  </UDashboardPanel>