Skip to main content
Text input is new to the React runtime in v4.36.0, and we’re actively refining it to feel as close to native text editing as possible across devices. In this first release, some mobile editing features, such as copy, cut, autocorrect, and auto-capitalization, may not be available yet to end users. See On-screen keyboards for details.

Overview

The React runtime delivers two kinds of keyboard input to a Rive graphic:
  • Key input - Key presses and releases, delivered to keyboard listeners in the graphic. For example, Enter to press a button or Escape to close a menu.
  • Text input - Characters that are typed, pasted, or composed with an input method editor (IME), inserted into a text input in the graphic.
Both build on focus: when the playing state machine has focus nodes, the runtime wires up key and text input along with keyboard navigation. Input goes to the focused node first, then bubbles up through its ancestors until a node handles it. Two things must be true for input to reach the graphic:
  • A node in the graphic has focus. Keyboard listeners and text inputs only receive input while a focus node has focus. The runtime does not listen for keys on document or window.
  • Browser focus is in the graphic. The runtime only handles keyboard events while browser focus is on the <canvas>, the semantics overlay, or the input capturing text described below.

Key input

When a key is pressed while a node has focus, the runtime sends the key to the graphic along with any held modifiers (Shift, Ctrl, Alt, Cmd). Key releases and auto-repeat press signals are sent too.
  • Browser defaults - When the graphic handles a key, the runtime calls preventDefault() on the event, so the browser doesn’t also act on it. Keys the graphic doesn’t handle keep their normal browser behavior.
  • IME composition - Keys pressed while an IME is composing belong to the IME and aren’t sent to the graphic. The composed text is inserted when the IME commits it.
  • Tab and arrow keys - A keyboard listener on the focused node takes priority over focus traversal. If the graphic handles Tab, focus doesn’t move, and keyboard users can’t leave the graphic with Tab. See Keyboard traps.

Text input

Text inputs in a Rive graphic accept typing, pasting, IME composition, and on-screen keyboards, but some native editing features aren’t available yet, particularly on mobile. See On-screen keyboards for the current limitations. To receive text, the runtime adds a hidden <input> next to the canvas that receives text from the browser and passes it to the graphic. While a text input has focus:
  • Typing - Typed characters and IME compositions are inserted into the text input.
  • Pasting - Pasting with a physical keyboard inserts plain text, and pasting on mobile may vary by browser. Line breaks are kept for multi-line text inputs and removed for single-line ones.
  • Copying - On a physical keyboard, Ctrl + C (Cmd + C on macOS) copies the selected text. Obscured text inputs, such as password fields, copy nothing.
  • Editing keys - Space, the arrow keys, Backspace, Delete, Home, End, and Enter don’t scroll the page or submit a surrounding form. Editing keys pressed with Ctrl, Alt, or Cmd keep their browser behavior unless the graphic handles them.

The hidden input

The hidden input exists whenever the runtime wires up keyboard input, even if the graphic has no text inputs, and is removed when you call cleanup() or removeRiveListeners(). It is:
  • An <input type="text"> inserted as a sibling to the canvas.
  • Outside the page’s tab order (tabindex="-1") and ignored by assistive technologies (aria-hidden="true") unless semantics is enabled.
  • Invisible and absolutely positioned over the canvas, with pointer-events: none so it can’t be discovered by pointer.
  • Always empty. Text that reaches the hidden input is sent to the state machine and cleared right away, so the text, caret, and selection live in the Rive graphic and the input’s value is empty.

On-screen keyboards

On touch devices, the on-screen keyboard opens when the user taps a text input in the graphic. The runtime focuses the hidden input while the tap is still being handled, which is what mobile browsers require before they show a keyboard. If a text input gains focus without a tap, for example from a state action, mobile browsers may not open the on-screen keyboard.
Because the hidden input stays empty, mobile browsers don’t offer their usual text editing tools, such as copy and cut, for Rive text inputs. Other conveniences the on-screen keyboard provides for native text fields may also be missing.

Text input with semantics

When semantics is enabled, the hidden input stands in for the focused text field in the accessibility tree, taking its label, hint, and states. This only happens when the focused node’s semantic role is text field, or the node has no semantics.

Integrating with your page

Forms, DOM queries, and CSS

The hidden input is a real <input> in your page, so anything that targets input elements generically will see it: a CSS rule for input, document.querySelectorAll("input"), or code that walks the fields of a surrounding <form>. Scope that code to your own inputs. There is only one hidden input per Rive instance, even when the graphic has several text inputs, and its value is always empty.

Positioning

The hidden input is absolutely positioned over the canvas, and mobile browsers scroll it into view when the on-screen keyboard opens. As with the semantics overlay, give the element wrapping the canvas position: relative so the hidden input and the canvas resolve their positions against the same ancestor.

Keyboard traps

If a focus node in the graphic handles Tab with a key input listener, or the graphic’s focus nodes are set to wrap around or stop at the edges, keyboard users need another way to leave the graphic, such as an Escape key input listener that clears focus. Your app can also clear focus with rive.clearFocus(). Once focus is cleared, the next Tab leaves the canvas.