@react-hive/honey-layout 17.5.0 → 17.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.
@@ -5973,24 +5973,28 @@ __webpack_require__.r(__webpack_exports__);
5973
5973
 
5974
5974
 
5975
5975
  /**
5976
- * Hook for interacting with an active overlay managed by `HoneyLayoutProvider`.
5976
+ * Returns an active overlay by ID and optionally attaches overlay event listeners.
5977
5977
  *
5978
- * @param targetOverlayId - The unique ID of the overlay you want to interact with.
5979
- * @param options - Optional configuration such as event handlers (e.g., `onKeyUp`).
5978
+ * This hook looks up an overlay registered in `HoneyLayoutProvider` by its ID.
5979
+ * It can also subscribe to overlay-level events, such as `keyup`, for the matched overlay.
5980
5980
  *
5981
- * @returns The overlay instance matching the provided ID, or `undefined` if not found.
5981
+ * @param targetOverlayId - The ID of the active overlay to find.
5982
+ * @param options - Optional overlay event handlers.
5983
+ *
5984
+ * @returns The matching active overlay instance, or `undefined` when the overlay is not registered.
5982
5985
  *
5983
5986
  * @remarks
5984
- * - This hook only works with overlays that are currently active.
5985
- * - If the overlay is not active or not registered, `undefined` will be returned.
5986
- * - Event handlers like `onKeyUp` are automatically registered and cleaned up for the overlay.
5987
+ * - The hook only works with overlays that are currently active.
5988
+ * - If the overlay is inactive, unregistered, or already removed from the stack, `undefined` is returned.
5989
+ * - The `onKeyUp` listener is attached only to the matched overlay.
5990
+ * - Event listeners are automatically cleaned up when the overlay, handler, or component lifecycle changes.
5987
5991
  *
5988
5992
  * @example
5989
5993
  * ```tsx
5990
5994
  * const overlay = useHoneyOverlay('my-overlay-id', {
5991
- * onKeyUp: (keyCode, e) => {
5995
+ * onKeyUp: (keyCode, overlay, e) => {
5992
5996
  * if (keyCode === 'Escape') {
5993
- * console.log('Escape key pressed!');
5997
+ * //
5994
5998
  * }
5995
5999
  * },
5996
6000
  * });
@@ -5998,7 +6002,7 @@ __webpack_require__.r(__webpack_exports__);
5998
6002
  */
5999
6003
  const useHoneyOverlay = (targetOverlayId, { onKeyUp } = {}) => {
6000
6004
  const { overlays } = (0,_hooks__WEBPACK_IMPORTED_MODULE_1__.useHoneyLayout)();
6001
- const overlay = overlays.find(overlay => overlay.id === targetOverlayId);
6005
+ const overlay = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => overlays.find(overlay => overlay.id === targetOverlayId), [overlays, targetOverlayId]);
6002
6006
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
6003
6007
  // If no overlay is found or no `onKeyUp` handler is provided, skip setting up the listener
6004
6008
  if (!overlay || !onKeyUp) {
@@ -6175,16 +6179,29 @@ __webpack_require__.r(__webpack_exports__);
6175
6179
 
6176
6180
 
6177
6181
  /**
6178
- * Hook to manage a stack of overlays, allowing registration and unregistration of overlays,
6179
- * as well as handling keyboard events for the topmost overlay.
6182
+ * Manages the active overlay stack and global keyboard event dispatching.
6183
+ *
6184
+ * The hook keeps registered overlays in stack order, where the latest registered overlay
6185
+ * is treated as the top-level overlay. Keyboard events are forwarded only to the top-level
6186
+ * overlay, allowing nested or overlapping overlays to handle key interactions predictably.
6187
+ *
6188
+ * @returns An object containing the active overlays stack and helper methods for registering
6189
+ * and unregistering overlays.
6180
6190
  */
6181
6191
  const useHoneyOverlays = () => {
6182
- const overlaysRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)([]);
6192
+ const [overlays, setOverlays] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)([]);
6183
6193
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
6194
+ /**
6195
+ * Handles global keyup events and forwards them to the top-level overlay.
6196
+ *
6197
+ * Only the latest registered overlay receives keyboard events. This prevents inactive
6198
+ * or visually hidden overlays lower in the stack from reacting to the same key press.
6199
+ *
6200
+ * @param e - The native keyboard event emitted by the document.
6201
+ */
6184
6202
  const handleKeyUp = (e) => {
6185
- const overlays = overlaysRef.current;
6186
6203
  if (!overlays.length) {
6187
- // No overlays to handle key events
6204
+ // No overlays to handle key events.
6188
6205
  return;
6189
6206
  }
6190
6207
  const topLevelOverlay = overlays[overlays.length - 1];
@@ -6194,13 +6211,19 @@ const useHoneyOverlays = () => {
6194
6211
  return () => {
6195
6212
  document.removeEventListener('keyup', handleKeyUp);
6196
6213
  };
6197
- }, []);
6214
+ }, [overlays]);
6198
6215
  /**
6199
- * Registers a new overlay and adds it to the stack.
6216
+ * Registers a new overlay and adds it to the top of the overlay stack.
6217
+ *
6218
+ * If no custom ID is provided, an ephemeral ID is generated automatically.
6219
+ * The returned overlay object exposes methods for storing its container element,
6220
+ * subscribing to overlay events, removing event listeners, and notifying registered
6221
+ * listeners when matching events occur.
6200
6222
  *
6201
- * @param overlayConfig - The configuration for the overlay, including optional ID and event handlers.
6223
+ * @param overlayConfig - The overlay configuration, including an optional ID, optional keyup
6224
+ * handler, and optional list of keyboard codes the overlay should listen to.
6202
6225
  *
6203
- * @returns The registered overlay object.
6226
+ * @returns The registered active overlay instance.
6204
6227
  */
