svelte-dnd-action 0.9.66 → 0.9.67
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/index.js +66 -27
- package/dist/index.mjs +66 -27
- package/package.json +1 -1
- package/src/helpers/intersection.js +69 -27
package/dist/index.js
CHANGED
|
@@ -509,52 +509,91 @@
|
|
|
509
509
|
var rect = getAbsoluteRect(el);
|
|
510
510
|
return rect.right < 0 || rect.left > document.documentElement.scrollWidth || rect.bottom < 0 || rect.top > document.documentElement.scrollHeight;
|
|
511
511
|
}
|
|
512
|
+
|
|
513
|
+
/**
|
|
514
|
+
* Computes the portion of an element that is actually visible inside its scrollable
|
|
515
|
+
* ancestor containers. If the element is clipped by any scrollable ancestor (overflow: auto|scroll),
|
|
516
|
+
* the returned rect is the clipped one. If it is not clipped by any scrollable ancestor but is
|
|
517
|
+
* partially or fully outside the viewport, the function returns the element's full bounding rect
|
|
518
|
+
* (i.e. it does NOT clip to the viewport).
|
|
519
|
+
*
|
|
520
|
+
* This is useful for distinguishing "hidden because parent scrolls" from
|
|
521
|
+
* "hidden because off-screen".
|
|
522
|
+
*
|
|
523
|
+
* @param {HTMLElement} element - The DOM element to measure.
|
|
524
|
+
* @returns {{top: number, bottom: number, left: number, right: number, width: number, height: number}}
|
|
525
|
+
* An object describing the visible rectangle in viewport coordinates.
|
|
526
|
+
*/
|
|
512
527
|
function getVisibleRectRecursive(element) {
|
|
528
|
+
// original rect of the element (can be off-screen)
|
|
513
529
|
var rect = element.getBoundingClientRect();
|
|
530
|
+
|
|
531
|
+
// this will be our "clipped by scroll containers" rect
|
|
514
532
|
var visibleRect = {
|
|
515
533
|
top: rect.top,
|
|
516
534
|
bottom: rect.bottom,
|
|
517
535
|
left: rect.left,
|
|
518
536
|
right: rect.right
|
|
519
537
|
};
|
|
538
|
+
var wasClippedByScrollY = false;
|
|
539
|
+
var wasClippedByScrollX = false;
|
|
520
540
|
|
|
521
|
-
//
|
|
541
|
+
// walk up and clip ONLY by scrollable ancestors
|
|
522
542
|
var parent = element.parentElement;
|
|
523
543
|
while (parent && parent !== document.body) {
|
|
524
|
-
var
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
var overflowY = window.getComputedStyle(parent).overflowY;
|
|
528
|
-
var overflowX = window.getComputedStyle(parent).overflowX;
|
|
544
|
+
var style = window.getComputedStyle(parent);
|
|
545
|
+
var overflowY = style.overflowY;
|
|
546
|
+
var overflowX = style.overflowX;
|
|
529
547
|
var isScrollableY = overflowY === "scroll" || overflowY === "auto";
|
|
530
548
|
var isScrollableX = overflowX === "scroll" || overflowX === "auto";
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
549
|
+
if (isScrollableY || isScrollableX) {
|
|
550
|
+
var parentRect = parent.getBoundingClientRect();
|
|
551
|
+
if (isScrollableY) {
|
|
552
|
+
// if we actually shrink, mark it
|
|
553
|
+
var newTop = Math.max(visibleRect.top, parentRect.top);
|
|
554
|
+
var newBottom = Math.min(visibleRect.bottom, parentRect.bottom);
|
|
555
|
+
if (newTop !== visibleRect.top || newBottom !== visibleRect.bottom) {
|
|
556
|
+
wasClippedByScrollY = true;
|
|
557
|
+
}
|
|
558
|
+
visibleRect.top = newTop;
|
|
559
|
+
visibleRect.bottom = newBottom;
|
|
560
|
+
}
|
|
561
|
+
if (isScrollableX) {
|
|
562
|
+
var newLeft = Math.max(visibleRect.left, parentRect.left);
|
|
563
|
+
var newRight = Math.min(visibleRect.right, parentRect.right);
|
|
564
|
+
if (newLeft !== visibleRect.left || newRight !== visibleRect.right) {
|
|
565
|
+
wasClippedByScrollX = true;
|
|
566
|
+
}
|
|
567
|
+
visibleRect.left = newLeft;
|
|
568
|
+
visibleRect.right = newRight;
|
|
569
|
+
}
|
|
540
570
|
}
|
|
541
571
|
parent = parent.parentElement;
|
|
542
572
|
}
|
|
543
573
|
|
|
544
|
-
//
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
574
|
+
// CASE 1: element was clipped by a scrollable container
|
|
575
|
+
// → return the clipped rect (this is your 500px content inside 250px scroller case)
|
|
576
|
+
if (wasClippedByScrollY || wasClippedByScrollX) {
|
|
577
|
+
return {
|
|
578
|
+
top: visibleRect.top,
|
|
579
|
+
bottom: visibleRect.bottom,
|
|
580
|
+
left: visibleRect.left,
|
|
581
|
+
right: visibleRect.right,
|
|
582
|
+
width: Math.max(0, visibleRect.right - visibleRect.left),
|
|
583
|
+
height: Math.max(0, visibleRect.bottom - visibleRect.top)
|
|
584
|
+
};
|
|
585
|
+
}
|
|
549
586
|
|
|
550
|
-
//
|
|
587
|
+
// CASE 2: not clipped by scroll containers
|
|
588
|
+
// → we want the element’s FULL rect, even if it’s off-screen
|
|
589
|
+
// i.e. do NOT clip to viewport
|
|
551
590
|
return {
|
|
552
|
-
top:
|
|
553
|
-
bottom:
|
|
554
|
-
left:
|
|
555
|
-
right:
|
|
556
|
-
width: Math.max(0,
|
|
557
|
-
height: Math.max(0,
|
|
591
|
+
top: rect.top,
|
|
592
|
+
bottom: rect.bottom,
|
|
593
|
+
left: rect.left,
|
|
594
|
+
right: rect.right,
|
|
595
|
+
width: Math.max(0, rect.right - rect.left),
|
|
596
|
+
height: Math.max(0, rect.bottom - rect.top)
|
|
558
597
|
};
|
|
559
598
|
}
|
|
560
599
|
|
package/dist/index.mjs
CHANGED
|
@@ -503,52 +503,91 @@ function isElementOffDocument(el) {
|
|
|
503
503
|
var rect = getAbsoluteRect(el);
|
|
504
504
|
return rect.right < 0 || rect.left > document.documentElement.scrollWidth || rect.bottom < 0 || rect.top > document.documentElement.scrollHeight;
|
|
505
505
|
}
|
|
506
|
+
|
|
507
|
+
/**
|
|
508
|
+
* Computes the portion of an element that is actually visible inside its scrollable
|
|
509
|
+
* ancestor containers. If the element is clipped by any scrollable ancestor (overflow: auto|scroll),
|
|
510
|
+
* the returned rect is the clipped one. If it is not clipped by any scrollable ancestor but is
|
|
511
|
+
* partially or fully outside the viewport, the function returns the element's full bounding rect
|
|
512
|
+
* (i.e. it does NOT clip to the viewport).
|
|
513
|
+
*
|
|
514
|
+
* This is useful for distinguishing "hidden because parent scrolls" from
|
|
515
|
+
* "hidden because off-screen".
|
|
516
|
+
*
|
|
517
|
+
* @param {HTMLElement} element - The DOM element to measure.
|
|
518
|
+
* @returns {{top: number, bottom: number, left: number, right: number, width: number, height: number}}
|
|
519
|
+
* An object describing the visible rectangle in viewport coordinates.
|
|
520
|
+
*/
|
|
506
521
|
function getVisibleRectRecursive(element) {
|
|
522
|
+
// original rect of the element (can be off-screen)
|
|
507
523
|
var rect = element.getBoundingClientRect();
|
|
524
|
+
|
|
525
|
+
// this will be our "clipped by scroll containers" rect
|
|
508
526
|
var visibleRect = {
|
|
509
527
|
top: rect.top,
|
|
510
528
|
bottom: rect.bottom,
|
|
511
529
|
left: rect.left,
|
|
512
530
|
right: rect.right
|
|
513
531
|
};
|
|
532
|
+
var wasClippedByScrollY = false;
|
|
533
|
+
var wasClippedByScrollX = false;
|
|
514
534
|
|
|
515
|
-
//
|
|
535
|
+
// walk up and clip ONLY by scrollable ancestors
|
|
516
536
|
var parent = element.parentElement;
|
|
517
537
|
while (parent && parent !== document.body) {
|
|
518
|
-
var
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
var overflowY = window.getComputedStyle(parent).overflowY;
|
|
522
|
-
var overflowX = window.getComputedStyle(parent).overflowX;
|
|
538
|
+
var style = window.getComputedStyle(parent);
|
|
539
|
+
var overflowY = style.overflowY;
|
|
540
|
+
var overflowX = style.overflowX;
|
|
523
541
|
var isScrollableY = overflowY === "scroll" || overflowY === "auto";
|
|
524
542
|
var isScrollableX = overflowX === "scroll" || overflowX === "auto";
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
543
|
+
if (isScrollableY || isScrollableX) {
|
|
544
|
+
var parentRect = parent.getBoundingClientRect();
|
|
545
|
+
if (isScrollableY) {
|
|
546
|
+
// if we actually shrink, mark it
|
|
547
|
+
var newTop = Math.max(visibleRect.top, parentRect.top);
|
|
548
|
+
var newBottom = Math.min(visibleRect.bottom, parentRect.bottom);
|
|
549
|
+
if (newTop !== visibleRect.top || newBottom !== visibleRect.bottom) {
|
|
550
|
+
wasClippedByScrollY = true;
|
|
551
|
+
}
|
|
552
|
+
visibleRect.top = newTop;
|
|
553
|
+
visibleRect.bottom = newBottom;
|
|
554
|
+
}
|
|
555
|
+
if (isScrollableX) {
|
|
556
|
+
var newLeft = Math.max(visibleRect.left, parentRect.left);
|
|
557
|
+
var newRight = Math.min(visibleRect.right, parentRect.right);
|
|
558
|
+
if (newLeft !== visibleRect.left || newRight !== visibleRect.right) {
|
|
559
|
+
wasClippedByScrollX = true;
|
|
560
|
+
}
|
|
561
|
+
visibleRect.left = newLeft;
|
|
562
|
+
visibleRect.right = newRight;
|
|
563
|
+
}
|
|
534
564
|
}
|
|
535
565
|
parent = parent.parentElement;
|
|
536
566
|
}
|
|
537
567
|
|
|
538
|
-
//
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
568
|
+
// CASE 1: element was clipped by a scrollable container
|
|
569
|
+
// → return the clipped rect (this is your 500px content inside 250px scroller case)
|
|
570
|
+
if (wasClippedByScrollY || wasClippedByScrollX) {
|
|
571
|
+
return {
|
|
572
|
+
top: visibleRect.top,
|
|
573
|
+
bottom: visibleRect.bottom,
|
|
574
|
+
left: visibleRect.left,
|
|
575
|
+
right: visibleRect.right,
|
|
576
|
+
width: Math.max(0, visibleRect.right - visibleRect.left),
|
|
577
|
+
height: Math.max(0, visibleRect.bottom - visibleRect.top)
|
|
578
|
+
};
|
|
579
|
+
}
|
|
543
580
|
|
|
544
|
-
//
|
|
581
|
+
// CASE 2: not clipped by scroll containers
|
|
582
|
+
// → we want the element’s FULL rect, even if it’s off-screen
|
|
583
|
+
// i.e. do NOT clip to viewport
|
|
545
584
|
return {
|
|
546
|
-
top:
|
|
547
|
-
bottom:
|
|
548
|
-
left:
|
|
549
|
-
right:
|
|
550
|
-
width: Math.max(0,
|
|
551
|
-
height: Math.max(0,
|
|
585
|
+
top: rect.top,
|
|
586
|
+
bottom: rect.bottom,
|
|
587
|
+
left: rect.left,
|
|
588
|
+
right: rect.right,
|
|
589
|
+
width: Math.max(0, rect.right - rect.left),
|
|
590
|
+
height: Math.max(0, rect.bottom - rect.top)
|
|
552
591
|
};
|
|
553
592
|
}
|
|
554
593
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "svelte-dnd-action",
|
|
3
3
|
"description": "*An awesome drag and drop library for Svelte 3 and 4 (not using the browser's built-in dnd, thanks god): Rich animations, nested containers, touch support and more *",
|
|
4
|
-
"version": "0.9.
|
|
4
|
+
"version": "0.9.67",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
7
|
"url": "git+https://github.com/isaacHagoel/svelte-dnd-action.git"
|
|
@@ -158,8 +158,25 @@ export function isElementOffDocument(el) {
|
|
|
158
158
|
return rect.right < 0 || rect.left > document.documentElement.scrollWidth || rect.bottom < 0 || rect.top > document.documentElement.scrollHeight;
|
|
159
159
|
}
|
|
160
160
|
|
|
161
|
+
/**
|
|
162
|
+
* Computes the portion of an element that is actually visible inside its scrollable
|
|
163
|
+
* ancestor containers. If the element is clipped by any scrollable ancestor (overflow: auto|scroll),
|
|
164
|
+
* the returned rect is the clipped one. If it is not clipped by any scrollable ancestor but is
|
|
165
|
+
* partially or fully outside the viewport, the function returns the element's full bounding rect
|
|
166
|
+
* (i.e. it does NOT clip to the viewport).
|
|
167
|
+
*
|
|
168
|
+
* This is useful for distinguishing "hidden because parent scrolls" from
|
|
169
|
+
* "hidden because off-screen".
|
|
170
|
+
*
|
|
171
|
+
* @param {HTMLElement} element - The DOM element to measure.
|
|
172
|
+
* @returns {{top: number, bottom: number, left: number, right: number, width: number, height: number}}
|
|
173
|
+
* An object describing the visible rectangle in viewport coordinates.
|
|
174
|
+
*/
|
|
161
175
|
function getVisibleRectRecursive(element) {
|
|
162
|
-
|
|
176
|
+
// original rect of the element (can be off-screen)
|
|
177
|
+
const rect = element.getBoundingClientRect();
|
|
178
|
+
|
|
179
|
+
// this will be our "clipped by scroll containers" rect
|
|
163
180
|
let visibleRect = {
|
|
164
181
|
top: rect.top,
|
|
165
182
|
bottom: rect.bottom,
|
|
@@ -167,43 +184,68 @@ function getVisibleRectRecursive(element) {
|
|
|
167
184
|
right: rect.right
|
|
168
185
|
};
|
|
169
186
|
|
|
170
|
-
|
|
187
|
+
let wasClippedByScrollY = false;
|
|
188
|
+
let wasClippedByScrollX = false;
|
|
189
|
+
|
|
190
|
+
// walk up and clip ONLY by scrollable ancestors
|
|
171
191
|
let parent = element.parentElement;
|
|
172
192
|
while (parent && parent !== document.body) {
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
const overflowY = window.getComputedStyle(parent).overflowY;
|
|
177
|
-
const overflowX = window.getComputedStyle(parent).overflowX;
|
|
193
|
+
const style = window.getComputedStyle(parent);
|
|
194
|
+
const overflowY = style.overflowY;
|
|
195
|
+
const overflowX = style.overflowX;
|
|
178
196
|
const isScrollableY = overflowY === "scroll" || overflowY === "auto";
|
|
179
197
|
const isScrollableX = overflowX === "scroll" || overflowX === "auto";
|
|
180
198
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
199
|
+
if (isScrollableY || isScrollableX) {
|
|
200
|
+
const parentRect = parent.getBoundingClientRect();
|
|
201
|
+
|
|
202
|
+
if (isScrollableY) {
|
|
203
|
+
// if we actually shrink, mark it
|
|
204
|
+
const newTop = Math.max(visibleRect.top, parentRect.top);
|
|
205
|
+
const newBottom = Math.min(visibleRect.bottom, parentRect.bottom);
|
|
206
|
+
if (newTop !== visibleRect.top || newBottom !== visibleRect.bottom) {
|
|
207
|
+
wasClippedByScrollY = true;
|
|
208
|
+
}
|
|
209
|
+
visibleRect.top = newTop;
|
|
210
|
+
visibleRect.bottom = newBottom;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
if (isScrollableX) {
|
|
214
|
+
const newLeft = Math.max(visibleRect.left, parentRect.left);
|
|
215
|
+
const newRight = Math.min(visibleRect.right, parentRect.right);
|
|
216
|
+
if (newLeft !== visibleRect.left || newRight !== visibleRect.right) {
|
|
217
|
+
wasClippedByScrollX = true;
|
|
218
|
+
}
|
|
219
|
+
visibleRect.left = newLeft;
|
|
220
|
+
visibleRect.right = newRight;
|
|
221
|
+
}
|
|
189
222
|
}
|
|
190
223
|
|
|
191
224
|
parent = parent.parentElement;
|
|
192
225
|
}
|
|
193
226
|
|
|
194
|
-
//
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
227
|
+
// CASE 1: element was clipped by a scrollable container
|
|
228
|
+
// → return the clipped rect (this is your 500px content inside 250px scroller case)
|
|
229
|
+
if (wasClippedByScrollY || wasClippedByScrollX) {
|
|
230
|
+
return {
|
|
231
|
+
top: visibleRect.top,
|
|
232
|
+
bottom: visibleRect.bottom,
|
|
233
|
+
left: visibleRect.left,
|
|
234
|
+
right: visibleRect.right,
|
|
235
|
+
width: Math.max(0, visibleRect.right - visibleRect.left),
|
|
236
|
+
height: Math.max(0, visibleRect.bottom - visibleRect.top)
|
|
237
|
+
};
|
|
238
|
+
}
|
|
199
239
|
|
|
200
|
-
//
|
|
240
|
+
// CASE 2: not clipped by scroll containers
|
|
241
|
+
// → we want the element’s FULL rect, even if it’s off-screen
|
|
242
|
+
// i.e. do NOT clip to viewport
|
|
201
243
|
return {
|
|
202
|
-
top:
|
|
203
|
-
bottom:
|
|
204
|
-
left:
|
|
205
|
-
right:
|
|
206
|
-
width: Math.max(0,
|
|
207
|
-
height: Math.max(0,
|
|
244
|
+
top: rect.top,
|
|
245
|
+
bottom: rect.bottom,
|
|
246
|
+
left: rect.left,
|
|
247
|
+
right: rect.right,
|
|
248
|
+
width: Math.max(0, rect.right - rect.left),
|
|
249
|
+
height: Math.max(0, rect.bottom - rect.top)
|
|
208
250
|
};
|
|
209
251
|
}
|