@react-hive/honey-layout 10.4.1 → 10.6.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.
@@ -13725,6 +13725,7 @@ __webpack_require__.r(__webpack_exports__);
13725
13725
  /* harmony export */ useHoneyMediaQuery: () => (/* reexport safe */ _use_honey_media_query__WEBPACK_IMPORTED_MODULE_1__.useHoneyMediaQuery),
13726
13726
  /* harmony export */ useHoneyOnChange: () => (/* reexport safe */ _use_honey_on_change__WEBPACK_IMPORTED_MODULE_0__.useHoneyOnChange),
13727
13727
  /* harmony export */ useHoneyOverlay: () => (/* reexport safe */ _use_honey_overlay__WEBPACK_IMPORTED_MODULE_6__.useHoneyOverlay),
13728
+ /* harmony export */ useHoneyRafLoop: () => (/* reexport safe */ _use_honey_raf_loop__WEBPACK_IMPORTED_MODULE_11__.useHoneyRafLoop),
13728
13729
  /* harmony export */ useHoneyResize: () => (/* reexport safe */ _use_honey_resize__WEBPACK_IMPORTED_MODULE_7__.useHoneyResize),
13729
13730
  /* harmony export */ useHoneySyntheticScroll: () => (/* reexport safe */ _use_honey_synthetic_scroll__WEBPACK_IMPORTED_MODULE_8__.useHoneySyntheticScroll),
13730
13731
  /* harmony export */ useHoneySyntheticScrollX: () => (/* reexport safe */ _use_honey_synthetic_scroll_x__WEBPACK_IMPORTED_MODULE_9__.useHoneySyntheticScrollX),
@@ -13742,6 +13743,8 @@ __webpack_require__.r(__webpack_exports__);
13742
13743
  /* harmony import */ var _use_honey_synthetic_scroll__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./use-honey-synthetic-scroll */ "./src/hooks/use-honey-synthetic-scroll.ts");
13743
13744
  /* harmony import */ var _use_honey_synthetic_scroll_x__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./use-honey-synthetic-scroll-x */ "./src/hooks/use-honey-synthetic-scroll-x.ts");
13744
13745
  /* harmony import */ var _use_honey_synthetic_scroll_y__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./use-honey-synthetic-scroll-y */ "./src/hooks/use-honey-synthetic-scroll-y.ts");
13746
+ /* harmony import */ var _use_honey_raf_loop__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./use-honey-raf-loop */ "./src/hooks/use-honey-raf-loop.ts");
13747
+
13745
13748
 
13746
13749
 
13747
13750
 
