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 CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "ketekny-ui-kit",
3
3
  "type": "module",
4
- "version": "1.0.35",
4
+ "version": "1.0.37",
5
5
  "description": "A Vue 3 UI component library with Tailwind CSS styling",
6
6
  "main": "index.js",
7
7
  "files": [
@@ -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="easy-checkbox"
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="easy-checkbox"
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 (event?.shiftKey && this.lastSelectionAnchorKey && key !== this.lastSelectionAnchorKey) {
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;