Lexical: Improved focus control for popup modal forms

Now moves focus to first field on open, and restores focus back to
editor on submit/close.
This commit is contained in:
Dan Brown
2025-12-07 15:02:06 +00:00
parent 1ee5711435
commit 6661ae8178
2 changed files with 19 additions and 0 deletions

View File

@@ -98,6 +98,13 @@ export class EditorForm extends EditorContainerUiElement {
this.definition = definition;
}
focusOnFirst() {
const focusable = this.getDOMElement().querySelector('input,select,textarea');
if (focusable) {
(focusable as HTMLElement).focus();
}
}
setValues(values: Record<string, string>) {
for (const name of Object.keys(values)) {
const field = this.getFieldByName(name);

View File

@@ -14,6 +14,7 @@ export interface EditorFormModalDefinition extends EditorModalDefinition {
export class EditorFormModal extends EditorContainerUiElement {
protected definition: EditorFormModalDefinition;
protected key: string;
protected originalFocus: Element|null = null;
constructor(definition: EditorFormModalDefinition, key: string) {
super([new EditorForm(definition.form)]);
@@ -22,6 +23,7 @@ export class EditorFormModal extends EditorContainerUiElement {
}
show(defaultValues: Record<string, string>) {
this.originalFocus = document.activeElement as Element;
const dom = this.getDOMElement();
document.body.append(dom);
@@ -31,11 +33,15 @@ export class EditorFormModal extends EditorContainerUiElement {
form.setOnSuccessfulSubmit(this.hide.bind(this));
this.getContext().manager.setModalActive(this.key, this);
form.focusOnFirst();
}
hide() {
this.getContext().manager.setModalInactive(this.key);
this.teardown();
if (this.originalFocus instanceof HTMLElement && this.originalFocus.isConnected) {
this.originalFocus.focus();
}
}
getForm(): EditorForm {
@@ -69,6 +75,12 @@ export class EditorFormModal extends EditorContainerUiElement {
}
});
wrapper.addEventListener('keydown', event => {
if (event.key === 'Escape') {
this.hide();
}
});
return wrapper;
}
}