@citolab/qti-components 7.6.0 → 7.8.1

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.
@@ -6255,6 +6255,24 @@
6255
6255
  }
6256
6256
  ]
6257
6257
  },
6258
+ {
6259
+ "kind": "method",
6260
+ "name": "getDropzoneRect",
6261
+ "privacy": "private",
6262
+ "return": {
6263
+ "type": {
6264
+ "text": "DOMRect"
6265
+ }
6266
+ },
6267
+ "parameters": [
6268
+ {
6269
+ "name": "el",
6270
+ "type": {
6271
+ "text": "HTMLElement"
6272
+ }
6273
+ }
6274
+ ]
6275
+ },
6258
6276
  {
6259
6277
  "kind": "method",
6260
6278
  "name": "findClosestDropzone",
@@ -7094,6 +7112,24 @@
7094
7112
  }
7095
7113
  ]
7096
7114
  },
7115
+ {
7116
+ "kind": "method",
7117
+ "name": "getDropzoneRect",
7118
+ "privacy": "private",
7119
+ "return": {
7120
+ "type": {
7121
+ "text": "DOMRect"
7122
+ }
7123
+ },
7124
+ "parameters": [
7125
+ {
7126
+ "name": "el",
7127
+ "type": {
7128
+ "text": "HTMLElement"
7129
+ }
7130
+ }
7131
+ ]
7132
+ },
7097
7133
  {
7098
7134
  "kind": "method",
7099
7135
  "name": "findClosestDropzone",
@@ -8798,6 +8834,28 @@
8798
8834
  "module": "src/lib/qti-components/qti-interaction/internal/drag-drop/drag-drop-interaction-mixin.ts"
8799
8835
  }
8800
8836
  },
8837
+ {
8838
+ "kind": "method",
8839
+ "name": "getDropzoneRect",
8840
+ "privacy": "private",
8841
+ "return": {
8842
+ "type": {
8843
+ "text": "DOMRect"
8844
+ }
8845
+ },
8846
+ "parameters": [
8847
+ {
8848
+ "name": "el",
8849
+ "type": {
8850
+ "text": "HTMLElement"
8851
+ }
8852
+ }
8853
+ ],
8854
+ "inheritedFrom": {
8855
+ "name": "DragDropInteractionMixin",
8856
+ "module": "src/lib/qti-components/qti-interaction/internal/drag-drop/drag-drop-interaction-mixin.ts"
8857
+ }
8858
+ },
8801
8859
  {
8802
8860
  "kind": "method",
8803
8861
  "name": "findClosestDropzone",
@@ -11898,6 +11956,28 @@
11898
11956
  "module": "src/lib/qti-components/qti-interaction/internal/drag-drop/drag-drop-interaction-mixin.ts"
11899
11957
  }
11900
11958
  },
11959
+ {
11960
+ "kind": "method",
11961
+ "name": "getDropzoneRect",
11962
+ "privacy": "private",
11963
+ "return": {
11964
+ "type": {
11965
+ "text": "DOMRect"
11966
+ }
11967
+ },
11968
+ "parameters": [
11969
+ {
11970
+ "name": "el",
11971
+ "type": {
11972
+ "text": "HTMLElement"
11973
+ }
11974
+ }
11975
+ ],
11976
+ "inheritedFrom": {
11977
+ "name": "DragDropInteractionMixin",
11978
+ "module": "src/lib/qti-components/qti-interaction/internal/drag-drop/drag-drop-interaction-mixin.ts"
11979
+ }
11980
+ },
11901
11981
  {
11902
11982
  "kind": "method",
11903
11983
  "name": "findClosestDropzone",
@@ -13908,6 +13988,28 @@
13908
13988
  "module": "src/lib/qti-components/qti-interaction/internal/drag-drop/drag-drop-interaction-mixin.ts"
13909
13989
  }
13910
13990
  },
