@paperbits/core
Version:
Paperbits core components.
78 lines (60 loc) • 2.56 kB
text/typescript
import { Events } from "@paperbits/common/events";
import * as ko from "knockout";
import PerfectScrollbar from "perfect-scrollbar";
ko.bindingHandlers["scrollable"] = {
init: (element: HTMLElement, valueAccessor) => {
const config = ko.unwrap(valueAccessor());
if (typeof config === "boolean" && config === false) {
return;
}
const configType = typeof config;
let scrollbar = new PerfectScrollbar(element);
if (configType === "object" && config.onEndReach) {
element.addEventListener("ps-y-reach-end", () => {
config.onEndReach();
});
}
const verticalScrollBar = element.querySelector(".ps__thumb-y");
verticalScrollBar.setAttribute("role", "scrollbar");
verticalScrollBar.setAttribute("aria-label", "Vertical scrollbar");
const checkElementSize = (): void => {
requestAnimationFrame(() => {
if (!scrollbar) {
return;
}
scrollbar.update();
setTimeout(checkElementSize, 100);
});
};
checkElementSize();
ko.utils.domNodeDisposal.addDisposeCallback(element, () => {
scrollbar.destroy();
scrollbar = null;
});
}
};
ko.bindingHandlers["scrolledIntoView"] = {
init: (element: HTMLElement, valueAccessor) => {
const config: any = ko.unwrap(valueAccessor());
let scrollTimeout;
const checkInView = () => {
const elementRect = element.getBoundingClientRect();
const parentElementRect = element.parentElement.getBoundingClientRect();
if ((elementRect.top >= parentElementRect.top && elementRect.top <= parentElementRect.bottom) ||
(elementRect.bottom >= parentElementRect.top && elementRect.bottom <= parentElementRect.bottom)) {
if (config.onInView) {
config.onInView();
}
}
};
const onParentScroll = () => {
clearTimeout(scrollTimeout);
scrollTimeout = setTimeout(checkInView, 200);
};
element.parentElement.addEventListener(Events.Scroll, onParentScroll);
checkInView();
ko.utils.domNodeDisposal.addDisposeCallback(element, () => {
element.parentElement.removeEventListener(Events.Scroll, onParentScroll);
});
}
};