From 5d738b4fe832ef1c554448440ede237c32632d10 Mon Sep 17 00:00:00 2001 From: bobzel Date: Wed, 12 Feb 2025 12:54:53 -0500 Subject: cleaning up how text boxes maintain focus when UI widgets are interacted with. --- .../views/nodes/formattedText/FormattedTextBox.tsx | 47 +++++++++++++--------- 1 file changed, 27 insertions(+), 20 deletions(-) (limited to 'src/client/views/nodes/formattedText/FormattedTextBox.tsx') diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx index a6870d65b..eb1f9d07b 100644 --- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx +++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx @@ -131,9 +131,15 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent { @@ -1315,7 +1320,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent { - if (this.EditorView && this._applyingChange !== this.fieldKey) { + if (this.EditorView && this.ApplyingChange !== this.fieldKey) { if (incomingValue?.data) { const updatedState = JSON.parse(incomingValue.data.Data); if (JSON.stringify(this.EditorView.state.toJSON()) !== JSON.stringify(updatedState)) { @@ -1405,7 +1410,6 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent (this.ProseRef?.children?.[0] as HTMLElement).focus(), 200); }; - IsFocused = false; @action onFocused = (e: React.FocusEvent): void => { - this.IsFocused = true; // applyDevTools.applyDevTools(this.EditorView); e.stopPropagation(); }; @@ -1780,18 +1782,23 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent { - let ele: HTMLElement | null = e.relatedTarget instanceof HTMLElement ? e.relatedTarget : null; - if (ele?.tabIndex === -1) { - for (; ele; ele = ele?.parentElement) { - if (ele?.className === 'fonticonbox') { - setTimeout(() => this._ref.current?.focus()); - break; - } + /** + * When a text box loses focus, it might be because a text button was clicked (eg, bold, italics) or color picker. + * In these cases, force focus back onto the text box. + * @param target + */ + tryKeepingFocus = (target: Element | null) => { + for (let newFocusEle = target instanceof HTMLElement ? target : null; newFocusEle; newFocusEle = newFocusEle?.parentElement) { + // test if parent of new focused element is a UI button (should be more specific than testing className) + if (newFocusEle?.className === 'fonticonbox' || newFocusEle?.className === 'popup-container') { + return this.EditorView?.focus(); // keep focus on text box } } - if (ele?.className !== 'fonticonbox') this.IsFocused = false; + }; + + @action + onBlur = (e: React.FocusEvent) => { + this.tryKeepingFocus(e.relatedTarget); if (this.ProseRef?.children[0] !== e.nativeEvent.target) return; if (!(this.EditorView?.state.selection instanceof NodeSelection) || this.EditorView.state.selection.node.type !== this.EditorView.state.schema.nodes.footnote) { const stordMarks = this.EditorView?.state.storedMarks?.slice(); -- cgit v1.2.3-70-g09d2