BlockKeys.tsx58 lines · main
1// @ts-nocheck
2import { KeyboardEvent, ReactNode, useCallback, useEffect, useRef } from 'react'
3
4import { useClickedOutside } from '@/hooks/ui/useClickedOutside'
5
6interface BlockKeysProps {
7 value: string | null
8 children: ReactNode
9 onEscape?: (value: string | null) => void
10 onEnter?: (value: string | null) => void
11 ignoreOutsideClicks?: boolean
12}
13
14/**
15 * Blocks key events from propagating
16 * We use this with cell editor to allow editor component to handle keys.
17 * Example: press enter to add newline on textEditor
18 */
19export const BlockKeys = ({
20 value,
21 children,
22 onEscape,
23 onEnter,
24 ignoreOutsideClicks = false,
25}: BlockKeysProps) => {
26 const ref = useRef(null)
27 const isClickedOutside = useClickedOutside(ref)
28
29 const handleKeyDown = useCallback(
30 (ev: KeyboardEvent<HTMLDivElement>) => {
31 switch (ev.key) {
32 case 'Escape':
33 ev.stopPropagation()
34 if (onEscape) onEscape(value)
35 break
36 case 'Enter':
37 ev.stopPropagation()
38 if (!ev.shiftKey && onEnter) {
39 ev.preventDefault()
40 onEnter(value)
41 }
42 break
43 }
44 },
45 [value]
46 )
47
48 useEffect(() => {
49 if (ignoreOutsideClicks) return
50 if (isClickedOutside && onEnter !== undefined) onEnter(value)
51 }, [isClickedOutside])
52
53 return (
54 <div ref={ref} onKeyDown={handleKeyDown}>
55 {children}
56 </div>
57 )
58}