canvas-datagrid 0.25.3 → 0.26.0
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/CHANGELOG.md +328 -1
- package/README.md +85 -67
- package/dist/canvas-datagrid.debug.js +7606 -3099
- package/dist/canvas-datagrid.debug.map +1 -1
- package/dist/canvas-datagrid.js +1 -1
- package/dist/canvas-datagrid.module.js +1 -1
- package/dist/canvas-datagrid.module.js.map +1 -1
- package/dist/types.d.ts +2508 -0
- package/lib/button.js +326 -0
- package/lib/component.js +51 -13
- package/lib/contextMenu.js +408 -30
- package/lib/defaults.js +100 -7
- package/lib/docs.js +121 -11
- package/lib/dom.js +239 -18
- package/lib/draw.js +1446 -206
- package/lib/events/index.js +2640 -0
- package/lib/events/util.js +165 -0
- package/lib/groups/util.js +42 -0
- package/lib/intf.js +908 -87
- package/lib/main.js +8 -1
- package/lib/publicMethods.js +773 -377
- package/lib/selections/index.js +989 -0
- package/lib/selections/type.d.ts +38 -0
- package/lib/selections/util.js +1320 -0
- package/lib/touch.js +20 -47
- package/package.json +32 -21
- package/lib/events.js +0 -1741
package/lib/dom.js
CHANGED
|
@@ -123,14 +123,27 @@ export default function (self) {
|
|
|
123
123
|
self.input.style.width = self.width - borderWidth - 1 + 'px';
|
|
124
124
|
return;
|
|
125
125
|
}
|
|
126
|
+
let groupAreaOffsetY = self.getColumnGroupAreaHeight();
|
|
127
|
+
let groupAreaOffsetX = self.getRowGroupAreaWidth();
|
|
128
|
+
if (self.parentNode) {
|
|
129
|
+
const { columnGroupsAreaHeight, rowGroupsAreaWidth } = self.parentNode;
|
|
130
|
+
if (columnGroupsAreaHeight) groupAreaOffsetY += columnGroupsAreaHeight;
|
|
131
|
+
if (rowGroupsAreaWidth) groupAreaOffsetX += rowGroupsAreaWidth;
|
|
132
|
+
}
|
|
126
133
|
self.input.style.left =
|
|
127
|
-
pos.left +
|
|
134
|
+
pos.left +
|
|
135
|
+
cell.x +
|
|
136
|
+
self.canvasOffsetLeft -
|
|
137
|
+
s.left +
|
|
138
|
+
groupAreaOffsetX +
|
|
139
|
+
'px';
|
|
128
140
|
self.input.style.top =
|
|
129
141
|
pos.top +
|
|
130
142
|
cell.y -
|
|
131
143
|
self.style.cellBorderWidth +
|
|
132
144
|
self.canvasOffsetTop -
|
|
133
145
|
s.top +
|
|
146
|
+
groupAreaOffsetY +
|
|
134
147
|
'px';
|
|
135
148
|
self.input.style.height = cell.height - borderWidth + 'px';
|
|
136
149
|
self.input.style.width = cell.width - self.style.cellPaddingLeft + 'px';
|
|
@@ -143,11 +156,16 @@ export default function (self) {
|
|
|
143
156
|
s = e,
|
|
144
157
|
h,
|
|
145
158
|
w;
|
|
159
|
+
let calculatedTree = false;
|
|
146
160
|
while (e.offsetParent && e.nodeName !== 'CANVAS-DATAGRID') {
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
161
|
+
const isTree = e.nodeType === 'canvas-datagrid-tree';
|
|
162
|
+
if (!isTree || !calculatedTree) {
|
|
163
|
+
x += e.offsetLeft;
|
|
164
|
+
y += e.offsetTop;
|
|
165
|
+
h = e.offsetHeight;
|
|
166
|
+
w = e.offsetWidth;
|
|
167
|
+
}
|
|
168
|
+
if (isTree) calculatedTree = true;
|
|
151
169
|
e = e.offsetParent;
|
|
152
170
|
}
|
|
153
171
|
if (ignoreScrollOffset) {
|
|
@@ -166,6 +184,10 @@ export default function (self) {
|
|
|
166
184
|
if (self.isChildGrid) {
|
|
167
185
|
pos.x -= self.canvasOffsetLeft;
|
|
168
186
|
pos.y -= self.canvasOffsetTop;
|
|
187
|
+
if (self.parentNode.rowGroupsAreaWidth)
|
|
188
|
+
pos.x -= self.parentNode.rowGroupsAreaWidth;
|
|
189
|
+
if (self.parentNode.columnGroupsAreaHeight)
|
|
190
|
+
pos.y -= self.parentNode.columnGroupsAreaHeight;
|
|
169
191
|
}
|
|
170
192
|
return {
|
|
171
193
|
x: pos.x,
|
|
@@ -173,6 +195,62 @@ export default function (self) {
|
|
|
173
195
|
rect: rect,
|
|
174
196
|
};
|
|
175
197
|
};
|
|
198
|
+
/**
|
|
199
|
+
* Watches the host element and its parent for size changes so a grid sized
|
|
200
|
+
* with auto/percentage dimensions follows layout changes (flex, splitters,
|
|
201
|
+
* tab switches) without an explicit `resize()` call (#289, #239).
|
|
202
|
+
* Falls back to the `window` resize listener when ResizeObserver is missing.
|
|
203
|
+
*/
|
|
204
|
+
self.initResizeObserver = function () {
|
|
205
|
+
if (self.isChildGrid || typeof window.ResizeObserver !== 'function') {
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
self.observedSizes = new Map();
|
|
209
|
+
self.resizeObserver = new window.ResizeObserver(function (entries) {
|
|
210
|
+
var changed = false;
|
|
211
|
+
entries.forEach(function (entry) {
|
|
212
|
+
var rect = entry.contentRect;
|
|
213
|
+
var last = self.observedSizes.get(entry.target);
|
|
214
|
+
if (!last || last.width !== rect.width || last.height !== rect.height) {
|
|
215
|
+
self.observedSizes.set(entry.target, {
|
|
216
|
+
width: rect.width,
|
|
217
|
+
height: rect.height,
|
|
218
|
+
});
|
|
219
|
+
changed = true;
|
|
220
|
+
}
|
|
221
|
+
});
|
|
222
|
+
if (!changed || self.disposed || self.resizeObserverFrame) {
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
// coalesce bursts of notifications into one resize per frame
|
|
226
|
+
self.resizeObserverFrame = requestAnimationFrame(function () {
|
|
227
|
+
self.resizeObserverFrame = undefined;
|
|
228
|
+
if (self.disposed) {
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
self.resize(true);
|
|
232
|
+
});
|
|
233
|
+
});
|
|
234
|
+
self.observeResizeTargets();
|
|
235
|
+
};
|
|
236
|
+
self.observeResizeTargets = function () {
|
|
237
|
+
if (!self.resizeObserver) {
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
self.resizeObserver.disconnect();
|
|
241
|
+
self.observedSizes = new Map();
|
|
242
|
+
var host = self.intf && self.intf.nodeType === 1 ? self.intf : self.canvas;
|
|
243
|
+
[host, host && host.parentNode].forEach(function (target) {
|
|
244
|
+
if (target && target.nodeType === 1) {
|
|
245
|
+
self.resizeObserver.observe(target);
|
|
246
|
+
}
|
|
247
|
+
});
|
|
248
|
+
};
|
|
249
|
+
self.unobserveResizeTargets = function () {
|
|
250
|
+
if (self.resizeObserver) {
|
|
251
|
+
self.resizeObserver.disconnect();
|
|
252
|
+
}
|
|
253
|
+
};
|
|
176
254
|
/**
|
|
177
255
|
* Ends editing, optionally aborting the edit.
|
|
178
256
|
* @memberof canvasDatagrid
|
|
@@ -182,7 +260,11 @@ export default function (self) {
|
|
|
182
260
|
*/
|
|
183
261
|
self.endEdit = function (abort) {
|
|
184
262
|
var cell = self.input.editCell,
|
|
185
|
-
y = cell.rowIndex
|
|
263
|
+
y = cell.rowIndex,
|
|
264
|
+
// Decide up front whether this is the "new row" placeholder. A
|
|
265
|
+
// beforeendedit handler may add or delete rows (#583), which would
|
|
266
|
+
// otherwise make the last real row look like the placeholder.
|
|
267
|
+
isNewRow = y === self.viewData.length;
|
|
186
268
|
function abortEdit() {
|
|
187
269
|
abort = true;
|
|
188
270
|
}
|
|
@@ -198,14 +280,18 @@ export default function (self) {
|
|
|
198
280
|
return false;
|
|
199
281
|
}
|
|
200
282
|
if (self.input.value !== cell.value && !abort) {
|
|
201
|
-
|
|
202
|
-
|
|
283
|
+
// key the change log by the bound (data) row index rather than the
|
|
284
|
+
// view index so sorting/filtering cannot misattribute edits (#418)
|
|
285
|
+
var changeIndex =
|
|
286
|
+
cell.boundRowIndex === undefined ? y : cell.boundRowIndex;
|
|
287
|
+
self.changes[changeIndex] = self.changes[changeIndex] || {};
|
|
288
|
+
self.changes[changeIndex][cell.header.name] = self.input.value;
|
|
203
289
|
if (!cell.data) {
|
|
204
|
-
self.
|
|
205
|
-
cell.data = self.
|
|
290
|
+
self.originalData[cell.boundRowIndex] = {};
|
|
291
|
+
cell.data = self.originalData[cell.boundRowIndex];
|
|
206
292
|
}
|
|
207
293
|
cell.data[cell.header.name] = self.input.value;
|
|
208
|
-
if (
|
|
294
|
+
if (isNewRow) {
|
|
209
295
|
if (
|
|
210
296
|
self.dispatchEvent('newrow', {
|
|
211
297
|
value: self.input.value,
|
|
@@ -220,6 +306,10 @@ export default function (self) {
|
|
|
220
306
|
self.addRow(cell.data);
|
|
221
307
|
self.createNewRowData();
|
|
222
308
|
}
|
|
309
|
+
self.dispatchDataChanged('edit', {
|
|
310
|
+
cell: cell,
|
|
311
|
+
value: self.input.value,
|
|
312
|
+
});
|
|
223
313
|
self.draw(true);
|
|
224
314
|
}
|
|
225
315
|
if (self.input.parentNode) {
|
|
@@ -340,6 +430,15 @@ export default function (self) {
|
|
|
340
430
|
self.input.style.position = 'absolute';
|
|
341
431
|
self.input.editCell = cell;
|
|
342
432
|
self.resizeEditInput();
|
|
433
|
+
if (enu && typeof self.input.showPicker === 'function') {
|
|
434
|
+
// open the enum <select> immediately (#230); browsers only allow this
|
|
435
|
+
// from a user gesture, so treat failure as harmless
|
|
436
|
+
try {
|
|
437
|
+
self.input.showPicker();
|
|
438
|
+
} catch (err) {
|
|
439
|
+
// no user activation
|
|
440
|
+
}
|
|
441
|
+
}
|
|
343
442
|
self.input.style.zIndex = self.style.editCellZIndex;
|
|
344
443
|
self.input.style.fontSize =
|
|
345
444
|
parseInt(self.style.editCellFontSize, 10) * self.scale + 'px';
|
|
@@ -348,6 +447,19 @@ export default function (self) {
|
|
|
348
447
|
var shouldClearCellValue = cellValueIsEmpty || inEnterMode;
|
|
349
448
|
|
|
350
449
|
self.input.value = shouldClearCellValue ? '' : cell.value;
|
|
450
|
+
let width = Math.round(
|
|
451
|
+
self.input.value.length *
|
|
452
|
+
parseInt(self.style.editCellFontSize, 10) *
|
|
453
|
+
0.7 *
|
|
454
|
+
self.scale,
|
|
455
|
+
);
|
|
456
|
+
if (width + self.style.cellPaddingLeft < cell.width) {
|
|
457
|
+
width = cell.width - self.style.cellPaddingLeft;
|
|
458
|
+
} else if (width > self.width - cell.x - self.style.scrollBarWidth) {
|
|
459
|
+
width = self.width - cell.x - self.style.scrollBarWidth;
|
|
460
|
+
self.input.style.height = 'auto';
|
|
461
|
+
}
|
|
462
|
+
self.input.style.width = width + 'px';
|
|
351
463
|
self.input.focus();
|
|
352
464
|
self.input.addEventListener('click', self.stopPropagation);
|
|
353
465
|
self.input.addEventListener('dblclick', self.stopPropagation);
|
|
@@ -369,7 +481,7 @@ export default function (self) {
|
|
|
369
481
|
// Move to cell in next or previous row
|
|
370
482
|
var nextRowIndex = e.shiftKey
|
|
371
483
|
? Math.max(0, ny - 1)
|
|
372
|
-
: Math.min(ny + 1, self.
|
|
484
|
+
: Math.min(ny + 1, self.viewData.length - 1);
|
|
373
485
|
|
|
374
486
|
if (nextRowIndex !== ny) {
|
|
375
487
|
self.scrollIntoView(nx, nextRowIndex);
|
|
@@ -386,7 +498,7 @@ export default function (self) {
|
|
|
386
498
|
ny = Math.max(0, ny - 1);
|
|
387
499
|
break;
|
|
388
500
|
case 'ArrowDown':
|
|
389
|
-
ny = Math.min(ny + 1, self.
|
|
501
|
+
ny = Math.min(ny + 1, self.viewData.length - 1);
|
|
390
502
|
break;
|
|
391
503
|
case 'ArrowLeft':
|
|
392
504
|
nx = Math.max(nx - 1, 0);
|
|
@@ -421,13 +533,27 @@ export default function (self) {
|
|
|
421
533
|
ny += 1;
|
|
422
534
|
}
|
|
423
535
|
if (ny < 0) {
|
|
424
|
-
ny = self.
|
|
536
|
+
ny = self.viewData.length - 1;
|
|
425
537
|
}
|
|
426
|
-
if (ny > self.
|
|
538
|
+
if (ny > self.viewData.length - 1) {
|
|
427
539
|
ny = 0;
|
|
428
540
|
}
|
|
429
541
|
self.scrollIntoView(nx, ny);
|
|
430
542
|
self.beginEditAt(nx, ny, e);
|
|
543
|
+
} else {
|
|
544
|
+
let width = Math.round(
|
|
545
|
+
self.input.value.length *
|
|
546
|
+
parseInt(self.style.editCellFontSize, 10) *
|
|
547
|
+
0.7 *
|
|
548
|
+
self.scale,
|
|
549
|
+
);
|
|
550
|
+
if (width + self.style.cellPaddingLeft < cell.width) {
|
|
551
|
+
width = cell.width - self.style.cellPaddingLeft;
|
|
552
|
+
} else if (width > self.width - cell.x - self.style.scrollBarWidth) {
|
|
553
|
+
width = self.width - cell.x - self.style.scrollBarWidth;
|
|
554
|
+
self.input.style.height = 'auto';
|
|
555
|
+
}
|
|
556
|
+
self.input.style.width = width + 'px';
|
|
431
557
|
}
|
|
432
558
|
});
|
|
433
559
|
|
|
@@ -435,6 +561,96 @@ export default function (self) {
|
|
|
435
561
|
};
|
|
436
562
|
self.createInlineStyle = function (el, className) {
|
|
437
563
|
var css = {
|
|
564
|
+
'canvas-datagrid-button-wrapper': {
|
|
565
|
+
display: 'inline-block',
|
|
566
|
+
padding: self.style.buttonPadding,
|
|
567
|
+
borderWidth: '1px',
|
|
568
|
+
borderStyle: 'solid',
|
|
569
|
+
borderColor: self.style.buttonBorderColor,
|
|
570
|
+
cursor: 'pointer',
|
|
571
|
+
background: self.style.buttonBackgroundColor,
|
|
572
|
+
userSelect: 'none',
|
|
573
|
+
},
|
|
574
|
+
'canvas-datagrid-button-wrapper:hover': {
|
|
575
|
+
borderColor: self.style.buttonBorderColor,
|
|
576
|
+
background: self.style.buttonHoverBackgroundColor,
|
|
577
|
+
},
|
|
578
|
+
'canvas-datagrid-button-wrapper:active': {
|
|
579
|
+
borderColor: self.style.buttonActiveBorderColor,
|
|
580
|
+
background: self.style.buttonActiveBackgroundColor,
|
|
581
|
+
},
|
|
582
|
+
'canvas-datagrid-button-icon': {
|
|
583
|
+
width: '18px',
|
|
584
|
+
height: '18px',
|
|
585
|
+
display: 'inline-block',
|
|
586
|
+
verticalAlign: 'middle',
|
|
587
|
+
},
|
|
588
|
+
'canvas-datagrid-button-arrow': {
|
|
589
|
+
display: 'inline-block',
|
|
590
|
+
color: self.style.buttonArrowColor,
|
|
591
|
+
fontSize: '9px',
|
|
592
|
+
},
|
|
593
|
+
'canvas-datagrid-button-menu-item-mobile': {
|
|
594
|
+
lineHeight: 'normal',
|
|
595
|
+
fontWeight: 'normal',
|
|
596
|
+
fontFamily: self.style.contextMenuFontFamily,
|
|
597
|
+
fontSize: self.style.contextMenuFontSize,
|
|
598
|
+
color: 'inherit',
|
|
599
|
+
background: 'inherit',
|
|
600
|
+
margin: self.style.contextMenuItemMargin,
|
|
601
|
+
borderRadius: self.style.contextMenuItemBorderRadius,
|
|
602
|
+
verticalAlign: 'middle',
|
|
603
|
+
},
|
|
604
|
+
'canvas-datagrid-button-menu-item': {
|
|
605
|
+
lineHeight: 'normal',
|
|
606
|
+
fontWeight: 'normal',
|
|
607
|
+
fontFamily: self.style.contextMenuFontFamily,
|
|
608
|
+
fontSize: self.style.contextMenuFontSize,
|
|
609
|
+
color: 'inherit',
|
|
610
|
+
background: 'inherit',
|
|
611
|
+
margin: self.style.contextMenuItemMargin,
|
|
612
|
+
borderRadius: self.style.contextMenuItemBorderRadius,
|
|
613
|
+
verticalAlign: 'middle',
|
|
614
|
+
},
|
|
615
|
+
'canvas-datagrid-button-menu-item:hover': {
|
|
616
|
+
background: self.style.contextMenuHoverBackground,
|
|
617
|
+
color: self.style.contextMenuHoverColor,
|
|
618
|
+
},
|
|
619
|
+
'canvas-datagrid-button-menu-label': {
|
|
620
|
+
margin: self.style.contextMenuLabelMargin,
|
|
621
|
+
display: self.style.contextMenuLabelDisplay,
|
|
622
|
+
minWidth: self.style.contextMenuLabelMinWidth,
|
|
623
|
+
maxWidth: self.style.contextMenuLabelMaxWidth,
|
|
624
|
+
},
|
|
625
|
+
'canvas-datagrid-button-menu-mobile': {
|
|
626
|
+
lineHeight: 'normal',
|
|
627
|
+
fontWeight: 'normal',
|
|
628
|
+
fontFamily: self.style.contextMenuFontFamily,
|
|
629
|
+
fontSize: self.style.contextMenuFontSize,
|
|
630
|
+
background: self.style.contextMenuBackground,
|
|
631
|
+
color: self.style.contextMenuColor,
|
|
632
|
+
border: self.style.contextMenuBorder,
|
|
633
|
+
padding: self.style.contextMenuPadding,
|
|
634
|
+
borderRadius: self.style.contextMenuBorderRadius,
|
|
635
|
+
opacity: self.style.contextMenuOpacity,
|
|
636
|
+
overflow: 'hidden',
|
|
637
|
+
whiteSpace: 'nowrap',
|
|
638
|
+
},
|
|
639
|
+
'canvas-datagrid-button-menu': {
|
|
640
|
+
lineHeight: 'normal',
|
|
641
|
+
fontWeight: 'normal',
|
|
642
|
+
fontFamily: self.style.contextMenuFontFamily,
|
|
643
|
+
fontSize: self.style.contextMenuFontSize,
|
|
644
|
+
background: self.style.contextMenuBackground,
|
|
645
|
+
color: self.style.contextMenuColor,
|
|
646
|
+
border: self.style.contextMenuBorder,
|
|
647
|
+
padding: self.style.contextMenuPadding,
|
|
648
|
+
borderRadius: self.style.contextMenuBorderRadius,
|
|
649
|
+
opacity: self.style.contextMenuOpacity,
|
|
650
|
+
overflow: 'hidden',
|
|
651
|
+
whiteSpace: 'nowrap',
|
|
652
|
+
cursor: self.style.contextMenuCursor,
|
|
653
|
+
},
|
|
438
654
|
'canvas-datagrid-context-menu-filter-input': {
|
|
439
655
|
height: '19px',
|
|
440
656
|
verticalAlign: 'bottom',
|
|
@@ -616,6 +832,7 @@ export default function (self) {
|
|
|
616
832
|
Object.keys(css[className]).map(function (prop) {
|
|
617
833
|
el.style[prop] = css[className][prop];
|
|
618
834
|
});
|
|
835
|
+
el.className = className;
|
|
619
836
|
}
|
|
620
837
|
return;
|
|
621
838
|
};
|
|
@@ -660,12 +877,15 @@ export default function (self) {
|
|
|
660
877
|
}
|
|
661
878
|
});
|
|
662
879
|
self.eventParent.addEventListener('scroll', self.resize, false);
|
|
663
|
-
self.eventParent.addEventListener('touchstart', self.touchstart,
|
|
664
|
-
|
|
880
|
+
self.eventParent.addEventListener('touchstart', self.touchstart, {
|
|
881
|
+
passive: true,
|
|
882
|
+
});
|
|
665
883
|
self.eventParent.addEventListener('mousedown', self.mousedown, false);
|
|
666
884
|
self.eventParent.addEventListener('dblclick', self.dblclick, false);
|
|
667
885
|
self.eventParent.addEventListener('click', self.click, false);
|
|
668
|
-
self.eventParent.addEventListener('
|
|
886
|
+
self.eventParent.addEventListener('mouseup', self.mouseup, false);
|
|
887
|
+
window.addEventListener('mouseup', self.mouseupOutsideGrid, false);
|
|
888
|
+
window.addEventListener('mousemove', self.mousemove);
|
|
669
889
|
self[self.isChildGrid ? 'parentGrid' : 'eventParent'].addEventListener(
|
|
670
890
|
'wheel',
|
|
671
891
|
self.scrollWheel,
|
|
@@ -679,5 +899,6 @@ export default function (self) {
|
|
|
679
899
|
self.controlInput.addEventListener('keyup', self.keyup, false);
|
|
680
900
|
self.controlInput.addEventListener('keydown', self.keydown, false);
|
|
681
901
|
window.addEventListener('resize', self.resize);
|
|
902
|
+
self.initResizeObserver();
|
|
682
903
|
};
|
|
683
904
|
}
|