@bagelink/vue 1.4.69 → 1.4.71
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/dist/components/dataTable/DataTable.vue.d.ts.map +1 -1
- package/dist/components/dataTable/useTableSelection.d.ts +1 -1
- package/dist/components/dataTable/useTableSelection.d.ts.map +1 -1
- package/dist/index.cjs +19 -19
- package/dist/index.mjs +19 -19
- package/dist/style.css +1 -1
- package/package.json +1 -1
- package/src/components/dataTable/DataTable.vue +20 -44
- package/src/components/dataTable/useTableSelection.ts +40 -1
package/package.json
CHANGED
|
@@ -121,76 +121,46 @@ const showLoading = computed(() => loading.value)
|
|
|
121
121
|
</script>
|
|
122
122
|
|
|
123
123
|
<template>
|
|
124
|
-
<div
|
|
125
|
-
class="table-list-wrap h-100"
|
|
126
|
-
v-bind="containerProps"
|
|
127
|
-
:class="{ overflowHiddenLoading: showLoading }"
|
|
128
|
-
>
|
|
124
|
+
<div class="table-list-wrap h-100" v-bind="containerProps" :class="{ overflowHiddenLoading: showLoading }">
|
|
129
125
|
<Loading v-if="showLoading" class="h100p" />
|
|
130
126
|
<div v-bind="wrapperProps" :class="{ 'pointer-events-none': showLoading }">
|
|
131
|
-
<table class="infinite-wrapper">
|
|
127
|
+
<table class="infinite-wrapper" :class="{ selecting: computedSelectedItems.length }">
|
|
132
128
|
<thead class="row first-row">
|
|
133
129
|
<th v-if="isSelectable">
|
|
134
|
-
<input
|
|
135
|
-
ref="allSelectorEl"
|
|
136
|
-
type="checkbox"
|
|
137
|
-
@click.stop
|
|
138
|
-
@change="(e) => toggleSelectAll(e)"
|
|
139
|
-
>
|
|
130
|
+
<input ref="allSelectorEl" type="checkbox" @click.stop @change="(e) => toggleSelectAll(e)">
|
|
140
131
|
<!-- @change="toggleSelectAll" -->
|
|
141
132
|
</th>
|
|
142
133
|
<th
|
|
143
|
-
v-for="field in computedSchema"
|
|
144
|
-
:key="field.id"
|
|
145
|
-
class="col"
|
|
134
|
+
v-for="field in computedSchema" :key="field.id" class="col"
|
|
146
135
|
@click="toggleSort(field?.id || '')"
|
|
147
136
|
>
|
|
148
137
|
<div class="flex">
|
|
149
138
|
{{ field.label || keyToLabel(field?.id) }}
|
|
150
|
-
<div
|
|
151
|
-
class="
|
|
152
|
-
:class="{ sorted: sortField === field?.id }"
|
|
153
|
-
>
|
|
154
|
-
<Icon
|
|
155
|
-
:class="{ desc: sortDirection === 'DESC' }"
|
|
156
|
-
icon="keyboard_arrow_up"
|
|
157
|
-
/>
|
|
139
|
+
<div class="list-arrows" :class="{ sorted: sortField === field?.id }">
|
|
140
|
+
<Icon :class="{ desc: sortDirection === 'DESC' }" icon="keyboard_arrow_up" />
|
|
158
141
|
</div>
|
|
159
142
|
</div>
|
|
160
143
|
</th>
|
|
161
144
|
</thead>
|
|
162
145
|
<tbody>
|
|
163
146
|
<tr
|
|
164
|
-
v-for="{ data: row } in list"
|
|
165
|
-
:key="row?.id || `row-${Math.random()}`"
|
|
147
|
+
v-for="{ data: row } in list" :key="row?.id || `row-${Math.random()}`"
|
|
166
148
|
class="row row-item position-relative"
|
|
167
149
|
:class="{ selected: row?.id && computedSelectedItems.includes(row.id) }"
|
|
168
|
-
@click="toggleSelectItem(row)"
|
|
150
|
+
@click="(event) => toggleSelectItem(row, event)"
|
|
169
151
|
>
|
|
170
152
|
<td v-if="isSelectable">
|
|
171
153
|
<div @click.stop>
|
|
172
|
-
<input
|
|
173
|
-
v-model="selectedItems"
|
|
174
|
-
type="checkbox"
|
|
175
|
-
:value="row?.id || ''"
|
|
176
|
-
>
|
|
154
|
+
<input v-model="selectedItems" type="checkbox" :value="row?.id || ''">
|
|
177
155
|
</div>
|
|
178
156
|
</td>
|
|
179
157
|
<td
|
|
180
|
-
v-for="field in computedSchema"
|
|
181
|
-
:key="`${field.id}-${row?.id || Math.random()}`"
|
|
158
|
+
v-for="field in computedSchema" :key="`${field.id}-${row?.id || Math.random()}`"
|
|
182
159
|
class="col"
|
|
183
160
|
>
|
|
184
|
-
<slot
|
|
185
|
-
v-if="field.id && slots?.[field.id]"
|
|
186
|
-
:name="field.id"
|
|
187
|
-
:row="row"
|
|
188
|
-
:field="field"
|
|
189
|
-
/>
|
|
161
|
+
<slot v-if="field.id && slots?.[field.id]" :name="field.id" :row="row" :field="field" />
|
|
190
162
|
<div v-else>
|
|
191
|
-
<component
|
|
192
|
-
:is="renderFieldForRow(field, row)"
|
|
193
|
-
/>
|
|
163
|
+
<component :is="renderFieldForRow(field, row)" />
|
|
194
164
|
</div>
|
|
195
165
|
</td>
|
|
196
166
|
</tr>
|
|
@@ -233,13 +203,19 @@ tbody tr.selected:hover {
|
|
|
233
203
|
border-radius: 5px;
|
|
234
204
|
object-fit: cover;
|
|
235
205
|
}
|
|
206
|
+
|
|
236
207
|
.col:has(img) {
|
|
237
208
|
padding-inline-end: 0.5rem;
|
|
238
209
|
}
|
|
239
210
|
|
|
240
|
-
.
|
|
211
|
+
.selecting .col {
|
|
212
|
+
user-select: none;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
.overflowHiddenLoading {
|
|
241
216
|
overflow: hidden !important;
|
|
242
217
|
}
|
|
218
|
+
|
|
243
219
|
.list-arrows.sorted .desc {
|
|
244
220
|
transform: rotate(180deg);
|
|
245
221
|
display: inline-block;
|
|
@@ -313,7 +289,7 @@ th {
|
|
|
313
289
|
padding: 0rem 0.25rem;
|
|
314
290
|
}
|
|
315
291
|
|
|
316
|
-
.col
|
|
292
|
+
.col>div {
|
|
317
293
|
display: flex;
|
|
318
294
|
gap: 0.5rem;
|
|
319
295
|
}
|
|
@@ -9,6 +9,7 @@ export interface UseTableSelectionOptions<T> extends TableSelectionOptions<T> {
|
|
|
9
9
|
|
|
10
10
|
export function useTableSelection<T extends { [key: string]: any }>(options: UseTableSelectionOptions<T>) {
|
|
11
11
|
const allSelectorEl = ref<HTMLInputElement>()
|
|
12
|
+
const lastSelectedIndex = ref<number | null>(null)
|
|
12
13
|
const computedSelectedItems = computed(() => options.selectedItems.value)
|
|
13
14
|
const isSelectable = computed(() => options.selectable === true && Array.isArray(options.selectedItems.value))
|
|
14
15
|
const allItems = $computed(() => options.data.value)
|
|
@@ -39,7 +40,37 @@ export function useTableSelection<T extends { [key: string]: any }>(options: Use
|
|
|
39
40
|
= !allSelected && options.selectedItems.value.length > 0
|
|
40
41
|
}
|
|
41
42
|
|
|
42
|
-
function toggleSelectItem(item: T) {
|
|
43
|
+
function toggleSelectItem(item: T, event?: MouseEvent) {
|
|
44
|
+
const currentIndex = allItems.findIndex(i => i.id === item.id)
|
|
45
|
+
|
|
46
|
+
// Handle Shift+click for range selection
|
|
47
|
+
if (event?.shiftKey && lastSelectedIndex.value !== null && currentIndex !== -1) {
|
|
48
|
+
const startIndex = Math.min(lastSelectedIndex.value, currentIndex)
|
|
49
|
+
const endIndex = Math.max(lastSelectedIndex.value, currentIndex)
|
|
50
|
+
|
|
51
|
+
// Get all items in the range
|
|
52
|
+
const rangeItems = allItems.slice(startIndex, endIndex + 1)
|
|
53
|
+
const rangeItemIds = rangeItems.map(i => i.id)
|
|
54
|
+
|
|
55
|
+
// Check if all items in range are currently selected
|
|
56
|
+
const allRangeSelected = rangeItemIds.every(id => options.selectedItems.value.includes(id)
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
if (allRangeSelected) {
|
|
60
|
+
// Deselect all items in range
|
|
61
|
+
options.selectedItems.value = options.selectedItems.value.filter(id => !rangeItemIds.includes(id)
|
|
62
|
+
)
|
|
63
|
+
} else {
|
|
64
|
+
// Select all items in range (add missing ones)
|
|
65
|
+
const newSelections = rangeItemIds.filter(id => !options.selectedItems.value.includes(id)
|
|
66
|
+
)
|
|
67
|
+
options.selectedItems.value.push(...newSelections)
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Regular single item selection logic
|
|
43
74
|
if (computedSelectedItems.value.length === 0) {
|
|
44
75
|
// Clean the item if a cleanData function is provided, otherwise use the default cleaning
|
|
45
76
|
const cleanItem = options.cleanData ? options.cleanData(item) : { ...item }
|
|
@@ -54,14 +85,19 @@ export function useTableSelection<T extends { [key: string]: any }>(options: Use
|
|
|
54
85
|
}
|
|
55
86
|
|
|
56
87
|
options.onSelect(cleanItem)
|
|
88
|
+
lastSelectedIndex.value = currentIndex
|
|
57
89
|
return
|
|
58
90
|
}
|
|
91
|
+
|
|
59
92
|
const index = computedSelectedItems.value.indexOf(item.id)
|
|
60
93
|
if (index > -1) {
|
|
61
94
|
options.selectedItems.value.splice(index, 1)
|
|
62
95
|
} else {
|
|
63
96
|
options.selectedItems.value.push(item.id)
|
|
64
97
|
}
|
|
98
|
+
|
|
99
|
+
// Update last selected index for future range selections
|
|
100
|
+
lastSelectedIndex.value = currentIndex
|
|
65
101
|
}
|
|
66
102
|
|
|
67
103
|
// Update toggleSelectAll to pass allItems to updateAllSelectorState
|
|
@@ -73,6 +109,9 @@ export function useTableSelection<T extends { [key: string]: any }>(options: Use
|
|
|
73
109
|
} else {
|
|
74
110
|
options.selectedItems.value = []
|
|
75
111
|
}
|
|
112
|
+
|
|
113
|
+
// Reset last selected index when selecting/deselecting all
|
|
114
|
+
lastSelectedIndex.value = null
|
|
76
115
|
}
|
|
77
116
|
|
|
78
117
|
return {
|