Xenia.Shortcuts (Xenia v0.1.1)

Copy Markdown View Source

Keyboard shortcuts for a JS island, handled in your LiveView.

<.monaco id="editor" shortcuts={%{"mod+s" => "save", "mod+shift+." => "bigger"}} />

def handle_event("save", %{"shortcut" => "mod+s"}, socket), do: ...

Every Xenia component takes shortcuts: a map from a key combination to the LiveView event it sends. Xenia listens only while focus is inside the component, so the same keys do their usual thing everywhere else on the page. A matched combination is handled before the JavaScript library sees it, and the browser doesn't act on it either.

Before the shortcut's event, the component's pending events are sent. So mod+s right after typing saves what was typed.

Writing a combination

Modifiers, then one key, joined with +:

  • mod is Cmd on a Mac and Ctrl elsewhere. Use it for the usual app shortcuts: mod+s, mod+k.
  • ctrl, alt, shift and meta mean those keys exactly. cmd is meta, option is alt.
  • The key is a letter, a digit, a symbol such as . or /, or a name: enter, escape, tab, space, backspace, delete, home, end, pageup, pagedown, arrowup, arrowdown, arrowleft, arrowright, f1 to f12, and plus for +.
  • With shift, write the key itself, not what Shift makes of it: mod+shift+., not mod+>.

Case and spaces don't matter: "Mod + Shift + S" is "mod+shift+s".

Browser shortcuts are not available

Xenia doesn't take over the shortcuts people use to control the browser and their computer. Using one raises an error:

  • zoom: mod+=, mod+-, mod+0, mod+plus
  • tabs and windows: mod+t, mod+n, mod+w, mod+q, mod+1 to mod+9, ctrl+tab, ctrl+pageup, ctrl+pagedown
  • reloading: mod+r, f5
  • the address bar: mod+l, alt+d, f6
  • back and forward: alt+arrowleft, alt+arrowright, mod+[, mod+]
  • full screen and developer tools: f11, f12, mod+alt+i, mod+shift+i
  • downloads and history: mod+j, mod+h, mod+shift+delete

The full list is reserved/0.

Summary

Functions

Normalizes a shortcuts map: each combination in its one written form, each event name checked.

The browser and system shortcuts Xenia refuses, as written in shortcuts.

Functions

normalize!(shortcuts, id \\ nil)

@spec normalize!(map(), String.t() | nil) :: %{required(String.t()) => String.t()}

Normalizes a shortcuts map: each combination in its one written form, each event name checked.

iex> Xenia.Shortcuts.normalize!(%{"Shift + Mod + S" => "save"})
%{"mod+shift+s" => "save"}

Raises ArgumentError for an invalid combination, a browser shortcut, two spellings of one combination, or an event name that isn't a string. id names the component in the message.

reserved()

@spec reserved() :: [String.t()]

The browser and system shortcuts Xenia refuses, as written in shortcuts.