ketekny-ui-kit 1.0.35 → 1.0.37
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/package.json +1 -1
- package/src/ui/kDatatable.vue +113 -3
package/package.json
CHANGED
package/src/ui/kDatatable.vue
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
'k-datatable-wrapper rounded-lg border border-primary/15',
|
|
6
6
|
disabled ? 'pointer-events-none opacity-60' : '',
|
|
7
7
|
]"
|
|
8
|
+
:style="{ '--k-datatable-checkbox-accent': themeColor }"
|
|
8
9
|
>
|
|
9
10
|
<EasyDataTable
|
|
10
11
|
v-bind="$attrs"
|
|
@@ -22,10 +23,11 @@
|
|
|
22
23
|
<div class="k-datatable-select-cell">
|
|
23
24
|
<input
|
|
24
25
|
type="checkbox"
|
|
25
|
-
class="
|
|
26
|
+
class="k-datatable-checkbox"
|
|
26
27
|
:checked="allSelectableSelected"
|
|
27
28
|
:indeterminate.prop="partiallySelectableSelected"
|
|
28
29
|
:disabled="disabled || pageSelectableKeys.length === 0"
|
|
30
|
+
@mousedown="captureSelectionInteraction"
|
|
29
31
|
@click.stop
|
|
30
32
|
@change="handleSelectAllChange"
|
|
31
33
|
/>
|
|
@@ -36,9 +38,11 @@
|
|
|
36
38
|
<div class="k-datatable-select-cell">
|
|
37
39
|
<input
|
|
38
40
|
type="checkbox"
|
|
39
|
-
class="
|
|
41
|
+
class="k-datatable-checkbox"
|
|
40
42
|
:checked="isItemSelected(slotItem)"
|
|
41
43
|
:disabled="disabled || !isItemSelectable(slotItem)"
|
|
44
|
+
:title="!isItemSelectable(slotItem) ? 'Row is not selectable' : ''"
|
|
45
|
+
@mousedown="captureSelectionInteraction"
|
|
42
46
|
@click.stop
|
|
43
47
|
@change="($event) => handleItemSelectionChange($event, slotItem)"
|
|
44
48
|
/>
|
|
@@ -101,6 +105,8 @@ export default {
|
|
|
101
105
|
selectedKeys: [],
|
|
102
106
|
selectedKeySet: new Set(),
|
|
103
107
|
lastSelectionAnchorKey: null,
|
|
108
|
+
pendingShiftSelection: false,
|
|
109
|
+
isShiftKeyPressed: false,
|
|
104
110
|
_pageSelectableKeys: [],
|
|
105
111
|
keyedItems: [],
|
|
106
112
|
currentItemsByKey: new Map(),
|
|
@@ -141,6 +147,16 @@ export default {
|
|
|
141
147
|
this.rebuildItemCaches();
|
|
142
148
|
this.applyExternalModelValue(this.modelValue);
|
|
143
149
|
},
|
|
150
|
+
mounted() {
|
|
151
|
+
window.addEventListener("keydown", this.handleWindowKeydown);
|
|
152
|
+
window.addEventListener("keyup", this.handleWindowKeyup);
|
|
153
|
+
window.addEventListener("blur", this.handleWindowBlur);
|
|
154
|
+
},
|
|
155
|
+
beforeUnmount() {
|
|
156
|
+
window.removeEventListener("keydown", this.handleWindowKeydown);
|
|
157
|
+
window.removeEventListener("keyup", this.handleWindowKeyup);
|
|
158
|
+
window.removeEventListener("blur", this.handleWindowBlur);
|
|
159
|
+
},
|
|
144
160
|
|
|
145
161
|
watch: {
|
|
146
162
|
items: {
|
|
@@ -173,8 +189,36 @@ export default {
|
|
|
173
189
|
},
|
|
174
190
|
|
|
175
191
|
methods: {
|
|
192
|
+
captureSelectionInteraction(event) {
|
|
193
|
+
this.pendingShiftSelection = Boolean(event?.shiftKey || this.isShiftKeyPressed);
|
|
194
|
+
if (event?.type === "mousedown" && event?.shiftKey && typeof event.preventDefault === "function") {
|
|
195
|
+
// Prevent browser range-text selection while using Shift+click for row-range selection.
|
|
196
|
+
event.preventDefault();
|
|
197
|
+
}
|
|
198
|
+
if (typeof window !== "undefined" && typeof window.getSelection === "function") {
|
|
199
|
+
const selection = window.getSelection();
|
|
200
|
+
if (selection && typeof selection.removeAllRanges === "function") {
|
|
201
|
+
selection.removeAllRanges();
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
},
|
|
205
|
+
handleWindowKeydown(event) {
|
|
206
|
+
if (event?.key === "Shift") {
|
|
207
|
+
this.isShiftKeyPressed = true;
|
|
208
|
+
}
|
|
209
|
+
},
|
|
210
|
+
handleWindowKeyup(event) {
|
|
211
|
+
if (event?.key === "Shift") {
|
|
212
|
+
this.isShiftKeyPressed = false;
|
|
213
|
+
}
|
|
214
|
+
},
|
|
215
|
+
handleWindowBlur() {
|
|
216
|
+
this.isShiftKeyPressed = false;
|
|
217
|
+
this.pendingShiftSelection = false;
|
|
218
|
+
},
|
|
176
219
|
handleSelectAllChange(event) {
|
|
177
220
|
if (this.effectiveSelectionMode !== "multiple" || this.disabled) return;
|
|
221
|
+
this.pendingShiftSelection = false;
|
|
178
222
|
const shouldSelect = Boolean(event?.target?.checked);
|
|
179
223
|
const nextKeySet = new Set(this.selectedKeys);
|
|
180
224
|
|
|
@@ -199,6 +243,8 @@ export default {
|
|
|
199
243
|
if (!sourceItem || !this.isItemSelectable(sourceItem)) return;
|
|
200
244
|
|
|
201
245
|
const shouldSelect = Boolean(event?.target?.checked);
|
|
246
|
+
const shiftPressed = Boolean(this.pendingShiftSelection || event?.shiftKey || this.isShiftKeyPressed);
|
|
247
|
+
this.pendingShiftSelection = false;
|
|
202
248
|
|
|
203
249
|
if (this.selectionMode === "single") {
|
|
204
250
|
this.commitSelectionByKeys(shouldSelect ? [key] : [], {
|
|
@@ -208,7 +254,7 @@ export default {
|
|
|
208
254
|
return;
|
|
209
255
|
}
|
|
210
256
|
|
|
211
|
-
if (
|
|
257
|
+
if (shiftPressed && this.lastSelectionAnchorKey && key !== this.lastSelectionAnchorKey) {
|
|
212
258
|
const selectableKeySet = new Set(this.selectableKeys);
|
|
213
259
|
const rangeKeys = this.resolveRangeKeys(this.lastSelectionAnchorKey, key).filter((rangeKey) =>
|
|
214
260
|
selectableKeySet.has(rangeKey),
|
|
@@ -569,6 +615,70 @@ export default {
|
|
|
569
615
|
justify-content: center;
|
|
570
616
|
}
|
|
571
617
|
|
|
618
|
+
.k-datatable-checkbox {
|
|
619
|
+
appearance: none;
|
|
620
|
+
-webkit-appearance: none;
|
|
621
|
+
width: 1rem;
|
|
622
|
+
height: 1rem;
|
|
623
|
+
margin: 0;
|
|
624
|
+
border: 1px solid #94a3b8;
|
|
625
|
+
border-radius: 0.2rem;
|
|
626
|
+
background-color: #fff;
|
|
627
|
+
display: grid;
|
|
628
|
+
place-content: center;
|
|
629
|
+
cursor: pointer;
|
|
630
|
+
transition: background-color 0.12s ease, border-color 0.12s ease, opacity 0.12s ease;
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
.k-datatable-checkbox::before {
|
|
634
|
+
content: "";
|
|
635
|
+
width: 0.58rem;
|
|
636
|
+
height: 0.32rem;
|
|
637
|
+
border: 2px solid #fff;
|
|
638
|
+
border-top: 0;
|
|
639
|
+
border-right: 0;
|
|
640
|
+
transform: rotate(-45deg) scale(0);
|
|
641
|
+
transform-origin: center;
|
|
642
|
+
transition: transform 0.12s ease;
|
|
643
|
+
margin-top: -0.05rem;
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
.k-datatable-checkbox:checked {
|
|
647
|
+
background-color: var(--k-datatable-checkbox-accent, #2563eb);
|
|
648
|
+
border-color: var(--k-datatable-checkbox-accent, #2563eb);
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
.k-datatable-checkbox:checked::before {
|
|
652
|
+
transform: rotate(-45deg) scale(1);
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
.k-datatable-checkbox:indeterminate {
|
|
656
|
+
background-color: var(--k-datatable-checkbox-accent, #2563eb);
|
|
657
|
+
border-color: var(--k-datatable-checkbox-accent, #2563eb);
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
.k-datatable-checkbox:indeterminate::before {
|
|
661
|
+
width: 0.52rem;
|
|
662
|
+
height: 0;
|
|
663
|
+
border: 0;
|
|
664
|
+
border-top: 2px solid #fff;
|
|
665
|
+
transform: scale(1);
|
|
666
|
+
margin-top: 0;
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
.k-datatable-checkbox:disabled {
|
|
670
|
+
cursor: not-allowed;
|
|
671
|
+
background-color: #e5e7eb;
|
|
672
|
+
border-color: #cbd5e1;
|
|
673
|
+
opacity: 1;
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
.k-datatable-checkbox:disabled:checked,
|
|
677
|
+
.k-datatable-checkbox:disabled:indeterminate {
|
|
678
|
+
background-color: #9ca3af;
|
|
679
|
+
border-color: #9ca3af;
|
|
680
|
+
}
|
|
681
|
+
|
|
572
682
|
/* Target the rows-per-page dropdown */
|
|
573
683
|
.customize-table .easy-data-table__footer select {
|
|
574
684
|
background-color: #fff;
|