Using the Keyboard with Stimulus

Giving your users the option to use the keyboard is a great way to make them happy campers. Common use cases are Escape to close a modal or dropdown and Command/Ctrl + Enter to submit a form.

Stimulus gives you the option to add this feature with ease. They are called KeyboardEvent Filters in the Stimulus docs.

How to use KeyboardEvent Filter

You can prepend any action with a different event (click, mouseover and keydown). Keydown also allows to add any keyboard key. Like so:

<div data-controller="dropdown" data-action="keydown.esc->dropdown#close" tabindex="0"></div>

Keep in mind that the focus needs to be on the given element. In above example tabindex=0 makes the element focusable.

Another common example is CMD+Enter to submit a form (instead of reaching for the submit button). This is easy enough as well as Stimulus allows you to combine keys:

<form data-controller="form">
  <textarea data-action="keydown.meta+enter->form#submit">
  </textarea>
  <button type="submit">Submit</button>
</form>

The Stimulus controller could then be as simple as:

import { Controller } from "@hotwired/stimulus"

export default class extends Controller {
  submit() {
    this.element.requestSubmit()
  }
}

Which keys can you use?

Out-of-the-box Stimulus support various keys. This is full list:

Key Name Value
enter Enter
tab Tab
esc Escape
space ” “
up ArrowUp
down ArrowDown
left ArrowLeft
right ArrowRight
home Home
end End
page_up PageUp
page_down PageDown
[a-z] [a-z]
[0-9] [0-9]

But you are not limited to these keys though!

Extend the default keys

If you read part 2 on creating a Notion-like editor, you maybe noticed there are two custom keys used: backspace and /. Let’s see how you can extend the default list of keyboard events by adding a custom schema.

In your app/javascript/controllers/application.js add the following:

// import { Application } from "@hotwired/stimulus"
import { Application, defaultSchema } from "@hotwired/stimulus"

const customSchema = {
  ...defaultSchema,
  keyMappings: {
    ...defaultSchema.keyMappings,
    backspace: "Backspace",
    slash: "/"
    // add any other key here
  }
}

// const application = Application.start()
const application = Application.start(document.documentElement, customSchema)

It imports the defaultSchema from the Stimulus package and extends it with the additional key mappings. Next it modifies the Application.start() method by specifying both the root element (document.documentElement) and the customized schema as parameters.

And that is it. I love this feature and use it quite a bit.

💡 If you are looking to add hotkeys in your app, check out this article. Interested in limiting clicks with certain keys, check out Stimulus FX (using the withKey custom action).

📚 Finally, if you want to be more comfortable as a Rails developer writing JavaScript, check out JavaScript for Rails Developers.

Get UI & Product Engineering Insights for Rails Apps (and product updates!)

Published at . Have suggestions or improvements on this content? Do reach out.

UI components Library for Ruby on Rails apps

$ 99 one-time
payment

View components
  • One-time Payment

  • Access to the Entire Library

  • Built using ViewComponent

  • Designed with Tailwind CSS

  • Enhanced with Hotwire