Example: Tab Handling

By default, CodeMirror does not handle the Tab key. This isn't an oversight—it is an intentional decision to make the default configuration pass the "no keyboard trap" criterion of the W3C Web Content Accessibility Guidelines.

Some users browse the web without access to a pointing device, and it is really unfriendly towards such users to have focusable inputs that they cannot escape from.

However, I understand that people expect the Tab key do something indentation-related in code editor controls. To that purpose, CodeMirror has a built-in escape hatch: If you press the Escape key, and then press Tab directly after it, the editor never handles the Tab press, so that you can use that to move focus. In addition, the default keymap binds Ctrl-m (or Shift-Alt-m) on macOS to the toggleTabFocusMode command, which toggles a similar behavior.

Unfortunately, since CodeMirror doesn't have a built-in help feature (and probably shouldn't, since it's just a component, not an application), users won't know this.

So if you really want to bind Tab, please start by making sure you mention one of these escape hatches somewhere in your documentation. Next, you can add your own key binding that binds Tab to some command, or use indentWithTab from the commands package.

import {basicSetup} from "codemirror"
import {EditorView, keymap} from "@codemirror/view"
import {indentWithTab} from "@codemirror/commands"
import {javascript} from "@codemirror/lang-javascript"

const doc = `if (true) {
  console.log("okay")
} else {
  console.log("oh no")
}
`

new EditorView({
  doc,
  extensions: [
    basicSetup,
    keymap.of([indentWithTab]),
    javascript()
  ],
  parent: document.querySelector("#editor")
})

Try it out: