• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

prabhuignoto / react-chrono / #99

08 Dec 2025 06:00PM UTC coverage: 64.754% (-25.9%) from 90.669%
#99

push

prabhuignoto
Update test command in coveralls workflow to align with Bun's command structure

2231 of 2661 branches covered (83.84%)

Branch coverage included in aggregate %.

14146 of 22630 relevant lines covered (62.51%)

15.0 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

88.89
/src/hooks/useEscapeKey.ts
1
import { useEffect, useCallback, useRef } from 'react';
1✔
2
import { useStableCallback } from './utils';
1✔
3

4
interface UseKeyHandlerOptions {
5
  enabled?: boolean;
6
  keys?: string | string[];
7
  keyCodes?: number | number[];
8
  eventType?: 'keyup' | 'keydown' | 'keypress';
9
  preventDefault?: boolean;
10
  stopPropagation?: boolean;
11
  metaKey?: boolean;
12
  ctrlKey?: boolean;
13
  altKey?: boolean;
14
  shiftKey?: boolean;
15
}
16

17
/**
18
 * Hook that triggers callback on specific key press(es)
19
 * Supports multiple keys and key combinations
20
 * @param callback - Function to call when key(s) are pressed
21
 * @param options - Configuration options
22
 */
23
export function useKeyHandler(
1✔
24
  callback: (event: KeyboardEvent) => void,
194✔
25
  options: UseKeyHandlerOptions = {},
194✔
26
) {
194✔
27
  const {
194✔
28
    enabled = true,
194✔
29
    keys = 'Escape',
194✔
30
    keyCodes = 27,
194✔
31
    eventType = 'keyup',
194✔
32
    preventDefault = true,
194✔
33
    stopPropagation = false,
194✔
34
    metaKey = false,
194✔
35
    ctrlKey = false,
194✔
36
    altKey = false,
194✔
37
    shiftKey = false,
194✔
38
  } = options;
194✔
39

40
  const stableCallback = useStableCallback(callback);
194✔
41
  const lastEnabled = useRef(enabled);
194✔
42

43
  // Normalize keys and keyCodes to arrays
44
  const keyArray = Array.isArray(keys) ? keys : [keys];
194✔
45
  const keyCodeArray = Array.isArray(keyCodes) ? keyCodes : [keyCodes];
194!
46

47
  const handleKey = useCallback(
194✔
48
    (e: KeyboardEvent) => {
194✔
49
      // Early return for better performance
50
      if (!lastEnabled.current) return;
13!
51

52
      // Check modifier keys
53
      if (metaKey && !e.metaKey) return;
13!
54
      if (ctrlKey && !e.ctrlKey) return;
13✔
55
      if (altKey && !e.altKey) return;
13!
56
      if (shiftKey && !e.shiftKey) return;
13!
57

58
      // Check if the pressed key matches any of the target keys
59
      const keyMatch = keyArray.includes(e.key);
12✔
60
      const keyCodeMatch =
12✔
61
        e.key === undefined && keyCodeArray.includes(e.keyCode);
13✔
62

63
      if (keyMatch || keyCodeMatch) {
13✔
64
        if (preventDefault) e.preventDefault();
11✔
65
        if (stopPropagation) e.stopPropagation();
11✔
66
        stableCallback(e);
11✔
67
      }
11✔
68
    },
13✔
69
    [
194✔
70
      keyArray,
194✔
71
      keyCodeArray,
194✔
72
      preventDefault,
194✔
73
      stopPropagation,
194✔
74
      metaKey,
194✔
75
      ctrlKey,
194✔
76
      altKey,
194✔
77
      shiftKey,
194✔
78
      stableCallback,
194✔
79
    ],
194✔
80
  );
194✔
81

82
  useEffect(() => {
194✔
83
    lastEnabled.current = enabled;
194✔
84

85
    if (!enabled) return;
194✔
86

87
    // Use passive listeners where possible for better scroll performance
88
    const listenerOptions =
192✔
89
      preventDefault || stopPropagation
194!
90
        ? { passive: false }
192!
91
        : { passive: true };
×
92

93
    document.addEventListener(eventType, handleKey, listenerOptions);
194✔
94

95
    return () => {
194✔
96
      document.removeEventListener(eventType, handleKey);
192✔
97
    };
192✔
98
  }, [eventType, handleKey, enabled, preventDefault, stopPropagation]);
194✔
99
}
194✔
100

101
/**
102
 * Legacy hook for backward compatibility
103
 * @deprecated Use useKeyHandler instead
104
 */
105
export default function useEscapeKey(
189✔
106
  callback: () => void,
189✔
107
  options: UseKeyHandlerOptions = {},
189✔
108
) {
189✔
109
  useKeyHandler(() => callback(), options);
189✔
110
}
189✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc