@jsenv/dom 0.6.0 → 0.7.0

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 (109) hide show
  1. package/dist/jsenv_dom.js +262 -330
  2. package/package.json +2 -4
  3. package/index.js +0 -124
  4. package/src/attr/add_attribute_effect.js +0 -93
  5. package/src/attr/attributes.js +0 -32
  6. package/src/color/color_constrast.js +0 -69
  7. package/src/color/color_parsing.js +0 -319
  8. package/src/color/color_scheme.js +0 -28
  9. package/src/color/pick_light_or_dark.js +0 -34
  10. package/src/color/resolve_css_color.js +0 -60
  11. package/src/demos/3_columns_resize_demo.html +0 -84
  12. package/src/demos/3_rows_resize_demo.html +0 -89
  13. package/src/demos/aside_and_main_demo.html +0 -93
  14. package/src/demos/coordinates_demo.html +0 -450
  15. package/src/demos/document_autoscroll_demo.html +0 -517
  16. package/src/demos/drag_gesture_constraints_demo.html +0 -701
  17. package/src/demos/drag_gesture_demo.html +0 -1047
  18. package/src/demos/drag_gesture_element_to_impact_demo.html +0 -445
  19. package/src/demos/drag_reference_element_demo.html +0 -480
  20. package/src/demos/flex_details_set_demo.html +0 -302
  21. package/src/demos/flex_details_set_demo_2.html +0 -315
  22. package/src/demos/visible_rect_demo.html +0 -525
  23. package/src/element_signature.js +0 -100
  24. package/src/interaction/drag/constraint_feedback_line.js +0 -92
  25. package/src/interaction/drag/drag_constraint.js +0 -659
  26. package/src/interaction/drag/drag_debug_markers.js +0 -635
  27. package/src/interaction/drag/drag_element_positioner.js +0 -382
  28. package/src/interaction/drag/drag_gesture.js +0 -566
  29. package/src/interaction/drag/drag_resize_demo.html +0 -571
  30. package/src/interaction/drag/drag_to_move.js +0 -301
  31. package/src/interaction/drag/drag_to_resize_gesture.js +0 -68
  32. package/src/interaction/drag/drop_target_detection.js +0 -148
  33. package/src/interaction/drag/sticky_frontiers.js +0 -160
  34. package/src/interaction/event_marker.js +0 -14
  35. package/src/interaction/focus/active_element.js +0 -33
  36. package/src/interaction/focus/arrow_navigation.js +0 -599
  37. package/src/interaction/focus/element_is_focusable.js +0 -57
  38. package/src/interaction/focus/element_visibility.js +0 -111
  39. package/src/interaction/focus/find_focusable.js +0 -21
  40. package/src/interaction/focus/focus_group.js +0 -91
  41. package/src/interaction/focus/focus_group_registry.js +0 -12
  42. package/src/interaction/focus/focus_nav.js +0 -12
  43. package/src/interaction/focus/focus_nav_event_marker.js +0 -14
  44. package/src/interaction/focus/focus_trap.js +0 -105
  45. package/src/interaction/focus/tab_navigation.js +0 -128
  46. package/src/interaction/focus/tests/focus_group_skip_tab_test.html +0 -206
  47. package/src/interaction/focus/tests/tree_focus_test.html +0 -304
  48. package/src/interaction/focus/tests/tree_focus_test.jsx +0 -261
  49. package/src/interaction/focus/tests/tree_focus_test_preact.html +0 -13
  50. package/src/interaction/isolate_interactions.js +0 -161
  51. package/src/interaction/keyboard.js +0 -26
  52. package/src/interaction/scroll/capture_scroll.js +0 -47
  53. package/src/interaction/scroll/is_scrollable.js +0 -159
  54. package/src/interaction/scroll/scroll_container.js +0 -110
  55. package/src/interaction/scroll/scroll_trap.js +0 -44
  56. package/src/interaction/scroll/scrollbar_size.js +0 -20
  57. package/src/interaction/scroll/wheel_through.js +0 -138
  58. package/src/iterable_weak_set.js +0 -66
  59. package/src/position/dom_coords.js +0 -340
  60. package/src/position/offset_parent.js +0 -15
  61. package/src/position/position_fixed.js +0 -15
  62. package/src/position/position_sticky.js +0 -213
  63. package/src/position/sticky_rect.js +0 -79
  64. package/src/position/visible_rect.js +0 -486
  65. package/src/pub_sub.js +0 -31
  66. package/src/size/can_take_size.js +0 -11
  67. package/src/size/details_content_full_height.js +0 -63
  68. package/src/size/flex_details_set.js +0 -974
  69. package/src/size/get_available_height.js +0 -22
  70. package/src/size/get_available_width.js +0 -22
  71. package/src/size/get_border_sizes.js +0 -14
  72. package/src/size/get_height.js +0 -4
  73. package/src/size/get_inner_height.js +0 -15
  74. package/src/size/get_inner_width.js +0 -15
  75. package/src/size/get_margin_sizes.js +0 -10
  76. package/src/size/get_max_height.js +0 -57
  77. package/src/size/get_max_width.js +0 -47
  78. package/src/size/get_min_height.js +0 -14
  79. package/src/size/get_min_width.js +0 -14
  80. package/src/size/get_padding_sizes.js +0 -10
  81. package/src/size/get_width.js +0 -4
  82. package/src/size/hooks/use_available_height.js +0 -27
  83. package/src/size/hooks/use_available_width.js +0 -27
  84. package/src/size/hooks/use_max_height.js +0 -10
  85. package/src/size/hooks/use_max_width.js +0 -10
  86. package/src/size/hooks/use_resize_status.js +0 -62
  87. package/src/size/resize.js +0 -695
  88. package/src/size/resolve_css_size.js +0 -32
  89. package/src/style/dom_styles.js +0 -97
  90. package/src/style/style_composition.js +0 -121
  91. package/src/style/style_controller.js +0 -345
  92. package/src/style/style_default.js +0 -153
  93. package/src/style/style_default_demo.html +0 -128
  94. package/src/style/style_parsing.js +0 -375
  95. package/src/transition/demos/animation_resumption_test.xhtml +0 -500
  96. package/src/transition/demos/height_toggle_test.xhtml +0 -515
  97. package/src/transition/dom_transition.js +0 -254
  98. package/src/transition/easing.js +0 -48
  99. package/src/transition/group_transition.js +0 -261
  100. package/src/transition/transform_style_parser.js +0 -32
  101. package/src/transition/transition_playback.js +0 -366
  102. package/src/transition/transition_timeline.js +0 -79
  103. package/src/traversal.js +0 -247
  104. package/src/ui_transition/demos/content_states_transition_demo.html +0 -628
  105. package/src/ui_transition/demos/smooth_height_transition_demo.html +0 -149
  106. package/src/ui_transition/demos/transition_testing.html +0 -354
  107. package/src/ui_transition/ui_transition.js +0 -1491
  108. package/src/utils.js +0 -69
  109. package/src/value_effect.js +0 -35
