'Plate editor: Cannot type in input element despite it being the active element
I have created a custom Plate Plugin for hyperlinks that adds an inline element in which you can type the url and the text that shall be displayed. Thus far the element works the way I expect it to. The trouble comes when trying to insert it via hotkey. The desired behavior is for the element to automatically gain focus after it is inserted so that the user can type in it right away. Right now however, the element is inserted upon pressing the hotkey combination, becomes the active element, and yet the user has to manually click inside it to begin typing.
This is what my createHyperLinkPlugin.ts looks like:
import {
KeyboardHandler,
LinkPlugin,
TElement,
createPluginFactory,
getPluginType,
insertNodes,
isUrl as isUrlProtocol,
withLink,
} from '@udecode/plate';
import { HyperLinkElement } from './HyperLink';
import isHotkey from 'is-hotkey';
export const ELEMENT_LINK = 'a';
const insertLink: KeyboardHandler<{}, LinkPlugin> =
(editor, { options: { hotkey } }) =>
(e) => {
const type = getPluginType(editor, ELEMENT_LINK);
if (hotkey && isHotkey(hotkey, e)) {
e.stopPropagation();
e.preventDefault();
insertNodes<TElement<HyperLinkElement>>(editor, {
type,
url: '',
children: [{ text: ' ' }],
properties: {
displayText: '',
isBeingEdited: true,
},
});
}
};
export const createHyperLinkPlugin = createPluginFactory<LinkPlugin>({
key: ELEMENT_LINK,
isElement: true,
isInline: true,
isVoid: true,
props: ({ element }) => ({ nodeProps: { url: element?.url } }),
handlers: {
onKeyDown: insertLink,
},
withOverrides: withLink,
options: {
isUrl: isUrlProtocol,
rangeBeforeOptions: {
matchString: ' ',
skipInvalid: true,
afterMatch: true,
},
hotkey: 'mod+k',
},
then: (editor, { type }) => ({
deserializeHtml: {
rules: [
{
validNodeName: 'A',
},
],
getNode: (el) => ({
type,
url: el.getAttribute('href'),
}),
},
}),
});
The HyperlinkComponent has two <input/> fields inside it, one of which gains focus on creation.
I encountered a very similar problem when adding the element by clicking on its corresponding button on the toolbar. There, i could fix it by using the onClick event instead of the onMouseDown event. It appeared that the mouseUp event that occured after the Element had been added somehow stole its focus.
I have observed something similar with the hotkey. If the hotkey is set to a singular key, for example 'k' and the onKeyUp handler is used, the element gains focus as one would expect and the user can immediately type in it. However, if the hotkey combination contains a modifier, the element is created, gains focus, but can not be written in before manually clicking on it. The chrome dev tools even tell me that the document.activeElement is indeed the input element I want to be able to type in.
Honestly I'm at a loss here as i don't even know whether this behavior is caused by plate, slate, react or just javascript itself. Thanks in advance to anyone who can share any insight into this.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
