Ghost/ghost/admin/app/components/gh-scroll-trigger.js

66 lines
1.8 KiB
JavaScript
Raw Normal View History

import Component from '@glimmer/component';
import {action} from '@ember/object';
import {inject as service} from '@ember/service';
// TODO: move to a util - duplicated in koenig-editor/koenig-link-input
function getScrollParent(node) {
const isElement = node instanceof HTMLElement;
const overflowY = isElement && window.getComputedStyle(node).overflowY;
const isScrollable = overflowY !== 'visible' && overflowY !== 'hidden';
if (!node) {
return null;
} else if (isScrollable && node.scrollHeight >= node.clientHeight) {
return node;
}
return getScrollParent(node.parentNode) || document.body;
}
export default class GhScrollTrigger extends Component {
@service inViewport;
@action
setupInViewport(element) {
this.loaderElement = element;
let viewportTolerance = this.args.triggerOffset || {};
// if triggerOffset is a number we use it for all dimensions
if (typeof viewportTolerance === 'number') {
viewportTolerance = {
top: viewportTolerance,
bottom: viewportTolerance,
left: viewportTolerance,
right: viewportTolerance
};
}
let options = {
viewportSpy: true,
viewportTolerance,
scrollableArea: this.args.scrollable || getScrollParent(element)
};
let {onEnter, onExit} = this.inViewport.watchElement(element, options);
onEnter(this.didEnterViewport.bind(this));
onExit(this.didExitViewport.bind(this));
this.args.registerElement?.(element);
}
didEnterViewport() {
this.args.enter?.();
}
didExitViewport() {
this.args.exit?.();
}
@action
teardownInViewport(element) {
this.inViewport.stopWatching(element);
}
}