Files
cinny/src/app/hooks/useAutocompleteEnter.ts
T

29 lines
1.1 KiB
TypeScript
Raw Normal View History

import { useEffect, useRef } from 'react';
import { isKeyHotkey } from 'is-hotkey';
/**
* Enter picks the top suggestion while an autocomplete list is showing, as in
* Discord / Slack / Element, instead of sending the half-typed text ("hey @bo").
*
* The listener runs in the window's capture phase so it sees Enter before the
* composer's own handler (which would submit), and only claims the key when
* `active` (the list has suggestions) — otherwise Enter sends as normal. IME
* composition and modified Enter (Shift/Ctrl/Alt/Meta) are left alone.
*/
export function useAutocompleteEnter(active: boolean, onSelect: () => void): void {
const selectRef = useRef(onSelect);
selectRef.current = onSelect;
useEffect(() => {
if (!active) return undefined;
const onKeyDown = (evt: KeyboardEvent) => {
if (evt.isComposing || !isKeyHotkey('enter', evt)) return;
evt.preventDefault();
evt.stopPropagation();
selectRef.current();
};
window.addEventListener('keydown', onKeyDown, true);
return () => window.removeEventListener('keydown', onKeyDown, true);
}, [active]);
}