@milaboratories/uikit 2.2.96 → 2.2.97

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.
Files changed (33) hide show
  1. package/.turbo/turbo-build.log +16 -16
  2. package/.turbo/turbo-type-check.log +1 -1
  3. package/CHANGELOG.md +8 -0
  4. package/dist/components/PlClipboard/PlClipboard.vue.d.ts +1 -1
  5. package/dist/components/PlElementList/PlElementList.vue.d.ts +19 -27
  6. package/dist/components/PlElementList/PlElementList.vue.d.ts.map +1 -1
  7. package/dist/components/PlElementList/PlElementList.vue2.js +155 -174
  8. package/dist/components/PlElementList/PlElementList.vue2.js.map +1 -1
  9. package/dist/components/PlElementList/PlElementListItem.vue.d.ts.map +1 -1
  10. package/dist/components/PlElementList/PlElementListItem.vue2.js +1 -1
  11. package/dist/components/PlElementList/PlElementListItem.vue2.js.map +1 -1
  12. package/dist/components/PlElementList/PlElementListItem.vue3.js +24 -24
  13. package/dist/components/PlElementList/utils.d.ts +0 -1
  14. package/dist/components/PlElementList/utils.d.ts.map +1 -1
  15. package/dist/components/PlElementList/utils.js +5 -11
  16. package/dist/components/PlElementList/utils.js.map +1 -1
  17. package/dist/components/PlErrorBoundary/PlErrorBoundary.vue.js +8 -8
  18. package/dist/components/PlFileInput/PlFileInput.vue.js +8 -8
  19. package/dist/components/PlIcon16/PlIcon16.vue.d.ts +1 -1
  20. package/dist/components/PlIcon24/PlIcon24.vue.d.ts +1 -1
  21. package/dist/components/PlSvg/PlSvg.vue.d.ts +1 -1
  22. package/dist/components/PlSvg/PlSvg.vue.d.ts.map +1 -1
  23. package/dist/components/PlSvg/PlSvg.vue2.js +24 -22
  24. package/dist/components/PlSvg/PlSvg.vue2.js.map +1 -1
  25. package/dist/composition/useWatchFetch.js +10 -10
  26. package/dist/lib/util/helpers/dist/index.js +108 -104
  27. package/dist/lib/util/helpers/dist/index.js.map +1 -1
  28. package/package.json +4 -4
  29. package/src/components/PlElementList/PlElementList.vue +116 -135
  30. package/src/components/PlElementList/PlElementListItem.vue +9 -1
  31. package/src/components/PlElementList/README.md +325 -72
  32. package/src/components/PlElementList/utils.ts +0 -9
  33. package/src/components/PlSvg/PlSvg.vue +2 -2
@@ -1,62 +1,72 @@
1
1
  <script generic="T extends unknown = unknown, K extends number | string = number | string" lang="ts" setup>
2
2
  import type { ShallowRef } from 'vue';
3
3
  import { computed, shallowRef, watch } from 'vue';
4
- import { isNil, shallowHash } from '@milaboratories/helpers';
4
+ import { isFunction, shallowHash } from '@milaboratories/helpers';
5
5
  import { useSortable } from '@vueuse/integrations/useSortable';
6
6
  import { type SortableEvent } from 'sortablejs';
7
- import { moveElements, optionalUpdateRef } from './utils.ts';
7
+ import { moveElements } from './utils.ts';
8
8
  import PlElementListItem from './PlElementListItem.vue';
9
9
 
10
10
  const itemsRef = defineModel<T[]>('items', { required: true });
11
- const draggableSetRef = defineModel<Set<K>>('draggableItems');
12
- const removableSetRef = defineModel<Set<K>>('removableItems');
13
-
14
- const expandableSetRef = defineModel<Set<K>>('expandableItems');
15
- const expandedSetRef = defineModel<Set<K>>('expandedItems');
16
-
17
- const pinnableSetRef = defineModel<Set<K>>('pinnableItems');
18
- const pinnedSetRef = defineModel<Set<K>>('pinnedItems');
19
-
20
- const toggableSetRef = defineModel<Set<K>>('toggableItems');
21
- const toggledSetRef = defineModel<Set<K>>('toggledItems');
22
11
 
