mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-12 16:14:25 +03:00
9223d0237c
refs https://github.com/TryGhost/Team/issues/1225 When the gif selector is activated we want to scroll as much of the picker into view as possible. - updated `scroll-into-view` modifier so it can work on bounding rects as well as offsets for those situations where a scroll parent is not the offset parent - only implemented "off bottom" behavior for now as that's all we need for this use-case - if the scroll adjustment would mean the top is cut off we readjust so that the top of the element is always visible
55 lines
2.1 KiB
JavaScript
55 lines
2.1 KiB
JavaScript
import getScrollParent from 'ghost-admin/utils/get-scroll-parent';
|
|
import {modifier} from 'ember-modifier';
|
|
|
|
export default modifier((element, [shouldScroll = true], {offset = 0, useViewport = true}) => {
|
|
if (shouldScroll) {
|
|
const scrollParent = getScrollParent(element);
|
|
|
|
// scrolls so the element is visible on-screen
|
|
if (useViewport) {
|
|
const elementRect = element.getBoundingClientRect();
|
|
const scrollParentRect = scrollParent.getBoundingClientRect();
|
|
|
|
// TODO: ensure scroll parent is visible?
|
|
|
|
const isOffTop = elementRect.top < 0;
|
|
const isOffBottom = elementRect.bottom > scrollParentRect.bottom;
|
|
|
|
if (isOffTop) {
|
|
// TODO: implement me
|
|
}
|
|
|
|
if (isOffBottom) {
|
|
let adjustment = Math.abs(scrollParentRect.bottom - elementRect.bottom);
|
|
|
|
// keep top on screen
|
|
if (elementRect.top - adjustment < offset) {
|
|
const readjustment = Math.abs(elementRect.top - adjustment - (offset * 2));
|
|
adjustment -= readjustment;
|
|
}
|
|
|
|
const top = scrollParent.scrollTop + adjustment + offset;
|
|
|
|
scrollParent.scrollTo({top, behavior: 'smooth'});
|
|
}
|
|
}
|
|
|
|
// scrolls so the element is visible inside of the scroll parent's viewport,
|
|
// may not result in element being visible on-screen if scroll parent is cut off
|
|
if (!useViewport) {
|
|
const isOffTop = element.offsetTop < scrollParent.scrollTop;
|
|
const isOffBottom = scrollParent.scrollTop + scrollParent.offsetHeight < element.offsetTop + element.offsetHeight;
|
|
|
|
if (isOffTop) {
|
|
const top = element.offsetTop - offset;
|
|
scrollParent.scrollTo({top, behavior: 'smooth'});
|
|
}
|
|
|
|
if (isOffBottom) {
|
|
const top = element.offsetTop - scrollParent.offsetHeight + element.offsetHeight + offset;
|
|
scrollParent.scrollTo({top, behavior: 'smooth'});
|
|
}
|
|
}
|
|
}
|
|
});
|