Fix focus handling when blocks are inserted with animation

Calling focus() on a block immediately after inserting it with animate:true has been broken since d3e58f7908, since the field only becomes focusable once the animation begins. Address this by adding a new 'focus' option to the BaseSequenceChild constructor and related insert methods, to indicate that the block should be focused as soon as it becomes available.
pull/9339/head
Matt Westcott 2022-10-13 15:44:14 +01:00
rodzic e0266c276a
commit c165814311
4 zmienionych plików z 28 dodań i 14 usunięć

Wyświetl plik

@ -125,6 +125,7 @@ export class BaseSequenceChild extends EventEmitter {
this.sequence = sequence;
const animate = opts && opts.animate;
const focus = opts && opts.focus;
const collapsed = opts && opts.collapsed;
this.strings = (opts && opts.strings) || {};
@ -248,7 +249,14 @@ export class BaseSequenceChild extends EventEmitter {
dom.hide();
setTimeout(() => {
dom.slideDown();
if (focus) {
// focus this field if we can do so without obtrusive UI behaviour
this.block.focus({ soft: true });
}
}, 10);
} else if (focus) {
// focus this field if we can do so without obtrusive UI behaviour
this.block.focus({ soft: true });
}
}
@ -450,11 +458,10 @@ export class BaseSequenceBlock {
_onRequestInsert(index, opts) {
/* handler for an 'insert new block' action */
const [blockDef, initialState, id] = this._getChildDataForInsertion(opts);
const newChild = this._insert(blockDef, initialState, id || null, index, {
this._insert(blockDef, initialState, id || null, index, {
animate: true,
focus: true,
});
// focus the newly added field if we can do so without obtrusive UI behaviour
newChild.focus({ soft: true });
}
blockCountChanged() {
@ -465,6 +472,7 @@ export class BaseSequenceBlock {
_insert(childBlockDef, initialState, id, index, opts) {
const prefix = this.prefix + '-' + this.blockCounter;
const animate = opts && opts.animate;
const focus = opts && opts.focus;
const collapsed = opts && opts.collapsed;
this.blockCounter++;
@ -499,6 +507,7 @@ export class BaseSequenceBlock {
this,
{
animate,
focus,
collapsed,
strings: this.blockDef.meta.strings,
},

Wyświetl plik

@ -223,10 +223,10 @@ export class ListBlock extends BaseSequenceBlock {
const animate = opts && opts.animate;
this.insert(childValue, index + 1, {
animate,
focus: true,
collapsed: child.collapsed,
id: newId,
});
this.children[index + 1].focus({ soft: true });
}
splitBlock(index, valueBefore, valueAfter, shouldMoveCommentFn, opts) {
@ -235,6 +235,7 @@ export class ListBlock extends BaseSequenceBlock {
child.setValue(valueBefore);
const newChild = this.insert(valueAfter, index + 1, {
animate,
focus: true,
collapsed: child.collapsed,
});
const oldContentPath = child.getContentPath();
@ -253,8 +254,6 @@ export class ListBlock extends BaseSequenceBlock {
}
});
}
// focus the newly added field if we can do so without obtrusive UI behaviour
this.children[index + 1].focus({ soft: true });
}
setError(errorList) {

Wyświetl plik

@ -386,9 +386,11 @@ export class StreamBlock extends BaseSequenceBlock {
const child = this.children[index];
const childState = child.getDuplicatedState();
const animate = opts && opts.animate;
this.insert(childState, index + 1, { animate, collapsed: child.collapsed });
// focus the newly added field if we can do so without obtrusive UI behaviour
this.children[index + 1].focus({ soft: true });
this.insert(childState, index + 1, {
animate,
focus: true,
collapsed: child.collapsed,
});
}
splitBlock(index, valueBefore, valueAfter, shouldMoveCommentFn, opts) {
@ -398,7 +400,7 @@ export class StreamBlock extends BaseSequenceBlock {
const newChild = this.insert(
{ type: initialState.type, id: uuidv4(), value: valueAfter },
index + 1,
{ animate, collapsed: child.collapsed },
{ animate, focus: true, collapsed: child.collapsed },
);
child.setState({
type: initialState.type,
@ -421,8 +423,6 @@ export class StreamBlock extends BaseSequenceBlock {
}
});
}
// focus the newly added field if we can do so without obtrusive UI behaviour
this.children[index + 1].focus({ soft: true });
}
setState(values) {

Wyświetl plik

@ -212,13 +212,19 @@ class DraftailInsertBlockCommand {
result.shouldMoveCommentFn,
);
}
this.addSibling.fn({ type: this.blockDef.name });
// setTimeout required to stop Draftail from giving itself focus again
setTimeout(() => {
this.addSibling.fn({ type: this.blockDef.name });
}, 20);
}, 50);
} else {
// Set the current block's content to the 'before' state, to remove the '/' separator and
// reset the editor state (closing the context menu)
this.widget.setState(result.stateBefore);
this.addSibling.fn({ type: this.blockDef.name });
// setTimeout required to stop Draftail from giving itself focus again
setTimeout(() => {
this.addSibling.fn({ type: this.blockDef.name });
}, 20);
}
}
}