@a-vision-software/vue-input-components 1.4.20 → 1.4.21
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.
- package/README.md +3 -1
- package/dist/src/types/list.d.ts +11 -2
- package/dist/vue-input-components.cjs.js +2 -2
- package/dist/vue-input-components.css +1 -1
- package/dist/vue-input-components.es.js +3355 -3343
- package/dist/vue-input-components.umd.js +2 -2
- package/package.json +1 -1
- package/src/components/List.vue +52 -28
- package/src/types/list.ts +12 -1
- package/src/views/ListTestView.vue +79 -2
package/package.json
CHANGED
package/src/components/List.vue
CHANGED
|
@@ -96,7 +96,7 @@
|
|
|
96
96
|
}"
|
|
97
97
|
@click="handleSort(column)"
|
|
98
98
|
>
|
|
99
|
-
<div class="list__column-header">
|
|
99
|
+
<div class="list__column-header" :title="column.headerTooltip">
|
|
100
100
|
<span>{{ column.label }}</span>
|
|
101
101
|
<span
|
|
102
102
|
v-if="column.sortable"
|
|
@@ -219,7 +219,7 @@ import { ref, computed, watch } from 'vue'
|
|
|
219
219
|
import TextInput from './TextInput.vue'
|
|
220
220
|
import Action from './Action.vue'
|
|
221
221
|
import Checkbox from './Checkbox.vue'
|
|
222
|
-
import type { ListProps, ListEmits, ListColumn, ListAction } from '../types/list'
|
|
222
|
+
import type { ListProps, ListEmits, ListColumn, ListAction, ListRowData } from '../types/list'
|
|
223
223
|
import { config } from '../config'
|
|
224
224
|
|
|
225
225
|
const props = withDefaults(defineProps<ListProps>(), {
|
|
@@ -341,6 +341,9 @@ const filteredData = computed(() => {
|
|
|
341
341
|
if (filterableColumns.length === 0) return props.data
|
|
342
342
|
|
|
343
343
|
return props.data.filter((row) => {
|
|
344
|
+
// Always include rows excluded from filtering
|
|
345
|
+
if (row.excludeFromFilter) return true
|
|
346
|
+
|
|
344
347
|
return filterableColumns.some((column) => {
|
|
345
348
|
const value = row[column.key]
|
|
346
349
|
if (value == null) return false
|
|
@@ -364,36 +367,57 @@ const filteredData = computed(() => {
|
|
|
364
367
|
})
|
|
365
368
|
|
|
366
369
|
const sortedAndFilteredData = computed(() => {
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
if (column.type === 'date') {
|
|
377
|
-
const dateA = new Date(aValue).getTime()
|
|
378
|
-
const dateB = new Date(bValue).getTime()
|
|
379
|
-
return (dateA - dateB) * sortOrder
|
|
370
|
+
// Separate fixed rows (excluded from sorting) from sortable rows
|
|
371
|
+
const fixedRows: ListRowData[] = []
|
|
372
|
+
const sortableRows: ListRowData[] = []
|
|
373
|
+
|
|
374
|
+
filteredData.value.forEach((row) => {
|
|
375
|
+
if (row.excludeFromSort) {
|
|
376
|
+
fixedRows.push(row)
|
|
377
|
+
} else {
|
|
378
|
+
sortableRows.push(row)
|
|
380
379
|
}
|
|
380
|
+
})
|
|
381
381
|
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
382
|
+
// Sort only the sortable rows if sorting is active
|
|
383
|
+
let sortedRows = sortableRows
|
|
384
|
+
if (sortColumn.value) {
|
|
385
|
+
sortedRows = [...sortableRows].sort((a, b) => {
|
|
386
|
+
const column = sortColumn.value!
|
|
387
|
+
const aValue = a[column.key]
|
|
388
|
+
const bValue = b[column.key]
|
|
389
|
+
const sortOrder = sortDirection.value === 'asc' ? 1 : -1
|
|
390
|
+
|
|
391
|
+
// Handle different data types
|
|
392
|
+
if (column.type === 'date') {
|
|
393
|
+
const dateA = new Date(aValue).getTime()
|
|
394
|
+
const dateB = new Date(bValue).getTime()
|
|
395
|
+
return (dateA - dateB) * sortOrder
|
|
396
|
+
}
|
|
385
397
|
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
return (aChecked - bChecked) * sortOrder
|
|
390
|
-
}
|
|
398
|
+
if (column.type === 'number') {
|
|
399
|
+
return (aValue - bValue) * sortOrder
|
|
400
|
+
}
|
|
391
401
|
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
402
|
+
if (column.type === 'checkbox') {
|
|
403
|
+
const aChecked = aValue?.modelValue || false
|
|
404
|
+
const bChecked = bValue?.modelValue || false
|
|
405
|
+
return (aChecked - bChecked) * sortOrder
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
// Default string comparison for text and other types
|
|
409
|
+
const stringA = String(aValue || '').toLowerCase()
|
|
410
|
+
const stringB = String(bValue || '').toLowerCase()
|
|
411
|
+
return stringA.localeCompare(stringB) * sortOrder
|
|
412
|
+
})
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
// Separate fixed rows by their fixed position
|
|
416
|
+
const topFixedRows = fixedRows.filter((row) => row.fixed === 'top')
|
|
417
|
+
const bottomFixedRows = fixedRows.filter((row) => row.fixed === 'bottom')
|
|
418
|
+
|
|
419
|
+
// Return rows in order: top fixed, sorted, bottom fixed
|
|
420
|
+
return [...topFixedRows, ...sortedRows, ...bottomFixedRows]
|
|
397
421
|
})
|
|
398
422
|
|
|
399
423
|
defineExpose({
|
package/src/types/list.ts
CHANGED
|
@@ -38,6 +38,7 @@ interface ListColumn {
|
|
|
38
38
|
minWidth?: string
|
|
39
39
|
maxWidth?: string
|
|
40
40
|
cellClasses?: conditionalClassList
|
|
41
|
+
headerTooltip?: string
|
|
41
42
|
}
|
|
42
43
|
|
|
43
44
|
interface ListFilter {
|
|
@@ -47,7 +48,7 @@ interface ListFilter {
|
|
|
47
48
|
|
|
48
49
|
interface ListProps {
|
|
49
50
|
columns: ListColumn[]
|
|
50
|
-
data:
|
|
51
|
+
data: ListRowData[]
|
|
51
52
|
actions?: ListActionProps[]
|
|
52
53
|
CSVDownload?: string
|
|
53
54
|
filter?: {
|
|
@@ -76,6 +77,15 @@ interface ListIconProps {
|
|
|
76
77
|
color?: string
|
|
77
78
|
}
|
|
78
79
|
|
|
80
|
+
interface ListRowData {
|
|
81
|
+
excludeFromSort?: boolean
|
|
82
|
+
excludeFromFilter?: boolean
|
|
83
|
+
fixed?: 'top' | 'bottom'
|
|
84
|
+
selected?: boolean
|
|
85
|
+
class?: string
|
|
86
|
+
[key: string]: any
|
|
87
|
+
}
|
|
88
|
+
|
|
79
89
|
export type {
|
|
80
90
|
ListPresentation,
|
|
81
91
|
ListProps,
|
|
@@ -85,4 +95,5 @@ export type {
|
|
|
85
95
|
ListIconProps,
|
|
86
96
|
ListColumn,
|
|
87
97
|
ListFilter,
|
|
98
|
+
ListRowData,
|
|
88
99
|
}
|
|
@@ -65,7 +65,13 @@
|
|
|
65
65
|
<script setup lang="ts">
|
|
66
66
|
import { ref } from 'vue'
|
|
67
67
|
import List from '@/components/List.vue'
|
|
68
|
-
import type {
|
|
68
|
+
import type {
|
|
69
|
+
ListColumn,
|
|
70
|
+
ListActionProps,
|
|
71
|
+
ListCheckboxProps,
|
|
72
|
+
ListIconProps,
|
|
73
|
+
ListRowData,
|
|
74
|
+
} from '@/types'
|
|
69
75
|
|
|
70
76
|
const autosaveActive = (info: any) => {
|
|
71
77
|
console.log('Autosave active', info)
|
|
@@ -130,6 +136,7 @@ const columns: ListColumn[] = [
|
|
|
130
136
|
filterable: false,
|
|
131
137
|
align: 'center',
|
|
132
138
|
width: '4rem',
|
|
139
|
+
headerTooltip: 'User status indicator',
|
|
133
140
|
},
|
|
134
141
|
{
|
|
135
142
|
key: 'name',
|
|
@@ -137,6 +144,7 @@ const columns: ListColumn[] = [
|
|
|
137
144
|
type: 'text',
|
|
138
145
|
sortable: true,
|
|
139
146
|
filterable: true,
|
|
147
|
+
headerTooltip: 'The full name of the user',
|
|
140
148
|
},
|
|
141
149
|
{
|
|
142
150
|
key: 'email',
|
|
@@ -144,6 +152,7 @@ const columns: ListColumn[] = [
|
|
|
144
152
|
type: 'email',
|
|
145
153
|
sortable: true,
|
|
146
154
|
filterable: true,
|
|
155
|
+
headerTooltip: 'Contact email address',
|
|
147
156
|
cellClasses: {
|
|
148
157
|
lightredEmail: (value: any) => value.includes('bob'),
|
|
149
158
|
},
|
|
@@ -154,6 +163,7 @@ const columns: ListColumn[] = [
|
|
|
154
163
|
type: 'date',
|
|
155
164
|
sortable: true,
|
|
156
165
|
width: '6rem',
|
|
166
|
+
headerTooltip: 'Account creation date',
|
|
157
167
|
},
|
|
158
168
|
{
|
|
159
169
|
key: 'active',
|
|
@@ -162,6 +172,7 @@ const columns: ListColumn[] = [
|
|
|
162
172
|
align: 'center',
|
|
163
173
|
sortable: true,
|
|
164
174
|
width: '4rem',
|
|
175
|
+
headerTooltip: 'Account active status',
|
|
165
176
|
},
|
|
166
177
|
{
|
|
167
178
|
key: 'actions',
|
|
@@ -172,7 +183,39 @@ const columns: ListColumn[] = [
|
|
|
172
183
|
},
|
|
173
184
|
]
|
|
174
185
|
|
|
175
|
-
const data = ref([
|
|
186
|
+
const data = ref<ListRowData[]>([
|
|
187
|
+
{
|
|
188
|
+
// This row will always appear at the top when sorting
|
|
189
|
+
excludeFromSort: true,
|
|
190
|
+
fixed: 'top',
|
|
191
|
+
selected: false,
|
|
192
|
+
select: <ListCheckboxProps>{
|
|
193
|
+
modelValue: false,
|
|
194
|
+
disabled: false,
|
|
195
|
+
onCheckboxClick: selectClick,
|
|
196
|
+
},
|
|
197
|
+
status: <ListIconProps>{
|
|
198
|
+
icon: 'crown',
|
|
199
|
+
color: 'gold',
|
|
200
|
+
},
|
|
201
|
+
name: 'Current User (Fixed at Top)',
|
|
202
|
+
email: 'current@example.com',
|
|
203
|
+
joined: '2024-01-01',
|
|
204
|
+
active: {
|
|
205
|
+
modelValue: true,
|
|
206
|
+
disabled: false,
|
|
207
|
+
autosave: autosaveActive,
|
|
208
|
+
onCheckboxClick: selectClick,
|
|
209
|
+
},
|
|
210
|
+
actions: <ListActionProps[]>[
|
|
211
|
+
{
|
|
212
|
+
id: 'edit',
|
|
213
|
+
label: 'Edit',
|
|
214
|
+
icon: 'edit',
|
|
215
|
+
onActionClick: rowActionClick,
|
|
216
|
+
},
|
|
217
|
+
],
|
|
218
|
+
},
|
|
176
219
|
{
|
|
177
220
|
class: 'testclass',
|
|
178
221
|
selected: false,
|
|
@@ -390,6 +433,36 @@ const data = ref([
|
|
|
390
433
|
},
|
|
391
434
|
],
|
|
392
435
|
},
|
|
436
|
+
{
|
|
437
|
+
// This row will always appear at the bottom when sorting and is excluded from filtering
|
|
438
|
+
excludeFromSort: true,
|
|
439
|
+
excludeFromFilter: true,
|
|
440
|
+
fixed: 'bottom',
|
|
441
|
+
select: <ListCheckboxProps>{
|
|
442
|
+
modelValue: false,
|
|
443
|
+
disabled: false,
|
|
444
|
+
onCheckboxClick: selectClick,
|
|
445
|
+
},
|
|
446
|
+
status: <ListIconProps>{
|
|
447
|
+
icon: 'info-circle',
|
|
448
|
+
color: 'blue',
|
|
449
|
+
},
|
|
450
|
+
name: 'Footer Row (Fixed at Bottom)',
|
|
451
|
+
email: 'footer@example.com',
|
|
452
|
+
joined: '2024-12-31',
|
|
453
|
+
active: {
|
|
454
|
+
modelValue: true,
|
|
455
|
+
disabled: false,
|
|
456
|
+
},
|
|
457
|
+
actions: <ListActionProps[]>[
|
|
458
|
+
{
|
|
459
|
+
id: 'info',
|
|
460
|
+
label: 'Info',
|
|
461
|
+
icon: 'info',
|
|
462
|
+
onActionClick: rowActionClick,
|
|
463
|
+
},
|
|
464
|
+
],
|
|
465
|
+
},
|
|
393
466
|
])
|
|
394
467
|
</script>
|
|
395
468
|
|
|
@@ -431,4 +504,8 @@ const data = ref([
|
|
|
431
504
|
:deep(.list-test__section .list__cell.lightredEmail) {
|
|
432
505
|
background-color: rgba(255, 0, 0, 0.1);
|
|
433
506
|
}
|
|
507
|
+
|
|
508
|
+
:deep(.list-test__section .list__row--testclass) {
|
|
509
|
+
background-color: rgba(155, 155, 0, 0.1);
|
|
510
|
+
}
|
|
434
511
|
</style>
|