23
12
  const props = withDefaults(
24
13
  defineProps<{
25
- getItemKey: (item: T, index: number) => K;
14
+ getItemKey?: (item: T, index: number) => K;
26
15
 
27
16
  itemClass?: string | string[] | ((item: T, index: number) => string | string[]);
28
- activeItems?: Set<K>;
17
+ isActive?: (item: T, index: number) => boolean;
29
18
 
30
- enableDragging?: boolean;
19
+ disableDragging?: boolean;
20
+ isDraggable?: (item: T, index: number) => boolean;
31
21
  onDragEnd?: (oldIndex: number, newIndex: number) => void | boolean;
32
22
  onSort?: (oldIndex: number, newIndex: number) => void | boolean;
33
23
 
34
- enableExpanding?: boolean;
35
- onExpand?: (item: T, index: number) => void | boolean;
36
-
37
- enableRemoving?: boolean;
24
+ disableRemoving?: boolean;
25
+ isRemovable?: (item: T, index: number) => boolean;
38
26
  onRemove?: (item: T, index: number) => void | boolean;
39
27
 
40
- enableToggling?: boolean;
41
- onToggle?: (item: T, index: number) => void | boolean;
28
+ disableExpanding?: boolean;
29
+ isExpandable?: (item: T, index: number) => boolean;
30
+ isExpanded?: (item: T, index: number) => boolean;
31
+ onExpand?: (item: T, index: number) => unknown;
32
+
33
+ disableToggling?: boolean;
34
+ isToggable?: (item: T, index: number) => boolean;
35
+ isToggled?: (item: T, index: number) => boolean;
36
+ onToggle?: (item: T, index: number) => unknown;
42
37
 
43
- enablePinning?: boolean;
38
+ disablePinning?: boolean;
39
+ isPinnable?: (item: T, index: number) => boolean;
40
+ isPinned?: (item: T, index: number) => boolean;
44
41
  onPin?: (item: T, index: number) => void | boolean;
45
42
  }>(), {
46
- itemClass: undefined,
47
- activeItems: undefined,
43
+ getItemKey: (item: T) => JSON.stringify(item) as K,
48
44
 
49
- enableDragging: undefined,
50
- enableRemoving: undefined,
51
- enableExpanding: undefined,
52
- enableToggling: undefined,
53
- enablePinning: undefined,
45
+ itemClass: undefined,
46
+ isActive: undefined,
54
47
 
48
+ disableDragging: undefined,
49
+ isDraggable: undefined,
55
50
  onDragEnd: undefined,
56
51
  onSort: undefined,
52
+
53
+ disableRemoving: undefined,
54
+ isRemovable: undefined,
57
55
  onRemove: undefined,
56
+
57
+ disableExpanding: undefined,
58
+ isExpandable: undefined,
59
+ isExpanded: undefined,
58
60
  onExpand: undefined,
61
+
62
+ disableToggling: undefined,
63
+ isToggable: undefined,
64
+ isToggled: undefined,
59
65
  onToggle: undefined,
66
+
67
+ disablePinning: undefined,
68
+ isPinnable: undefined,
69
+ isPinned: undefined,
60
70
  onPin: undefined,
61
71
  },
62
72
  );
@@ -71,30 +81,45 @@ const slots = defineSlots<{
71
81
  }>();
72
82
 
73
83
  const dndSortingEnabled = computed((): boolean => {
74
- return props.enableDragging !== false;
84
+ return props.disableDragging !== true;
75
85
  });
76
86
 
77
- const pinnedItemsRef = computed(() => itemsRef.value.filter(isPinned));
87
+ const pinnedItemsRef = computed(() => itemsRef.value.filter(isPinnedItem));
78
88
  const hasPinnedItems = computed(() => pinnedItemsRef.value.length > 0);
79
89
 