@@ -13895,11 +13898,11 @@ const useHoneyDrag = (draggableElementRef, { skipOnEndDragWhenStopped = false, e
13895
13898
  };
13896
13899
  const releaseDrag = async (isTriggerOnEndDrag, e) => {
13897
13900
  await stopDrag(isTriggerOnEndDrag, e);
13898
- window.removeEventListener('mousemove', mouseMoveHandler);
13899
- window.removeEventListener('mouseup', mouseUpHandler);
13900
- window.removeEventListener('touchmove', touchMoveHandler);
13901
- window.removeEventListener('touchend', touchEndHandler);
13902
- window.removeEventListener('touchcancel', touchCancelHandler);
13901
+ window.removeEventListener('mousemove', mouseMoveHandler, { capture: true });
13902
+ window.removeEventListener('mouseup', mouseUpHandler, { capture: true });
13903
+ window.removeEventListener('touchmove', touchMoveHandler, { capture: true });
13904
+ window.removeEventListener('touchend', touchEndHandler, { capture: true });
13905
+ window.removeEventListener('touchcancel', touchCancelHandler, { capture: true });
13903
13906
  };
13904
13907
  const mouseUpHandler = async (e) => {
13905
13908
  await releaseDrag(true, e);
@@ -13943,15 +13946,16 @@ const useHoneyDrag = (draggableElementRef, { skipOnEndDragWhenStopped = false, e
13943
13946
  await startDrag(touch.clientX, touch.clientY, e);
13944
13947
  window.addEventListener('touchmove', touchMoveHandler, {
13945
13948
  passive: true,
13949
+ capture: true,
13946
13950
  });
13947
- window.addEventListener('touchend', touchEndHandler);
13948
- window.addEventListener('touchcancel', touchCancelHandler);
13951
+ window.addEventListener('touchend', touchEndHandler, { capture: true });
13952
+ window.addEventListener('touchcancel', touchCancelHandler, { capture: true });
13949
13953
  };
13950
13954
  const mouseDownHandler = async (e) => {
13951
13955
  e.stopPropagation();
13952
13956
  await startDrag(e.clientX, e.clientY, e);
13953
- window.addEventListener('mousemove', mouseMoveHandler);
13954
- window.addEventListener('mouseup', mouseUpHandler);
13957
+ window.addEventListener('mousemove', mouseMoveHandler, { capture: true });
13958
+ window.addEventListener('mouseup', mouseUpHandler, { capture: true });
13955
13959
  };
13956
13960
  draggableElement.addEventListener('mousedown', mouseDownHandler);
13957
13961
  draggableElement.addEventListener('touchstart', touchStartHandler, {
@@ -14166,6 +14170,149 @@ const useHoneyOverlay = (targetOverlayId, { onKeyUp } = {}) => {
14166
14170
  };
14167
14171
 
14168
14172
 
14173
+ /***/ },
14174
+
14175
+ /***/ "./src/hooks/use-honey-raf-loop.ts"
14176
+ /*!*****************************************!*\
14177
+ !*** ./src/hooks/use-honey-raf-loop.ts ***!
14178
+ \*****************************************/
14179
+ (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
14180
+
14181
+ "use strict";
14182
+ __webpack_require__.r(__webpack_exports__);
14183
+ /* harmony export */ __webpack_require__.d(__webpack_exports__, {
14184
+ /* harmony export */ useHoneyRafLoop: () => (/* binding */ useHoneyRafLoop)
14185
+ /* harmony export */ });
14186
+ /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ "react");
14187
+ /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
14188
+
14189
+ /**
14190
+ * A hook for running a controlled `requestAnimationFrame` loop.
14191
+ *
14192
+ * Features:
14193
+ * - Explicit RAF lifecycle control (`start` / `stop`)
14194
+ * - Delta time (`dt`) calculation with frame clamping
14195
+ * - Automatic cleanup on unmounting
14196
+ * - Conservative handling of tab visibility changes (mobile-safe)
14197
+ * - Safe error handling (stops loop on exception)
14198
+ *
14199
+ * Visibility behavior:
14200
+ * - The RAF loop is always stopped when the document becomes hidden
14201
+ * - Automatic resume is disabled by default and must be explicitly enabled
14202
+ *
14203
+ * This hook is designed for gesture handling, inertia, physics simulations,
14204
+ * and animation loops that must not trigger React re-renders on every frame.
14205
+ *
14206
+ * @param callback - Function invoked on each animation frame.
14207
+ * @param options - Optional configuration for the RAF loop.
14208
+ *
14209
+ * @returns Control helpers and RAF loop state.
14210
+ *
14211
+ * @example
14212
+ * ```ts
14213
+ * // Gesture-driven inertia (recommended usage)
14214
+ * // The RAF loop stops itself when motion decays.
14215
+ *
14216
+ * const velocityRef = useRef({ x: 12, y: 4 });
14217
+ *
14218
+ * const onFrame = useCallback<HoneyRafCallback>(
14219
+ * (dtMs, { stop }) => {
14220
+ * velocityRef.current.x *= 0.94;
14221
+ * velocityRef.current.y *= 0.94;
14222
+ *
14223
+ * setPosition(p => ({
14224
+ * x: p.x + velocityRef.current.x,
14225
+ * y: p.y + velocityRef.current.y,
14226
+ * }));
14227
+ *
14228
+ * if (
14229
+ * Math.abs(velocityRef.current.x) < 0.1 &&
14230
+ * Math.abs(velocityRef.current.y) < 0.1
14231
+ * ) {
14232
+ * stop(); // terminate RAF loop
14233
+ * }
14234
+ * },
14235
+ * [],
14236
+ * );
14237
+ *
14238
+ * useHoneyRafLoop(onFrame);
14239
+ * ```
14240
+ */
14241
+ const useHoneyRafLoop = (callback, { autoStart = false, resumeOnVisibility = false, maxDeltaMs = 32, // ~30fps clamp
14242
+ onError, } = {}) => {
14243
+ const rafIdRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
14244
+ const lastTimeRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
14245
+ const callbackRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(callback);
14246
+ // Always keep the latest callback without restarting RAF
14247
+ callbackRef.current = callback;
14248
+ const [isRafLoopRunning, setIsRafLoopRunning] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false);
14249
+ const loop = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(time => {
14250
+ if (lastTimeRef.current === null) {
14251
+ lastTimeRef.current = time;
14252
+ }
14253
+ let dt = time - lastTimeRef.current;
14254
+ lastTimeRef.current = time;
14255
+ // Clamp delta (prevents jumps after background tab / lag)
14256
+ if (dt > maxDeltaMs) {
14257
+ dt = maxDeltaMs;
14258
+ }
14259
+ try {
14260
+ callbackRef.current(dt, {
14261
+ stop: stopRafLoop,
14262
+ });
14263
+ rafIdRef.current = requestAnimationFrame(loop);
14264
+ }
14265
+ catch (e) {
14266
+ stopRafLoop();
14267
+ onError?.(e);
14268
+ }
14269
+ }, [maxDeltaMs, onError]);
14270
+ const startRafLoop = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
14271
+ if (rafIdRef.current !== null) {
14272
+ return;
14273
+ }
14274
+ lastTimeRef.current = null;
14275
+ setIsRafLoopRunning(true);
14276
+ rafIdRef.current = requestAnimationFrame(loop);
14277
+ }, [loop]);
14278
+ const stopRafLoop = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
14279
+ if (rafIdRef.current === null) {
14280
+ return;
14281
+ }
14282
+ cancelAnimationFrame(rafIdRef.current);
14283
+ rafIdRef.current = null;
14284
+ lastTimeRef.current = null;
14285
+ setIsRafLoopRunning(false);
14286
+ }, []);
14287
+ (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
14288
+ if (autoStart) {
14289
+ startRafLoop();
14290
+ }
14291
+ return stopRafLoop;
14292
+ }, [autoStart, startRafLoop, stopRafLoop]);
14293
+ // Pause when a tab is hidden (important for mobile)
14294
+ (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
14295
+ const onVisibilityChange = () => {
14296
+ if (document.hidden) {
14297
+ stopRafLoop();
14298
+ }
14299
+ else if (resumeOnVisibility && autoStart) {
14300
+ startRafLoop();
14301
+ }
14302
+ };
14303
+ document.addEventListener('visibilitychange', onVisibilityChange);
14304
+ return () => {
14305
+ document.removeEventListener('visibilitychange', onVisibilityChange);
14306
+ };
14307
+ }, [autoStart, resumeOnVisibility, startRafLoop, stopRafLoop]);
14308
+ return {
14309
+ startRafLoop,
14310
+ stopRafLoop,
14311
+ isRafLoopRunning,
14312
+ };
14313
+ };
14314
+
14315
+
14169
14316
  /***/ },
