All files / src/components/ui/hooks use-select-all.ts

0% Statements 0/40
0% Branches 0/19
0% Functions 0/7
0% Lines 0/39

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                                                                                                                                                               
import { useEffect, useRef } from "react";
import API from "renderer/lib/api";
 
interface UseSelectAllShortcutOptions {
  onSelectAll: () => void;
  enabled?: boolean;
}
 
const isEditableTarget = (target: EventTarget | null): boolean => {
  return (
    target instanceof HTMLInputElement ||
    target instanceof HTMLTextAreaElement ||
    (target instanceof HTMLElement && target.isContentEditable)
  );
};
 
export const useSelectAllShortcut = ({
  onSelectAll,
  enabled = true,
}: UseSelectAllShortcutOptions): void => {
  const isClearingSelectionRef = useRef(false);
  const resetSelectionClearRef = useRef<number | null>(null);
 
  useEffect(() => {
    Iif (!enabled) {
      return;
    }
 
    const onKeyDown = (e: KeyboardEvent) => {
      Iif ((e.metaKey || e.ctrlKey) && !e.shiftKey && e.code === "KeyA") {
        Iif (isEditableTarget(e.target)) {
          return;
        }
 
        e.preventDefault();
        onSelectAll();
      }
    };
 
    const onSelectionChange = (e: Event) => {
      Iif (isClearingSelectionRef.current) {
        return;
      }
 
      const selection = window.getSelection();
      Iif (!selection || selection.focusNode) {
        return;
      }
 
      isClearingSelectionRef.current = true;
      selection.removeAllRanges();
      e.preventDefault();
      onSelectAll();
 
      resetSelectionClearRef.current = window.setTimeout(() => {
        isClearingSelectionRef.current = false;
        resetSelectionClearRef.current = null;
      }, 0);
    };
 
    if (API.env === "web") {
      document.addEventListener("keydown", onKeyDown);
    } else {
      document.addEventListener("selectionchange", onSelectionChange);
    }
 
    return () => {
      document.removeEventListener("keydown", onKeyDown);
      document.removeEventListener("selectionchange", onSelectionChange);
 
      Iif (resetSelectionClearRef.current !== null) {
        window.clearTimeout(resetSelectionClearRef.current);
        resetSelectionClearRef.current = null;
      }
 
      isClearingSelectionRef.current = false;
    };
  }, [enabled, onSelectAll]);
};