Setting the focus to an input within a custom node view on arrow down?

I just finished reading through the docs (really pleased with the documentation for this project, by the way) and I’m trying to put together a little hello world for an editor concept but I’m a bit stuck.

I have successfully created a custom node view and can render it to the editor. Essentially, the node view is inline and contains editable content (a contentDOM property), but also contains an input element which can be used to update a custom attribute on the node:

<span class="custom-node">
    <div class="content"></div>
    <div class="input-container" contenteditable="false">
        <input />

My idea is that when a user has their cursor within the content and presses arrow down, I would set the focus to the input. The input would have an on blur event listener that updates the parent node’s attribute, and would return focus to the editor when the user presses enter or arrow up.

I’m thinking I could just add these event listeners to the input within the NodeView’s class constructor, but I’m unsure of how I should handle the case of capturing the initial arrow down event when the user is editing the node’s content. I’m also unsure if there is a way to detect when the user has the caret within the content at all, say, to toggle an active class on the node.

Thank you for any pointers anyone can provide.

A regular keydown handler on the focused element, I’d say.

focus/blur DOM events on the element?

Thanks, marjin. Maybe I’m just being dense but I’m not sure I’ve got that.

If I just do e.g. this:

this.contentDOM = document.createElement('div')


this.contentDOM.addEventListener('keydown', e => {

In the constructor of the node view, the callback doesn’t fire. Do you mean like handleKeyDown in the EditorProps?

Very messy but this seems to work in terms of reacting to the keydown event on my node view and moving the focus into its input element. In the editor props:

handleKeyDown(view, event) {
    if (event.key === 'ArrowDown') {
        if (view.state.selection.$ === 'custom-node') {
            const parentElement = view.domAtPos(

            const input = parentElement.querySelector('.input')


            return true

I feel like this isn’t the “right” way to do this though…

Oh, I thought this was a node view with its own, separately focused control. No, if it’s just using contentDOM then DOM events won’t fire on it directly. To handle keys, just add key handlers to the editor, and check whether the selection is in a place you can handle. To style depending on whether the cursor is in the node, you could create a plugin that adds a decoration around such a node when the selection is in it.