@jsenv/dom 0.6.1 → 0.7.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.
Files changed (109) hide show
  1. package/dist/jsenv_dom.js +339 -327
  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 -1470
  108. package/src/utils.js +0 -69
  109. package/src/value_effect.js +0 -35
@@ -1,138 +0,0 @@
1
- /**
2
- * Creates intuitive scrolling behavior when scrolling over an element that needs to stay interactive
3
- * (we can't use pointer-events: none). Instead of scrolling the document unexpectedly,
4
- * finds and scrolls the appropriate scrollable container behind the overlay.
5
- */
6
-
7
- import { isScrollable } from "./is_scrollable.js";
8
- import { getScrollContainer } from "./scroll_container.js";
9
-
10
- export const allowWheelThrough = (element, connectedElement) => {
11
- const isElementOrDescendant = (possibleDescendant) => {
12
- return (
13
- possibleDescendant === element || element.contains(possibleDescendant)
14
- );
15
- };
16
- const tryToScrollOne = (element, wheelEvent) => {
17
- if (element === document.documentElement) {
18
- // let browser handle document scrolling
19
- return true;
20
- }
21
-
22
- const { deltaX, deltaY } = wheelEvent;
23
- // we found what we want: a scrollable container behind the element
24
- // we try to scroll it.
25
- const elementCanApplyScrollDeltaX =
26
- deltaX && canApplyScrollDelta(element, deltaX, "x");
27
- const elementCanApplyScrollDeltaY =
28
- deltaY && canApplyScrollDelta(element, deltaY, "y");
29
- if (!elementCanApplyScrollDeltaX && !elementCanApplyScrollDeltaY) {
30
- return false;
31
- }
32
- if (!isScrollable(element)) {
33
- return false;
34
- }
35
- const belongsToElement = isElementOrDescendant(element);
36
- if (belongsToElement) {
37
- // let browser handle the scroll on the element itself
38
- return true;
39
- }
40
- wheelEvent.preventDefault();
41
- applyWheelScrollThrough(element, wheelEvent);
42
- return true;
43
- };
44
-
45
- if (connectedElement) {
46
- const onWheel = (wheelEvent) => {
47
- const connectedScrollContainer = getScrollContainer(connectedElement);
48
- if (connectedScrollContainer === document.documentElement) {
49
- // the connected scrollable parent is the document
50
- // there is nothing to do, browser native scroll will work as we want
51
- return;
52
- }
53
-
54
- const elementsBehindMouse = document.elementsFromPoint(
55
- wheelEvent.clientX,
56
- wheelEvent.clientY,
57
- );
58
- for (const elementBehindMouse of elementsBehindMouse) {
59
- // try to scroll element itself
60
- if (tryToScrollOne(elementBehindMouse, wheelEvent)) {
61
- return;
62
- }
63
- const belongsToElement = isElementOrDescendant(elementBehindMouse);
64
- // try to scroll what is behind
65
- if (!belongsToElement) {
66
- break;
67
- }
68
- }
69
- // At this stage the element has no scrollable parts
70
- // we can try to scroll the connected scrollable parent
71
- tryToScrollOne(connectedScrollContainer, wheelEvent);
72
- };
73
- element.addEventListener("wheel", onWheel);
74
- return;
75
- }
76
-
77
- const onWheel = (wheelEvent) => {
78
- const elementsBehindMouse = document.elementsFromPoint(
79
- wheelEvent.clientX,
80
- wheelEvent.clientY,
81
- );
82
- for (const elementBehindMouse of elementsBehindMouse) {
83
- // try to scroll element itself
84
- if (tryToScrollOne(elementBehindMouse, wheelEvent)) {
85
- return;
86
- }
87
- const belongsToElement = isElementOrDescendant(elementBehindMouse);
88
- if (belongsToElement) {
89
- // keep searching if something in our element is scrollable
90
- continue;
91
- }
92
- // our element is not scrollable, try to scroll the container behind the mouse
93
- const scrollContainer = getScrollContainer(elementBehindMouse);
94
- if (tryToScrollOne(scrollContainer, wheelEvent)) {
95
- return;
96
- }
97
- }
98
- };
99
- element.addEventListener("wheel", onWheel);
100
- };
101
-
102
- const canApplyScrollDelta = (element, delta, axis) => {
103
- const {
104
- clientWidth,
105
- clientHeight,
106
- scrollWidth,
107
- scrollHeight,
108
- scrollLeft,
109
- scrollTop,
110
- } = element;
111
-
112
- let size = axis === "x" ? clientWidth : clientHeight;
113
- let currentScroll = axis === "x" ? scrollLeft : scrollTop;
114
- let scrollEnd = axis === "x" ? scrollWidth : scrollHeight;
115
-
116
- if (size === scrollEnd) {
117
- // when scrollWidth === clientWidth, there is no scroll to apply
118
- return false;
119
- }
120
- if (delta < 0 && currentScroll <= 0) {
121
- // when scrollLeft is 0, we can't scroll to the left
122
- return false;
123
- }
124
- if (delta > 0 && currentScroll + size >= scrollEnd) {
125
- // when scrollLeft + size >= scrollWidth, we can't scroll to the right
126
- return false;
127
- }
128
- return true;
129
- };
130
-
131
- const applyWheelScrollThrough = (element, wheelEvent) => {
132
- wheelEvent.preventDefault();
133
- element.scrollBy({
134
- top: wheelEvent.deltaY,
135
- left: wheelEvent.deltaX,
136
- behavior: wheelEvent.deltaMode === 0 ? "auto" : "smooth", // optional tweak
137
- });
138
- };
@@ -1,66 +0,0 @@
1
- export const createIterableWeakSet = () => {
2
- const objectWeakRefSet = new Set();
3
-
4
- return {
5
- add: (object) => {
6
- const objectWeakRef = new WeakRef(object);
7
- objectWeakRefSet.add(objectWeakRef);
8
- },
9
-
10
- delete: (object) => {
11
- for (const weakRef of objectWeakRefSet) {
12
- if (weakRef.deref() === object) {
13
- objectWeakRefSet.delete(weakRef);
14
- return true;
15
- }
16
- }
17
- return false;
18
- },
19
-
20
- *[Symbol.iterator]() {
21
- for (const objectWeakRef of objectWeakRefSet) {
22
- const object = objectWeakRef.deref();
23
- if (object === undefined) {
24
- objectWeakRefSet.delete(objectWeakRef);
25
- continue;
26
- }
27
- yield object;
28
- }
29
- },
30
-
31
- has: (object) => {
32
- for (const weakRef of objectWeakRefSet) {
33
- const objectCandidate = weakRef.deref();
34
- if (objectCandidate === undefined) {
35
- objectWeakRefSet.delete(weakRef);
36
- continue;
37
- }
38
- if (objectCandidate === object) {
39
- return true;
40
- }
41
- }
42
- return false;
43
- },
44
-
45
- clear: () => {
46
- objectWeakRefSet.clear();
47
- },
48
-
49
- get size() {
50
- return objectWeakRefSet.size;
51
- },
52
-
53
- getStats: () => {
54
- let alive = 0;
55
- let dead = 0;
56
- for (const weakRef of objectWeakRefSet) {
57
- if (weakRef.deref() !== undefined) {
58
- alive++;
59
- } else {
60
- dead++;
61
- }
62
- }
63
- return { total: objectWeakRefSet.size, alive, dead };
64
- },
65
- };
66
- };
@@ -1,340 +0,0 @@
1
- /**
2
- * DOM Coordinate Systems: The Missing APIs Problem
3
- *
4
- * When positioning and moving DOM elements, we commonly need coordinate information.
5
- * The web platform provides getBoundingClientRect() which gives viewport-relative coordinates,
6
- * but this creates several challenges when working with scrollable containers:
7
- *
8
- * ## The Problem
9
- *
10
- * 1. **Basic positioning**: getBoundingClientRect() works great for viewport-relative positioning
11
- * 2. **Document scrolling**: When document has scroll, we add document.scrollLeft/scrollTop
12
- * 3. **Scroll containers**: When elements are inside scrollable containers, we need coordinates
13
- * relative to that container, not the document
14
- *
15
- * ## Missing Browser APIs
16
- *
17
- * The web platform lacks essential APIs for scroll container workflows:
18
- * - No equivalent of getBoundingClientRect() relative to scroll container
19
- * - No built-in way to get element coordinates in scroll container space
20
- * - Manual coordinate conversion is error-prone and inconsistent
21
- *
22
- * ## This Module's Solution
23
- *
24
- * This module provides the missing coordinate APIs that work seamlessly with scroll containers:
25
- * - **getScrollRelativeRect()**: element rect relative to scroll container (PRIMARY API)
26
- * - **getMouseEventScrollRelativeRect()**: Mouse coordinates in scroll container space
27
- * - **convertScrollRelativeRectInto()**: Convert scroll-relative rect to element positioning coordinates
28
- *
29
- * These APIs abstract away the complexity of coordinate system conversion and provide
30
- * a consistent interface for element positioning regardless of scroll container depth.
31
- *
32
- * ## Primary API: getScrollRelativeRect()
33
- *
34
- * This is the main API you want - element rectangle relative to scroll container:
35
- *
36
- * ```js
37
- * const rect = element.getBoundingClientRect(); // viewport-relative
38
- * const scrollRect = getScrollRelativeRect(element, scrollContainer); // scroll-relative
39
- * ```
40
- *
41
- * Returns: { left, top, right, bottom, width, height, scrollLeft, scrollTop, scrollContainer, ...metadata }
42
- *
43
- * The scroll values are included so you can calculate scroll-absolute coordinates yourself:
44
- * ```js
45
- * const { left, top, scrollLeft, scrollTop } = getScrollRelativeRect(element);
46
- * const scrollAbsoluteLeft = left + scrollLeft;
47
- * const scrollAbsoluteTop = top + scrollTop;
48
- * ```
49
- *
50
- * ## Secondary APIs:
51
- *
52
- * - **getMouseEventScrollRelativeRect()**: Get mouse coordinates as a rect in scroll container space
53
- * - **convertScrollRelativeRectInto()**: Convert from scroll-relative coordinates to element positioning coordinates (for setting element.style.left/top)
54
- *
55
- * ## Coordinate System Terminology:
56
- *
57
- * - **Viewport-relative**: getBoundingClientRect() coordinates - relative to browser viewport
58
- * - **Scroll-relative**: Coordinates relative to scroll container (ignoring current scroll position)
59
- * - **Scroll-absolute**: Scroll-relative + scroll position (element's position in full scrollable content)
60
- * - **Element coordinates**: Coordinates for positioning elements (via element.style.left/top)
61
- *
62
- * ## Legacy Coordinate System Diagrams
63
- *
64
- * X-Axis Coordinate Systems in Web Development
65
- *
66
- * Diagram showing horizontal positioning and scrollbars:
67
- *
68
- * VIEWPORT (visible part of the document)
69
- * ┌───────────────────────────────────────────────┐
70
- * │ │
71
- * │ │
72
- * │ container.offsetLeft: 20px │
73
- * │ ┼─────────────────────────────┐ │
74
- * │ │ │ │
75
- * │ │ │ │
76
- * │ │ el.offsetLeft: 100px │ │
77
- * │ │ ┼─────┐ │ │
78
- * │ │ │ │ │ │
79
- * │ │ └─────┘ │ │
80
- * │ │ │ │
81
- * │ │ ░░░███░░░░░░░░░░░░░░░░░░░░░ │ │
82
- * │ └─────│───────────────────────┘ │
83
- * │ container.scrollLeft: 50px │
84
- * │ │
85
- * │ │
86
- * │ ░░░░░░░███░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│
87
- * └─────────│─────────────────────────────────────┘
88
- * document.scrollLeft: 200px
89
- *
90
- *
91
- * Left coordinate for the element:
92
- *
93
- * Document coordinates (absolute position in full document)
94
- * • Result: 320px
95
- * • Detail: container.offsetLeft + element.offsetLeft + document.scrollLeft
96
- * 20 + 100 + 200 = 320px
97
- *
98
- * Viewport coordinates (getBoundingClientRect().left):
99
- * • Result: 120px
100
- * • Detail: container.offsetLeft + element.offsetLeft
101
- * 20 + 100 = 120px
102
- *
103
- * Scroll coordinates (position within scroll container):
104
- * • Result: 50px
105
- * • Detail: element.offsetLeft - container.scrollLeft
106
- * 100 - 50 = 50px
107
- *
108
- * Scroll behavior examples:
109
- *
110
- * When document scrolls (scrollLeft: 200px → 300px):
111
- * • Document coordinates: 320px → 420px
112
- * • Viewport coordinates: 120px → 120px (unchanged)
113
- * • Scroll coordinates: 50px → 50px (unchanged)
114
- *
115
- * When container scrolls (scrollLeft: 50px → 100px):
116
- * • Document coordinates: 320px → 270px
117
- * • Viewport coordinates: 120px → 70px
118
- * • Scroll coordinates: 50px → 0px
119
- */
120
-
121
- import { getScrollContainer } from "../interaction/scroll/scroll_container.js";
122
- import { getBorderSizes } from "../size/get_border_sizes.js";
123
-
124
- const { documentElement } = document;
125
-
126
- /**
127
- * Get element rectangle relative to its scroll container
128
- *
129
- * @param {Element} element - The element to get coordinates for
130
- * @param {Element} [scrollContainer] - Optional scroll container (auto-detected if not provided)
131
- * @param {object} [options] - Configuration options
132
- * @returns {object} { left, top, right, bottom, width, height, scrollLeft, scrollTop, scrollContainer, ...metadata }
133
- */
134
- export const getScrollRelativeRect = (
135
- element,
136
- scrollContainer = getScrollContainer(element),
137
- { useOriginalPositionEvenIfSticky = false } = {},
138
- ) => {
139
- const {
140
- left: leftViewport,
141
- top: topViewport,
142
- width,
143
- height,
144
- } = element.getBoundingClientRect();
145
-
146
- let fromFixed = false;
147
- let fromStickyLeft;
148
- let fromStickyTop;
149
- let fromStickyLeftAttr;
150
- let fromStickyTopAttr;
151
- const scrollLeft = scrollContainer.scrollLeft;
152
- const scrollTop = scrollContainer.scrollTop;
153
- const scrollContainerIsDocument = scrollContainer === documentElement;
154
- const createScrollRelativeRect = (leftScrollRelative, topScrollRelative) => {
155
- const isStickyLeftOrHasStickyLeftAttr = Boolean(
156
- fromStickyLeft || fromStickyLeftAttr,
157
- );
158
- const isStickyTopOrHasStickyTopAttr = Boolean(
159
- fromStickyTop || fromStickyTopAttr,
160
- );
161
- return {
162
- left: leftScrollRelative,
163
- top: topScrollRelative,
164
- right: leftScrollRelative + width,
165
- bottom: topScrollRelative + height,
166
-
167
- // metadata
168
- width,
169
- height,
170
- scrollContainer,
171
- scrollContainerIsDocument,
172
- scrollLeft,
173
- scrollTop,
174
- fromFixed,
175
- fromStickyLeft,
176
- fromStickyTop,
177
- fromStickyLeftAttr,
178
- fromStickyTopAttr,
179
- isStickyLeftOrHasStickyLeftAttr,
180
- isStickyTopOrHasStickyTopAttr,
181
- isSticky:
182
- isStickyLeftOrHasStickyLeftAttr || isStickyTopOrHasStickyTopAttr,
183
- };
184
- };
185
-
186
- sticky: {
187
- const computedStyle = getComputedStyle(element);
188
- sticky_position: {
189
- const usePositionSticky = computedStyle.position === "sticky";
190
- if (usePositionSticky) {
191
- // For CSS position:sticky elements, use scrollable-relative coordinates
192
- const [leftScrollRelative, topScrollRelative] =
193
- viewportPosToScrollRelativePos(
194
- leftViewport,
195
- topViewport,
196
- scrollContainer,
197
- );
198
- const isStickyLeft = computedStyle.left !== "auto";
199
- const isStickyTop = computedStyle.top !== "auto";
200
- fromStickyLeft = isStickyLeft
201
- ? { value: parseFloat(computedStyle.left) || 0 }
202
- : undefined;
203
- fromStickyTop = isStickyTop
204
- ? { value: parseFloat(computedStyle.top) || 0 }
205
- : undefined;
206
- return createScrollRelativeRect(leftScrollRelative, topScrollRelative);
207
- }
208
- }
209
- sticky_attribute: {
210
- const hasStickyLeftAttribute = element.hasAttribute("data-sticky-left");
211
- const hasStickyTopAttribute = element.hasAttribute("data-sticky-top");
212
- const useStickyAttribute =
213
- hasStickyLeftAttribute || hasStickyTopAttribute;
214
- if (useStickyAttribute) {
215
- // Handle virtually sticky obstacles (<col> or <tr>) - elements with data-sticky attributes
216
- // but not CSS position:sticky. Calculate their position based on scroll and sticky behavior
217
- let [leftScrollRelative, topScrollRelative] =
218
- viewportPosToScrollRelativePos(
219
- leftViewport,
220
- topViewport,
221
- scrollContainer,
222
- );
223
- if (hasStickyLeftAttribute) {
224
- const leftCssValue = parseFloat(computedStyle.left) || 0;
225
- fromStickyLeftAttr = { value: leftCssValue };
226
- if (useOriginalPositionEvenIfSticky) {
227
- // For obstacles: use original position only (ignore sticky behavior)
228
- } else {
229
- const scrollLeft = scrollContainer.scrollLeft;
230
- const stickyPosition = scrollLeft + leftCssValue;
231
- const leftWithScroll = leftScrollRelative + scrollLeft;
232
- if (stickyPosition > leftWithScroll) {
233
- leftScrollRelative = leftCssValue; // Element is stuck
234
- } else {
235
- // Element in natural position
236
- }
237
- }
238
- }
239
- if (hasStickyTopAttribute) {
240
- const topCssValue = parseFloat(computedStyle.top) || 0;
241
- fromStickyTopAttr = { value: topCssValue };
242
- if (useOriginalPositionEvenIfSticky) {
243
- // For obstacles: use original position only (ignore sticky behavior)
244
- } else {
245
- const scrollTop = scrollContainer.scrollTop;
246
- const stickyPosition = scrollTop + topCssValue;
247
- const topWithScroll = topScrollRelative + scrollTop;
248
- if (stickyPosition > topWithScroll) {
249
- topScrollRelative = topCssValue; // Element is stuck
250
- } else {
251
- // Element in natural position
252
- }
253
- }
254
- }
255
- return createScrollRelativeRect(leftScrollRelative, topScrollRelative);
256
- }
257
- }
258
- }
259
-
260
- // For normal elements, use scrollable-relative coordinates
261
- const [leftScrollRelative, topScrollRelative] =
262
- viewportPosToScrollRelativePos(leftViewport, topViewport, scrollContainer);
263
- return createScrollRelativeRect(leftScrollRelative, topScrollRelative);
264
- };
265
- const viewportPosToScrollRelativePos = (
266
- leftViewport,
267
- topViewport,
268
- scrollContainer,
269
- ) => {
270
- const scrollContainerIsDocument = scrollContainer === documentElement;
271
- if (scrollContainerIsDocument) {
272
- return [leftViewport, topViewport];
273
- }
274
- const { left: scrollContainerLeftViewport, top: scrollContainerTopViewport } =
275
- scrollContainer.getBoundingClientRect();
276
- return [
277
- leftViewport - scrollContainerLeftViewport,
278
- topViewport - scrollContainerTopViewport,
279
- ];
280
- };
281
-
282
- export const addScrollToRect = (scrollRelativeRect) => {
283
- const { left, top, width, height, scrollLeft, scrollTop } =
284
- scrollRelativeRect;
285
- const leftWithScroll = left + scrollLeft;
286
- const topWithScroll = top + scrollTop;
287
- return {
288
- ...scrollRelativeRect,
289
- left: leftWithScroll,
290
- top: topWithScroll,
291
- right: leftWithScroll + width,
292
- bottom: topWithScroll + height,
293
- };
294
- };
295
-
296
- // https://github.com/w3c/csswg-drafts/issues/3329
297
- // Return the portion of the element that is visible for this scoll container
298
- export const getScrollBox = (scrollContainer) => {
299
- if (scrollContainer === documentElement) {
300
- const { clientWidth, clientHeight } = documentElement;
301
-
302
- return {
303
- left: 0,
304
- top: 0,
305
- right: clientWidth,
306
- bottom: clientHeight,
307
- width: clientWidth,
308
- height: clientHeight,
309
- };
310
- }
311
-
312
- const { clientWidth, clientHeight } = scrollContainer;
313
- const scrollContainerBorderSizes = getBorderSizes(scrollContainer);
314
- const left = scrollContainerBorderSizes.left;
315
- const top = scrollContainerBorderSizes.top;
316
- const right = left + clientWidth;
317
- const bottom = top + clientHeight;
318
- return {
319
- left,
320
- top,
321
- right,
322
- bottom,
323
- width: clientWidth,
324
- height: clientHeight,
325
- };
326
- };
327
- // https://developer.mozilla.org/en-US/docs/Glossary/Scroll_container#scrollport
328
- export const getScrollport = (scrollBox, scrollContainer) => {
329
- const { left, top, width, height } = scrollBox;
330
- const leftWithScroll = left + scrollContainer.scrollLeft;
331
- const topWithScroll = top + scrollContainer.scrollTop;
332
- const rightWithScroll = leftWithScroll + width;
333
- const bottomWithScroll = topWithScroll + height;
334
- return {
335
- left: leftWithScroll,
336
- top: topWithScroll,
337
- right: rightWithScroll,
338
- bottom: bottomWithScroll,
339
- };
340
- };
@@ -1,15 +0,0 @@
1
- export const getPositionedParent = (element) => {
2
- let parent = element.parentElement;
3
- while (parent && parent !== document.body) {
4
- const position = window.getComputedStyle(parent).position;
5
- if (
6
- position === "relative" ||
7
- position === "absolute" ||
8
- position === "fixed"
9
- ) {
10
- return parent;
11
- }
12
- parent = parent.parentElement;
13
- }
14
- return document.body;
15
- };
@@ -1,15 +0,0 @@
1
- export const findSelfOrAncestorFixedPosition = (element) => {
2
- let current = element;
3
- while (true) {
4
- const computedStyle = window.getComputedStyle(current);
5
- if (computedStyle.position === "fixed") {
6
- const { left, top } = current.getBoundingClientRect();
7
- return [left, top];
8
- }
9
- current = current.parentElement;
10
- if (!current || current === document.documentElement) {
11
- break;
12
- }
13
- }
14
- return null;
15
- };