13991
+ {
13992
+ "kind": "method",
13993
+ "name": "getDropzoneRect",
13994
+ "privacy": "private",
13995
+ "return": {
13996
+ "type": {
13997
+ "text": "DOMRect"
13998
+ }
13999
+ },
14000
+ "parameters": [
14001
+ {
14002
+ "name": "el",
14003
+ "type": {
14004
+ "text": "HTMLElement"
14005
+ }
14006
+ }
14007
+ ],
14008
+ "inheritedFrom": {
14009
+ "name": "DragDropInteractionMixin",
14010
+ "module": "src/lib/qti-components/qti-interaction/internal/drag-drop/drag-drop-interaction-mixin.ts"
14011
+ }
14012
+ },
13911
14013
  {
13912
14014
  "kind": "method",
13913
14015
  "name": "findClosestDropzone",
@@ -17147,6 +17249,28 @@
17147
17249
  "module": "src/lib/qti-components/qti-interaction/internal/drag-drop/drag-drop-interaction-mixin.ts"
17148
17250
  }
17149
17251
  },
17252
+ {
17253
+ "kind": "method",
17254
+ "name": "getDropzoneRect",
17255
+ "privacy": "private",
17256
+ "return": {
17257
+ "type": {
17258
+ "text": "DOMRect"
17259
+ }
17260
+ },
17261
+ "parameters": [
17262
+ {
17263
+ "name": "el",
17264
+ "type": {
17265
+ "text": "HTMLElement"
17266
+ }
17267
+ }
17268
+ ],
17269
+ "inheritedFrom": {
17270
+ "name": "DragDropInteractionMixin",
17271
+ "module": "src/lib/qti-components/qti-interaction/internal/drag-drop/drag-drop-interaction-mixin.ts"
17272
+ }
17273
+ },
17150
17274
  {
17151
17275
  "kind": "method",
17152
17276
  "name": "findClosestDropzone",
@@ -18534,6 +18658,28 @@
18534
18658
  "module": "src/lib/qti-components/qti-interaction/internal/drag-drop/drag-drop-interaction-mixin.ts"
18535
18659
  }
18536
18660
  },
18661
+ {
18662
+ "kind": "method",
18663
+ "name": "getDropzoneRect",
18664
+ "privacy": "private",
18665
+ "return": {
18666
+ "type": {
18667
+ "text": "DOMRect"
18668
+ }
18669
+ },
18670
+ "parameters": [
18671
+ {
18672
+ "name": "el",
18673
+ "type": {
18674
+ "text": "HTMLElement"
18675
+ }
18676
+ }
18677
+ ],
18678
+ "inheritedFrom": {
18679
+ "name": "DragDropInteractionMixin",
18680
+ "module": "src/lib/qti-components/qti-interaction/internal/drag-drop/drag-drop-interaction-mixin.ts"
18681
+ }
18682
+ },
18537
18683
  {
18538
18684
  "kind": "method",
18539
18685
  "name": "findClosestDropzone",
@@ -28537,6 +28683,14 @@
28537
28683
  }
28538
28684
  }
28539
28685
  ],
28686
+ "events": [
28687
+ {
28688
+ "name": "qti-stamp-context-updated",
28689
+ "type": {
28690
+ "text": "CustomEvent"
28691
+ }
28692
+ }
28693
+ ],
28540
28694
  "attributes": [
28541
28695
  {
28542
28696
  "name": "debug",
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  item_default
3
- } from "./chunk-LSEB52SP.js";
3
+ } from "./chunk-PT5ASWGQ.js";
4
4
  import {
5
5
  watch
6
6
  } from "./chunk-ELDMXTUQ.js";
@@ -362,4 +362,4 @@ export {
362
362
  ItemShowCorrectResponse,
363
363
  QtiItem
364
364
  };
