Preserve card edit scroll position
This commit is contained in:
1 parent
ec6364b32b
commit
01fa2bc2b6
2 files changed
+57
-2
No files matched your search
@@ -2,9 +2,53 @@
|
||||
'use strict';
|
||||
|
||||
const cardSelector = '[data-shared-editable-action-card]';
|
||||
const scrollRestoreStates = new WeakMap();
|
||||
|
||||
const getCard = (element) => element.closest(cardSelector);
|
||||
|
||||
const getScrollContainer = (element) => {
|
||||
let candidate = element?.parentElement || null;
|
||||
|
||||
while (candidate && candidate !== document.body) {
|
||||
const style = window.getComputedStyle(candidate);
|
||||
const scrollable = /(auto|scroll|overlay)/.test(style.overflowY);
|
||||
if (scrollable && candidate.scrollHeight > candidate.clientHeight) {
|
||||
return candidate;
|
||||
}
|
||||
candidate = candidate.parentElement;
|
||||
}
|
||||
|
||||
return document.scrollingElement || document.documentElement;
|
||||
};
|
||||
|
||||
const captureScrollPosition = (root, card) => {
|
||||
const container = getScrollContainer(card);
|
||||
scrollRestoreStates.set(root, {
|
||||
card,
|
||||
container,
|
||||
top: container.scrollTop,
|
||||
left: container.scrollLeft,
|
||||
scheduled: false,
|
||||
});
|
||||
};
|
||||
|
||||
const restoreScrollPosition = (root) => {
|
||||
const state = scrollRestoreStates.get(root);
|
||||
if (!state || state.scheduled) {
|
||||
return;
|
||||
}
|
||||
|
||||
state.scheduled = true;
|
||||
requestAnimationFrame(() => {
|
||||
requestAnimationFrame(() => {
|
||||
if (state.container?.isConnected) {
|
||||
state.container.scrollTo({ top: state.top, left: state.left, behavior: 'auto' });
|
||||
}
|
||||
scrollRestoreStates.delete(root);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
const getDirectDeleteElement = (card, selector) => Array.from(card?.children || [])
|
||||
.find((child) => child.matches(selector)) || null;
|
||||
|
||||
@@ -93,7 +137,9 @@
|
||||
root.addEventListener('click', (event) => {
|
||||
const edit = event.target.closest('[data-shared-editable-card-edit]');
|
||||
if (edit && root.contains(edit)) {
|
||||
setEditMode(getCard(edit), true);
|
||||
const card = getCard(edit);
|
||||
captureScrollPosition(root, card);
|
||||
setEditMode(card, true);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -102,6 +148,7 @@
|
||||
const card = getCard(cancel);
|
||||
resetDeleteConfirmation(card);
|
||||
setEditMode(card, false);
|
||||
scrollRestoreStates.delete(root);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -117,6 +164,14 @@
|
||||
}
|
||||
});
|
||||
|
||||
const scrollObserver = new MutationObserver(() => {
|
||||
const state = scrollRestoreStates.get(root);
|
||||
if (state && !root.contains(state.card)) {
|
||||
restoreScrollPosition(root);
|
||||
}
|
||||
});
|
||||
scrollObserver.observe(root, { childList: true, subtree: true });
|
||||
|
||||
root.addEventListener('input', (event) => {
|
||||
const input = event.target.closest('[data-shared-editable-card-delete-input]');
|
||||
if (input && root.contains(input)) {
|
||||
|
||||
Reference in new issue
Block a user