| 11 |
11 |
static values = {sticky: Boolean}
|
| 12 |
12 |
|
| 13 |
13 |
connect() {
|
| 14 |
|
if (!this.isIntersecting && !this.isHeaderOverflowX) {
|
| 15 |
|
this.stickyValue = true;
|
| 16 |
|
}
|
| 17 |
|
|
|
14 |
this.headIntersecting = this.isHeadIntersecting;
|
|
15 |
this.tableIntersecting = this.isTableIntersecting;
|
|
16 |
this.updateStickyVisibility();
|
| 18 |
17 |
this.observe();
|
| 19 |
18 |
}
|
| 20 |
19 |
|
| ... | ... | |
| 31 |
30 |
}
|
| 32 |
31 |
|
| 33 |
32 |
disconnect() {
|
| 34 |
|
this.intersectionObserver?.disconnect();
|
|
33 |
this.headIntersectionObserver?.disconnect();
|
|
34 |
this.tableIntersectionObserver?.disconnect();
|
| 35 |
35 |
this.resizeObserver?.disconnect();
|
| 36 |
36 |
}
|
| 37 |
37 |
|
| 38 |
38 |
observe() {
|
| 39 |
|
this.intersectionObserver = new IntersectionObserver(entries => {
|
|
39 |
this.headIntersectionObserver = new IntersectionObserver(entries => {
|
| 40 |
40 |
entries.forEach(entry => {
|
| 41 |
|
if (!entry.isIntersecting && !this.isHeaderOverflowX) {
|
| 42 |
|
this.stickyValue = true;
|
| 43 |
|
}
|
| 44 |
|
if (entry.isIntersecting && !this.isHeaderOverflowX) {
|
| 45 |
|
this.stickyValue = false;
|
| 46 |
|
}
|
|
41 |
this.headIntersecting = entry.isIntersecting;
|
|
42 |
this.updateStickyVisibility();
|
|
43 |
})
|
|
44 |
}, {
|
|
45 |
rootMargin: `-${this.stickyTopOffset}px 0px 0px 0px`
|
|
46 |
});
|
|
47 |
|
|
48 |
this.tableIntersectionObserver = new IntersectionObserver(entries => {
|
|
49 |
entries.forEach(entry => {
|
|
50 |
this.tableIntersecting = entry.isIntersecting;
|
|
51 |
this.updateStickyVisibility();
|
| 47 |
52 |
})
|
| 48 |
53 |
}, {
|
| 49 |
54 |
rootMargin: `-${this.stickyTopOffset}px 0px 0px 0px`
|
| 50 |
55 |
});
|
| 51 |
56 |
|
| 52 |
57 |
this.resizeObserver = new ResizeObserver(() => {
|
| 53 |
|
if (!this.isIntersecting && this.isHeaderOverflowX) {
|
| 54 |
|
this.stickyValue = false;
|
| 55 |
|
}
|
| 56 |
|
if (!this.isIntersecting && !this.isHeaderOverflowX) {
|
| 57 |
|
this.stickyValue = true;
|
| 58 |
|
}
|
|
58 |
this.headIntersecting = this.isHeadIntersecting;
|
|
59 |
this.tableIntersecting = this.isTableIntersecting;
|
|
60 |
this.updateStickyVisibility();
|
| 59 |
61 |
this.syncWidth();
|
| 60 |
62 |
});
|
| 61 |
63 |
|
| 62 |
|
this.intersectionObserver.observe(this.headTarget);
|
|
64 |
this.headIntersectionObserver.observe(this.headTarget);
|
|
65 |
this.tableIntersectionObserver.observe(this.originalTable);
|
| 63 |
66 |
this.resizeObserver.observe(this.headTarget);
|
| 64 |
67 |
}
|
| 65 |
68 |
|
|
69 |
updateStickyVisibility() {
|
|
70 |
this.stickyValue = !this.headIntersecting && this.tableIntersecting && !this.isHeaderOverflowX;
|
|
71 |
}
|
|
72 |
|
| 66 |
73 |
syncWidth(e) {
|
| 67 |
74 |
const headRect = this.headTarget.getBoundingClientRect()
|
| 68 |
75 |
|
| ... | ... | |
| 90 |
97 |
}
|
| 91 |
98 |
}
|
| 92 |
99 |
|
| 93 |
|
get isIntersecting() {
|
|
100 |
get isHeadIntersecting() {
|
| 94 |
101 |
return this.headTarget.getBoundingClientRect().top > this.stickyTopOffset
|
| 95 |
102 |
}
|
| 96 |
103 |
|
|
104 |
get isTableIntersecting() {
|
|
105 |
const tableRect = this.originalTable.getBoundingClientRect();
|
|
106 |
|
|
107 |
return tableRect.bottom > this.stickyTopOffset && tableRect.top < window.innerHeight
|
|
108 |
}
|
|
109 |
|
| 97 |
110 |
get isHeaderOverflowX() {
|
| 98 |
111 |
return this.element.scrollWidth > this.element.clientWidth;
|
| 99 |
112 |
}
|
| 100 |
113 |
|
|
114 |
get originalTable() {
|
|
115 |
return this.headTarget.closest('table');
|
|
116 |
}
|
|
117 |
|
| 101 |
118 |
get stickyTopOffset() {
|
| 102 |
119 |
this.prepare()
|
| 103 |
120 |
|