80
- const unpinnedItemsRef = computed(() => itemsRef.value.filter((item, index) => !isPinned(item, index)));
90
+ const unpinnedItemsRef = computed(() => itemsRef.value.filter((item, index) => !isPinnedItem(item, index)));
81
91
  const hasUnpinnedItems = computed(() => unpinnedItemsRef.value.length > 0);
82
92
 
83
93
  const domProjectionItemsRef = shallowRef<undefined | T[]>();
84
94
  const pinnedContainerRef = shallowRef<HTMLElement>();
85
95
  const unpinnedContainerRef = shallowRef<HTMLElement>();
86
96
 
97
+ // version fix problem with sync between data and rendered values
98
+ const getKey = (item: T, index: number) => {
99
+ return `${versionRef.value}-${props.getItemKey(item, index)}`;
100
+ };
101
+ const pinnedKeysRef = computed(() => pinnedItemsRef.value.map(getKey));
102
+ const unpinnedKeysRef = computed(() => unpinnedItemsRef.value.map(getKey));
103
+
87
104
  // version fix problem with sync between data and rendered values when items have been changed
88
105
  const versionRef = computed<number>((oldVersion) => {
89
- const currentVersion = shallowHash(...itemsRef.value.map(props.getItemKey));
106
+ const currentKeys = itemsRef.value.map(props.getItemKey);
90
107
 
91
- if (domProjectionItemsRef.value === undefined) return oldVersion ?? currentVersion;
108
+ if (domProjectionItemsRef.value === undefined) return oldVersion ?? shallowHash(...currentKeys);
109
+ if (currentKeys.length !== domProjectionItemsRef.value.length) return shallowHash(...currentKeys);
92
110
 
93
- const lastSortedVersion = shallowHash(...domProjectionItemsRef.value.map(props.getItemKey));
111
+ const domProjectionKeys = domProjectionItemsRef.value.map(props.getItemKey);
112
+ const domProjectionKeysSet = new Set(domProjectionKeys);
94
113
 
95
- if (currentVersion === lastSortedVersion) return oldVersion ?? currentVersion;
114
+ for (let i = 0; i < currentKeys.length; i++) {
115
+ const hasInconsistentPosition = domProjectionKeysSet.has(currentKeys[i]) && domProjectionKeys[i] !== currentKeys[i];
96
116
 
97
- return oldVersion !== currentVersion ? currentVersion : lastSortedVersion;
117
+ if (hasInconsistentPosition) {
118
+ return shallowHash(...currentKeys);
119
+ }
120
+ }
121
+
122
+ return oldVersion ?? shallowHash(...currentKeys);
98
123
  });
99
124
 
100
125
  createSortable(hasPinnedItems, pinnedContainerRef, pinnedItemsRef, () => 0);
@@ -117,7 +142,9 @@ function createSortable(toggler: ShallowRef<boolean>, elRef: ShallowRef<undefine
117
142
  }
118
143
  },
119
144
  });
120
- watch(toggler, (on) => on ? sortable.start() : sortable.stop());
145
+ watch([() => props.disableDragging, toggler], ([disabled, on]) => disabled || !on ? sortable.stop() : sortable.start(), {
146
+ immediate: true,
147
+ });
121
148
 
122
149
  return sortable;
123
150
  }
@@ -133,77 +160,56 @@ function moveItems(oldIndex: number, newIndex: number, afterUpdateDom: boolean)
133
160
 
134
161
  if (!preventDefault) {
135
162
  moveElements(itemsRef.value, oldIndex, newIndex);
136
- optionalUpdateRef(itemsRef);
137
163
  }
138
164
  }
139
165
 
