fix(wysiwyg): Implement programmatic rendering to eliminate focus loss during typing
- Convert parent component to use static rendering with programmatic DOM manipulation - Remove all reactive state that could trigger re-renders during editing - Delay content sync to avoid interference with typing (2s auto-save) - Update all block operations to use manual DOM updates instead of Lit re-renders - Fix specific issue where typing + arrow keys caused focus loss - Add comprehensive focus management documentation
This commit is contained in:
@ -34,12 +34,20 @@ export class WysiwygBlockOperations {
|
||||
...blocks.slice(blockIndex + 1)
|
||||
];
|
||||
|
||||
// Insert the new block element programmatically if we have the editor
|
||||
if (this.component.editorContentRef) {
|
||||
const afterWrapper = this.component.editorContentRef.querySelector(`[data-block-id="${afterBlock.id}"]`);
|
||||
if (afterWrapper) {
|
||||
const newWrapper = this.component.createBlockElement(newBlock);
|
||||
afterWrapper.insertAdjacentElement('afterend', newWrapper);
|
||||
}
|
||||
}
|
||||
|
||||
this.component.updateValue();
|
||||
this.component.requestUpdate();
|
||||
|
||||
if (focusNewBlock && newBlock.type !== 'divider') {
|
||||
// Wait for the component to update
|
||||
await this.component.updateComplete;
|
||||
// Give DOM time to settle
|
||||
await new Promise(resolve => setTimeout(resolve, 0));
|
||||
|
||||
// Focus the new block
|
||||
await this.focusBlock(newBlock.id, 'start');
|
||||
@ -51,6 +59,15 @@ export class WysiwygBlockOperations {
|
||||
*/
|
||||
removeBlock(blockId: string): void {
|
||||
this.component.blocks = this.component.blocks.filter((b: IBlock) => b.id !== blockId);
|
||||
|
||||
// Remove the block element programmatically if we have the editor
|
||||
if (this.component.editorContentRef) {
|
||||
const wrapper = this.component.editorContentRef.querySelector(`[data-block-id="${blockId}"]`);
|
||||
if (wrapper) {
|
||||
wrapper.remove();
|
||||
}
|
||||
}
|
||||
|
||||
this.component.updateValue();
|
||||
}
|
||||
|
||||
@ -72,9 +89,6 @@ export class WysiwygBlockOperations {
|
||||
* Focuses a specific block
|
||||
*/
|
||||
async focusBlock(blockId: string, cursorPosition: 'start' | 'end' | number = 'start'): Promise<void> {
|
||||
// First ensure the component is updated
|
||||
await this.component.updateComplete;
|
||||
|
||||
const wrapperElement = this.component.shadowRoot!.querySelector(`[data-block-id="${blockId}"]`);
|
||||
if (wrapperElement) {
|
||||
const blockComponent = wrapperElement.querySelector('dees-wysiwyg-block') as any;
|
||||
@ -110,8 +124,13 @@ export class WysiwygBlockOperations {
|
||||
if (metadata) {
|
||||
block.metadata = metadata;
|
||||
}
|
||||
|
||||
// Update the block element programmatically if we have the editor
|
||||
if (this.component.editorContentRef) {
|
||||
this.component.updateBlockElement(blockId);
|
||||
}
|
||||
|
||||
this.component.updateValue();
|
||||
this.component.requestUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user