365
- //# sourceMappingURL=chunk-GG4NR5OR.js.map
365
+ //# sourceMappingURL=chunk-4QSZJYSB.js.map
@@ -3,7 +3,7 @@ import {
3
3
  convertNumberToUniversalFormat,
4
4
  liveQuery,
5
5
  removeDoubleSlashes
6
- } from "./chunk-2WTHXWS3.js";
6
+ } from "./chunk-YD7FVKDP.js";
7
7
  import {
8
8
  watch
9
9
  } from "./chunk-ELDMXTUQ.js";
@@ -744,6 +744,9 @@ var DragDropInteractionMixin = (superClass, draggablesSelector, droppablesSelect
744
744
  // Last touch target
745
745
  this.currentDropTarget = null;
746
746
  // Current droppable element
747
+ this.onMove = this.handleTouchMove.bind(this);
748
+ this.onEnd = this.handleTouchEnd.bind(this);
749
+ this.onCancel = this.handleTouchCancel.bind(this);
747
750
  this.MIN_DRAG_DISTANCE = 5;
748
751
  // Minimum pixel movement to start dragging
749
752
  this.DRAG_CLONE_OPACITY = 1;
@@ -852,11 +855,11 @@ var DragDropInteractionMixin = (superClass, draggablesSelector, droppablesSelect
852
855
  if (this.isMatchTabular()) return;
853
856
  const disabled = this.hasAttribute("disabled");
854
857
  if (!disabled) {
855
- document.addEventListener("touchmove", this.handleTouchMove.bind(this), { passive: false });
856
- document.addEventListener("mousemove", this.handleTouchMove.bind(this), { passive: false });
857
- document.addEventListener("touchend", this.handleTouchEnd.bind(this), { passive: false });
858
- document.addEventListener("mouseup", this.handleTouchEnd.bind(this), { passive: false });
859
- document.addEventListener("touchcancel", this.handleTouchCancel.bind(this), { passive: false });
858
+ document.addEventListener("mousemove", this.onMove, { passive: false });
859
+ document.addEventListener("mouseup", this.onEnd, { passive: false });
860
+ document.addEventListener("touchmove", this.onMove, { passive: false });
861
+ document.addEventListener("touchend", this.onEnd, { passive: false });
862
+ document.addEventListener("touchcancel", this.onCancel, { passive: false });
860
863
  }
861
864
  const draggables = Array.from(this.querySelectorAll(draggablesSelector) || []).concat(
862
865
  Array.from(this.shadowRoot?.querySelectorAll(draggablesSelector) || [])
@@ -995,11 +998,11 @@ var DragDropInteractionMixin = (superClass, draggablesSelector, droppablesSelect
995
998
  this.resizeObserver.disconnect();
996
999
  this.resizeObserver = null;
997
1000
  }
998
- document.removeEventListener("touchmove", this.handleTouchMove);
999
- document.removeEventListener("mousemove", this.handleTouchMove);
1000
- document.removeEventListener("touchend", this.handleTouchEnd);
1001
- document.removeEventListener("mouseup", this.handleTouchEnd);
1002
- document.removeEventListener("touchcancel", this.handleTouchCancel);
1001
+ document.removeEventListener("mousemove", this.onMove);
1002
+ document.removeEventListener("mouseup", this.onEnd);
1003
+ document.removeEventListener("touchmove", this.onMove);
1004
+ document.removeEventListener("touchend", this.onEnd);
1005
+ document.removeEventListener("touchcancel", this.onCancel);
1003
1006
  }
1004
1007
  handleTouchMove(e) {
1005
1008
  if (this.isMatchTabular()) return;
@@ -1031,7 +1034,7 @@ var DragDropInteractionMixin = (superClass, draggablesSelector, droppablesSelect
1031
1034
  }
1032
1035
  handleTouchEnd(e) {
1033
1036
  if (this.isMatchTabular()) return;
1034
- if (this.isDragging) {
1037
+ if (this.isDragging || this.isDraggable || this.dragClone) {
1035
1038
  this.resetDragState();
1036
1039
  }
1037
1040
  this._internals.states.delete("--dragzone-active");
@@ -1285,30 +1288,38 @@ var DragDropInteractionMixin = (superClass, draggablesSelector, droppablesSelect
1285
1288
  const yDist = Math.abs(touch.clientY - this.touchStartPoint.y);
1286
1289
  return xDist + yDist;
1287
1290
  }
1291
+ getDropzoneRect(el) {
1292
+ const slot = el.shadowRoot?.querySelector('slot[part="dropslot"]');
1293
+ return (slot ?? el).getBoundingClientRect();
1294
+ }
1288
1295
  findClosestDropzone() {
1289
- const allActiveDropzones = this.allDropzones.filter((d) => !d.hasAttribute("disabled"));
1290
- if (!this.dragClone || allActiveDropzones.length === 0) return null;
1296
+ const activeDrops = this.allDropzones.filter((d) => !d.hasAttribute("disabled"));
1297
+ if (!this.dragClone || activeDrops.length === 0) return null;
1291
1298
  const dragRect = this.dragClone.getBoundingClientRect();
1292
1299
  let closestDropzone = null;
1293
- let maxOverlapArea = 0;
1294
- for (const dropzone of allActiveDropzones) {
1295
- const dropRect = dropzone.getBoundingClientRect();
1296
- const overlapArea = this.calculateOverlapArea(dragRect, dropRect);
1297
- if (overlapArea > maxOverlapArea) {
1298
- maxOverlapArea = overlapArea;
1299
- closestDropzone = dropzone;
1300
+ let maxArea = 0;
1301
+ const prefer = (elements) => {
1302
+ for (const dz of elements) {
1303
+ const dzRect = this.getDropzoneRect(dz);
1304
+ const area = this.calculateOverlapArea(dragRect, dzRect);
1305
+ if (area > maxArea) {
1306
+ maxArea = area;
1307
+ closestDropzone = dz;
1308
+ }
1300
1309
  }
1310
+ };
1311
+ prefer(this.droppables.filter((droppable) => !droppable.hasAttribute("disabled")));
1312
+ if (!closestDropzone) {
1313
+ prefer(this.dragContainers.filter((drags) => !drags.hasAttribute("disabled")));
1301
1314
  }
1302
1315
  if (!closestDropzone) {
1303
- let minDistance = 200;
1304
- for (const dropzone of allActiveDropzones) {
1305
- const dropRect = dropzone.getBoundingClientRect();
1306
- const distance = Math.sqrt(
1307
- Math.pow(dragRect.left - dropRect.left, 2) + Math.pow(dragRect.top - dropRect.top, 2)
1308
- );
1309
- if (distance < minDistance) {
1310
- minDistance = distance;
1311
- closestDropzone = dropzone;
1316
+ let minDist = Number.POSITIVE_INFINITY;
1317
+ for (const dz of activeDrops) {
1318
+ const dzRect = this.getDropzoneRect(dz);
1319
+ const dist = Math.hypot(dragRect.left - dzRect.left, dragRect.top - dzRect.top);
1320
+ if (dist < minDist) {
1321
+ minDist = dist;
1322
+ closestDropzone = dz;
1312
1323
  }
1313
1324
  }
1314
1325
  }
@@ -1453,6 +1464,15 @@ var qti_associate_interaction_styles_default = css4`
1453
1464
  gap: 0.5rem;
1454
1465
  }
1455
1466
 
1467
+ [part='drop-list'][active] {
1468
+ border-color: var(--qti-border-active) !important;
1469
+ background-color: var(--qti-bg-active) !important;
1470
+ }
1471
+
1472
+ [part='drop-list'][enabled] {
1473
+ background-color: var(--qti-bg-active) !important;
1474
+ }
1475
+
1456
1476
  :host::part(associables-container) {
1457
1477
  display: flex;
1458
1478
  padding: 0.5rem;
@@ -3142,11 +3162,13 @@ import { css as css15 } from "lit";
3142
3162
  var qti_hotspot_interaction_styles_default = css15`
3143
3163
  slot:not([name='prompt']) {
3144
3164
  position: relative; /* qti-hotspot-choice relative to the slot */
3145
- display: block;
3165
+ display: inline-block;
3146
3166
  width: fit-content; /* hotspots not stretching further if image is at max size */
3167
+ line-height: 0; /* remove gaps below image */
3147
3168
  }
3148
3169
  ::slotted(img) {
3149
3170
  /* image not selectable anymore */
3171
+ display: block;
3150
3172
  pointer-events: none;
3151
3173
  user-select: none;
3152
3174
  /* width:100%; */
@@ -3155,19 +3177,40 @@ var qti_hotspot_interaction_styles_default = css15`
3155
3177
 
3156
3178
  // src/lib/qti-components/qti-interaction/qti-hotspot-interaction/qti-hotspot-interaction.ts
3157
3179
  var QtiHotspotInteraction = class extends ChoicesMixin(Interaction, "qti-hotspot-choice") {
3180
+ constructor() {
3181
+ super(...arguments);
3182
+ this.imageLoadPromise = null;
3183
+ }
3158
3184
  render() {
3159
3185
  return html18`
3160
3186
  <slot name="prompt"></slot>
3161
3187
  <slot></slot>
3162
3188
  `;
3163
3189
  }
3164
- positionHotspotOnRegister(e) {
3190
+ getImageLoadPromise(img) {
3191
+ if (!this.imageLoadPromise) {
3192
+ if (img.naturalWidth > 0 && img.naturalHeight > 0) {
3193
+ this.imageLoadPromise = Promise.resolve(img);
3194
+ } else {
3195
+ this.imageLoadPromise = new Promise((resolve) => {
3196
+ const handler = () => {
3197
+ img.removeEventListener("load", handler);
3198
+ resolve(img);
3199
+ };
3200
+ img.addEventListener("load", handler);
3201
+ });
3202
+ }
3203
+ }
3204
+ return this.imageLoadPromise;
3205
+ }
3206
+ async positionHotspotOnRegister(e) {
3165
3207
  const img = this.querySelector("img");
3166
3208
  const hotspot = e.target;
3167
3209
  const coords = hotspot.getAttribute("coords");
3168
3210
  const shape = hotspot.getAttribute("shape");
3169
3211
  const coordsNumber = coords.split(",").map((s) => parseInt(s));
3170
- positionShapes(shape, coordsNumber, img, hotspot);
3212
+ const loadedImg = await this.getImageLoadPromise(img);
3213
+ positionShapes(shape, coordsNumber, loadedImg, hotspot);
3171
3214
  }
3172
3215
  connectedCallback() {
3173
3216
  super.connectedCallback();
@@ -3882,6 +3925,15 @@ var qti_order_interaction_styles_default = css22`
3882
3925
  flex: 1;
3883
3926
  }
3884
3927
 
3928
+ [part='drop-list'][active] {
3929
+ border-color: var(--qti-border-active) !important;
3930
+ background-color: var(--qti-bg-active) !important;
3931
+ }
3932
+
3933
+ [part='drop-list'][enabled] {
3934
+ background-color: var(--qti-bg-active) !important;
3935
+ }
3936
+
3885
3937
  [part='container'] {
3886
3938
  display: flex;
3887
3939
  gap: 0.5rem;
@@ -8761,4 +8813,4 @@ export {
8761
8813
  QtiOutcomeDeclaration,
8762
8814
  QtiResponseDeclaration
8763
8815
  };
8764
- //# sourceMappingURL=chunk-G7ZPPP7O.js.map
8816
+ //# sourceMappingURL=chunk-7YO5JFT3.js.map