mirror of
https://github.com/gristlabs/grist-core.git
synced 2026-03-02 04:09:24 +00:00
(core) Scrolling to the active record when editor is activated
Summary: When an editor is activated by typing, the active view should be scrolled to the active record. Test Plan: new tests Reviewers: georgegevoian Reviewed By: georgegevoian Differential Revision: https://phab.getgrist.com/D3196
This commit is contained in:
@@ -278,25 +278,53 @@ exports.cssClass = cssClass;
|
||||
function scrollChildIntoView(valueOrFunc) {
|
||||
return makeBinding(valueOrFunc, doScrollChildIntoView);
|
||||
}
|
||||
function doScrollChildIntoView(elem, index) {
|
||||
// Key at which we will store the index to scroll for async scrolling.
|
||||
const indexKey = Symbol();
|
||||
function doScrollChildIntoView(elem, index, sync) {
|
||||
if (index === null) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
const scrolly = ko.utils.domData.get(elem, "scrolly");
|
||||
if (scrolly) {
|
||||
// Delay this in case it's triggered while other changes are processed (e.g. splices).
|
||||
return new Promise((resolve, reject) => {
|
||||
setTimeout(() => {
|
||||
try {
|
||||
if (!scrolly.isDisposed()) {
|
||||
scrolly.scrollRowIntoView(index);
|
||||
if (sync) {
|
||||
scrolly.scrollRowIntoView(index);
|
||||
// Clear async index for scrolling.
|
||||
elem[indexKey] = null;
|
||||
return Promise.resolve();
|
||||
} else {
|
||||
// Delay this in case it's triggered while other changes are processed (e.g. splices).
|
||||
|
||||
// Scrolling is asynchronous, so in case there is already
|
||||
// active scroll queued, we will change the target index.
|
||||
// For example:
|
||||
// doScrollChildIntoView(el, 10, false) # sets the index to 10 and queues a Promise1
|
||||
// doScrollChildIntoView(el, 20, false) # updates index to 20 and queues a Promise2
|
||||
// ....
|
||||
// Promise1 moves to 20, and clears the index.
|
||||
// Promise2 checks the index is null and just returns.
|
||||
elem[indexKey] = index;
|
||||
return new Promise((resolve, reject) => {
|
||||
setTimeout(() => {
|
||||
try {
|
||||
// If scroll was cancelled (there was another call after, that finished
|
||||
// and cleared the index) return.
|
||||
if (elem[indexKey] === null) {
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
if (!scrolly.isDisposed()) {
|
||||
scrolly.scrollRowIntoView(elem[indexKey]);
|
||||
}
|
||||
resolve();
|
||||
} catch(err) {
|
||||
reject(err);
|
||||
} finally {
|
||||
// Clear the index, any subsequent async scrolls will be cancelled (on the if test above).
|
||||
elem[indexKey] = null;
|
||||
}
|
||||
resolve();
|
||||
} catch(err) {
|
||||
reject(err);
|
||||
}
|
||||
}, 0);
|
||||
});
|
||||
}, 0);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
const child = elem.children[index];
|
||||
if (child) {
|
||||
@@ -312,8 +340,8 @@ function doScrollChildIntoView(elem, index) {
|
||||
child.scrollIntoView(false); // ..bottom if scrolling down.
|
||||
}
|
||||
}
|
||||
return Promise.resolve();
|
||||
}
|
||||
return Promise.resolve();
|
||||
}
|
||||
exports.scrollChildIntoView = scrollChildIntoView;
|
||||
exports.doScrollChildIntoView = doScrollChildIntoView;
|
||||
|
||||
Reference in New Issue
Block a user