@atlaskit/editor-plugin-table
Version:
Table plugin for the @atlaskit/editor
112 lines (110 loc) • 5.27 kB
JavaScript
import _defineProperty from "@babel/runtime/helpers/defineProperty";
import rafSchedule from 'raf-schd';
import { TableCssClassName as ClassName, ShadowEvent } from '../types';
import { updateShadowListForStickyStyles } from './update-overflow-shadows';
export class OverflowShadowsObserver {
// updateShadowState is a method to update shadow key
constructor(updateShadowState, _table, wrapper) {
_defineProperty(this, "leftShadowSentinel", null);
_defineProperty(this, "rightShadowSentinel", null);
_defineProperty(this, "shadowsObserved", false);
_defineProperty(this, "isSticky", false);
_defineProperty(this, "stickyRowHeight", 0);
_defineProperty(this, "init", () => {
const table = this.table;
if (!this.wrapper || !table) {
return;
}
if (!this.tableIntersectionObserver) {
const intersectonOnbserverCallback = entry => {
if (entry.target !== this.leftShadowSentinel && entry.target !== this.rightShadowSentinel) {
return;
}
this.updateStickyShadowsHeightIfChanged();
this.updateShadowState(this.leftShadowSentinel === entry.target ? ShadowEvent.SHOW_BEFORE_SHADOW : ShadowEvent.SHOW_AFTER_SHADOW, entry.intersectionRatio !== 1);
};
this.tableIntersectionObserver = new IntersectionObserver((entries, _) => {
entries.forEach(entry => intersectonOnbserverCallback(entry));
}, {
threshold: [0, 1],
root: this.wrapper,
rootMargin: '0px'
});
return;
}
});
_defineProperty(this, "observeShadowSentinels", isSticky => {
var _this$table, _this$table2;
if (this.isSticky === isSticky) {
return;
}
this.isSticky = !!isSticky;
// reset height
this.stickyRowHeight = 0;
// update sticky shadows
this.updateStickyShadowsHeightIfChanged();
this.leftShadowSentinel = (_this$table = this.table) === null || _this$table === void 0 ? void 0 : _this$table.querySelector(`.${ClassName.TABLE_SHADOW_SENTINEL_LEFT}`);
this.rightShadowSentinel = (_this$table2 = this.table) === null || _this$table2 === void 0 ? void 0 : _this$table2.querySelector(`.${ClassName.TABLE_SHADOW_SENTINEL_RIGHT}`);
if (this.tableIntersectionObserver && this.leftShadowSentinel && this.rightShadowSentinel && !this.shadowsObserved) {
this.tableIntersectionObserver.disconnect();
this.tableIntersectionObserver.observe(this.leftShadowSentinel);
this.tableIntersectionObserver.observe(this.rightShadowSentinel);
this.shadowsObserved = true;
}
});
/**
* Takes a heightStyle if it can be computed in a less expensive manner,
* e.g. bounds on an IntersectionObserverEntry, otherwise proceed with
* reading it from sticky cell
*/
_defineProperty(this, "updateStickyShadows", rafSchedule(stickyRowHeight => {
var _this$wrapper;
if (!this.isSticky) {
return;
}
const stickyCell = this.getStickyCell();
if (!stickyCell || !((_this$wrapper = this.wrapper) !== null && _this$wrapper !== void 0 && _this$wrapper.parentElement)) {
return;
}
// Reflow Warning! - stickyCell.clientHeight
const newStickyRowHeight = stickyRowHeight || stickyCell.clientHeight + 1;
if (newStickyRowHeight !== this.stickyRowHeight) {
var _this$wrapper2, _this$wrapper2$parent, _this$wrapper3, _this$wrapper3$parent;
this.stickyRowHeight = newStickyRowHeight;
const heightStyleOrCompute = `${newStickyRowHeight}px`;
// Use getElementsByClassName here for a live node list to capture
// sticky shadows
const liveRightShadows = (_this$wrapper2 = this.wrapper) === null || _this$wrapper2 === void 0 ? void 0 : (_this$wrapper2$parent = _this$wrapper2.parentElement) === null || _this$wrapper2$parent === void 0 ? void 0 : _this$wrapper2$parent.getElementsByClassName(`${ClassName.TABLE_RIGHT_SHADOW}`);
const liveLeftShadows = (_this$wrapper3 = this.wrapper) === null || _this$wrapper3 === void 0 ? void 0 : (_this$wrapper3$parent = _this$wrapper3.parentElement) === null || _this$wrapper3$parent === void 0 ? void 0 : _this$wrapper3$parent.getElementsByClassName(`${ClassName.TABLE_LEFT_SHADOW}`);
updateShadowListForStickyStyles(heightStyleOrCompute, liveLeftShadows);
updateShadowListForStickyStyles(heightStyleOrCompute, liveRightShadows);
}
}));
this.updateShadowState = updateShadowState;
this.table = _table;
this.wrapper = wrapper;
this.init();
}
updateStickyShadowsHeightIfChanged() {
if (!this.isSticky) {
return;
}
const stickyCell = this.getStickyCell();
if (!stickyCell) {
return;
}
this.updateStickyShadows();
}
getStickyCell() {
var _this$wrapper4;
const stickyRow = (_this$wrapper4 = this.wrapper) === null || _this$wrapper4 === void 0 ? void 0 : _this$wrapper4.querySelector('tr.sticky');
const stickyCell = stickyRow && stickyRow.firstElementChild;
return stickyCell;
}
dispose() {
if (this.tableIntersectionObserver) {
this.tableIntersectionObserver.disconnect();
this.tableIntersectionObserver = undefined;
}
}
}