@jsenv/dom 0.6.1 → 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 +259 -314
  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,566 +0,0 @@
1
- /**
2
- * Drag Gesture System
3
- *
4
- * TODO: rename moveX/moveY en juste x/y
5
- * puisque move c'est perturbant sachant que c'est drag + scroll
6
- * et que drag c'est juste la partie mouvement de la souris
7
- *
8
- * donc juste x/y ca seras surement mieux
9
- *
10
- */
11
-
12
- import { createPubSub } from "../../pub_sub.js";
13
- import { findFocusable } from "../focus/find_focusable.js";
14
- import { isolateInteractions } from "../isolate_interactions.js";
15
-
16
- export const createDragGestureController = (options = {}) => {
17
- const {
18
- name,
19
- onGrab,
20
- onDragStart,
21
- onDrag,
22
- onRelease,
23
- threshold = 5,
24
- direction: defaultDirection = { x: true, y: true },
25
- documentInteractions = "auto",
26
- backdrop = true,
27
- backdropZIndex = 999999,
28
- } = options;
29
-
30
- const dragGestureController = {
31
- grab: null,
32
- gravViaPointer: null,
33
- };
34
-
35
- const grab = ({
36
- element,
37
- direction = defaultDirection,
38
- event = new CustomEvent("programmatic"),
39
- grabX = 0,
40
- grabY = 0,
41
- cursor = "grabbing",
42
- scrollContainer = document.documentElement,
43
- layoutScrollableLeft: scrollableLeftAtGrab = 0,
44
- layoutScrollableTop: scrollableTopAtGrab = 0,
45
- } = {}) => {
46
- if (!element) {
47
- throw new Error("element is required");
48
- }
49
- if (!direction.x && !direction.y) {
50
- return null;
51
- }
52
-
53
- const [publishBeforeDrag, addBeforeDragCallback] = createPubSub();
54
- const [publishDrag, addDragCallback] = createPubSub();
55
- const [publishRelease, addReleaseCallback] = createPubSub();
56
- if (onDrag) {
57
- addDragCallback(onDrag);
58
- }
59
- if (onRelease) {
60
- addReleaseCallback(onRelease);
61
- }
62
-
63
- const scrollLeftAtGrab = scrollContainer.scrollLeft;
64
- const scrollTopAtGrab = scrollContainer.scrollTop;
65
- const leftAtGrab = scrollLeftAtGrab + scrollableLeftAtGrab;
66
- const topAtGrab = scrollTopAtGrab + scrollableTopAtGrab;
67
- const createLayout = (x, y) => {
68
- const { scrollLeft, scrollTop } = scrollContainer;
69
- const left = scrollableLeftAtGrab + x;
70
- const top = scrollableTopAtGrab + y;
71
- const scrollableLeft = left - scrollLeft;
72
- const scrollableTop = top - scrollTop;
73
- const layoutProps = {
74
- // Raw input coordinates (dragX - grabX + scrollContainer.scrollLeft)
75
- x,
76
- y,
77
- // container scrolls when layout is created
78
- scrollLeft,
79
- scrollTop,
80
- // Position relative to container excluding scrolls
81
- scrollableLeft,
82
- scrollableTop,
83
- // Position relative to container including scrolls
84
- left,
85
- top,
86
- // Delta since grab (number representing how much we dragged)
87
- xDelta: left - leftAtGrab,
88
- yDelta: top - topAtGrab,
89
- };
90
- return layoutProps;
91
- };
92
-
93
- const grabLayout = createLayout(
94
- grabX + scrollContainer.scrollLeft,
95
- grabY + scrollContainer.scrollTop,
96
- );
97
- const gestureInfo = {
98
- name,
99
- direction,
100
- started: !threshold,
101
- status: "grabbed",
102
-
103
- element,
104
- scrollContainer,
105
- grabX, // x grab coordinate (excluding scroll)
106
- grabY, // y grab coordinate (excluding scroll)
107
- grabLayout,
108
- leftAtGrab,
109
- topAtGrab,
110
-
111
- dragX: grabX, // coordinate of the last drag (excluding scroll of the scrollContainer)
112
- dragY: grabY, // coordinate of the last drag (excluding scroll of the scrollContainer)
113
- layout: grabLayout,
114
-
115
- isGoingUp: undefined,
116
- isGoingDown: undefined,
117
- isGoingLeft: undefined,
118
- isGoingRight: undefined,
119
-
120
- // metadata about interaction sources
121
- grabEvent: event,
122
- dragEvent: null,
123
- releaseEvent: null,
124
- };
125
- definePropertyAsReadOnly(gestureInfo, "name");
126
- definePropertyAsReadOnly(gestureInfo, "direction");
127
- definePropertyAsReadOnly(gestureInfo, "scrollContainer");
128
- definePropertyAsReadOnly(gestureInfo, "grabX");
129
- definePropertyAsReadOnly(gestureInfo, "grabY");
130
- definePropertyAsReadOnly(gestureInfo, "grabLayout");
131
- definePropertyAsReadOnly(gestureInfo, "leftAtGrab");
132
- definePropertyAsReadOnly(gestureInfo, "topAtGrab");
133
- definePropertyAsReadOnly(gestureInfo, "grabEvent");
134
-
135
- document_interactions: {
136
- if (documentInteractions === "manual") {
137
- break document_interactions;
138
- }
139
- /*
140
- GOAL: Take control of document-level interactions during drag gestures
141
-
142
- WHY: During drag operations, we need to prevent conflicting user interactions that would:
143
- 1. Interfere with the drag gesture (competing pointer events, focus changes)
144
- 2. Break the visual feedback (inconsistent cursors, hover states)
145
- 3. Cause unwanted scrolling (keyboard shortcuts, wheel events in restricted directions)
146
- 4. Create accessibility issues (focus jumping, screen reader confusion)
147
-
148
- STRATEGY: Create a controlled interaction environment by:
149
- 1. VISUAL CONTROL: Use a backdrop to unify cursor appearance and block pointer events
150
- 2. INTERACTION ISOLATION: Make non-dragged elements inert to prevent interference
151
- 3. FOCUS MANAGEMENT: Control focus location and prevent focus changes during drag
152
- 4. SELECTIVE SCROLLING: Allow scrolling only in directions supported by the drag gesture
153
-
154
- IMPLEMENTATION:
155
- */
156
-
157
- // 1. INTERACTION ISOLATION: Make everything except the dragged element inert
158
- // This prevents keyboard events, pointer interactions, and screen reader navigation
159
- // on non-relevant elements during the drag operation
160
- const cleanupInert = isolateInteractions([
161
- element,
162
- ...Array.from(document.querySelectorAll("[data-droppable]")),
163
- ]);
164
- addReleaseCallback(() => {
165
- cleanupInert();
166
- });
167
-
168
- // 2. VISUAL CONTROL: Backdrop for consistent cursor and pointer event blocking
169
- if (backdrop) {
170
- const backdropElement = document.createElement("div");
171
- backdropElement.className = "navi_drag_gesture_backdrop";
172
- backdropElement.ariaHidden = "true";
173
- backdropElement.setAttribute("data-backdrop", "");
174
- backdropElement.style.zIndex = backdropZIndex;
175
- backdropElement.style.cursor = cursor;
176
-
177
- // Handle wheel events on backdrop for directionally-constrained drag gestures
178
- // (e.g., table column resize should only allow horizontal scrolling)
179
- if (!direction.x || !direction.y) {
180
- backdropElement.onwheel = (e) => {
181
- e.preventDefault();
182
- const scrollX = direction.x ? e.deltaX : 0;
183
- const scrollY = direction.y ? e.deltaY : 0;
184
- scrollContainer.scrollBy({
185
- left: scrollX,
186
- top: scrollY,
187
- behavior: "auto",
188
- });
189
- };
190
- }
191
- document.body.appendChild(backdropElement);
192
- addReleaseCallback(() => {
193
- backdropElement.remove();
194
- });
195
- }
196
-
197
- // 3. FOCUS MANAGEMENT: Control and stabilize focus during drag
198
- const { activeElement } = document;
199
- const focusableElement = findFocusable(element);
200
- // Focus the dragged element (or document.body as fallback) to establish clear focus context
201
- // This also ensure any keydown event listened by the currently focused element
202
- // won't be available during drag
203
- const elementToFocus = focusableElement || document.body;
204
- elementToFocus.focus({
205
- preventScroll: true,
206
- });
207
- addReleaseCallback(() => {
208
- // Restore original focus on release
209
- activeElement.focus({
210
- preventScroll: true,
211
- });
212
- });
213
- // Prevent Tab navigation entirely (focus should stay stable)
214
- const onkeydown = (e) => {
215
- if (e.key === "Tab") {
216
- e.preventDefault();
217
- return;
218
- }
219
- };
220
- document.addEventListener("keydown", onkeydown);
221
- addReleaseCallback(() => {
222
- document.removeEventListener("keydown", onkeydown);
223
- });
224
-
225
- // 4. SELECTIVE SCROLLING: Allow keyboard scrolling only in supported directions
226
- scroll_via_keyboard: {
227
- const onDocumentKeydown = (keyboardEvent) => {
228
- // Vertical scrolling keys - prevent if vertical movement not supported
229
- if (
230
- keyboardEvent.key === "ArrowUp" ||
231
- keyboardEvent.key === "ArrowDown" ||
232
- keyboardEvent.key === " " ||
233
- keyboardEvent.key === "PageUp" ||
234
- keyboardEvent.key === "PageDown" ||
235
- keyboardEvent.key === "Home" ||
236
- keyboardEvent.key === "End"
237
- ) {
238
- if (!direction.y) {
239
- keyboardEvent.preventDefault();
240
- }
241
- return;
242
- }
243
- // Horizontal scrolling keys - prevent if horizontal movement not supported
244
- if (
245
- keyboardEvent.key === "ArrowLeft" ||
246
- keyboardEvent.key === "ArrowRight"
247
- ) {
248
- if (!direction.x) {
249
- keyboardEvent.preventDefault();
250
- }
251
- return;
252
- }
253
- };
254
- document.addEventListener("keydown", onDocumentKeydown);
255
- addReleaseCallback(() => {
256
- document.removeEventListener("keydown", onDocumentKeydown);
257
- });
258
- }
259
- }
260
-
261
- // Set up scroll event handling to adjust drag position when scrolling occurs
262
- drag_on_scroll: {
263
- let isHandlingScroll = false;
264
- const handleScroll = (scrollEvent) => {
265
- if (isHandlingScroll) {
266
- return;
267
- }
268
- isHandlingScroll = true;
269
- drag(gestureInfo.dragX, gestureInfo.dragY, { event: scrollEvent });
270
- isHandlingScroll = false;
271
- };
272
- const scrollEventReceiver =
273
- scrollContainer === document.documentElement
274
- ? document
275
- : scrollContainer;
276
- scrollEventReceiver.addEventListener("scroll", handleScroll, {
277
- passive: true,
278
- });
279
- addReleaseCallback(() => {
280
- scrollEventReceiver.removeEventListener("scroll", handleScroll, {
281
- passive: true,
282
- });
283
- });
284
- }
285
-
286
- const determineDragData = ({
287
- dragX,
288
- dragY,
289
- dragEvent,
290
- isRelease = false,
291
- }) => {
292
- // === ÉTAT INITIAL (au moment du grab) ===
293
- const { grabX, grabY, grabLayout } = gestureInfo;
294
- // === CE QUI EST DEMANDÉ (où on veut aller) ===
295
- // Calcul de la direction basé sur le mouvement précédent
296
- // (ne tient pas compte du mouvement final une fois les contraintes appliquées)
297
- // (ici on veut connaitre l'intention)
298
- // on va utiliser cela pour savoir vers où on scroll si nécéssaire par ex
299
- const currentDragX = gestureInfo.dragX;
300
- const currentDragY = gestureInfo.dragY;
301
- const isGoingLeft = dragX < currentDragX;
302
- const isGoingRight = dragX > currentDragX;
303
- const isGoingUp = dragY < currentDragY;
304
- const isGoingDown = dragY > currentDragY;
305
-
306
- const layoutXRequested = direction.x
307
- ? scrollContainer.scrollLeft + (dragX - grabX)
308
- : grabLayout.scrollLeft;
309
- const layoutYRequested = direction.y
310
- ? scrollContainer.scrollTop + (dragY - grabY)
311
- : grabLayout.scrollTop;
312
- const layoutRequested = createLayout(layoutXRequested, layoutYRequested);
313
- const currentLayout = gestureInfo.layout;
314
- let layout;
315
- if (
316
- layoutRequested.x === currentLayout.x &&
317
- layoutRequested.y === currentLayout.y
318
- ) {
319
- layout = currentLayout;
320
- } else {
321
- // === APPLICATION DES CONTRAINTES ===
322
- let layoutConstrained = layoutRequested;
323
- const limitLayout = (left, top) => {
324
- layoutConstrained = createLayout(
325
- left === undefined
326
- ? layoutConstrained.x
327
- : left - scrollableLeftAtGrab,
328
- top === undefined ? layoutConstrained.y : top - scrollableTopAtGrab,
329
- );
330
- };
331
-
332
- publishBeforeDrag(layoutRequested, currentLayout, limitLayout, {
333
- dragEvent,
334
- isRelease,
335
- });
336
- // === ÉTAT FINAL ===
337
- layout = layoutConstrained;
338
- }
339
-
340
- const dragData = {
341
- dragX,
342
- dragY,
343
- layout,
344
-
345
- isGoingLeft,
346
- isGoingRight,
347
- isGoingUp,
348
- isGoingDown,
349
-
350
- status: isRelease ? "released" : "dragging",
351
- dragEvent: isRelease ? gestureInfo.dragEvent : dragEvent,
352
- releaseEvent: isRelease ? dragEvent : null,
353
- };
354
-
355
- if (isRelease) {
356
- return dragData;
357
- }
358
- if (!gestureInfo.started && threshold) {
359
- const deltaX = Math.abs(dragX - grabX);
360
- const deltaY = Math.abs(dragY - grabY);
361
- if (direction.x && direction.y) {
362
- // Both directions: check both axes
363
- if (deltaX < threshold && deltaY < threshold) {
364
- return dragData;
365
- }
366
- } else if (direction.x) {
367
- if (deltaX < threshold) {
368
- return dragData;
369
- }
370
- } else if (direction.y) {
371
- if (deltaY < threshold) {
372
- return dragData;
373
- }
374
- }
375
- dragData.started = true;
376
- }
377
- return dragData;
378
- };
379
-
380
- const drag = (
381
- dragX = gestureInfo.dragX, // Scroll container relative X coordinate
382
- dragY = gestureInfo.dragY, // Scroll container relative Y coordinate
383
- { event = new CustomEvent("programmatic"), isRelease = false } = {},
384
- ) => {
385
- if (import.meta.dev && (isNaN(dragX) || isNaN(dragY))) {
386
- throw new Error(`Invalid drag coordinates x=${dragX} y=${dragY}`);
387
- }
388
-
389
- const dragData = determineDragData({
390
- dragX,
391
- dragY,
392
- dragEvent: event,
393
- isRelease,
394
- });
395
- const startedPrevious = gestureInfo.started;
396
- const layoutPrevious = gestureInfo.layout;
397
- // previousGestureInfo = { ...gestureInfo };
398
- Object.assign(gestureInfo, dragData);
399
- if (!startedPrevious && gestureInfo.started) {
400
- onDragStart?.(gestureInfo);
401
- }
402
- const someLayoutChange = gestureInfo.layout !== layoutPrevious;
403
- publishDrag(
404
- gestureInfo,
405
- // we still publish drag event even when unchanged
406
- // because UI might need to adjust when document scrolls
407
- // even if nothing truly changes visually the element
408
- // can decide to stick to the scroll for example
409
- someLayoutChange,
410
- );
411
- };
412
-
413
- const release = ({
414
- event = new CustomEvent("programmatic"),
415
- releaseX = gestureInfo.dragX,
416
- releaseY = gestureInfo.dragY,
417
- } = {}) => {
418
- drag(releaseX, releaseY, { event, isRelease: true });
419
- publishRelease(gestureInfo);
420
- };
421
-
422
- onGrab?.(gestureInfo);
423
- const dragGesture = {
424
- gestureInfo,
425
- addBeforeDragCallback,
426
- addDragCallback,
427
- addReleaseCallback,
428
- drag,
429
- release,
430
- };
431
- return dragGesture;
432
- };
433
- dragGestureController.grab = grab;
434
-
435
- const initDragByPointer = (grabEvent, dragOptions, initializer) => {
436
- if (grabEvent.button !== undefined && grabEvent.button !== 0) {
437
- return null;
438
- }
439
- const target = grabEvent.target;
440
- if (!target.closest) {
441
- // target is a text node
442
- return null;
443
- }
444
- const mouseEventCoords = (mouseEvent) => {
445
- const { clientX, clientY } = mouseEvent;
446
- return [clientX, clientY];
447
- };
448
- const [grabX, grabY] = mouseEventCoords(grabEvent);
449
- const dragGesture = dragGestureController.grab({
450
- grabX,
451
- grabY,
452
- event: grabEvent,
453
- ...dragOptions,
454
- });
455
- const dragViaPointer = (dragEvent) => {
456
- const [mouseDragX, mouseDragY] = mouseEventCoords(dragEvent);
457
- dragGesture.drag(mouseDragX, mouseDragY, {
458
- event: dragEvent,
459
- });
460
- };
461
- const releaseViaPointer = (mouseupEvent) => {
462
- const [mouseReleaseX, mouseReleaseY] = mouseEventCoords(mouseupEvent);
463
- dragGesture.release({
464
- event: mouseupEvent,
465
- releaseX: mouseReleaseX,
466
- releaseY: mouseReleaseY,
467
- });
468
- };
469
- dragGesture.dragViaPointer = dragViaPointer;
470
- dragGesture.releaseViaPointer = releaseViaPointer;
471
- const cleanup = initializer({
472
- onMove: dragViaPointer,
473
- onRelease: releaseViaPointer,
474
- });
475
- dragGesture.addReleaseCallback(() => {
476
- cleanup();
477
- });
478
- return dragGesture;
479
- };
480
-
481
- const grabViaPointer = (grabEvent, options) => {
482
- if (grabEvent.type === "pointerdown") {
483
- return initDragByPointer(grabEvent, options, ({ onMove, onRelease }) => {
484
- const target = grabEvent.target;
485
- target.setPointerCapture(grabEvent.pointerId);
486
- target.addEventListener("lostpointercapture", onRelease);
487
- target.addEventListener("pointercancel", onRelease);
488
- target.addEventListener("pointermove", onMove);
489
- target.addEventListener("pointerup", onRelease);
490
- return () => {
491
- target.releasePointerCapture(grabEvent.pointerId);
492
- target.removeEventListener("lostpointercapture", onRelease);
493
- target.removeEventListener("pointercancel", onRelease);
494
- target.removeEventListener("pointermove", onMove);
495
- target.removeEventListener("pointerup", onRelease);
496
- };
497
- });
498
- }
499
- if (grabEvent.type === "mousedown") {
500
- console.warn(
501
- `Received "mousedown" event, "pointerdown" events are recommended to perform drag gestures.`,
502
- );
503
- return initDragByPointer(grabEvent, options, ({ onMove, onRelease }) => {
504
- const onPointerUp = (pointerEvent) => {
505
- // <button disabled> for example does not emit mouseup if we release mouse over it
506
- // -> we add "pointerup" to catch mouseup occuring on disabled element
507
- if (pointerEvent.pointerType === "mouse") {
508
- onRelease(pointerEvent);
509
- }
510
- };
511
- document.addEventListener("mousemove", onMove);
512
- document.addEventListener("mouseup", onRelease);
513
- document.addEventListener("pointerup", onPointerUp);
514
- return () => {
515
- document.removeEventListener("mousemove", onMove);
516
- document.removeEventListener("mouseup", onRelease);
517
- document.removeEventListener("pointerup", onPointerUp);
518
- };
519
- });
520
- }
521
- throw new Error(
522
- `Unsupported "${grabEvent.type}" evenet passed to grabViaPointer. "pointerdown" was expected.`,
523
- );
524
- };
525
- dragGestureController.grabViaPointer = grabViaPointer;
526
-
527
- return dragGestureController;
528
- };
529
-
530
- export const dragAfterThreshold = (
531
- grabEvent,
532
- dragGestureInitializer,
533
- threshold,
534
- ) => {
535
- const significantDragGestureController = createDragGestureController({
536
- threshold,
537
- // allow interaction for this intermediate gesture:
538
- // user should still be able to scroll or interact with the document
539
- // only once the gesture is significant we take control
540
- documentInteractions: "manual",
541
- onDragStart: (gestureInfo) => {
542
- significantDragGesture.release(); // kill that gesture
543
- const dragGesture = dragGestureInitializer();
544
- dragGesture.dragViaPointer(gestureInfo.dragEvent);
545
- },
546
- });
547
- const significantDragGesture =
548
- significantDragGestureController.grabViaPointer(grabEvent, {
549
- element: grabEvent.target,
550
- });
551
- };
552
-
553
- const definePropertyAsReadOnly = (object, propertyName) => {
554
- Object.defineProperty(object, propertyName, {
555
- writable: false,
556
- value: object[propertyName],
557
- });
558
- };
559
-
560
- import.meta.css = /* css */ `
561
- .navi_drag_gesture_backdrop {
562
- position: fixed;
563
- inset: 0;
564
- user-select: none;
565
- }
566
- `;