14170
14317
 
14171
14318
  /***/ "./src/hooks/use-honey-resize.ts"
@@ -15260,6 +15407,7 @@ __webpack_require__.r(__webpack_exports__);
15260
15407
  /* harmony export */ useHoneyOverlay: () => (/* reexport safe */ _hooks__WEBPACK_IMPORTED_MODULE_5__.useHoneyOverlay),
15261
15408
  /* harmony export */ useHoneyPopup: () => (/* reexport safe */ _components__WEBPACK_IMPORTED_MODULE_3__.useHoneyPopup),
15262
15409
  /* harmony export */ useHoneyPopupContext: () => (/* reexport safe */ _components__WEBPACK_IMPORTED_MODULE_3__.useHoneyPopupContext),
15410
+ /* harmony export */ useHoneyRafLoop: () => (/* reexport safe */ _hooks__WEBPACK_IMPORTED_MODULE_5__.useHoneyRafLoop),
15263
15411
  /* harmony export */ useHoneyResize: () => (/* reexport safe */ _hooks__WEBPACK_IMPORTED_MODULE_5__.useHoneyResize),
15264
15412
  /* harmony export */ useHoneySyntheticScroll: () => (/* reexport safe */ _hooks__WEBPACK_IMPORTED_MODULE_5__.useHoneySyntheticScroll),
15265
15413
  /* harmony export */ useHoneySyntheticScrollX: () => (/* reexport safe */ _hooks__WEBPACK_IMPORTED_MODULE_5__.useHoneySyntheticScrollX),