Repository: excalidraw/excalidraw
File: packages/excalidraw/components/HintViewer.tsx (TypeScript)

Code before:

const getHints = ({
  appState,
  isMobile,
  device,
  app,
}: HintViewerProps): null | string | string[] => {
  const { activeTool, isResizing, isRotating, lastPointerDownWith } = appState;
  const multiMode = appState.multiElement !== null;

  if (
    appState.openSidebar?.name === DEFAULT_SIDEBAR.name &&
    appState.openSidebar.tab === CANVAS_SEARCH_TAB &&
    appState.searchMatches?.matches.length
  ) {
    return t("hints.dismissSearch", {
      shortcut: getTaggedShortcutKey(t("keys.escape")),
    });
  }

  if (appState.openSidebar && !device.editor.canFitSidebar) {
    return null;
  }

  if (isEraserActive(appState)) {
    return t("hints.eraserRevert", {
      shortcut: getTaggedShortcutKey("Alt"),
    });
  }
  if (activeTool.type === "arrow" || activeTool.type === "line") {
    if (multiMode) {
      return t("hints.linearElementMulti", {
        shortcut_1: getTaggedShortcutKey(t("keys.escape")),
        shortcut_2: getTaggedShortcutKey(t("keys.enter")),
      });
    }
    if (activeTool.type === "arrow") {
      return t("hints.arrowTool", {
        shortcut: getTaggedShortcutKey("A"),
      });
    }
    return t("hints.linearElement");
  }

  if (activeTool.type === "freedraw") {
    return t("hints.freeDraw");
  }

  if (activeTool.type === "text") {
    return t("hints.text");
  }

Review comment (refactor):
Alt/Cmd/Ctrl etc. should also be translated. I'm thinking the translation itself should happen in `getShortcutKey()`, but that's currently a util method in a package that ideally shouldn't be importing i18n helpers.

Two options:

1) move the helper out to `packages/excalidraw`
2) introduce a second intermediate helper `parseShortcutKey` that returns normalized key code instead of string for display purposes, e.g. `CtrlOrCmd` -> `ctrl`, which we we'd then pipe into `t("keys.${normalizedKey}")`.

downside of (2) is we still want to translate the keys in other parts of the UI that currently uses `getShortcutKey()` anyway. So I'm thinking going with (1).

Code after:
const getHints = ({
  appState,
  isMobile,
  device,
  app,
}: HintViewerProps): null | string | string[] => {
  const { activeTool, isResizing, isRotating, lastPointerDownWith } = appState;
  const multiMode = appState.multiElement !== null;

  if (
    appState.openSidebar?.name === DEFAULT_SIDEBAR.name &&
    appState.openSidebar.tab === CANVAS_SEARCH_TAB &&
    appState.searchMatches?.matches.length
  ) {
    return t("hints.dismissSearch", {
      shortcut: getTaggedShortcutKey("Escape"),
    });
  }

  if (appState.openSidebar && !device.editor.canFitSidebar) {
    return null;
  }

  if (isEraserActive(appState)) {
    return t("hints.eraserRevert", {
      shortcut: getTaggedShortcutKey("Alt"),
    });
  }
  if (activeTool.type === "arrow" || activeTool.type === "line") {
    if (multiMode) {
      return t("hints.linearElementMulti", {
        shortcut_1: getTaggedShortcutKey("Escape"),
        shortcut_2: getTaggedShortcutKey("Enter"),
      });
    }
    if (activeTool.type === "arrow") {
      return t("hints.arrowTool", {
        shortcut: getTaggedShortcutKey("A"),
      });
    }
    return t("hints.linearElement");
  }

  if (activeTool.type === "freedraw") {
    return t("hints.freeDraw");
  }

  if (activeTool.type === "text") {
    return t("hints.text");
  }