export default function KeystrokeGroup()

in packages/dashboard-app/src/components/ui/keystrokeInput.tsx [117:222]


export default function KeystrokeGroup({
  id,
  defaults,
}: {
  id: string;
  defaults: string[];
}) {
  // `id` has the `autocomplete.${command}` format. We just want the command.
  const command = id.split(".")[1];

  const keybindings = useKeybindings(command, defaults);
  const { listening, setListening } = useContext(ListenerContext);
  const [inputValue, setInputValue] = useState<string[] | null>(null);
  const [isInvalid, setIsInvalid] = useState(false);

  const inputOpen = listening === id;

  type keypressEvent = {
    key: string;
    keyCode: number;
    metaKey: boolean;
    ctrlKey: boolean;
    shiftKey: boolean;
    altKey: boolean;
    preventDefault: () => void;
    stopPropagation: () => void;
  };

  const handleKeyPress = useCallback((e: keypressEvent) => {
    const keys = new Set<string>();
    if (e.metaKey) keys.add("command");
    if (e.ctrlKey) keys.add("control");
    if (e.shiftKey) keys.add("shift");
    if (e.altKey) keys.add("option");
    const key = getKeyName(e.keyCode);

    const isInvalidCombination =
      keys.has("command") ||
      (keys.has("control") &&
        key !== "control" &&
        !VALID_CONTROL_KEYS.includes(key));
    setIsInvalid(isInvalidCombination);

    if (key) keys.add(key);
    setInputValue(Array.from(keys));
    e.preventDefault();
    e.stopPropagation();
  }, []);

  useEffect(() => {
    if (inputOpen) return;

    setIsInvalid(false);
    setInputValue(null);
  }, [inputOpen]);

  useEffect(() => {
    if (!inputOpen) return;
    // attach the event listener
    document.addEventListener("keydown", handleKeyPress);

    // remove the event listener
    return () => {
      document.removeEventListener("keydown", handleKeyPress);
    };
  }, [handleKeyPress, inputOpen]);

  function cancelKeystroke() {
    setInputValue(null);
    setListening(null);
  }

  function openInput() {
    setListening(id);
  }

  return (
    <div className="flex flex-col gap-1">
      <div className="flex gap-2 flex-wrap">
        {keybindings.map((k: string, i: number) => (
          <Keystroke keybinding={k} key={i} />
        ))}
        {inputOpen ? (
          <Input
            command={command}
            value={inputValue as string[]}
            invalid={isInvalid}
            cancel={cancelKeystroke}
          />
        ) : (
          <button
            onClick={openInput}
            className="p-1 px-[6px] hover:bg-black/5 rounded-lg"
          >
            <Plus className="h-3 w-3" />
          </button>
        )}
      </div>
      {isInvalid && (
        <span className="text-xs font-medium text-red-500 pl-8">
          Sorry, that combination is invalid.
        </span>
      )}
    </div>
  );
}