140
- function isActive(item: T, index: number): boolean {
141
- const k = props.getItemKey(item, index);
142
- return props.activeItems?.has(k) ?? false;
166
+ function isActiveItem(item: T, index: number): boolean {
167
+ return props.isActive?.(item, index) ?? false;
143
168
  }
144
169
 
145
- function isDraggable(item: T, index: number): boolean {
146
- const k = props.getItemKey(item, index);
147
- if (props.enableDragging === false) return false;
148
- return (draggableSetRef.value?.has(k) ?? true);
170
+ function isDraggableItem(item: T, index: number): boolean {
171
+ if (props.disableDragging === true) return false;
172
+ return (props.isDraggable?.(item, index) ?? true);
149
173
  }
150
174
 
151
- function isToggable(item: T, index: number): boolean {
152
- const k = props.getItemKey(item, index);
153
- if (props.enableToggling === false) return false;
154
- return !isNil(toggledSetRef.value) && (toggableSetRef.value?.has(k) ?? true);
175
+ function isRemovableItem(item: T, index: number): boolean {
176
+ if (props.disableRemoving === true) return false;
177
+ return (props.isRemovable?.(item, index) ?? true);
155
178
  }
156
179
 
157
- function isToggled(item: T, index: number): boolean {
158
- const k = props.getItemKey(item, index);
159
- return toggledSetRef.value?.has(k) ?? false;
180
+ function isToggableItem(item: T, index: number): boolean {
181
+ if (props.disableToggling === true) return false;
182
+ return (props.isToggable?.(item, index) ?? (isFunction(props.isToggled) || isFunction(props.onToggle)));
160
183
  }
161
184
 
162
- function isPinnable(item: T, index: number): boolean {
163
- const k = props.getItemKey(item, index);
164
- if (props.enablePinning === false) return false;
165
- return !isNil(pinnedSetRef.value) && (pinnableSetRef.value?.has(k) ?? true);
185
+ function isToggledItem(item: T, index: number): boolean {
186
+ return props.isToggled?.(item, index) ?? false;
166
187
  }
167
188
 
168
- function isPinned(item: T, index: number): boolean {
169
- const k = props.getItemKey(item, index);
170
- return pinnedSetRef.value?.has(k) ?? false;
189
+ function isPinnableItem(item: T, index: number): boolean {
190
+ if (props.disablePinning === true) return false;
191
+ return (props.isPinnable?.(item, index) ?? (isFunction(props.isPinned) || isFunction(props.onPin)));
171
192
  }
172
193
 
173
- function isExpandable(item: T, index: number): boolean {
174
- const k = props.getItemKey(item, index);
175
- if (props.enableExpanding === false) return false;
176
- return !isNil(expandedSetRef.value) && (expandableSetRef.value?.has(k) ?? true);
194
+ function isPinnedItem(item: T, index: number): boolean {
195
+ return props.isPinned?.(item, index) ?? false;
177
196
  }
178
197
 
179
- function isExpanded(item: T, index: number): boolean {
180
- const k = props.getItemKey(item, index);
181
- return expandedSetRef.value?.has(k) ?? false;
198
+ function isExpandableItem(item: T, index: number): boolean {
199
+ if (props.disableExpanding === true) return false;
200
+ return (props.isExpandable?.(item, index) ?? (isFunction(props.isExpanded) || isFunction(props.onExpand)));
182
201
  }
183
202
 
184
- function isRemovable(item: T, index: number): boolean {
185
- const k = props.getItemKey(item, index);
186
- if (props.enableRemoving === false) return false;
187
- if (removableSetRef.value?.has(k) === false) return false;
188
- return props.enableRemoving === true || typeof props.onRemove === 'function';
203
+ function isExpandedItem(item: T, index: number): boolean {
204
+ return props.isExpanded?.(item, index) ?? false;
189
205
  }
190
206
 
191
207
  function handleExpand(item: T, index: number) {
192
- if (props.onExpand?.(item, index) === false || isNil(expandedSetRef.value)) return;
193
- const k = props.getItemKey(item, index);
194
- const expanded = expandedSetRef.value;
195
- if (expanded.has(k)) expanded.delete(k);
196
- else expanded.add(k);
197
- optionalUpdateRef(expandedSetRef);
208
+ props.onExpand?.(item, index);
198
209
  }
199
210
 
200
211
  function handleToggle(item: T, index: number) {
201
- if (props.onToggle?.(item, index) === false || isNil(toggledSetRef.value)) return;
202
- const k = props.getItemKey(item, index);
203
- const toggled = toggledSetRef.value;
204
- if (toggled.has(k)) toggled.delete(k);
205
- else toggled.add(k);
206
- optionalUpdateRef(toggledSetRef);
212
+ props.onToggle?.(item, index);
207
213
  }
208
214
 
209
215
  function handlePin(item: T, index: number) {
@@ -211,43 +217,18 @@ function handlePin(item: T, index: number) {
211
217
  throw new Error('Pinnable item not found');
212
218
  }
213
219
 
214
- if (props.onPin?.(item, index) === false || isNil(pinnedSetRef.value)) return;
220
+ const alreadyPinned = pinnedItemsRef.value.includes(item);
221
+
222
+ if (props.onPin?.(item, index) === false) return;
215
223
 
216
- const k = props.getItemKey(item, index);
217
- const pinned = pinnedSetRef.value;
218
- const alreadyPinned = pinned.has(k);
219
- if (alreadyPinned) pinned.delete(k);
220
- else pinned.add(k);
221
- optionalUpdateRef(pinnedSetRef);
222
- moveItems(index, pinned.size + (alreadyPinned ? 0 : -1), false);
224
+ moveItems(index, pinnedItemsRef.value.length + (alreadyPinned ? 0 : -1), false);
223
225
  }
224
226
 
225
227
  function handleRemove(item: T, index: number) {
226
- if (props.onRemove?.(item, index) !== false) {
227
- const k = props.getItemKey(item, index);
228
-
229
- itemsRef.value.splice(index, 1);
230
- optionalUpdateRef(itemsRef);
231
-
232
- if (pinnedSetRef.value?.has(k)) {
233
- pinnedSetRef.value.delete(k);
234
- optionalUpdateRef(pinnedSetRef);
235
- }
236
-
237
- if (toggledSetRef.value?.has(k)) {
238
- toggledSetRef.value.delete(k);
239
- optionalUpdateRef(toggledSetRef);
240
- }
241
- }
228
+ if (props.onRemove?.(item, index) === false) return;
229
+ itemsRef.value.splice(index, 1);
242
230
  }
243
231
 
244
- // version fix problem with sync between data and rendered values
245
- const getKey = (item: T, index: number) => {
246
- return `${versionRef.value}-${props.getItemKey(item, index)}`;
247
- };
248
- const pinnedKeysRef = computed(() => pinnedItemsRef.value.map(getKey));
249
- const unpinnedKeysRef = computed(() => unpinnedItemsRef.value.map(getKey));
250
-
251
232
  const getItemClass = (item: T, index: number): null | string | string[] => {
252
233
  if (typeof props.itemClass === 'function') {
253
234
  return props.itemClass(item, index);
@@ -267,15 +248,15 @@ const getItemClass = (item: T, index: number): null | string | string[] => {
267
248
  :index="pinnedIndex"
268
249
  :item="pinnedItem"
269
250
  :showDragHandle="dndSortingEnabled"
270
- :isActive="isActive(pinnedItem, pinnedIndex)"
271
- :isDraggable="isDraggable(pinnedItem, pinnedIndex)"
272
- :isRemovable="isRemovable(pinnedItem, pinnedIndex)"
273
- :isToggable="isToggable(pinnedItem, pinnedIndex)"
274
- :isToggled="isToggled(pinnedItem, pinnedIndex)"
275
- :isPinnable="isPinnable(pinnedItem, pinnedIndex)"
276
- :isPinned="isPinned(pinnedItem, pinnedIndex)"
277
- :isExpandable="isExpandable(pinnedItem, pinnedIndex)"
278
- :isExpanded="isExpanded(pinnedItem, pinnedIndex)"
251
+ :isActive="isActiveItem(pinnedItem, pinnedIndex)"
252
+ :isDraggable="isDraggableItem(pinnedItem, pinnedIndex)"
253
+ :isRemovable="isRemovableItem(pinnedItem, pinnedIndex)"
254
+ :isToggable="isToggableItem(pinnedItem, pinnedIndex)"
255
+ :isToggled="isToggledItem(pinnedItem, pinnedIndex)"
256
+ :isPinnable="isPinnableItem(pinnedItem, pinnedIndex)"
257
+ :isPinned="true"
258
+ :isExpandable="isExpandableItem(pinnedItem, pinnedIndex)"
259
+ :isExpanded="isExpandedItem(pinnedItem, pinnedIndex)"
279
260
 
280
261
  @click="emits('itemClick', pinnedItem)"
281
262
  @remove="handleRemove"
@@ -296,18 +277,18 @@ const getItemClass = (item: T, index: number): null | string | string[] => {
296
277
  v-for="(unpinnedItem, unpinnedIndex) in unpinnedItemsRef" :key="unpinnedKeysRef[unpinnedIndex]"
297
278
  :class="[$style.item, getItemClass(unpinnedItem, unpinnedIndex)]"
298
279
 
299
- :index="unpinnedIndex + (pinnedSetRef?.size ?? 0)"
280
+ :index="unpinnedIndex + (pinnedItemsRef?.length ?? 0)"
300
281
  :item="unpinnedItem"
301
282
  :showDragHandle="dndSortingEnabled"
302
- :isActive="isActive(unpinnedItem, unpinnedIndex)"
303
- :isDraggable="isDraggable(unpinnedItem, unpinnedIndex)"
304
- :isRemovable="isRemovable(unpinnedItem, unpinnedIndex)"
305
- :isToggable="isToggable(unpinnedItem, unpinnedIndex)"
306
- :isToggled="isToggled(unpinnedItem, unpinnedIndex)"
307
- :isPinnable="isPinnable(unpinnedItem, unpinnedIndex)"
308
- :isPinned="isPinned(unpinnedItem, unpinnedIndex)"
309
- :isExpandable="isExpandable(unpinnedItem, unpinnedIndex)"
310
- :isExpanded="isExpanded(unpinnedItem, unpinnedIndex)"
283
+ :isActive="isActiveItem(unpinnedItem, unpinnedIndex)"
284
+ :isDraggable="isDraggableItem(unpinnedItem, unpinnedIndex)"
285
+ :isRemovable="isRemovableItem(unpinnedItem, unpinnedIndex)"
286
+ :isToggable="isToggableItem(unpinnedItem, unpinnedIndex)"
287
+ :isToggled="isToggledItem(unpinnedItem, unpinnedIndex)"
288
+ :isPinnable="isPinnableItem(unpinnedItem, unpinnedIndex)"
289
+ :isPinned="false"
290
+ :isExpandable="isExpandableItem(unpinnedItem, unpinnedIndex)"
291
+ :isExpanded="isExpandedItem(unpinnedItem, unpinnedIndex)"
311
292
 
312
293
  @click="emits('itemClick', unpinnedItem)"
313
294
  @remove="handleRemove"
@@ -86,7 +86,10 @@ const emit = defineEmits<{
86
86
  </div>
87
87
  </div>
88
88
  </div>
89
- <div v-if="hasContentSlot && props.isExpanded" :class="$style.body">
89
+ <div
90
+ v-if="hasContentSlot && props.isExpanded"
91
+ :class="[$style.body, { [$style.disabled]: props.isToggled }]"
92
+ >
90
93
  <slot name="content" :item="props.item" :index="props.index" />
91
94
  </div>
92
95
  </div>
@@ -144,6 +147,7 @@ const emit = defineEmits<{
144
147
  display: flex;
145
148
  align-items: center;
146
149
  padding: 8px;
150
+ min-height: 40px;
147
151
  border-radius: var(--border-radius) var(--border-radius) 0 0;
148
152
  background: var(--head-background);
149
153
 
@@ -180,6 +184,10 @@ const emit = defineEmits<{
180
184
  gap: 12px;
181
185
  padding: 24px;
182
186
  border-radius: 0 0 var(--border-radius) var(--border-radius);
187
+
188
+ &.disabled {
189
+ pointer-events: none;
190
+ }
183
191
  }
184
192
 
185
193
  .actions {