@@ -1,301 +0,0 @@
1
- import { getScrollBox, getScrollport } from "../../position/dom_coords.js";
2
- import { createStyleController } from "../../style/style_controller.js";
3
- import { getScrollContainer } from "../scroll/scroll_container.js";
4
- import { initDragConstraints } from "./drag_constraint.js";
5
- import { createDragElementPositioner } from "./drag_element_positioner.js";
6
- import { createDragGestureController } from "./drag_gesture.js";
7
- import { applyStickyFrontiersToAutoScrollArea } from "./sticky_frontiers.js";
8
-
9
- const dragStyleController = createStyleController("drag_to_move");
10
-
11
- export const createDragToMoveGestureController = ({
12
- stickyFrontiers = true,
13
- // Padding to reduce the area used to autoscroll by this amount (applied after sticky frontiers)
14
- // This creates an invisible space around the area where elements cannot be dragged
15
- autoScrollAreaPadding = 0,
16
- // constraints,
17
- areaConstraint = "scroll", // "scroll" | "scrollport" | "none" | {left,top,right,bottom} | function
18
- obstaclesContainer,
19
- obstacleAttributeName = "data-drag-obstacle",
20
- // Visual feedback line connecting mouse cursor to the moving grab point when constraints prevent following
21
- // This provides intuitive feedback during drag operations when the element cannot reach the mouse
22
- // position due to obstacles, boundaries, or other constraints. The line originates from where the mouse
23
- // initially grabbed the element, but moves with the element to show the current anchor position.
24
- // It becomes visible when there's a significant distance between mouse and grab point.
25
- showConstraintFeedbackLine = true,
26
- showDebugMarkers = true,
27
- resetPositionAfterRelease = false,
28
- ...options
29
- } = {}) => {
30
- const initGrabToMoveElement = (
31
- dragGesture,
32
- { element, referenceElement, elementToMove, convertScrollablePosition },
33
- ) => {
34
- const direction = dragGesture.gestureInfo.direction;
35
- const dragGestureName = dragGesture.gestureInfo.name;
36
- const scrollContainer = dragGesture.gestureInfo.scrollContainer;
37
- const elementImpacted = elementToMove || element;
38
- const translateXAtGrab = dragStyleController.getUnderlyingValue(
39
- elementImpacted,
40
- "transform.translateX",
41
- );
42
- const translateYAtGrab = dragStyleController.getUnderlyingValue(
43
- elementImpacted,
44
- "transform.translateY",
45
- );
46
- dragGesture.addReleaseCallback(() => {
47
- if (resetPositionAfterRelease) {
48
- dragStyleController.clear(elementImpacted);
49
- } else {
50
- dragStyleController.commit(elementImpacted);
51
- }
52
- });
53
-
54
- let elementWidth;
55
- let elementHeight;
56
- {
57
- const updateElementDimension = () => {
58
- const elementRect = element.getBoundingClientRect();
59
- elementWidth = elementRect.width;
60
- elementHeight = elementRect.height;
61
- };
62
- updateElementDimension();
63
- dragGesture.addBeforeDragCallback(updateElementDimension);
64
- }
65
-
66
- let scrollArea;
67
- {
68
- // computed at start so that scrollWidth/scrollHeight are fixed
69
- // even if the dragging side effects increases them afterwards
70
- scrollArea = {
71
- left: 0,
72
- top: 0,
73
- right: scrollContainer.scrollWidth,
74
- bottom: scrollContainer.scrollHeight,
75
- };
76
- }
77
-
78
- let scrollport;
79
- let autoScrollArea;
80
- {
81
- // for visible are we also want to snapshot the widht/height
82
- // and we'll add scrollContainer container scrolls during drag (getScrollport does that)
83
- const scrollBox = getScrollBox(scrollContainer);
84
- const updateScrollportAndAutoScrollArea = () => {
85
- scrollport = getScrollport(scrollBox, scrollContainer);
86
- autoScrollArea = scrollport;
87
- if (stickyFrontiers) {
88
- autoScrollArea = applyStickyFrontiersToAutoScrollArea(
89
- autoScrollArea,
90
- {
91
- scrollContainer,
92
- direction,
93
- dragGestureName,
94
- },
95
- );
96
- }
97
- if (autoScrollAreaPadding > 0) {
98
- autoScrollArea = {
99
- paddingLeft: autoScrollAreaPadding,
100
- paddingTop: autoScrollAreaPadding,
101
- paddingRight: autoScrollAreaPadding,
102
- paddingBottom: autoScrollAreaPadding,
103
- left: autoScrollArea.left + autoScrollAreaPadding,
104
- top: autoScrollArea.top + autoScrollAreaPadding,
105
- right: autoScrollArea.right - autoScrollAreaPadding,
106
- bottom: autoScrollArea.bottom - autoScrollAreaPadding,
107
- };
108
- }
109
- };
110
- updateScrollportAndAutoScrollArea();
111
- dragGesture.addBeforeDragCallback(updateScrollportAndAutoScrollArea);
112
- }
113
-
114
- // Set up dragging attribute
115
- element.setAttribute("data-grabbed", "");
116
- dragGesture.addReleaseCallback(() => {
117
- element.removeAttribute("data-grabbed");
118
- });
119
-
120
- // Will be used for dynamic constraints on sticky elements
121
- let hasCrossedScrollportLeftOnce = false;
122
- let hasCrossedScrollportTopOnce = false;
123
- const dragConstraints = initDragConstraints(dragGesture, {
124
- areaConstraint,
125
- obstaclesContainer: obstaclesContainer || scrollContainer,
126
- obstacleAttributeName,
127
- showConstraintFeedbackLine,
128
- showDebugMarkers,
129
- referenceElement,
130
- });
131
- dragGesture.addBeforeDragCallback(
132
- (layoutRequested, currentLayout, limitLayout, { dragEvent }) => {
133
- dragConstraints.applyConstraints(
134
- layoutRequested,
135
- currentLayout,
136
- limitLayout,
137
- {
138
- elementWidth,
139
- elementHeight,
140
- scrollArea,
141
- scrollport,
142
- hasCrossedScrollportLeftOnce,
143
- hasCrossedScrollportTopOnce,
144
- autoScrollArea,
145
- dragEvent,
146
- },
147
- );
148
- },
149
- );
150
-
151
- const dragToMove = (gestureInfo) => {
152
- const { isGoingDown, isGoingUp, isGoingLeft, isGoingRight, layout } =
153
- gestureInfo;
154
- const left = layout.left;
155
- const top = layout.top;
156
- const right = left + elementWidth;
157
- const bottom = top + elementHeight;
158
-
159
- auto_scroll: {
160
- hasCrossedScrollportLeftOnce =
161
- hasCrossedScrollportLeftOnce || left < scrollport.left;
162
- hasCrossedScrollportTopOnce =
163
- hasCrossedScrollportTopOnce || top < scrollport.top;
164
-
165
- const getScrollMove = (axis) => {
166
- const isGoingPositive = axis === "x" ? isGoingRight : isGoingDown;
167
- if (isGoingPositive) {
168
- const elementEnd = axis === "x" ? right : bottom;
169
- const autoScrollAreaEnd =
170
- axis === "x" ? autoScrollArea.right : autoScrollArea.bottom;
171
-
172
- if (elementEnd <= autoScrollAreaEnd) {
173
- return 0;
174
- }
175
- const scrollAmountNeeded = elementEnd - autoScrollAreaEnd;
176
- return scrollAmountNeeded;
177
- }
178
-
179
- const isGoingNegative = axis === "x" ? isGoingLeft : isGoingUp;
180
- if (!isGoingNegative) {
181
- return 0;
182
- }
183
-
184
- const referenceOrEl = referenceElement || element;
185
- const canAutoScrollNegative =
186
- axis === "x"
187
- ? !referenceOrEl.hasAttribute("data-sticky-left") ||
188
- hasCrossedScrollportLeftOnce
189
- : !referenceOrEl.hasAttribute("data-sticky-top") ||
190
- hasCrossedScrollportTopOnce;
191
- if (!canAutoScrollNegative) {
192
- return 0;
193
- }
194
-
195
- const elementStart = axis === "x" ? left : top;
196
- const autoScrollAreaStart =
197
- axis === "x" ? autoScrollArea.left : autoScrollArea.top;
198
- if (elementStart >= autoScrollAreaStart) {
199
- return 0;
200
- }
201
-
202
- const scrollAmountNeeded = autoScrollAreaStart - elementStart;
203
- return -scrollAmountNeeded;
204
- };
205
-
206
- let scrollLeftTarget;
207
- let scrollTopTarget;
208
- if (direction.x) {
209
- const containerScrollLeftMove = getScrollMove("x");
210
- if (containerScrollLeftMove) {
211
- scrollLeftTarget =
212
- scrollContainer.scrollLeft + containerScrollLeftMove;
213
- }
214
- }
215
- if (direction.y) {
216
- const containerScrollTopMove = getScrollMove("y");
217
- if (containerScrollTopMove) {
218
- scrollTopTarget =
219
- scrollContainer.scrollTop + containerScrollTopMove;
220
- }
221
- }
222
- // now we know what to do, do it
223
- if (scrollLeftTarget !== undefined) {
224
- scrollContainer.scrollLeft = scrollLeftTarget;
225
- }
226
- if (scrollTopTarget !== undefined) {
227
- scrollContainer.scrollTop = scrollTopTarget;
228
- }
229
- }
230
-
231
- move: {
232
- const { scrollableLeft, scrollableTop } = layout;
233
- const [positionedLeft, positionedTop] = convertScrollablePosition(
234
- scrollableLeft,
235
- scrollableTop,
236
- );
237
- const transform = {};
238
- if (direction.x) {
239
- const leftTarget = positionedLeft;
240
- const leftAtGrab = dragGesture.gestureInfo.leftAtGrab;
241
- const leftDelta = leftTarget - leftAtGrab;
242
- const translateX = translateXAtGrab
243
- ? translateXAtGrab + leftDelta
244
- : leftDelta;
245
- transform.translateX = translateX;
246
- // console.log({
247
- // leftAtGrab,
248
- // scrollableLeft,
249
- // left,
250
- // leftTarget,
251
- // });
252
- }
253
- if (direction.y) {
254
- const topTarget = positionedTop;
255
- const topAtGrab = dragGesture.gestureInfo.topAtGrab;
256
- const topDelta = topTarget - topAtGrab;
257
- const translateY = translateYAtGrab
258
- ? translateYAtGrab + topDelta
259
- : topDelta;
260
- transform.translateY = translateY;
261
- }
262
- dragStyleController.set(elementImpacted, {
263
- transform,
264
- });
265
- }
266
- };
267
- dragGesture.addDragCallback(dragToMove);
268
- };
269
-
270
- const dragGestureController = createDragGestureController(options);
271
- const grab = dragGestureController.grab;
272
- dragGestureController.grab = ({
273
- element,
274
- referenceElement,
275
- elementToMove,
276
- ...rest
277
- } = {}) => {
278
- const scrollContainer = getScrollContainer(referenceElement || element);
279
- const [
280
- elementScrollableLeft,
281
- elementScrollableTop,
282
- convertScrollablePosition,
283
- ] = createDragElementPositioner(element, referenceElement, elementToMove);
284
- const dragGesture = grab({
285
- element,
286
- scrollContainer,
287
- layoutScrollableLeft: elementScrollableLeft,
288
- layoutScrollableTop: elementScrollableTop,
289
- ...rest,
290
- });
291
- initGrabToMoveElement(dragGesture, {
292
- element,
293
- referenceElement,
294
- elementToMove,
295
- convertScrollablePosition,
296
- });
297
- return dragGesture;
298
- };
299
-
300
- return dragGestureController;
301
- };
@@ -1,68 +0,0 @@
1
- import { createDragGestureController } from "./drag_gesture.js";
2
-
3
- export const startDragToResizeGesture = (
4
- pointerdownEvent,
5
- { onDragStart, onDrag, onRelease, ...options },
6
- ) => {
7
- const target = pointerdownEvent.target;
8
- if (!target.closest) {
9
- return null;
10
- }
11
- const elementWithDataResizeHandle = target.closest("[data-resize-handle]");
12
- if (!elementWithDataResizeHandle) {
13
- return null;
14
- }
15
- let elementToResize;
16
- const dataResizeHandle =
17
- elementWithDataResizeHandle.getAttribute("data-resize-handle");
18
- if (!dataResizeHandle || dataResizeHandle === "true") {
19
- elementToResize = elementWithDataResizeHandle.closest("[data-resize]");
20
- } else {
21
- elementToResize = document.querySelector(`#${dataResizeHandle}`);
22
- }
23
- if (!elementToResize) {
24
- console.warn("No element to resize found");
25
- return null;
26
- }
27
- // inspired by https://developer.mozilla.org/en-US/docs/Web/CSS/resize
28
- // "horizontal", "vertical", "both"
29
- const resizeDirection = getResizeDirection(elementToResize);
30
- if (!resizeDirection.x && !resizeDirection.y) {
31
- return null;
32
- }
33
-
34
- const dragToResizeGestureController = createDragGestureController({
35
- gestureAttribute: "data-resizing",
36
- onDragStart: (...args) => {
37
- onDragStart?.(...args);
38
- },
39
- onDrag,
40
- onRelease: (...args) => {
41
- elementWithDataResizeHandle.removeAttribute("data-active");
42
- onRelease?.(...args);
43
- },
44
- });
45
- elementWithDataResizeHandle.setAttribute("data-active", "");
46
- const dragToResizeGesture = dragToResizeGestureController.grabViaPointer(
47
- pointerdownEvent,
48
- {
49
- element: elementToResize,
50
- direction: resizeDirection,
51
- cursor:
52
- resizeDirection.x && resizeDirection.y
53
- ? "nwse-resize"
54
- : resizeDirection.x
55
- ? "ew-resize"
56
- : "ns-resize",
57
- ...options,
58
- },
59
- );
60
- return dragToResizeGesture;
61
- };
62
-
63
- const getResizeDirection = (element) => {
64
- const direction = element.getAttribute("data-resize");
65
- const x = direction === "horizontal" || direction === "both";
66
- const y = direction === "vertical" || direction === "both";
67
- return { x, y };
68
- };
@@ -1,148 +0,0 @@
1
- /**
2
- * Detects the drop target based on what element is actually under the mouse cursor.
3
- * Uses document.elementsFromPoint() to respect visual stacking order naturally.
4
- *
5
- * @param {Object} gestureInfo - Gesture information
6
- * @param {Element[]} targetElements - Array of potential drop target elements
7
- * @returns {Object|null} Drop target info with elementSide or null if no valid target found
8
- */
9
- export const getDropTargetInfo = (gestureInfo, targetElements) => {
10
- const dragElement = gestureInfo.element;
11
- const dragElementRect = dragElement.getBoundingClientRect();
12
- const intersectingTargets = [];
13
- let someTargetIsCol;
14
- let someTargetIsTr;
15
- for (const targetElement of targetElements) {
16
- const targetRect = targetElement.getBoundingClientRect();
17
- if (!rectangleAreIntersecting(dragElementRect, targetRect)) {
18
- continue;
19
- }
20
- if (!someTargetIsCol && targetElement.tagName === "COL") {
21
- someTargetIsCol = true;
22
- }
23
- if (!someTargetIsTr && targetElement.tagName === "TR") {
24
- someTargetIsTr = true;
25
- }
26
- intersectingTargets.push(targetElement);
27
- }
28
-
29
- if (intersectingTargets.length === 0) {
30
- return null;
31
- }
32
-
33
- const dragElementCenterX = dragElementRect.left + dragElementRect.width / 2;
34
- const dragElementCenterY = dragElementRect.top + dragElementRect.height / 2;
35
- // Clamp coordinates to viewport to avoid issues with elementsFromPoint
36
- const viewportWidth = document.documentElement.clientWidth;
37
- const viewportHeight = document.documentElement.clientHeight;
38
- const clientX =
39
- dragElementCenterX < 0
40
- ? 0
41
- : dragElementCenterX > viewportWidth
42
- ? viewportWidth - 1
43
- : dragElementCenterX;
44
- const clientY =
45
- dragElementCenterY < 0
46
- ? 0
47
- : dragElementCenterY > viewportHeight
48
- ? viewportHeight - 1
49
- : dragElementCenterY;
50
-
51
- // Find the first target element in the stack (topmost visible target)
52
- const elementsUnderDragElement = document.elementsFromPoint(clientX, clientY);
53
- let targetElement = null;
54
- let targetIndex = -1;
55
- for (const element of elementsUnderDragElement) {
56
- // First, check if the element itself is a target
57
- const directIndex = intersectingTargets.indexOf(element);
58
- if (directIndex !== -1) {
59
- targetElement = element;
60
- targetIndex = directIndex;
61
- break;
62
- }
63
- // Special case: if element is <td> or <th> and not in targets,
64
- // try to find its corresponding <col> element
65
- if (!isTableCell(element)) {
66
- continue;
67
- }
68
- try_col: {
69
- if (!someTargetIsCol) {
70
- break try_col;
71
- }
72
- const tableCellCol = findTableCellCol(element);
73
- if (!tableCellCol) {
74
- break try_col;
75
- }
76
- const colIndex = intersectingTargets.indexOf(tableCellCol);
77
- if (colIndex === -1) {
78
- break try_col;
79
- }
80
- targetElement = tableCellCol;
81
- targetIndex = colIndex;
82
- break;
83
- }
84
- try_tr: {
85
- if (!someTargetIsTr) {
86
- break try_tr;
87
- }
88
- const tableRow = element.closest("tr");
89
- const rowIndex = targetElements.indexOf(tableRow);
90
- if (rowIndex === -1) {
91
- break try_tr;
92
- }
93
- targetElement = tableRow;
94
- targetIndex = rowIndex;
95
- break;
96
- }
97
- }
98
- if (!targetElement) {
99
- targetElement = intersectingTargets[0];
100
- targetIndex = 0;
101
- }
102
-
103
- // Determine position within the target for both axes
104
- const targetRect = targetElement.getBoundingClientRect();
105
- const targetCenterX = targetRect.left + targetRect.width / 2;
106
- const targetCenterY = targetRect.top + targetRect.height / 2;
107
- const result = {
108
- index: targetIndex,
109
- element: targetElement,
110
- elementSide: {
111
- x: dragElementRect.left < targetCenterX ? "start" : "end",
112
- y: dragElementRect.top < targetCenterY ? "start" : "end",
113
- },
114
- intersecting: intersectingTargets,
115
- };
116
- return result;
117
- };
118
-
119
- const rectangleAreIntersecting = (r1, r2) => {
120
- return !(
121
- r2.left > r1.right ||
122
- r2.right < r1.left ||
123
- r2.top > r1.bottom ||
124
- r2.bottom < r1.top
125
- );
126
- };
127
-
128
- const isTableCell = (el) => {
129
- return el.tagName === "TD" || el.tagName === "TH";
130
- };
131
-
132
- /**
133
- * Find the corresponding <col> element for a given <td> or <th> cell
134
- * @param {Element} cellElement - The <td> or <th> element
135
- * @param {Element[]} targetColElements - Array of <col> elements to search in
136
- * @returns {Element|null} The corresponding <col> element or null if not found
137
- */
138
- const findTableCellCol = (cellElement) => {
139
- const table = cellElement.closest("table");
140
- const colgroup = table.querySelector("colgroup");
141
- if (!colgroup) {
142
- return null;
143
- }
144
- const cols = colgroup.querySelectorAll("col");
145
- const columnIndex = cellElement.cellIndex;
146
- const correspondingCol = cols[columnIndex];
147
- return correspondingCol;
148
- };
@@ -1,160 +0,0 @@
1
- import { getElementSignature } from "../../element_signature.js";
2
- import { getScrollRelativeRect } from "../../position/dom_coords.js";
3
-
4
- export const applyStickyFrontiersToAutoScrollArea = (
5
- autoScrollArea,
6
- { direction, scrollContainer, dragName },
7
- ) => {
8
- let { left, right, top, bottom } = autoScrollArea;
9
-
10
- if (direction.x) {
11
- const horizontalStickyFrontiers = createStickyFrontierOnAxis(
12
- scrollContainer,
13
- {
14
- name: dragName,
15
- scrollContainer,
16
- primarySide: "left",
17
- oppositeSide: "right",
18
- },
19
- );
20
- for (const horizontalStickyFrontier of horizontalStickyFrontiers) {
21
- const { side, bounds, element } = horizontalStickyFrontier;
22
- if (side === "left") {
23
- if (bounds.right <= left) {
24
- continue;
25
- }
26
- left = bounds.right;
27
- if (import.meta.dev && left > right) {
28
- console.warn(
29
- `Sticky frontier created invalid horizontal visible area: left (${left}) > right (${right}). Original: left=${bounds.right}, right=${right}`,
30
- {
31
- frontierElement: element,
32
- frontierBounds: bounds,
33
- dragName,
34
- },
35
- );
36
- }
37
- continue;
38
- }
39
- // right
40
- if (bounds.left >= right) {
41
- continue;
42
- }
43
- right = bounds.left;
44
- if (import.meta.dev && left > right) {
45
- console.warn(
46
- `Sticky frontier created invalid horizontal visible area: left (${left}) > right (${right}). Original: left=${left}, right=${bounds.left}`,
47
- {
48
- frontierElement: element,
49
- frontierBounds: bounds,
50
- dragName,
51
- },
52
- );
53
- }
54
- continue;
55
- }
56
- }
57
-
58
- if (direction.y) {
59
- const verticalStickyFrontiers = createStickyFrontierOnAxis(
60
- scrollContainer,
61
- {
62
- name: dragName,
63
- scrollContainer,
64
- primarySide: "top",
65
- oppositeSide: "bottom",
66
- },
67
- );
68
- for (const verticalStickyFrontier of verticalStickyFrontiers) {
69
- const { side, bounds, element } = verticalStickyFrontier;
70
-
71
- // Frontier acts as a top barrier - constrains from the bottom edge of the frontier
72
- if (side === "top") {
73
- if (bounds.bottom <= top) {
74
- continue;
75
- }
76
- top = bounds.bottom;
77
- if (import.meta.dev && top > bottom) {
78
- console.warn(
79
- `Sticky frontier created invalid vertical visible area: top (${top}) > bottom (${bottom}). Original: top=${bounds.bottom}, bottom=${bottom}`,
80
- {
81
- frontierElement: element,
82
- frontierBounds: bounds,
83
- dragName,
84
- },
85
- );
86
- }
87
- continue;
88
- }
89
-
90
- // Frontier acts as a bottom barrier - constrains from the top edge of the frontier
91
- if (bounds.top >= bottom) {
92
- continue;
93
- }
94
- bottom = bounds.top;
95
- if (import.meta.dev && top > bottom) {
96
- console.warn(
97
- `Sticky frontier created invalid vertical visible area: top (${top}) > bottom (${bottom}). Original: top=${top}, bottom=${bounds.top}`,
98
- {
99
- frontierElement: element,
100
- frontierBounds: bounds,
101
- dragName,
102
- },
103
- );
104
- }
105
- continue;
106
- }
107
- }
108
-
109
- return { left, right, top, bottom };
110
- };
111
-
112
- const createStickyFrontierOnAxis = (
113
- element,
114
- { name, scrollContainer, primarySide, oppositeSide },
115
- ) => {
116
- const primaryAttrName = `data-drag-sticky-${primarySide}-frontier`;
117
- const oppositeAttrName = `data-drag-sticky-${oppositeSide}-frontier`;
118
- const frontiers = element.querySelectorAll(
119
- `[${primaryAttrName}], [${oppositeAttrName}]`,
120
- );
121
- const matchingStickyFrontiers = [];
122
- for (const frontier of frontiers) {
123
- if (frontier.closest("[data-drag-ignore]")) {
124
- continue;
125
- }
126
- const hasPrimary = frontier.hasAttribute(primaryAttrName);
127
- const hasOpposite = frontier.hasAttribute(oppositeAttrName);
128
- // Check if element has both sides (invalid)
129
- if (hasPrimary && hasOpposite) {
130
- const elementSignature = getElementSignature(frontier);
131
- console.warn(
132
- `Sticky frontier element (${elementSignature}) has both ${primarySide} and ${oppositeSide} attributes.
133
- A sticky frontier should only have one side attribute.`,
134
- );
135
- continue;
136
- }
137
- const attrName = hasPrimary ? primaryAttrName : oppositeAttrName;
138
- const attributeValue = frontier.getAttribute(attrName);
139
- if (attributeValue && name) {
140
- const frontierNames = attributeValue.split(",");
141
- const isMatching = frontierNames.some(
142
- (frontierName) =>
143
- frontierName.trim().toLowerCase() === name.toLowerCase(),
144
- );
145
- if (!isMatching) {
146
- continue;
147
- }
148
- }
149
- const frontierBounds = getScrollRelativeRect(frontier, scrollContainer);
150
- const stickyFrontierObject = {
151
- type: "sticky-frontier",
152
- element: frontier,
153
- side: hasPrimary ? primarySide : oppositeSide,
154
- bounds: frontierBounds,
155
- name: `sticky_frontier_${hasPrimary ? primarySide : oppositeSide} (${getElementSignature(frontier)})`,
156
- };
157
- matchingStickyFrontiers.push(stickyFrontierObject);
158
- }
159
- return matchingStickyFrontiers;
160
- };
@@ -1,14 +0,0 @@
1
- export const createEventMarker = (symbolName) => {
2
- const symbol = Symbol.for(symbolName);
3
-
4
- const isMarked = (event) => {
5
- return Boolean(event[symbol]);
6
- };
7
-
8
- return {
9
- mark: (event) => {
10
- event[symbol] = true;
11
- },
12
- isMarked,
13
- };
14
- };