6205
6228
  const registerOverlay = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(overlayConfig => {
6206
6229
  const overlayId = overlayConfig.id ?? (0,_react_hive_honey_utils__WEBPACK_IMPORTED_MODULE_1__.generateEphemeralId)();
@@ -6211,18 +6234,54 @@ const useHoneyOverlays = () => {
6211
6234
  const overlay = {
6212
6235
  containerRef,
6213
6236
  id: overlayId,
6237
+ /**
6238
+ * Stores the overlay container element reference.
6239
+ *
6240
+ * This allows consumers and overlay helpers to access the DOM element associated
6241
+ * with the active overlay after it has been mounted.
6242
+ *
6243
+ * @param element - The overlay container element, or `null` when unavailable.
6244
+ */
6214
6245
  setContainerRef: element => {
6215
6246
  containerRef.current = element;
6216
6247
  },
6248
+ /**
6249
+ * Adds a listener for a supported overlay event.
6250
+ *
6251
+ * @param type - The overlay event type to listen for.
6252
+ * @param handler - The event handler to call when the event is notified.
6253
+ */
6217
6254
  addListener: (type, handler) => {
6218
6255
  listeners.push([type, handler]);
6219
6256
  },
6257
+ /**
6258
+ * Removes a previously registered overlay event listener.
6259
+ *
6260
+ * The listener is removed only when both the event type and handler reference match.
6261
+ *
6262
+ * @param targetType - The event type of the listener to remove.
6263
+ * @param targetHandler - The exact handler reference to remove.
6264
+ */
6220
6265
  removeListener: (targetType, targetHandler) => {
6221
6266
  const targetListenerIndex = listeners.findIndex(([type, listenerHandler]) => type === targetType && listenerHandler === targetHandler);
6222
6267
  if (targetListenerIndex !== -1) {
6223
6268
  listeners.splice(targetListenerIndex, 1);
6224
6269
  }
6225
6270
  },
6271
+ /**
6272
+ * Notifies matching listeners for a specific overlay event.
6273
+ *
6274
+ * If `listenKeys` is provided in the overlay config, listeners are called only when
6275
+ * the received key code is included in that list. When no `listenKeys` are provided,
6276
+ * all key codes are accepted.
6277
+ *
6278
+ * The native event is prevented before listeners are called, ensuring handled overlay
6279
+ * keyboard interactions do not trigger default browser behaviour.
6280
+ *
6281
+ * @param targetEventType - The event type being dispatched.
6282
+ * @param keyCode - The keyboard code associated with the event.
6283
+ * @param e - The native keyboard event.
6284
+ */
6226
6285
  notifyListeners: (targetEventType, keyCode, e) => {
6227
6286
  const listenKeys = overlayConfig.listenKeys ?? [];
6228
6287
  if (!listenKeys.length || listenKeys.includes(keyCode)) {
@@ -6235,19 +6294,21 @@ const useHoneyOverlays = () => {
6235
6294
  }
6236
6295
  },
6237
6296
  };
6238
- overlaysRef.current.push(overlay);
6297
+ setOverlays(prevOverlays => [...prevOverlays, overlay]);
6239
6298
  return overlay;
6240
6299
  }, []);
6241
6300
  /**
6242
- * Unregisters an overlay by its ID and removes it from the stack.
6301
+ * Unregisters an overlay by ID and removes it from the overlay stack.
6243
6302
  *
6244
- * @param targetOverlayId - The ID of the overlay to be removed.
6303
+ * This should usually be called when an overlay is deactivated or unmounted.
6304
+ *
6305
+ * @param targetOverlayId - The ID of the overlay to remove.
6245
6306
  */
6246
6307
  const unregisterOverlay = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(targetOverlayId => {
6247
- overlaysRef.current = overlaysRef.current.filter(overlay => overlay.id !== targetOverlayId);
6308
+ setOverlays(prevOverlays => prevOverlays.filter(overlay => overlay.id !== targetOverlayId));
6248
6309
  }, []);
6249
6310
  return {
6250
- overlays: overlaysRef.current,
6311
+ overlays,
6251
6312
  registerOverlay,
6252
6313
  unregisterOverlay,
6253
6314
  };