-
Notifications
You must be signed in to change notification settings - Fork 0
/
ColumnsSyncObserver.ts
82 lines (64 loc) · 1.67 KB
/
ColumnsSyncObserver.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
import {
ResizeObserver,
ResizeObserverCallback,
ResizeObserverEntry
} from './ResizeObserver';
export class ColumnsSyncObserver {
private ro: ResizeObserver = null;
private callback: ResizeObserverCallback = null;
private source: HTMLElement = null;
private target: HTMLElement = null;
constructor(callback?: ResizeObserverCallback) {
this.callback = callback;
this.ro = new ResizeObserver(this.sync.bind(this));
}
observe(source: HTMLElement, target: HTMLElement) {
const {
source: prevSource,
ro
} = this;
if (source === null || target === null) {
return;
}
this.source = source;
this.target = target;
if (source !== prevSource) {
ro.disconnect();
Array.from(source.children).forEach((cell) => {
ro.observe(cell);
});
}
this.sync();
}
sync(entries: ResizeObserverEntry[] = [], observer: ResizeObserver = this.ro) {
const {
callback,
source,
target
} = this;
if (source !== null && target !== null) {
syncColumns(source, target);
}
if (typeof callback === 'function') {
callback(entries, observer);
}
}
destroy() {
this.ro.disconnect();
this.ro = null;
this.callback = null;
this.source = null;
this.target = null;
}
}
export function syncColumns(sourceRow: HTMLElement, targetRow: HTMLElement) {
const sourceChildren = Array.from(sourceRow.children) as HTMLElement[];
const targetChildren = Array.from(targetRow.children) as HTMLElement[];
const columnsWidths = sourceChildren.map(cell => cell.offsetWidth);
const sourceChildrenCount = sourceChildren.length;
targetChildren.forEach((cell, i) => {
if (i < sourceChildrenCount) {
cell.style.width = `${columnsWidths[i]}px`;
}
});
}