@fullcalendar/scrollgrid 5.11.2 → 6.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/main.cjs.js +373 -403
- package/main.global.js +371 -452
- package/main.global.min.js +2 -2
- package/main.js +374 -404
- package/main.js.map +1 -1
- package/package.json +4 -4
package/main.cjs.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
FullCalendar Scheduler
|
|
2
|
+
FullCalendar Scheduler v6.0.0-beta.1
|
|
3
3
|
Docs & License: https://fullcalendar.io/scheduler
|
|
4
4
|
(c) 2022 Adam Shaw
|
|
5
5
|
*/
|
|
@@ -9,19 +9,17 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
9
9
|
|
|
10
10
|
var common = require('@fullcalendar/common');
|
|
11
11
|
var premiumCommonPlugin = require('@fullcalendar/premium-common');
|
|
12
|
-
var tslib = require('tslib');
|
|
13
12
|
|
|
14
13
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
15
14
|
|
|
16
15
|
var premiumCommonPlugin__default = /*#__PURE__*/_interopDefaultLegacy(premiumCommonPlugin);
|
|
17
16
|
|
|
18
|
-
|
|
17
|
+
const WHEEL_EVENT_NAMES = 'wheel mousewheel DomMouseScroll MozMousePixelScroll'.split(' ');
|
|
19
18
|
/*
|
|
20
19
|
ALSO, with the ability to disable touch
|
|
21
20
|
*/
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
var _this = this;
|
|
21
|
+
class ScrollListener {
|
|
22
|
+
constructor(el) {
|
|
25
23
|
this.el = el;
|
|
26
24
|
this.emitter = new common.Emitter();
|
|
27
25
|
this.isScrolling = false;
|
|
@@ -32,56 +30,54 @@ var ScrollListener = /** @class */ (function () {
|
|
|
32
30
|
this.scrollWaiter = new common.DelayedRunner(this._handleScrollWaited.bind(this));
|
|
33
31
|
// Handlers
|
|
34
32
|
// ----------------------------------------------------------------------------------------------
|
|
35
|
-
this.handleScroll =
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
33
|
+
this.handleScroll = () => {
|
|
34
|
+
this.startScroll();
|
|
35
|
+
this.emitter.trigger('scroll', this.isRecentlyWheeled, this.isTouching);
|
|
36
|
+
this.isRecentlyScrolled = true;
|
|
37
|
+
this.scrollWaiter.request(500);
|
|
40
38
|
};
|
|
41
39
|
// will fire *before* the scroll event is fired (might not cause a scroll)
|
|
42
|
-
this.handleWheel =
|
|
43
|
-
|
|
44
|
-
|
|
40
|
+
this.handleWheel = () => {
|
|
41
|
+
this.isRecentlyWheeled = true;
|
|
42
|
+
this.wheelWaiter.request(500);
|
|
45
43
|
};
|
|
46
44
|
// will fire *before* the scroll event is fired (might not cause a scroll)
|
|
47
|
-
this.handleTouchStart =
|
|
48
|
-
|
|
45
|
+
this.handleTouchStart = () => {
|
|
46
|
+
this.isTouching = true;
|
|
49
47
|
};
|
|
50
|
-
this.handleTouchEnd =
|
|
51
|
-
|
|
48
|
+
this.handleTouchEnd = () => {
|
|
49
|
+
this.isTouching = false;
|
|
52
50
|
// if the user ended their touch, and the scroll area wasn't moving,
|
|
53
51
|
// we consider this to be the end of the scroll.
|
|
54
|
-
if (!
|
|
55
|
-
|
|
52
|
+
if (!this.isRecentlyScrolled) {
|
|
53
|
+
this.endScroll(); // won't fire if already ended
|
|
56
54
|
}
|
|
57
55
|
};
|
|
58
56
|
el.addEventListener('scroll', this.handleScroll);
|
|
59
57
|
el.addEventListener('touchstart', this.handleTouchStart, { passive: true });
|
|
60
58
|
el.addEventListener('touchend', this.handleTouchEnd);
|
|
61
|
-
for (
|
|
62
|
-
var eventName = WHEEL_EVENT_NAMES_1[_i];
|
|
59
|
+
for (let eventName of WHEEL_EVENT_NAMES) {
|
|
63
60
|
el.addEventListener(eventName, this.handleWheel);
|
|
64
61
|
}
|
|
65
62
|
}
|
|
66
|
-
|
|
67
|
-
|
|
63
|
+
destroy() {
|
|
64
|
+
let { el } = this;
|
|
68
65
|
el.removeEventListener('scroll', this.handleScroll);
|
|
69
66
|
el.removeEventListener('touchstart', this.handleTouchStart, { passive: true });
|
|
70
67
|
el.removeEventListener('touchend', this.handleTouchEnd);
|
|
71
|
-
for (
|
|
72
|
-
var eventName = WHEEL_EVENT_NAMES_2[_i];
|
|
68
|
+
for (let eventName of WHEEL_EVENT_NAMES) {
|
|
73
69
|
el.removeEventListener(eventName, this.handleWheel);
|
|
74
70
|
}
|
|
75
|
-
}
|
|
71
|
+
}
|
|
76
72
|
// Start / Stop
|
|
77
73
|
// ----------------------------------------------------------------------------------------------
|
|
78
|
-
|
|
74
|
+
startScroll() {
|
|
79
75
|
if (!this.isScrolling) {
|
|
80
76
|
this.isScrolling = true;
|
|
81
77
|
this.emitter.trigger('scrollStart', this.isRecentlyWheeled, this.isTouching);
|
|
82
78
|
}
|
|
83
|
-
}
|
|
84
|
-
|
|
79
|
+
}
|
|
80
|
+
endScroll() {
|
|
85
81
|
if (this.isScrolling) {
|
|
86
82
|
this.emitter.trigger('scrollEnd');
|
|
87
83
|
this.isScrolling = false;
|
|
@@ -90,33 +86,32 @@ var ScrollListener = /** @class */ (function () {
|
|
|
90
86
|
this.scrollWaiter.clear();
|
|
91
87
|
this.wheelWaiter.clear();
|
|
92
88
|
}
|
|
93
|
-
}
|
|
94
|
-
|
|
89
|
+
}
|
|
90
|
+
_handleScrollWaited() {
|
|
95
91
|
this.isRecentlyScrolled = false;
|
|
96
92
|
// only end the scroll if not currently touching.
|
|
97
93
|
// if touching, the scrolling will end later, on touchend.
|
|
98
94
|
if (!this.isTouching) {
|
|
99
95
|
this.endScroll(); // won't fire if already ended
|
|
100
96
|
}
|
|
101
|
-
}
|
|
102
|
-
|
|
97
|
+
}
|
|
98
|
+
_handleWheelWaited() {
|
|
103
99
|
this.isRecentlyWheeled = false;
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
}());
|
|
100
|
+
}
|
|
101
|
+
}
|
|
107
102
|
|
|
108
103
|
// TODO: assume the el has no borders?
|
|
109
104
|
function getScrollCanvasOrigin(scrollEl) {
|
|
110
|
-
|
|
111
|
-
|
|
105
|
+
let rect = scrollEl.getBoundingClientRect();
|
|
106
|
+
let edges = common.computeEdges(scrollEl); // TODO: pass in isRtl?
|
|
112
107
|
return {
|
|
113
108
|
left: rect.left + edges.borderLeft + edges.scrollbarLeft - getScrollFromLeftEdge(scrollEl),
|
|
114
109
|
top: rect.top + edges.borderTop - scrollEl.scrollTop,
|
|
115
110
|
};
|
|
116
111
|
}
|
|
117
112
|
function getScrollFromLeftEdge(el) {
|
|
118
|
-
|
|
119
|
-
|
|
113
|
+
let scrollLeft = el.scrollLeft;
|
|
114
|
+
let computedStyles = window.getComputedStyle(el); // TODO: pass in isRtl instead?
|
|
120
115
|
if (computedStyles.direction === 'rtl') {
|
|
121
116
|
switch (getRtlScrollSystem()) {
|
|
122
117
|
case 'negative':
|
|
@@ -128,7 +123,7 @@ function getScrollFromLeftEdge(el) {
|
|
|
128
123
|
return scrollLeft;
|
|
129
124
|
}
|
|
130
125
|
function setScrollFromLeftEdge(el, scrollLeft) {
|
|
131
|
-
|
|
126
|
+
let computedStyles = window.getComputedStyle(el); // TODO: pass in isRtl instead?
|
|
132
127
|
if (computedStyles.direction === 'rtl') {
|
|
133
128
|
switch (getRtlScrollSystem()) {
|
|
134
129
|
case 'reverse':
|
|
@@ -143,12 +138,12 @@ function setScrollFromLeftEdge(el, scrollLeft) {
|
|
|
143
138
|
}
|
|
144
139
|
// Horizontal Scroll System Detection
|
|
145
140
|
// ----------------------------------------------------------------------------------------------
|
|
146
|
-
|
|
141
|
+
let _rtlScrollSystem;
|
|
147
142
|
function getRtlScrollSystem() {
|
|
148
143
|
return _rtlScrollSystem || (_rtlScrollSystem = detectRtlScrollSystem());
|
|
149
144
|
}
|
|
150
145
|
function detectRtlScrollSystem() {
|
|
151
|
-
|
|
146
|
+
let el = document.createElement('div');
|
|
152
147
|
el.style.position = 'absolute';
|
|
153
148
|
el.style.top = '-1000px';
|
|
154
149
|
el.style.width = '1px';
|
|
@@ -158,7 +153,7 @@ function detectRtlScrollSystem() {
|
|
|
158
153
|
el.style.fontSize = '100px';
|
|
159
154
|
el.innerHTML = 'A';
|
|
160
155
|
document.body.appendChild(el);
|
|
161
|
-
|
|
156
|
+
let system;
|
|
162
157
|
if (el.scrollLeft > 0) {
|
|
163
158
|
system = 'positive'; // scroll is a positive number from the left edge
|
|
164
159
|
}
|
|
@@ -175,8 +170,8 @@ function detectRtlScrollSystem() {
|
|
|
175
170
|
return system;
|
|
176
171
|
}
|
|
177
172
|
|
|
178
|
-
|
|
179
|
-
|
|
173
|
+
const IS_MS_EDGE = typeof navigator !== 'undefined' && /Edge/.test(navigator.userAgent); // TODO: what about Chromeum-based Edge?
|
|
174
|
+
const STICKY_SELECTOR = '.fc-sticky';
|
|
180
175
|
/*
|
|
181
176
|
useful beyond the native position:sticky for these reasons:
|
|
182
177
|
- support in IE11
|
|
@@ -187,20 +182,19 @@ This is because we attach the coords with JS, and the VDOM might take away the f
|
|
|
187
182
|
|
|
188
183
|
TODO: don't query text-align:center. isn't compatible with flexbox centering. instead, check natural X coord within parent container
|
|
189
184
|
*/
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
var _this = this;
|
|
185
|
+
class StickyScrolling {
|
|
186
|
+
constructor(scrollEl, isRtl) {
|
|
193
187
|
this.scrollEl = scrollEl;
|
|
194
188
|
this.isRtl = isRtl;
|
|
195
189
|
this.usingRelative = null;
|
|
196
|
-
this.updateSize =
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
if (
|
|
203
|
-
|
|
190
|
+
this.updateSize = () => {
|
|
191
|
+
let { scrollEl } = this;
|
|
192
|
+
let els = common.findElements(scrollEl, STICKY_SELECTOR);
|
|
193
|
+
let elGeoms = this.queryElGeoms(els);
|
|
194
|
+
let viewportWidth = scrollEl.clientWidth;
|
|
195
|
+
let viewportHeight = scrollEl.clientHeight;
|
|
196
|
+
if (this.usingRelative) {
|
|
197
|
+
let elDestinations = this.computeElDestinations(elGeoms, viewportWidth); // read before prepPositioning
|
|
204
198
|
assignRelativePositions(els, elGeoms, elDestinations, viewportWidth, viewportHeight);
|
|
205
199
|
}
|
|
206
200
|
else {
|
|
@@ -216,23 +210,22 @@ var StickyScrolling = /** @class */ (function () {
|
|
|
216
210
|
this.listener.emitter.on('scrollEnd', this.updateSize);
|
|
217
211
|
}
|
|
218
212
|
}
|
|
219
|
-
|
|
213
|
+
destroy() {
|
|
220
214
|
if (this.listener) {
|
|
221
215
|
this.listener.destroy();
|
|
222
216
|
}
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
for (
|
|
229
|
-
|
|
230
|
-
var parentBound = common.translateRect(common.computeInnerRect(el.parentNode, true, true), // weird way to call this!!!
|
|
217
|
+
}
|
|
218
|
+
queryElGeoms(els) {
|
|
219
|
+
let { scrollEl, isRtl } = this;
|
|
220
|
+
let canvasOrigin = getScrollCanvasOrigin(scrollEl);
|
|
221
|
+
let elGeoms = [];
|
|
222
|
+
for (let el of els) {
|
|
223
|
+
let parentBound = common.translateRect(common.computeInnerRect(el.parentNode, true, true), // weird way to call this!!!
|
|
231
224
|
-canvasOrigin.left, -canvasOrigin.top);
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
225
|
+
let elRect = el.getBoundingClientRect();
|
|
226
|
+
let computedStyles = window.getComputedStyle(el);
|
|
227
|
+
let textAlign = window.getComputedStyle(el.parentNode).textAlign; // ask the parent
|
|
228
|
+
let naturalBound = null;
|
|
236
229
|
if (textAlign === 'start') {
|
|
237
230
|
textAlign = isRtl ? 'right' : 'left';
|
|
238
231
|
}
|
|
@@ -244,25 +237,25 @@ var StickyScrolling = /** @class */ (function () {
|
|
|
244
237
|
-canvasOrigin.top - (parseFloat(computedStyles.top) || 0));
|
|
245
238
|
}
|
|
246
239
|
elGeoms.push({
|
|
247
|
-
parentBound
|
|
248
|
-
naturalBound
|
|
240
|
+
parentBound,
|
|
241
|
+
naturalBound,
|
|
249
242
|
elWidth: elRect.width,
|
|
250
243
|
elHeight: elRect.height,
|
|
251
|
-
textAlign
|
|
244
|
+
textAlign,
|
|
252
245
|
});
|
|
253
246
|
}
|
|
254
247
|
return elGeoms;
|
|
255
|
-
}
|
|
248
|
+
}
|
|
256
249
|
// only for IE
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
return elGeoms.map(
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
250
|
+
computeElDestinations(elGeoms, viewportWidth) {
|
|
251
|
+
let { scrollEl } = this;
|
|
252
|
+
let viewportTop = scrollEl.scrollTop;
|
|
253
|
+
let viewportLeft = getScrollFromLeftEdge(scrollEl);
|
|
254
|
+
let viewportRight = viewportLeft + viewportWidth;
|
|
255
|
+
return elGeoms.map((elGeom) => {
|
|
256
|
+
let { elWidth, elHeight, parentBound, naturalBound } = elGeom;
|
|
257
|
+
let destLeft; // relative to canvas topleft
|
|
258
|
+
let destTop; // "
|
|
266
259
|
switch (elGeom.textAlign) {
|
|
267
260
|
case 'left':
|
|
268
261
|
destLeft = viewportLeft;
|
|
@@ -281,16 +274,15 @@ var StickyScrolling = /** @class */ (function () {
|
|
|
281
274
|
destTop = Math.max(destTop, naturalBound.top); // better to use natural top for upper bound
|
|
282
275
|
return { left: destLeft, top: destTop };
|
|
283
276
|
});
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
}());
|
|
277
|
+
}
|
|
278
|
+
}
|
|
287
279
|
function assignRelativePositions(els, elGeoms, elDestinations, viewportWidth, viewportHeight) {
|
|
288
|
-
els.forEach(
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
280
|
+
els.forEach((el, i) => {
|
|
281
|
+
let { naturalBound, parentBound } = elGeoms[i];
|
|
282
|
+
let parentWidth = parentBound.right - parentBound.left;
|
|
283
|
+
let parentHeight = parentBound.bottom - parentBound.bottom;
|
|
284
|
+
let left;
|
|
285
|
+
let top;
|
|
294
286
|
if (parentWidth > viewportWidth ||
|
|
295
287
|
parentHeight > viewportHeight) {
|
|
296
288
|
left = elDestinations[i].left - naturalBound.left;
|
|
@@ -302,17 +294,17 @@ function assignRelativePositions(els, elGeoms, elDestinations, viewportWidth, vi
|
|
|
302
294
|
}
|
|
303
295
|
common.applyStyle(el, {
|
|
304
296
|
position: 'relative',
|
|
305
|
-
left
|
|
297
|
+
left,
|
|
306
298
|
right: -left,
|
|
307
|
-
top
|
|
299
|
+
top,
|
|
308
300
|
});
|
|
309
301
|
});
|
|
310
302
|
}
|
|
311
303
|
function assignStickyPositions(els, elGeoms, viewportWidth) {
|
|
312
|
-
els.forEach(
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
304
|
+
els.forEach((el, i) => {
|
|
305
|
+
let { textAlign, elWidth, parentBound } = elGeoms[i];
|
|
306
|
+
let parentWidth = parentBound.right - parentBound.left;
|
|
307
|
+
let left;
|
|
316
308
|
if (textAlign === 'center' &&
|
|
317
309
|
parentWidth > viewportWidth) {
|
|
318
310
|
left = (viewportWidth - elWidth) / 2;
|
|
@@ -321,13 +313,13 @@ function assignStickyPositions(els, elGeoms, viewportWidth) {
|
|
|
321
313
|
left = '';
|
|
322
314
|
}
|
|
323
315
|
common.applyStyle(el, {
|
|
324
|
-
left
|
|
316
|
+
left,
|
|
325
317
|
right: left,
|
|
326
318
|
top: 0,
|
|
327
319
|
});
|
|
328
320
|
});
|
|
329
321
|
}
|
|
330
|
-
|
|
322
|
+
let _isStickySupported;
|
|
331
323
|
function getStickySupported() {
|
|
332
324
|
if (_isStickySupported == null) {
|
|
333
325
|
_isStickySupported = computeStickySupported();
|
|
@@ -335,44 +327,42 @@ function getStickySupported() {
|
|
|
335
327
|
return _isStickySupported;
|
|
336
328
|
}
|
|
337
329
|
function computeStickySupported() {
|
|
338
|
-
|
|
330
|
+
let el = document.createElement('div');
|
|
339
331
|
el.style.position = 'sticky';
|
|
340
332
|
document.body.appendChild(el);
|
|
341
|
-
|
|
333
|
+
let val = window.getComputedStyle(el).position;
|
|
342
334
|
common.removeElement(el);
|
|
343
335
|
return val === 'sticky';
|
|
344
336
|
}
|
|
345
337
|
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
_this.state = {
|
|
338
|
+
class ClippedScroller extends common.BaseComponent {
|
|
339
|
+
constructor() {
|
|
340
|
+
super(...arguments);
|
|
341
|
+
this.elRef = common.createRef();
|
|
342
|
+
this.state = {
|
|
352
343
|
xScrollbarWidth: 0,
|
|
353
344
|
yScrollbarWidth: 0,
|
|
354
345
|
};
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
common.setRef(
|
|
346
|
+
this.handleScroller = (scroller) => {
|
|
347
|
+
this.scroller = scroller;
|
|
348
|
+
common.setRef(this.props.scrollerRef, scroller);
|
|
358
349
|
};
|
|
359
|
-
|
|
360
|
-
|
|
350
|
+
this.handleSizing = () => {
|
|
351
|
+
let { props } = this;
|
|
361
352
|
if (props.overflowY === 'scroll-hidden') {
|
|
362
|
-
|
|
353
|
+
this.setState({ yScrollbarWidth: this.scroller.getYScrollbarWidth() });
|
|
363
354
|
}
|
|
364
355
|
if (props.overflowX === 'scroll-hidden') {
|
|
365
|
-
|
|
356
|
+
this.setState({ xScrollbarWidth: this.scroller.getXScrollbarWidth() });
|
|
366
357
|
}
|
|
367
358
|
};
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
var overcomeBottom = 0;
|
|
359
|
+
}
|
|
360
|
+
render() {
|
|
361
|
+
let { props, state, context } = this;
|
|
362
|
+
let isScrollbarOnLeft = context.isRtl && common.getIsRtlScrollbarOnLeft();
|
|
363
|
+
let overcomeLeft = 0;
|
|
364
|
+
let overcomeRight = 0;
|
|
365
|
+
let overcomeBottom = 0;
|
|
376
366
|
if (props.overflowX === 'scroll-hidden') {
|
|
377
367
|
overcomeBottom = state.xScrollbarWidth;
|
|
378
368
|
}
|
|
@@ -390,54 +380,49 @@ var ClippedScroller = /** @class */ (function (_super) {
|
|
|
390
380
|
common.createElement(common.Scroller, { ref: this.handleScroller, elRef: this.props.scrollerElRef, overflowX: props.overflowX === 'scroll-hidden' ? 'scroll' : props.overflowX, overflowY: props.overflowY === 'scroll-hidden' ? 'scroll' : props.overflowY, overcomeLeft: overcomeLeft, overcomeRight: overcomeRight, overcomeBottom: overcomeBottom, maxHeight: typeof props.maxHeight === 'number'
|
|
391
381
|
? (props.maxHeight + (props.overflowX === 'scroll-hidden' ? state.xScrollbarWidth : 0))
|
|
392
382
|
: '', liquid: props.liquid, liquidIsAbsolute: true }, props.children)));
|
|
393
|
-
}
|
|
394
|
-
|
|
383
|
+
}
|
|
384
|
+
componentDidMount() {
|
|
395
385
|
this.handleSizing();
|
|
396
386
|
this.context.addResizeHandler(this.handleSizing);
|
|
397
|
-
}
|
|
398
|
-
|
|
387
|
+
}
|
|
388
|
+
componentDidUpdate(prevProps) {
|
|
399
389
|
if (!common.isPropsEqual(prevProps, this.props)) { // an external change?
|
|
400
390
|
this.handleSizing();
|
|
401
391
|
}
|
|
402
|
-
}
|
|
403
|
-
|
|
392
|
+
}
|
|
393
|
+
componentWillUnmount() {
|
|
404
394
|
this.context.removeResizeHandler(this.handleSizing);
|
|
405
|
-
}
|
|
406
|
-
|
|
395
|
+
}
|
|
396
|
+
needsXScrolling() {
|
|
407
397
|
return this.scroller.needsXScrolling();
|
|
408
|
-
}
|
|
409
|
-
|
|
398
|
+
}
|
|
399
|
+
needsYScrolling() {
|
|
410
400
|
return this.scroller.needsYScrolling();
|
|
411
|
-
}
|
|
412
|
-
|
|
413
|
-
}(common.BaseComponent));
|
|
401
|
+
}
|
|
402
|
+
}
|
|
414
403
|
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
var _this = this;
|
|
404
|
+
class ScrollSyncer {
|
|
405
|
+
constructor(isVertical, scrollEls) {
|
|
418
406
|
this.isVertical = isVertical;
|
|
419
407
|
this.scrollEls = scrollEls;
|
|
420
408
|
this.isPaused = false;
|
|
421
|
-
this.scrollListeners = scrollEls.map(
|
|
409
|
+
this.scrollListeners = scrollEls.map((el) => this.bindScroller(el));
|
|
422
410
|
}
|
|
423
|
-
|
|
424
|
-
for (
|
|
425
|
-
var scrollListener = _a[_i];
|
|
411
|
+
destroy() {
|
|
412
|
+
for (let scrollListener of this.scrollListeners) {
|
|
426
413
|
scrollListener.destroy();
|
|
427
414
|
}
|
|
428
|
-
}
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
_this.assignMaster(el);
|
|
415
|
+
}
|
|
416
|
+
bindScroller(el) {
|
|
417
|
+
let { scrollEls, isVertical } = this;
|
|
418
|
+
let scrollListener = new ScrollListener(el);
|
|
419
|
+
const onScroll = (isWheel, isTouch) => {
|
|
420
|
+
if (!this.isPaused) {
|
|
421
|
+
if (!this.masterEl || (this.masterEl !== el && (isWheel || isTouch))) {
|
|
422
|
+
this.assignMaster(el);
|
|
437
423
|
}
|
|
438
|
-
if (
|
|
439
|
-
for (
|
|
440
|
-
var otherEl = scrollEls_1[_i];
|
|
424
|
+
if (this.masterEl === el) { // dealing with current
|
|
425
|
+
for (let otherEl of scrollEls) {
|
|
441
426
|
if (otherEl !== el) {
|
|
442
427
|
if (isVertical) {
|
|
443
428
|
otherEl.scrollTop = el.scrollTop;
|
|
@@ -450,69 +435,64 @@ var ScrollSyncer = /** @class */ (function () {
|
|
|
450
435
|
}
|
|
451
436
|
}
|
|
452
437
|
};
|
|
453
|
-
|
|
454
|
-
if (
|
|
455
|
-
|
|
438
|
+
const onScrollEnd = () => {
|
|
439
|
+
if (this.masterEl === el) {
|
|
440
|
+
this.masterEl = null;
|
|
456
441
|
}
|
|
457
442
|
};
|
|
458
443
|
scrollListener.emitter.on('scroll', onScroll);
|
|
459
444
|
scrollListener.emitter.on('scrollEnd', onScrollEnd);
|
|
460
445
|
return scrollListener;
|
|
461
|
-
}
|
|
462
|
-
|
|
446
|
+
}
|
|
447
|
+
assignMaster(el) {
|
|
463
448
|
this.masterEl = el;
|
|
464
|
-
for (
|
|
465
|
-
var scrollListener = _a[_i];
|
|
449
|
+
for (let scrollListener of this.scrollListeners) {
|
|
466
450
|
if (scrollListener.el !== el) {
|
|
467
451
|
scrollListener.endScroll(); // to prevent residual scrolls from reclaiming master
|
|
468
452
|
}
|
|
469
453
|
}
|
|
470
|
-
}
|
|
454
|
+
}
|
|
471
455
|
/*
|
|
472
456
|
will normalize the scrollLeft value
|
|
473
457
|
*/
|
|
474
|
-
|
|
458
|
+
forceScrollLeft(scrollLeft) {
|
|
475
459
|
this.isPaused = true;
|
|
476
|
-
for (
|
|
477
|
-
var listener = _a[_i];
|
|
460
|
+
for (let listener of this.scrollListeners) {
|
|
478
461
|
setScrollFromLeftEdge(listener.el, scrollLeft);
|
|
479
462
|
}
|
|
480
463
|
this.isPaused = false;
|
|
481
|
-
}
|
|
482
|
-
|
|
464
|
+
}
|
|
465
|
+
forceScrollTop(top) {
|
|
483
466
|
this.isPaused = true;
|
|
484
|
-
for (
|
|
485
|
-
var listener = _a[_i];
|
|
467
|
+
for (let listener of this.scrollListeners) {
|
|
486
468
|
listener.el.scrollTop = top;
|
|
487
469
|
}
|
|
488
470
|
this.isPaused = false;
|
|
489
|
-
}
|
|
490
|
-
|
|
491
|
-
}());
|
|
471
|
+
}
|
|
472
|
+
}
|
|
492
473
|
|
|
493
474
|
/*
|
|
494
475
|
TODO: make <ScrollGridSection> subcomponent
|
|
495
476
|
NOTE: doesn't support collapsibleWidth (which is sortof a hack anyway)
|
|
496
477
|
*/
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
_this.clippedScrollerRefs = new common.RefMap();
|
|
478
|
+
class ScrollGrid extends common.BaseComponent {
|
|
479
|
+
constructor() {
|
|
480
|
+
super(...arguments);
|
|
481
|
+
this.compileColGroupStats = common.memoizeArraylike(compileColGroupStat, isColGroupStatsEqual);
|
|
482
|
+
this.renderMicroColGroups = common.memoizeArraylike(common.renderMicroColGroup); // yucky to memoize VNodes, but much more efficient for consumers
|
|
483
|
+
this.clippedScrollerRefs = new common.RefMap();
|
|
504
484
|
// doesn't hold non-scrolling els used just for padding
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
485
|
+
this.scrollerElRefs = new common.RefMap(this._handleScrollerEl.bind(this));
|
|
486
|
+
this.chunkElRefs = new common.RefMap(this._handleChunkEl.bind(this));
|
|
487
|
+
this.stickyScrollings = [];
|
|
488
|
+
this.scrollSyncersBySection = {};
|
|
489
|
+
this.scrollSyncersByColumn = {};
|
|
510
490
|
// for row-height-syncing
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
491
|
+
this.rowUnstableMap = new Map(); // no need to groom. always self-cancels
|
|
492
|
+
this.rowInnerMaxHeightMap = new Map();
|
|
493
|
+
this.anyRowHeightsChanged = false;
|
|
494
|
+
this.recentSizingCnt = 0;
|
|
495
|
+
this.state = {
|
|
516
496
|
shrinkWidths: [],
|
|
517
497
|
forceYScrollbars: false,
|
|
518
498
|
forceXScrollbars: false,
|
|
@@ -520,61 +500,60 @@ var ScrollGrid = /** @class */ (function (_super) {
|
|
|
520
500
|
scrollerClientHeights: {},
|
|
521
501
|
sectionRowMaxHeights: [],
|
|
522
502
|
};
|
|
523
|
-
|
|
524
|
-
if (!
|
|
503
|
+
this.handleSizing = (isForcedResize, sectionRowMaxHeightsChanged) => {
|
|
504
|
+
if (!this.allowSizing()) {
|
|
525
505
|
return;
|
|
526
506
|
}
|
|
527
507
|
if (!sectionRowMaxHeightsChanged) { // something else changed, probably external
|
|
528
|
-
|
|
508
|
+
this.anyRowHeightsChanged = true;
|
|
529
509
|
}
|
|
530
|
-
|
|
510
|
+
let otherState = {};
|
|
531
511
|
// if reacting to self-change of sectionRowMaxHeightsChanged, or not stable, don't do anything
|
|
532
|
-
if (isForcedResize || (!sectionRowMaxHeightsChanged && !
|
|
533
|
-
otherState.sectionRowMaxHeights =
|
|
512
|
+
if (isForcedResize || (!sectionRowMaxHeightsChanged && !this.rowUnstableMap.size)) {
|
|
513
|
+
otherState.sectionRowMaxHeights = this.computeSectionRowMaxHeights();
|
|
534
514
|
}
|
|
535
|
-
|
|
536
|
-
if (!
|
|
537
|
-
|
|
515
|
+
this.setState(Object.assign(Object.assign({ shrinkWidths: this.computeShrinkWidths() }, this.computeScrollerDims()), otherState), () => {
|
|
516
|
+
if (!this.rowUnstableMap.size) {
|
|
517
|
+
this.updateStickyScrolling(); // needs to happen AFTER final positioning committed to DOM
|
|
538
518
|
}
|
|
539
519
|
});
|
|
540
520
|
};
|
|
541
|
-
|
|
542
|
-
|
|
521
|
+
this.handleRowHeightChange = (rowEl, isStable) => {
|
|
522
|
+
let { rowUnstableMap, rowInnerMaxHeightMap } = this;
|
|
543
523
|
if (!isStable) {
|
|
544
524
|
rowUnstableMap.set(rowEl, true);
|
|
545
525
|
}
|
|
546
526
|
else {
|
|
547
527
|
rowUnstableMap.delete(rowEl);
|
|
548
|
-
|
|
528
|
+
let innerMaxHeight = getRowInnerMaxHeight(rowEl);
|
|
549
529
|
if (!rowInnerMaxHeightMap.has(rowEl) || rowInnerMaxHeightMap.get(rowEl) !== innerMaxHeight) {
|
|
550
530
|
rowInnerMaxHeightMap.set(rowEl, innerMaxHeight);
|
|
551
|
-
|
|
531
|
+
this.anyRowHeightsChanged = true;
|
|
552
532
|
}
|
|
553
|
-
if (!rowUnstableMap.size &&
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
sectionRowMaxHeights:
|
|
533
|
+
if (!rowUnstableMap.size && this.anyRowHeightsChanged) {
|
|
534
|
+
this.anyRowHeightsChanged = false;
|
|
535
|
+
this.setState({
|
|
536
|
+
sectionRowMaxHeights: this.computeSectionRowMaxHeights(),
|
|
557
537
|
});
|
|
558
538
|
}
|
|
559
539
|
}
|
|
560
540
|
};
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
var _b = this.getDims(); _b[0]; _b[1];
|
|
541
|
+
}
|
|
542
|
+
render() {
|
|
543
|
+
let { props, state, context } = this;
|
|
544
|
+
let { shrinkWidths } = state;
|
|
545
|
+
let colGroupStats = this.compileColGroupStats(props.colGroups.map((colGroup) => [colGroup]));
|
|
546
|
+
let microColGroupNodes = this.renderMicroColGroups(colGroupStats.map((stat, i) => [stat.cols, shrinkWidths[i]]));
|
|
547
|
+
let classNames = common.getScrollGridClassNames(props.liquid, context);
|
|
548
|
+
this.getDims();
|
|
570
549
|
// TODO: make DRY
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
550
|
+
let sectionConfigs = props.sections;
|
|
551
|
+
let configCnt = sectionConfigs.length;
|
|
552
|
+
let configI = 0;
|
|
553
|
+
let currentConfig;
|
|
554
|
+
let headSectionNodes = [];
|
|
555
|
+
let bodySectionNodes = [];
|
|
556
|
+
let footSectionNodes = [];
|
|
578
557
|
while (configI < configCnt && (currentConfig = sectionConfigs[configI]).type === 'header') {
|
|
579
558
|
headSectionNodes.push(this.renderSection(currentConfig, configI, colGroupStats, microColGroupNodes, state.sectionRowMaxHeights, true));
|
|
580
559
|
configI += 1;
|
|
@@ -587,53 +566,52 @@ var ScrollGrid = /** @class */ (function (_super) {
|
|
|
587
566
|
footSectionNodes.push(this.renderSection(currentConfig, configI, colGroupStats, microColGroupNodes, state.sectionRowMaxHeights, true));
|
|
588
567
|
configI += 1;
|
|
589
568
|
}
|
|
590
|
-
|
|
591
|
-
|
|
569
|
+
const isBuggy = !common.getCanVGrowWithinCell(); // see NOTE in SimpleScrollGrid
|
|
570
|
+
const roleAttrs = { role: 'rowgroup' };
|
|
592
571
|
return common.createElement('table', {
|
|
593
572
|
ref: props.elRef,
|
|
594
573
|
role: 'grid',
|
|
595
574
|
className: classNames.join(' '),
|
|
596
|
-
}, renderMacroColGroup(colGroupStats, shrinkWidths), Boolean(!isBuggy && headSectionNodes.length) && common.createElement
|
|
597
|
-
}
|
|
598
|
-
|
|
599
|
-
var _this = this;
|
|
575
|
+
}, renderMacroColGroup(colGroupStats, shrinkWidths), Boolean(!isBuggy && headSectionNodes.length) && common.createElement('thead', roleAttrs, ...headSectionNodes), Boolean(!isBuggy && bodySectionNodes.length) && common.createElement('tbody', roleAttrs, ...bodySectionNodes), Boolean(!isBuggy && footSectionNodes.length) && common.createElement('tfoot', roleAttrs, ...footSectionNodes), isBuggy && common.createElement('tbody', roleAttrs, ...headSectionNodes, ...bodySectionNodes, ...footSectionNodes));
|
|
576
|
+
}
|
|
577
|
+
renderSection(sectionConfig, sectionIndex, colGroupStats, microColGroupNodes, sectionRowMaxHeights, isHeader) {
|
|
600
578
|
if ('outerContent' in sectionConfig) {
|
|
601
579
|
return (common.createElement(common.Fragment, { key: sectionConfig.key }, sectionConfig.outerContent));
|
|
602
580
|
}
|
|
603
|
-
return (common.createElement("tr", { key: sectionConfig.key, role: "presentation", className: common.getSectionClassNames(sectionConfig, this.props.liquid).join(' ') }, sectionConfig.chunks.map(
|
|
604
|
-
}
|
|
605
|
-
|
|
581
|
+
return (common.createElement("tr", { key: sectionConfig.key, role: "presentation", className: common.getSectionClassNames(sectionConfig, this.props.liquid).join(' ') }, sectionConfig.chunks.map((chunkConfig, i) => this.renderChunk(sectionConfig, sectionIndex, colGroupStats[i], microColGroupNodes[i], chunkConfig, i, (sectionRowMaxHeights[sectionIndex] || [])[i] || [], isHeader))));
|
|
582
|
+
}
|
|
583
|
+
renderChunk(sectionConfig, sectionIndex, colGroupStat, microColGroupNode, chunkConfig, chunkIndex, rowHeights, isHeader) {
|
|
606
584
|
if ('outerContent' in chunkConfig) {
|
|
607
585
|
return (common.createElement(common.Fragment, { key: chunkConfig.key }, chunkConfig.outerContent));
|
|
608
586
|
}
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
587
|
+
let { state } = this;
|
|
588
|
+
let { scrollerClientWidths, scrollerClientHeights } = state;
|
|
589
|
+
let [sectionCnt, chunksPerSection] = this.getDims();
|
|
590
|
+
let index = sectionIndex * chunksPerSection + chunkIndex;
|
|
591
|
+
let sideScrollIndex = (!this.context.isRtl || common.getIsRtlScrollbarOnLeft()) ? chunksPerSection - 1 : 0;
|
|
592
|
+
let isVScrollSide = chunkIndex === sideScrollIndex;
|
|
593
|
+
let isLastSection = sectionIndex === sectionCnt - 1;
|
|
594
|
+
let forceXScrollbars = isLastSection && state.forceXScrollbars; // NOOOO can result in `null`
|
|
595
|
+
let forceYScrollbars = isVScrollSide && state.forceYScrollbars; // NOOOO can result in `null`
|
|
596
|
+
let allowXScrolling = colGroupStat && colGroupStat.allowXScrolling; // rename?
|
|
597
|
+
let allowYScrolling = common.getAllowYScrolling(this.props, sectionConfig); // rename? do in section func?
|
|
598
|
+
let chunkVGrow = common.getSectionHasLiquidHeight(this.props, sectionConfig); // do in section func?
|
|
599
|
+
let expandRows = sectionConfig.expandRows && chunkVGrow;
|
|
600
|
+
let tableMinWidth = (colGroupStat && colGroupStat.totalColMinWidth) || '';
|
|
601
|
+
let content = common.renderChunkContent(sectionConfig, chunkConfig, {
|
|
624
602
|
tableColGroupNode: microColGroupNode,
|
|
625
|
-
tableMinWidth
|
|
603
|
+
tableMinWidth,
|
|
626
604
|
clientWidth: scrollerClientWidths[index] !== undefined ? scrollerClientWidths[index] : null,
|
|
627
605
|
clientHeight: scrollerClientHeights[index] !== undefined ? scrollerClientHeights[index] : null,
|
|
628
|
-
expandRows
|
|
606
|
+
expandRows,
|
|
629
607
|
syncRowHeights: Boolean(sectionConfig.syncRowHeights),
|
|
630
608
|
rowSyncHeights: rowHeights,
|
|
631
609
|
reportRowHeightChange: this.handleRowHeightChange,
|
|
632
610
|
}, isHeader);
|
|
633
|
-
|
|
611
|
+
let overflowX = forceXScrollbars ? (isLastSection ? 'scroll' : 'scroll-hidden') :
|
|
634
612
|
!allowXScrolling ? 'hidden' :
|
|
635
613
|
(isLastSection ? 'auto' : 'scroll-hidden');
|
|
636
|
-
|
|
614
|
+
let overflowY = forceYScrollbars ? (isVScrollSide ? 'scroll' : 'scroll-hidden') :
|
|
637
615
|
!allowYScrolling ? 'hidden' :
|
|
638
616
|
(isVScrollSide ? 'auto' : 'scroll-hidden');
|
|
639
617
|
// it *could* be possible to reduce DOM wrappers by only doing a ClippedScroller when allowXScrolling or allowYScrolling,
|
|
@@ -644,27 +622,27 @@ var ScrollGrid = /** @class */ (function (_super) {
|
|
|
644
622
|
ref: this.chunkElRefs.createRef(index),
|
|
645
623
|
role: 'presentation',
|
|
646
624
|
}, content);
|
|
647
|
-
}
|
|
648
|
-
|
|
625
|
+
}
|
|
626
|
+
componentDidMount() {
|
|
649
627
|
this.getStickyScrolling = common.memoizeArraylike(initStickyScrolling, null, destroyStickyScrolling);
|
|
650
628
|
this.getScrollSyncersBySection = common.memoizeHashlike(initScrollSyncer.bind(this, true), null, destroyScrollSyncer);
|
|
651
629
|
this.getScrollSyncersByColumn = common.memoizeHashlike(initScrollSyncer.bind(this, false), null, destroyScrollSyncer);
|
|
652
630
|
this.updateScrollSyncers();
|
|
653
631
|
this.handleSizing(false);
|
|
654
632
|
this.context.addResizeHandler(this.handleSizing);
|
|
655
|
-
}
|
|
656
|
-
|
|
633
|
+
}
|
|
634
|
+
componentDidUpdate(prevProps, prevState) {
|
|
657
635
|
this.updateScrollSyncers();
|
|
658
636
|
// TODO: need better solution when state contains non-sizing things
|
|
659
637
|
this.handleSizing(false, prevState.sectionRowMaxHeights !== this.state.sectionRowMaxHeights);
|
|
660
|
-
}
|
|
661
|
-
|
|
638
|
+
}
|
|
639
|
+
componentWillUnmount() {
|
|
662
640
|
this.context.removeResizeHandler(this.handleSizing);
|
|
663
641
|
this.destroyStickyScrolling();
|
|
664
642
|
this.destroyScrollSyncers();
|
|
665
|
-
}
|
|
666
|
-
|
|
667
|
-
|
|
643
|
+
}
|
|
644
|
+
allowSizing() {
|
|
645
|
+
let now = new Date();
|
|
668
646
|
if (!this.lastSizingDate ||
|
|
669
647
|
now.valueOf() > this.lastSizingDate.valueOf() + common.config.SCROLLGRID_RESIZE_INTERVAL) {
|
|
670
648
|
this.lastSizingDate = now;
|
|
@@ -672,39 +650,38 @@ var ScrollGrid = /** @class */ (function (_super) {
|
|
|
672
650
|
return true;
|
|
673
651
|
}
|
|
674
652
|
return (this.recentSizingCnt += 1) <= 10;
|
|
675
|
-
}
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
colGroupStats.forEach(function (colGroupStat, i) {
|
|
653
|
+
}
|
|
654
|
+
computeShrinkWidths() {
|
|
655
|
+
let colGroupStats = this.compileColGroupStats(this.props.colGroups.map((colGroup) => [colGroup]));
|
|
656
|
+
let [sectionCnt, chunksPerSection] = this.getDims();
|
|
657
|
+
let cnt = sectionCnt * chunksPerSection;
|
|
658
|
+
let shrinkWidths = [];
|
|
659
|
+
colGroupStats.forEach((colGroupStat, i) => {
|
|
683
660
|
if (colGroupStat.hasShrinkCol) {
|
|
684
|
-
|
|
661
|
+
let chunkEls = this.chunkElRefs.collect(i, cnt, chunksPerSection); // in one col
|
|
685
662
|
shrinkWidths[i] = common.computeShrinkWidth(chunkEls);
|
|
686
663
|
}
|
|
687
664
|
});
|
|
688
665
|
return shrinkWidths;
|
|
689
|
-
}
|
|
666
|
+
}
|
|
690
667
|
// has the side effect of grooming rowInnerMaxHeightMap
|
|
691
668
|
// TODO: somehow short-circuit if there are no new height changes
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
for (
|
|
697
|
-
|
|
698
|
-
|
|
669
|
+
computeSectionRowMaxHeights() {
|
|
670
|
+
let newHeightMap = new Map();
|
|
671
|
+
let [sectionCnt, chunksPerSection] = this.getDims();
|
|
672
|
+
let sectionRowMaxHeights = [];
|
|
673
|
+
for (let sectionI = 0; sectionI < sectionCnt; sectionI += 1) {
|
|
674
|
+
let sectionConfig = this.props.sections[sectionI];
|
|
675
|
+
let assignableHeights = []; // chunk, row
|
|
699
676
|
if (sectionConfig && sectionConfig.syncRowHeights) {
|
|
700
|
-
|
|
701
|
-
for (
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
677
|
+
let rowHeightsByChunk = [];
|
|
678
|
+
for (let chunkI = 0; chunkI < chunksPerSection; chunkI += 1) {
|
|
679
|
+
let index = sectionI * chunksPerSection + chunkI;
|
|
680
|
+
let rowHeights = [];
|
|
681
|
+
let chunkEl = this.chunkElRefs.currentMap[index];
|
|
705
682
|
if (chunkEl) {
|
|
706
|
-
rowHeights = common.findElements(chunkEl, '.fc-scrollgrid-sync-table tr').map(
|
|
707
|
-
|
|
683
|
+
rowHeights = common.findElements(chunkEl, '.fc-scrollgrid-sync-table tr').map((rowEl) => {
|
|
684
|
+
let max = getRowInnerMaxHeight(rowEl);
|
|
708
685
|
newHeightMap.set(rowEl, max);
|
|
709
686
|
return max;
|
|
710
687
|
});
|
|
@@ -714,30 +691,30 @@ var ScrollGrid = /** @class */ (function (_super) {
|
|
|
714
691
|
}
|
|
715
692
|
rowHeightsByChunk.push(rowHeights);
|
|
716
693
|
}
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
for (
|
|
720
|
-
|
|
694
|
+
let rowCnt = rowHeightsByChunk[0].length;
|
|
695
|
+
let isEqualRowCnt = true;
|
|
696
|
+
for (let chunkI = 1; chunkI < chunksPerSection; chunkI += 1) {
|
|
697
|
+
let isOuterContent = sectionConfig.chunks[chunkI] && sectionConfig.chunks[chunkI].outerContent !== undefined; // can be null
|
|
721
698
|
if (!isOuterContent && rowHeightsByChunk[chunkI].length !== rowCnt) { // skip outer content
|
|
722
699
|
isEqualRowCnt = false;
|
|
723
700
|
break;
|
|
724
701
|
}
|
|
725
702
|
}
|
|
726
703
|
if (!isEqualRowCnt) {
|
|
727
|
-
|
|
728
|
-
for (
|
|
704
|
+
let chunkHeightSums = [];
|
|
705
|
+
for (let chunkI = 0; chunkI < chunksPerSection; chunkI += 1) {
|
|
729
706
|
chunkHeightSums.push(sumNumbers(rowHeightsByChunk[chunkI]) + rowHeightsByChunk[chunkI].length);
|
|
730
707
|
}
|
|
731
|
-
|
|
732
|
-
for (
|
|
733
|
-
|
|
734
|
-
|
|
708
|
+
let maxTotalSum = Math.max(...chunkHeightSums);
|
|
709
|
+
for (let chunkI = 0; chunkI < chunksPerSection; chunkI += 1) {
|
|
710
|
+
let rowInChunkCnt = rowHeightsByChunk[chunkI].length;
|
|
711
|
+
let rowInChunkTotalHeight = maxTotalSum - rowInChunkCnt; // subtract border
|
|
735
712
|
// height of non-first row. we do this to avoid rounding, because it's unreliable within a table
|
|
736
|
-
|
|
713
|
+
let rowInChunkHeightOthers = Math.floor(rowInChunkTotalHeight / rowInChunkCnt);
|
|
737
714
|
// whatever is leftover goes to the first row
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
715
|
+
let rowInChunkHeightFirst = rowInChunkTotalHeight - rowInChunkHeightOthers * (rowInChunkCnt - 1);
|
|
716
|
+
let rowInChunkHeights = [];
|
|
717
|
+
let row = 0;
|
|
741
718
|
if (row < rowInChunkCnt) {
|
|
742
719
|
rowInChunkHeights.push(rowInChunkHeightFirst);
|
|
743
720
|
row += 1;
|
|
@@ -750,19 +727,19 @@ var ScrollGrid = /** @class */ (function (_super) {
|
|
|
750
727
|
}
|
|
751
728
|
}
|
|
752
729
|
else {
|
|
753
|
-
for (
|
|
730
|
+
for (let chunkI = 0; chunkI < chunksPerSection; chunkI += 1) {
|
|
754
731
|
assignableHeights.push([]);
|
|
755
732
|
}
|
|
756
|
-
for (
|
|
757
|
-
|
|
758
|
-
for (
|
|
759
|
-
|
|
733
|
+
for (let row = 0; row < rowCnt; row += 1) {
|
|
734
|
+
let rowHeightsAcrossChunks = [];
|
|
735
|
+
for (let chunkI = 0; chunkI < chunksPerSection; chunkI += 1) {
|
|
736
|
+
let h = rowHeightsByChunk[chunkI][row];
|
|
760
737
|
if (h != null) { // protect against outerContent
|
|
761
738
|
rowHeightsAcrossChunks.push(h);
|
|
762
739
|
}
|
|
763
740
|
}
|
|
764
|
-
|
|
765
|
-
for (
|
|
741
|
+
let maxHeight = Math.max(...rowHeightsAcrossChunks);
|
|
742
|
+
for (let chunkI = 0; chunkI < chunksPerSection; chunkI += 1) {
|
|
766
743
|
assignableHeights[chunkI].push(maxHeight);
|
|
767
744
|
}
|
|
768
745
|
}
|
|
@@ -772,41 +749,41 @@ var ScrollGrid = /** @class */ (function (_super) {
|
|
|
772
749
|
}
|
|
773
750
|
this.rowInnerMaxHeightMap = newHeightMap;
|
|
774
751
|
return sectionRowMaxHeights;
|
|
775
|
-
}
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
for (
|
|
788
|
-
|
|
789
|
-
|
|
752
|
+
}
|
|
753
|
+
computeScrollerDims() {
|
|
754
|
+
let scrollbarWidth = common.getScrollbarWidths();
|
|
755
|
+
let [sectionCnt, chunksPerSection] = this.getDims();
|
|
756
|
+
let sideScrollI = (!this.context.isRtl || common.getIsRtlScrollbarOnLeft()) ? chunksPerSection - 1 : 0;
|
|
757
|
+
let lastSectionI = sectionCnt - 1;
|
|
758
|
+
let currentScrollers = this.clippedScrollerRefs.currentMap;
|
|
759
|
+
let scrollerEls = this.scrollerElRefs.currentMap;
|
|
760
|
+
let forceYScrollbars = false;
|
|
761
|
+
let forceXScrollbars = false;
|
|
762
|
+
let scrollerClientWidths = {};
|
|
763
|
+
let scrollerClientHeights = {};
|
|
764
|
+
for (let sectionI = 0; sectionI < sectionCnt; sectionI += 1) { // along edge
|
|
765
|
+
let index = sectionI * chunksPerSection + sideScrollI;
|
|
766
|
+
let scroller = currentScrollers[index];
|
|
790
767
|
if (scroller && scroller.needsYScrolling()) {
|
|
791
768
|
forceYScrollbars = true;
|
|
792
769
|
break;
|
|
793
770
|
}
|
|
794
771
|
}
|
|
795
|
-
for (
|
|
796
|
-
|
|
797
|
-
|
|
772
|
+
for (let chunkI = 0; chunkI < chunksPerSection; chunkI += 1) { // along last row
|
|
773
|
+
let index = lastSectionI * chunksPerSection + chunkI;
|
|
774
|
+
let scroller = currentScrollers[index];
|
|
798
775
|
if (scroller && scroller.needsXScrolling()) {
|
|
799
776
|
forceXScrollbars = true;
|
|
800
777
|
break;
|
|
801
778
|
}
|
|
802
779
|
}
|
|
803
|
-
for (
|
|
804
|
-
for (
|
|
805
|
-
|
|
806
|
-
|
|
780
|
+
for (let sectionI = 0; sectionI < sectionCnt; sectionI += 1) {
|
|
781
|
+
for (let chunkI = 0; chunkI < chunksPerSection; chunkI += 1) {
|
|
782
|
+
let index = sectionI * chunksPerSection + chunkI;
|
|
783
|
+
let scrollerEl = scrollerEls[index];
|
|
807
784
|
if (scrollerEl) {
|
|
808
785
|
// TODO: weird way to get this. need harness b/c doesn't include table borders
|
|
809
|
-
|
|
786
|
+
let harnessEl = scrollerEl.parentNode;
|
|
810
787
|
scrollerClientWidths[index] = Math.floor(harnessEl.getBoundingClientRect().width - ((chunkI === sideScrollI && forceYScrollbars)
|
|
811
788
|
? scrollbarWidth.y // use global because scroller might not have scrollbars yet but will need them in future
|
|
812
789
|
: 0));
|
|
@@ -816,94 +793,92 @@ var ScrollGrid = /** @class */ (function (_super) {
|
|
|
816
793
|
}
|
|
817
794
|
}
|
|
818
795
|
}
|
|
819
|
-
return { forceYScrollbars
|
|
820
|
-
}
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
stickyScrollings.forEach(
|
|
796
|
+
return { forceYScrollbars, forceXScrollbars, scrollerClientWidths, scrollerClientHeights };
|
|
797
|
+
}
|
|
798
|
+
updateStickyScrolling() {
|
|
799
|
+
let { isRtl } = this.context;
|
|
800
|
+
let argsByKey = this.scrollerElRefs.getAll().map((scrollEl) => [scrollEl, isRtl]);
|
|
801
|
+
let stickyScrollings = this.getStickyScrolling(argsByKey);
|
|
802
|
+
stickyScrollings.forEach((stickyScrolling) => stickyScrolling.updateSize());
|
|
826
803
|
this.stickyScrollings = stickyScrollings;
|
|
827
|
-
}
|
|
828
|
-
|
|
804
|
+
}
|
|
805
|
+
destroyStickyScrolling() {
|
|
829
806
|
this.stickyScrollings.forEach(destroyStickyScrolling);
|
|
830
|
-
}
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
for (
|
|
838
|
-
|
|
839
|
-
|
|
807
|
+
}
|
|
808
|
+
updateScrollSyncers() {
|
|
809
|
+
let [sectionCnt, chunksPerSection] = this.getDims();
|
|
810
|
+
let cnt = sectionCnt * chunksPerSection;
|
|
811
|
+
let scrollElsBySection = {};
|
|
812
|
+
let scrollElsByColumn = {};
|
|
813
|
+
let scrollElMap = this.scrollerElRefs.currentMap;
|
|
814
|
+
for (let sectionI = 0; sectionI < sectionCnt; sectionI += 1) {
|
|
815
|
+
let startIndex = sectionI * chunksPerSection;
|
|
816
|
+
let endIndex = startIndex + chunksPerSection;
|
|
840
817
|
scrollElsBySection[sectionI] = common.collectFromHash(scrollElMap, startIndex, endIndex, 1); // use the filtered
|
|
841
818
|
}
|
|
842
|
-
for (
|
|
819
|
+
for (let col = 0; col < chunksPerSection; col += 1) {
|
|
843
820
|
scrollElsByColumn[col] = this.scrollerElRefs.collect(col, cnt, chunksPerSection); // DON'T use the filtered
|
|
844
821
|
}
|
|
845
822
|
this.scrollSyncersBySection = this.getScrollSyncersBySection(scrollElsBySection);
|
|
846
823
|
this.scrollSyncersByColumn = this.getScrollSyncersByColumn(scrollElsByColumn);
|
|
847
|
-
}
|
|
848
|
-
|
|
824
|
+
}
|
|
825
|
+
destroyScrollSyncers() {
|
|
849
826
|
common.mapHash(this.scrollSyncersBySection, destroyScrollSyncer);
|
|
850
827
|
common.mapHash(this.scrollSyncersByColumn, destroyScrollSyncer);
|
|
851
|
-
}
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
828
|
+
}
|
|
829
|
+
getChunkConfigByIndex(index) {
|
|
830
|
+
let chunksPerSection = this.getDims()[1];
|
|
831
|
+
let sectionI = Math.floor(index / chunksPerSection);
|
|
832
|
+
let chunkI = index % chunksPerSection;
|
|
833
|
+
let sectionConfig = this.props.sections[sectionI];
|
|
857
834
|
return sectionConfig && sectionConfig.chunks[chunkI];
|
|
858
|
-
}
|
|
859
|
-
|
|
860
|
-
|
|
835
|
+
}
|
|
836
|
+
forceScrollLeft(col, scrollLeft) {
|
|
837
|
+
let scrollSyncer = this.scrollSyncersByColumn[col];
|
|
861
838
|
if (scrollSyncer) {
|
|
862
839
|
scrollSyncer.forceScrollLeft(scrollLeft);
|
|
863
840
|
}
|
|
864
|
-
}
|
|
865
|
-
|
|
866
|
-
|
|
841
|
+
}
|
|
842
|
+
forceScrollTop(sectionI, scrollTop) {
|
|
843
|
+
let scrollSyncer = this.scrollSyncersBySection[sectionI];
|
|
867
844
|
if (scrollSyncer) {
|
|
868
845
|
scrollSyncer.forceScrollTop(scrollTop);
|
|
869
846
|
}
|
|
870
|
-
}
|
|
871
|
-
|
|
872
|
-
|
|
847
|
+
}
|
|
848
|
+
_handleChunkEl(chunkEl, key) {
|
|
849
|
+
let chunkConfig = this.getChunkConfigByIndex(parseInt(key, 10));
|
|
873
850
|
if (chunkConfig) { // null if section disappeared. bad, b/c won't null-set the elRef
|
|
874
851
|
common.setRef(chunkConfig.elRef, chunkEl);
|
|
875
852
|
}
|
|
876
|
-
}
|
|
877
|
-
|
|
878
|
-
|
|
853
|
+
}
|
|
854
|
+
_handleScrollerEl(scrollerEl, key) {
|
|
855
|
+
let chunkConfig = this.getChunkConfigByIndex(parseInt(key, 10));
|
|
879
856
|
if (chunkConfig) { // null if section disappeared. bad, b/c won't null-set the elRef
|
|
880
857
|
common.setRef(chunkConfig.scrollerElRef, scrollerEl);
|
|
881
858
|
}
|
|
882
|
-
}
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
859
|
+
}
|
|
860
|
+
getDims() {
|
|
861
|
+
let sectionCnt = this.props.sections.length;
|
|
862
|
+
let chunksPerSection = sectionCnt ? this.props.sections[0].chunks.length : 0;
|
|
886
863
|
return [sectionCnt, chunksPerSection];
|
|
887
|
-
}
|
|
888
|
-
|
|
889
|
-
}(common.BaseComponent));
|
|
864
|
+
}
|
|
865
|
+
}
|
|
890
866
|
ScrollGrid.addStateEquality({
|
|
891
867
|
shrinkWidths: common.isArraysEqual,
|
|
892
868
|
scrollerClientWidths: common.isPropsEqual,
|
|
893
869
|
scrollerClientHeights: common.isPropsEqual,
|
|
894
870
|
});
|
|
895
871
|
function sumNumbers(numbers) {
|
|
896
|
-
|
|
897
|
-
for (
|
|
898
|
-
var n = numbers_1[_i];
|
|
872
|
+
let sum = 0;
|
|
873
|
+
for (let n of numbers) {
|
|
899
874
|
sum += n;
|
|
900
875
|
}
|
|
901
876
|
return sum;
|
|
902
877
|
}
|
|
903
878
|
function getRowInnerMaxHeight(rowEl) {
|
|
904
|
-
|
|
879
|
+
let innerHeights = common.findElements(rowEl, '.fc-scrollgrid-sync-inner').map(getElHeight);
|
|
905
880
|
if (innerHeights.length) {
|
|
906
|
-
return Math.max
|
|
881
|
+
return Math.max(...innerHeights);
|
|
907
882
|
}
|
|
908
883
|
return 0;
|
|
909
884
|
}
|
|
@@ -911,53 +886,48 @@ function getElHeight(el) {
|
|
|
911
886
|
return el.offsetHeight; // better to deal with integers, for rounding, for PureComponent
|
|
912
887
|
}
|
|
913
888
|
function renderMacroColGroup(colGroupStats, shrinkWidths) {
|
|
914
|
-
|
|
915
|
-
|
|
889
|
+
let children = colGroupStats.map((colGroupStat, i) => {
|
|
890
|
+
let width = colGroupStat.width;
|
|
916
891
|
if (width === 'shrink') {
|
|
917
892
|
width = colGroupStat.totalColWidth + common.sanitizeShrinkWidth(shrinkWidths[i]) + 1; // +1 for border :(
|
|
918
893
|
}
|
|
919
894
|
return ( // eslint-disable-next-line react/jsx-key
|
|
920
|
-
common.createElement("col", { style: { width
|
|
895
|
+
common.createElement("col", { style: { width } }));
|
|
921
896
|
});
|
|
922
|
-
return common.createElement
|
|
897
|
+
return common.createElement('colgroup', {}, ...children);
|
|
923
898
|
}
|
|
924
899
|
function compileColGroupStat(colGroupConfig) {
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
900
|
+
let totalColWidth = sumColProp(colGroupConfig.cols, 'width'); // excludes "shrink"
|
|
901
|
+
let totalColMinWidth = sumColProp(colGroupConfig.cols, 'minWidth');
|
|
902
|
+
let hasShrinkCol = common.hasShrinkWidth(colGroupConfig.cols);
|
|
903
|
+
let allowXScrolling = colGroupConfig.width !== 'shrink' && Boolean(totalColWidth || totalColMinWidth || hasShrinkCol);
|
|
929
904
|
return {
|
|
930
|
-
hasShrinkCol
|
|
931
|
-
totalColWidth
|
|
932
|
-
totalColMinWidth
|
|
933
|
-
allowXScrolling
|
|
905
|
+
hasShrinkCol,
|
|
906
|
+
totalColWidth,
|
|
907
|
+
totalColMinWidth,
|
|
908
|
+
allowXScrolling,
|
|
934
909
|
cols: colGroupConfig.cols,
|
|
935
910
|
width: colGroupConfig.width,
|
|
936
911
|
};
|
|
937
912
|
}
|
|
938
913
|
function sumColProp(cols, propName) {
|
|
939
|
-
|
|
940
|
-
for (
|
|
941
|
-
|
|
942
|
-
var val = col[propName];
|
|
914
|
+
let total = 0;
|
|
915
|
+
for (let col of cols) {
|
|
916
|
+
let val = col[propName];
|
|
943
917
|
if (typeof val === 'number') {
|
|
944
918
|
total += val * (col.span || 1);
|
|
945
919
|
}
|
|
946
920
|
}
|
|
947
921
|
return total;
|
|
948
922
|
}
|
|
949
|
-
|
|
923
|
+
const COL_GROUP_STAT_EQUALITY = {
|
|
950
924
|
cols: common.isColPropsEqual,
|
|
951
925
|
};
|
|
952
926
|
function isColGroupStatsEqual(stat0, stat1) {
|
|
953
927
|
return common.compareObjs(stat0, stat1, COL_GROUP_STAT_EQUALITY);
|
|
954
928
|
}
|
|
955
929
|
// for memoizers...
|
|
956
|
-
function initScrollSyncer(isVertical) {
|
|
957
|
-
var scrollEls = [];
|
|
958
|
-
for (var _i = 1; _i < arguments.length; _i++) {
|
|
959
|
-
scrollEls[_i - 1] = arguments[_i];
|
|
960
|
-
}
|
|
930
|
+
function initScrollSyncer(isVertical, ...scrollEls) {
|
|
961
931
|
return new ScrollSyncer(isVertical, scrollEls);
|
|
962
932
|
}
|
|
963
933
|
function destroyScrollSyncer(scrollSyncer) {
|