All files / src/components/SearchPanel useContextMenu.hook.ts

100% Statements 27/27
100% Branches 3/3
100% Functions 3/3
100% Lines 27/27

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 971x                                                         1x                                                       1x 1x 6x   6x               6x 6x 2x 2x   2x 2x 2x 2x 2x 2x   6x       6x 6x 1x 1x   6x 6x 6x 6x 6x 6x  
import { useState, MouseEvent } from 'react';
 
/**
 * Context menu state object containing position and product data.
 * @source
 */
interface ContextMenuState {
  /** X coordinate for menu positioning (in pixels from left edge) */
  x: number;
  /** Y coordinate for menu positioning (in pixels from top edge) */
  y: number;
  /** Product data associated with the context menu */
  product: Product;
}
 
/**
 * Return type for the useContextMenu hook.
 * Contains context menu state and handler functions.
 * @source
 */
interface UseContextMenuReturn {
  /** Current context menu state, null when menu is closed */
  contextMenu: ContextMenuState | null;
  /** Function to handle context menu open events */
  handleContextMenu: (event: MouseEvent, product: Product) => void;
  /** Function to close the context menu */
  handleCloseContextMenu: () => void;
}
 
/**
 * Hook to manage context menu state and positioning for table rows.
 * Provides handlers for opening, closing, and positioning a context menu.
 *
 * This hook manages the visibility and positioning of a context menu that appears
 * when users right-click on table rows. It captures the mouse position and
 * associated product data to display relevant actions.
 *
 * @returns Context menu state and handlers
 *
 * @example
 * ```tsx
 * const { contextMenu, handleContextMenu, handleCloseContextMenu } = useContextMenu();
 *
 * // In table row:
 * <tr onContextMenu={(e) => handleContextMenu(e, row.original)}>
 *
 * // Render menu:
 * {contextMenu && (
 *   <ContextMenu
 *     x={contextMenu.x}
 *     y={contextMenu.y}
 *     product={contextMenu.product}
 *     onClose={handleCloseContextMenu}
 *   />
 * )}
 * ```
 * @source
 */
export function useContextMenu(): UseContextMenuReturn {
  const [contextMenu, setContextMenu] = useState<ContextMenuState | null>(null);
 
  /**
   * Handles context menu open events from right-click actions.
   * Prevents the default browser context menu and captures the mouse
   * position and product data for the custom context menu.
   *
   * @param event - The mouse event from the right-click
   * @param product - The product data associated with the clicked row
   * @source
   */
  const handleContextMenu = (event: MouseEvent, product: Product) => {
    event.preventDefault();
    event.stopPropagation();
 
    setContextMenu({
      x: event.clientX,
      y: event.clientY,
      product,
    });
  };
 
  /**
   * Closes the context menu by setting the state to null.
   * This hides the context menu from the UI.
   * @source
   */
  const handleCloseContextMenu = () => {
    setContextMenu(null);
  };
 
  return {
    contextMenu,
    handleContextMenu,
    handleCloseContextMenu,
  };
}