aboutsummaryrefslogtreecommitdiffstats
path: root/packages/excalidraw/components/FontPicker/keyboardNavHandlers.ts
blob: 19c4adcccda88be64cf062cffb768a3268a80b0d (plain) (blame)
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
import type { Node } from "../../utils";
import { KEYS } from "../../keys";
import { type FontDescriptor } from "./FontPickerList";

interface FontPickerKeyNavHandlerProps {
  event: React.KeyboardEvent<HTMLDivElement>;
  inputRef: React.RefObject<HTMLInputElement | null>;
  hoveredFont: Node<FontDescriptor> | undefined;
  filteredFonts: Node<FontDescriptor>[];
  onClose: () => void;
  onSelect: (value: number) => void;
  onHover: (value: number) => void;
}

export const fontPickerKeyHandler = ({
  event,
  inputRef,
  hoveredFont,
  filteredFonts,
  onClose,
  onSelect,
  onHover,
}: FontPickerKeyNavHandlerProps) => {
  if (
    !event[KEYS.CTRL_OR_CMD] &&
    event.shiftKey &&
    event.key.toLowerCase() === KEYS.F
  ) {
    // refocus input on the popup trigger shortcut
    inputRef.current?.focus();
    return true;
  }

  if (event.key === KEYS.ESCAPE) {
    onClose();
    return true;
  }

  if (event.key === KEYS.ENTER) {
    if (hoveredFont?.value) {
      onSelect(hoveredFont.value);
    }

    return true;
  }

  if (event.key === KEYS.ARROW_DOWN) {
    if (hoveredFont?.next) {
      onHover(hoveredFont.next.value);
    } else if (filteredFonts[0]?.value) {
      onHover(filteredFonts[0].value);
    }

    return true;
  }

  if (event.key === KEYS.ARROW_UP) {
    if (hoveredFont?.prev) {
      onHover(hoveredFont.prev.value);
    } else if (filteredFonts[filteredFonts.length - 1]?.value) {
      onHover(filteredFonts[filteredFonts.length - 1].value);
    }

    return true;
  }
};