@nanoporetech-digital/components 5.1.3 → 5.2.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/CHANGELOG.md +26 -0
- package/dist/cjs/{component-store-74d25f63.js → component-store-f1dc1276.js} +2 -2
- package/dist/cjs/{component-store-74d25f63.js.map → component-store-f1dc1276.js.map} +1 -1
- package/dist/cjs/index.cjs.js +1 -1
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/cjs/nano-algolia-filter.cjs.entry.js +2 -2
- package/dist/cjs/nano-algolia-input.cjs.entry.js +2 -2
- package/dist/cjs/nano-algolia.cjs.entry.js +2 -2
- package/dist/cjs/nano-checkbox-group.cjs.entry.js +1 -1
- package/dist/cjs/nano-components.cjs.js +1 -1
- package/dist/cjs/nano-datalist_3.cjs.entry.js +1 -1
- package/dist/cjs/nano-dialog.cjs.entry.js +2 -2
- package/dist/cjs/nano-global-nav-user-profile_3.cjs.entry.js +2 -2
- package/dist/cjs/nano-global-nav-user-profile_3.cjs.entry.js.map +1 -1
- package/dist/cjs/nano-global-nav.cjs.entry.js +2 -2
- package/dist/cjs/nano-input.cjs.entry.js +1 -1
- package/dist/cjs/nano-overflow-nav.cjs.entry.js +1 -1
- package/dist/cjs/nano-range.cjs.entry.js +1 -1
- package/dist/cjs/nano-resize-observe_2.cjs.entry.js +3 -1
- package/dist/cjs/nano-resize-observe_2.cjs.entry.js.map +1 -1
- package/dist/cjs/nano-sortable.cjs.entry.js +16 -8
- package/dist/cjs/nano-sortable.cjs.entry.js.map +1 -1
- package/dist/cjs/nano-split-pane.cjs.entry.js +1 -1
- package/dist/cjs/nano-sticker.cjs.entry.js +4 -2
- package/dist/cjs/nano-sticker.cjs.entry.js.map +1 -1
- package/dist/cjs/nano-tab-group.cjs.entry.js +2 -2
- package/dist/cjs/{nano-table-5a7a4d53.js → nano-table-10a40ab3.js} +557 -185
- package/dist/cjs/nano-table-10a40ab3.js.map +1 -0
- package/dist/cjs/nano-table.cjs.entry.js +2 -2
- package/dist/cjs/{table.worker-77e56070.js → table.worker-f04588c1.js} +4 -4
- package/dist/cjs/table.worker-f04588c1.js.map +1 -0
- package/dist/cjs/{table.worker-bd51e29f.js → table.worker-f258383d.js} +1 -1
- package/dist/cjs/{throttle-f55496c8.js → throttle-dfa64b9e.js} +17 -20
- package/dist/cjs/throttle-dfa64b9e.js.map +1 -0
- package/dist/collection/components/resize-observe/resize-observe.js +21 -1
- package/dist/collection/components/resize-observe/resize-observe.js.map +1 -1
- package/dist/collection/components/select/select.css +0 -1
- package/dist/collection/components/sortable/sortable.js +3 -7
- package/dist/collection/components/sortable/sortable.js.map +1 -1
- package/dist/collection/components/sticker/sticker.js +11 -5
- package/dist/collection/components/sticker/sticker.js.map +1 -1
- package/dist/collection/components/table/table-interface.js.map +1 -1
- package/dist/collection/components/table/table.cell.js +43 -10
- package/dist/collection/components/table/table.cell.js.map +1 -1
- package/dist/collection/components/table/table.css +38 -55
- package/dist/collection/components/table/table.header.js +4 -9
- package/dist/collection/components/table/table.header.js.map +1 -1
- package/dist/collection/components/table/table.js +101 -47
- package/dist/collection/components/table/table.js.map +1 -1
- package/dist/collection/components/table/table.pin-service.js +382 -0
- package/dist/collection/components/table/table.pin-service.js.map +1 -0
- package/dist/collection/components/table/table.row.js +39 -46
- package/dist/collection/components/table/table.row.js.map +1 -1
- package/dist/collection/components/table/table.utils.js +0 -124
- package/dist/collection/components/table/table.utils.js.map +1 -1
- package/dist/collection/components/table/table.worker.js +1 -0
- package/dist/collection/components/table/table.worker.js.map +1 -1
- package/dist/collection/utils/events.js +27 -0
- package/dist/collection/utils/events.js.map +1 -0
- package/dist/collection/utils/throttle.js +16 -19
- package/dist/collection/utils/throttle.js.map +1 -1
- package/dist/components/nano-sortable.js +15 -7
- package/dist/components/nano-sortable.js.map +1 -1
- package/dist/components/resize-observe.js +3 -1
- package/dist/components/resize-observe.js.map +1 -1
- package/dist/components/select.js +1 -1
- package/dist/components/select.js.map +1 -1
- package/dist/components/sticker.js +3 -1
- package/dist/components/sticker.js.map +1 -1
- package/dist/components/table.js +530 -187
- package/dist/components/table.js.map +1 -1
- package/dist/components/table.worker.js +1 -1
- package/dist/components/throttle.js +16 -19
- package/dist/components/throttle.js.map +1 -1
- package/dist/esm/{component-store-244a8431.js → component-store-c23ebc9c.js} +2 -2
- package/dist/esm/{component-store-244a8431.js.map → component-store-c23ebc9c.js.map} +1 -1
- package/dist/esm/index.js +1 -1
- package/dist/esm/loader.js +1 -1
- package/dist/esm/nano-algolia-filter.entry.js +2 -2
- package/dist/esm/nano-algolia-input.entry.js +2 -2
- package/dist/esm/nano-algolia.entry.js +2 -2
- package/dist/esm/nano-checkbox-group.entry.js +1 -1
- package/dist/esm/nano-components.js +1 -1
- package/dist/esm/nano-datalist_3.entry.js +1 -1
- package/dist/esm/nano-dialog.entry.js +2 -2
- package/dist/esm/nano-global-nav-user-profile_3.entry.js +2 -2
- package/dist/esm/nano-global-nav-user-profile_3.entry.js.map +1 -1
- package/dist/esm/nano-global-nav.entry.js +2 -2
- package/dist/esm/nano-input.entry.js +1 -1
- package/dist/esm/nano-overflow-nav.entry.js +1 -1
- package/dist/esm/nano-range.entry.js +1 -1
- package/dist/esm/nano-resize-observe_2.entry.js +3 -1
- package/dist/esm/nano-resize-observe_2.entry.js.map +1 -1
- package/dist/esm/nano-sortable.entry.js +16 -8
- package/dist/esm/nano-sortable.entry.js.map +1 -1
- package/dist/esm/nano-split-pane.entry.js +1 -1
- package/dist/esm/nano-sticker.entry.js +4 -2
- package/dist/esm/nano-sticker.entry.js.map +1 -1
- package/dist/esm/nano-tab-group.entry.js +2 -2
- package/dist/esm/{nano-table-026a0d30.js → nano-table-2bbcaa8d.js} +558 -186
- package/dist/esm/nano-table-2bbcaa8d.js.map +1 -0
- package/dist/esm/nano-table.entry.js +2 -2
- package/dist/esm/{table.worker-c17a27ed.js → table.worker-7324ad73.js} +4 -4
- package/dist/esm/table.worker-7324ad73.js.map +1 -0
- package/dist/esm/{table.worker-bd51e29f.js → table.worker-f258383d.js} +1 -1
- package/dist/esm/{throttle-7836544e.js → throttle-ac4fcefa.js} +17 -20
- package/dist/esm/throttle-ac4fcefa.js.map +1 -0
- package/dist/nano-components/index.esm.js +1 -1
- package/dist/nano-components/nano-components.esm.js +1 -1
- package/dist/nano-components/nano-components.esm.js.map +1 -1
- package/dist/nano-components/{p-7d6065c6.entry.js → p-0697795a.entry.js} +2 -2
- package/dist/nano-components/p-0697795a.entry.js.map +1 -0
- package/dist/nano-components/{p-6975f110.entry.js → p-192902e0.entry.js} +2 -2
- package/dist/nano-components/{p-a6ff5ca6.js → p-1a0b5bc3.js} +2 -2
- package/dist/nano-components/{p-3a761d77.entry.js → p-1b791810.entry.js} +2 -2
- package/dist/nano-components/p-39aec880.entry.js +5 -0
- package/dist/nano-components/{p-3b4b7f40.entry.js → p-3eb6d833.entry.js} +2 -2
- package/dist/nano-components/{p-a1c0afb6.entry.js → p-4884b65a.entry.js} +2 -2
- package/dist/nano-components/p-52ae36ec.js +5 -0
- package/dist/nano-components/{p-34501eae.entry.js → p-565793a2.entry.js} +2 -2
- package/dist/nano-components/p-5aae2588.entry.js +5 -0
- package/dist/nano-components/p-5aae2588.entry.js.map +1 -0
- package/dist/nano-components/{p-935aef3d.entry.js → p-6920ad69.entry.js} +2 -2
- package/dist/nano-components/{p-1c6c94cb.entry.js → p-7baa9e14.entry.js} +2 -2
- package/dist/nano-components/p-7bff5224.js +5 -0
- package/dist/nano-components/p-7bff5224.js.map +1 -0
- package/dist/nano-components/{p-f60fe933.entry.js → p-898cbac7.entry.js} +2 -2
- package/dist/nano-components/p-9b533dc3.js +5 -0
- package/dist/nano-components/p-9b533dc3.js.map +1 -0
- package/dist/nano-components/{p-ace1ffc2.entry.js → p-a362bd23.entry.js} +2 -2
- package/dist/nano-components/{p-eb6c9191.entry.js → p-b72df1aa.entry.js} +2 -2
- package/dist/nano-components/{p-9c4efe14.entry.js → p-bf18e298.entry.js} +2 -2
- package/dist/nano-components/p-bf18e298.entry.js.map +1 -0
- package/dist/nano-components/p-ce5efc3f.entry.js +5 -0
- package/dist/nano-components/p-ce5efc3f.entry.js.map +1 -0
- package/dist/nano-components/{p-1b687f96.entry.js → p-d0eefd52.entry.js} +2 -2
- package/dist/nano-components/{p-1a9d9956.entry.js → p-d74e2642.entry.js} +2 -2
- package/dist/nano-components/{p-bd51e29f.js → p-f258383d.js} +1 -1
- package/dist/types/components/resize-observe/resize-observe.d.ts +2 -0
- package/dist/types/components/sortable/sortable.d.ts +0 -1
- package/dist/types/components/sticker/sticker.d.ts +2 -2
- package/dist/types/components/table/table-interface.d.ts +23 -11
- package/dist/types/components/table/table.cell.d.ts +0 -7
- package/dist/types/components/table/table.d.ts +10 -8
- package/dist/types/components/table/table.header.d.ts +0 -1
- package/dist/types/components/table/table.pin-service.d.ts +90 -0
- package/dist/types/components/table/table.row.d.ts +3 -2
- package/dist/types/components/table/table.utils.d.ts +0 -27
- package/dist/types/components.d.ts +29 -11
- package/dist/types/utils/events.d.ts +15 -0
- package/dist/types/utils/throttle.d.ts +1 -1
- package/docs-json.json +59 -24
- package/docs-vscode.json +2 -2
- package/hydrate/index.js +580 -194
- package/package.json +2 -2
- package/dist/cjs/nano-table-5a7a4d53.js.map +0 -1
- package/dist/cjs/table.worker-77e56070.js.map +0 -1
- package/dist/cjs/throttle-f55496c8.js.map +0 -1
- package/dist/esm/nano-table-026a0d30.js.map +0 -1
- package/dist/esm/table.worker-c17a27ed.js.map +0 -1
- package/dist/esm/throttle-7836544e.js.map +0 -1
- package/dist/nano-components/p-15217442.entry.js +0 -5
- package/dist/nano-components/p-15217442.entry.js.map +0 -1
- package/dist/nano-components/p-2e63676f.js +0 -5
- package/dist/nano-components/p-30cc21c2.entry.js +0 -5
- package/dist/nano-components/p-59eb9caa.js +0 -5
- package/dist/nano-components/p-59eb9caa.js.map +0 -1
- package/dist/nano-components/p-7759d185.entry.js +0 -5
- package/dist/nano-components/p-7759d185.entry.js.map +0 -1
- package/dist/nano-components/p-7d6065c6.entry.js.map +0 -1
- package/dist/nano-components/p-9746b0a5.js +0 -5
- package/dist/nano-components/p-9746b0a5.js.map +0 -1
- package/dist/nano-components/p-9c4efe14.entry.js.map +0 -1
- /package/dist/nano-components/{p-6975f110.entry.js.map → p-192902e0.entry.js.map} +0 -0
- /package/dist/nano-components/{p-a6ff5ca6.js.map → p-1a0b5bc3.js.map} +0 -0
- /package/dist/nano-components/{p-3a761d77.entry.js.map → p-1b791810.entry.js.map} +0 -0
- /package/dist/nano-components/{p-2e63676f.js.map → p-39aec880.entry.js.map} +0 -0
- /package/dist/nano-components/{p-3b4b7f40.entry.js.map → p-3eb6d833.entry.js.map} +0 -0
- /package/dist/nano-components/{p-a1c0afb6.entry.js.map → p-4884b65a.entry.js.map} +0 -0
- /package/dist/nano-components/{p-30cc21c2.entry.js.map → p-52ae36ec.js.map} +0 -0
- /package/dist/nano-components/{p-34501eae.entry.js.map → p-565793a2.entry.js.map} +0 -0
- /package/dist/nano-components/{p-935aef3d.entry.js.map → p-6920ad69.entry.js.map} +0 -0
- /package/dist/nano-components/{p-1c6c94cb.entry.js.map → p-7baa9e14.entry.js.map} +0 -0
- /package/dist/nano-components/{p-f60fe933.entry.js.map → p-898cbac7.entry.js.map} +0 -0
- /package/dist/nano-components/{p-ace1ffc2.entry.js.map → p-a362bd23.entry.js.map} +0 -0
- /package/dist/nano-components/{p-eb6c9191.entry.js.map → p-b72df1aa.entry.js.map} +0 -0
- /package/dist/nano-components/{p-1b687f96.entry.js.map → p-d0eefd52.entry.js.map} +0 -0
- /package/dist/nano-components/{p-1a9d9956.entry.js.map → p-d74e2642.entry.js.map} +0 -0
@@ -5,7 +5,7 @@
|
|
5
5
|
|
6
6
|
const index = require('./index-71f899a7.js');
|
7
7
|
const math = require('./math-a8123703.js');
|
8
|
-
const throttle = require('./throttle-
|
8
|
+
const throttle = require('./throttle-dfa64b9e.js');
|
9
9
|
const index$1 = require('./index-99649bef.js');
|
10
10
|
|
11
11
|
const CSSNAMESPACE = 'nano-tbl';
|
@@ -112,7 +112,7 @@ const createWorkerProxy = (worker, workerMsgId, exportedMethod) => (
|
|
112
112
|
})
|
113
113
|
);
|
114
114
|
|
115
|
-
const workerPromise = Promise.resolve().then(function () { return require('./table.worker-
|
115
|
+
const workerPromise = Promise.resolve().then(function () { return require('./table.worker-f04588c1.js'); }).then(m => m.worker);
|
116
116
|
const createWorkerStore = /*@__PURE__*/createWorkerProxy(workerPromise, 'stencil.table.worker', 'createWorkerStore');
|
117
117
|
const syncConfigToWorker = /*@__PURE__*/createWorkerProxy(workerPromise, 'stencil.table.worker', 'syncConfigToWorker');
|
118
118
|
const syncDataToWorker = /*@__PURE__*/createWorkerProxy(workerPromise, 'stencil.table.worker', 'syncDataToWorker');
|
@@ -363,92 +363,6 @@ function colheadFootRender(col) {
|
|
363
363
|
const tpl = col === null || col === void 0 ? void 0 : col.columnTemplate;
|
364
364
|
return tpl ? (tpl(index.h, col)) : (index.h(index.Fragment, null, col.title));
|
365
365
|
}
|
366
|
-
const stickyHIOs = new WeakMap();
|
367
|
-
const stickyVIOs = new WeakMap();
|
368
|
-
/**
|
369
|
-
* Adds element to Intersection Observer. Fires when element changes on the x axis
|
370
|
-
* @param el - an element to observe
|
371
|
-
* @param pos - the edge to watch (start or end)
|
372
|
-
* @param cb - callback when an intersection state changes.
|
373
|
-
*/
|
374
|
-
function addHObserver(el, pos, cb) {
|
375
|
-
if (stickyHIOs.get(el))
|
376
|
-
return;
|
377
|
-
const store = fetchStores();
|
378
|
-
const root = store.general.state.scrollParent;
|
379
|
-
const observer = new IntersectionObserver(([e]) => {
|
380
|
-
const rootBounds = e.rootBounds || document.scrollingElement.getBoundingClientRect();
|
381
|
-
const positions = {};
|
382
|
-
if (pos === 'start') {
|
383
|
-
positions.start =
|
384
|
-
e.boundingClientRect.x - (rootBounds.x + root.scrollLeft) < 0 &&
|
385
|
-
!e.isIntersecting;
|
386
|
-
}
|
387
|
-
if (pos === 'end') {
|
388
|
-
// TODO - sort these out for RtL
|
389
|
-
positions.end =
|
390
|
-
e.boundingClientRect.right > e.boundingClientRect.width &&
|
391
|
-
!e.isIntersecting;
|
392
|
-
}
|
393
|
-
if (!!cb)
|
394
|
-
cb(positions);
|
395
|
-
}, {
|
396
|
-
threshold: [1],
|
397
|
-
rootMargin: '1px 0px 100px 0px',
|
398
|
-
root: root === document.scrollingElement ? null : root,
|
399
|
-
});
|
400
|
-
stickyHIOs.set(el, observer);
|
401
|
-
if (store.general.state.isReady) {
|
402
|
-
observer.observe(el);
|
403
|
-
}
|
404
|
-
else {
|
405
|
-
store.general.state.host.addEventListener('nanoTblReady', () => {
|
406
|
-
observer.observe(el);
|
407
|
-
}, { once: true });
|
408
|
-
}
|
409
|
-
}
|
410
|
-
/**
|
411
|
-
* Adds element to Intersection Observer. Fires when element changes on the y axis
|
412
|
-
* @param el - an element to observe
|
413
|
-
* @param pos - the edge to watch (start or end)
|
414
|
-
* @param cb - callback when an intersection state changes.
|
415
|
-
*/
|
416
|
-
function addVObserver(el, pos, cb) {
|
417
|
-
if (stickyVIOs.get(el))
|
418
|
-
return;
|
419
|
-
const store = fetchStores();
|
420
|
-
const root = store.general.state.scrollParent;
|
421
|
-
const observer = new IntersectionObserver(([e]) => {
|
422
|
-
const rootBounds = e.rootBounds || document.scrollingElement.getBoundingClientRect();
|
423
|
-
const positions = {};
|
424
|
-
if (pos === 'top') {
|
425
|
-
positions.top =
|
426
|
-
e.boundingClientRect.y - (rootBounds.y + root.scrollTop) < 0 &&
|
427
|
-
!e.isIntersecting;
|
428
|
-
}
|
429
|
-
if (pos === 'bottom') {
|
430
|
-
const boundingClientRect = e.target.getBoundingClientRect();
|
431
|
-
positions.bottom =
|
432
|
-
boundingClientRect.height + boundingClientRect.y >
|
433
|
-
rootBounds.height && !e.isIntersecting;
|
434
|
-
}
|
435
|
-
if (!!cb)
|
436
|
-
cb(positions);
|
437
|
-
}, {
|
438
|
-
threshold: [1],
|
439
|
-
rootMargin: '0px 100px 0px 100px',
|
440
|
-
root: root === document.scrollingElement ? null : root,
|
441
|
-
});
|
442
|
-
stickyVIOs.set(el, observer);
|
443
|
-
if (store.general.state.isReady) {
|
444
|
-
observer.observe(el);
|
445
|
-
}
|
446
|
-
else {
|
447
|
-
store.general.state.host.addEventListener('nanoTblReady', () => {
|
448
|
-
observer.observe(el);
|
449
|
-
}, { once: true });
|
450
|
-
}
|
451
|
-
}
|
452
366
|
function headerPinClasses(type, vPinned, toString = false) {
|
453
367
|
const classes = {
|
454
368
|
[`${CSSNAMESPACE}__${type}`]: true,
|
@@ -518,7 +432,7 @@ function isInViewport(el, percentVisible = 100) {
|
|
518
432
|
percentVisible);
|
519
433
|
}
|
520
434
|
|
521
|
-
const TableColHead = ({ column,
|
435
|
+
const TableColHead = ({ column, onColumnSortClick, defaults, }) => {
|
522
436
|
// Sort handling
|
523
437
|
function handleColumnSortClick(e) {
|
524
438
|
let order;
|
@@ -543,7 +457,7 @@ const TableColHead = ({ column, headRenderer, onColumnSortClick, onColumnPinned,
|
|
543
457
|
extraProps = column.columnProperties(column) || extraProps;
|
544
458
|
}
|
545
459
|
const baseProps = {
|
546
|
-
class: Object.assign(Object.assign({}, headerPinClasses('th',
|
460
|
+
class: Object.assign(Object.assign({}, headerPinClasses('th', column.pinned)), { [`${CSSNAMESPACE}__pin--start`]: column.pinned === 'start', [`${CSSNAMESPACE}__pin--end`]: column.pinned === 'end', [`${CSSNAMESPACE}__ordered`]: !!column.order, [`${CSSNAMESPACE}__filtered`]: column.filter !== undefined && column.filter !== null }),
|
547
461
|
};
|
548
462
|
let props = extraProps ? mergeProperties(baseProps, extraProps) : baseProps;
|
549
463
|
const content = colheadFootRender(column);
|
@@ -560,12 +474,7 @@ const TableColHead = ({ column, headRenderer, onColumnSortClick, onColumnPinned,
|
|
560
474
|
: 'none';
|
561
475
|
props = Object.assign(Object.assign({}, props), { 'aria-sort': sort });
|
562
476
|
}
|
563
|
-
return (index.h("th", Object.assign({}, props, {
|
564
|
-
if (['end', 'start'].includes(column.pinned))
|
565
|
-
addHObserver(th, column.pinned, onColumnPinned);
|
566
|
-
if (['top', 'bottom'].includes(headRenderer.pinned))
|
567
|
-
addVObserver(th, headRenderer.pinned, onColumnPinned);
|
568
|
-
}, key: column.prop }), isSortable() ? (index.h("button", { class: {
|
477
|
+
return (index.h("th", Object.assign({}, props, { key: column.prop }), isSortable() ? (index.h("button", { class: {
|
569
478
|
[`${CSSNAMESPACE}__order-btn`]: true,
|
570
479
|
[`${CSSNAMESPACE}__cell-content`]: true,
|
571
480
|
}, onClick: handleColumnSortClick },
|
@@ -593,6 +502,7 @@ function cellRender(rowIndex, colIndex) {
|
|
593
502
|
const columns = store.config.state.columns;
|
594
503
|
const tpl = (_a = columns[colIndex]) === null || _a === void 0 ? void 0 : _a.cellTemplate;
|
595
504
|
const model = colDataModel(rowIndex, colIndex);
|
505
|
+
const tableInstance = index.getRenderingRef();
|
596
506
|
if (!!model.cellModel && columns[colIndex].type === 'date') {
|
597
507
|
const d = new Date(model.cellModel);
|
598
508
|
if (d instanceof Date && !isNaN(d)) {
|
@@ -601,7 +511,28 @@ function cellRender(rowIndex, colIndex) {
|
|
601
511
|
: d;
|
602
512
|
}
|
603
513
|
}
|
604
|
-
|
514
|
+
// Wrap the h pragma, then we can know if we're using Stencil's
|
515
|
+
// jsx renderer or a different one
|
516
|
+
let hCalled = false;
|
517
|
+
const hWrap = (...args) => {
|
518
|
+
hCalled = true;
|
519
|
+
return index.h(...args);
|
520
|
+
};
|
521
|
+
let tplResult = tpl ? tpl(hWrap, model) : undefined;
|
522
|
+
if (tplResult &&
|
523
|
+
tableInstance.customRenderer &&
|
524
|
+
tplResult['$attrs$'] === undefined &&
|
525
|
+
!(tplResult instanceof Element) &&
|
526
|
+
typeof tplResult !== 'string' &&
|
527
|
+
!hCalled) {
|
528
|
+
// template result is jsx *not* from Stencil.
|
529
|
+
// Render it now and output it later.
|
530
|
+
const templateEle = document.createElement('template');
|
531
|
+
// @ts-expect-error
|
532
|
+
tableInstance.customRenderer(tplResult, templateEle.content);
|
533
|
+
tplResult = templateEle;
|
534
|
+
}
|
535
|
+
return tplResult ? (tplResult) : model.cellModel !== undefined && model.cellModel !== null ? (index.h(index.Fragment, null, (_b = model.cellModel) === null || _b === void 0 ? void 0 : _b.toString())) : ('');
|
605
536
|
}
|
606
537
|
const baseCellClasses = (colIndex, toString = false) => {
|
607
538
|
const store = fetchStores();
|
@@ -617,11 +548,12 @@ const baseCellClasses = (colIndex, toString = false) => {
|
|
617
548
|
return classListToStr(classes);
|
618
549
|
return classes;
|
619
550
|
};
|
620
|
-
const TableCell
|
551
|
+
const TableCell = ({ rowIndex, colIndex, nestedContent, }) => {
|
621
552
|
const Content = () => nestedContent
|
622
553
|
? nestedContent()
|
623
554
|
: cellRender(rowIndex, colIndex) || (index.h("span", { class: "placeholder" }, "\u00A0"));
|
624
555
|
let CellType = 'td';
|
556
|
+
const tableInstance = index.getRenderingRef();
|
625
557
|
const store = fetchStores();
|
626
558
|
const column = store.config.state.columns[colIndex];
|
627
559
|
let props = mergeCellProperties(rowIndex, colIndex, {
|
@@ -633,14 +565,23 @@ const TableCell$1 = ({ rowIndex, colIndex, nestedContent, }) => {
|
|
633
565
|
? Object.assign(Object.assign({}, props), { scope: 'rowgroup' }) : Object.assign(Object.assign({}, props), { scope: 'row' });
|
634
566
|
CellType = 'th';
|
635
567
|
}
|
636
|
-
const ContentWrap = (props) =>
|
637
|
-
|
638
|
-
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
-
|
643
|
-
|
568
|
+
const ContentWrap = (props) => {
|
569
|
+
const content = Content();
|
570
|
+
return (index.h("div", Object.assign({ ref: (d) => {
|
571
|
+
if (d && content instanceof Element) {
|
572
|
+
d.replaceChildren();
|
573
|
+
d.append(content['content'] || content);
|
574
|
+
}
|
575
|
+
} }, props, { class: {
|
576
|
+
[`${CSSNAMESPACE}__cell-content`]: true,
|
577
|
+
[`${CSSNAMESPACE}__cell-content--wrap`]: !!column.wrap,
|
578
|
+
}, innerHTML: typeof content === 'string' && content.includes('<')
|
579
|
+
? content
|
580
|
+
: undefined }), (typeof content !== 'string' || !content.includes('<')) &&
|
581
|
+
!(content instanceof Element) &&
|
582
|
+
content));
|
583
|
+
};
|
584
|
+
return (index.h(CellType, Object.assign({ role: tableInstance.type === 'grid' ? 'gridcell' : undefined }, props), column.autoTooltip && !column.wrap ? (index.h("nano-resize-observe", { notifyContentFit: "x", onNanoResizeContentFitChange: (e) => (e.target.firstElementChild.disabled =
|
644
585
|
e.detail.x) },
|
645
586
|
index.h("nano-tooltip", { disabled: true, placement: "top", onNanoShow: (e) => (e.target.closest(CellType).style.zIndex = '100'), onNanoHide: (e) => (e.target.closest(CellType).style.zIndex = '') },
|
646
587
|
index.h(ContentWrap, null),
|
@@ -648,14 +589,18 @@ const TableCell$1 = ({ rowIndex, colIndex, nestedContent, }) => {
|
|
648
589
|
index.h(Content, null))))) : (index.h(ContentWrap, null))));
|
649
590
|
};
|
650
591
|
|
651
|
-
const
|
652
|
-
const cell = (index.h("div", { class: {
|
592
|
+
const tableCellContent = (props, children, ctx) => {
|
593
|
+
const cell = (index.h("div", Object.assign({}, props.wrapperProps, { class: {
|
653
594
|
[`${CSSNAMESPACE}__cell-content`]: true,
|
654
|
-
[`${CSSNAMESPACE}__cell-content--wrap`]: wrap,
|
655
|
-
} }, children));
|
656
|
-
return header ? index.h("th", { scope:
|
595
|
+
[`${CSSNAMESPACE}__cell-content--wrap`]: props.wrap,
|
596
|
+
} }), children));
|
597
|
+
return props.header ? (index.h("th", Object.assign({ scope: ctx }, props.cellProps), cell)) : (index.h("td", Object.assign({}, props.cellProps), cell));
|
657
598
|
};
|
658
|
-
const TableRow = ({ rowRenderer, rowIndex, rowModel
|
599
|
+
const TableRow = ({ rowRenderer, rowIndex, rowModel }, children, utils) => {
|
600
|
+
// helper, generates <td> or <th>
|
601
|
+
const TableCell = ({ header, wrap, cellProps, wrapperProps }, children) => {
|
602
|
+
return tableCellContent({ header, wrap, cellProps, wrapperProps }, children, 'row');
|
603
|
+
};
|
659
604
|
let extraProps = {};
|
660
605
|
if (!rowModel) {
|
661
606
|
const model = rowDataModel(rowIndex);
|
@@ -665,13 +610,28 @@ const TableRow = ({ rowRenderer, rowIndex, rowModel, onColumnPinned }, children,
|
|
665
610
|
extraProps =
|
666
611
|
rowRenderer.rowProperties({ rowModel, rowIndex }) || extraProps;
|
667
612
|
}
|
668
|
-
let
|
613
|
+
let rowPinned;
|
669
614
|
if ((rowRenderer === null || rowRenderer === void 0 ? void 0 : rowRenderer.pinned) && typeof rowRenderer.pinned === 'function') {
|
670
|
-
|
615
|
+
rowPinned = rowRenderer.pinned({ rowModel, rowIndex });
|
671
616
|
}
|
672
|
-
const
|
673
|
-
const props = extraProps ? mergeProperties(baseProps, extraProps) : baseProps;
|
617
|
+
const props = mergeProperties({ class: headerPinClasses('tr', rowPinned, true) }, extraProps);
|
674
618
|
const tpl = rowRenderer === null || rowRenderer === void 0 ? void 0 : rowRenderer.template;
|
619
|
+
/**
|
620
|
+
* Applies appropriate classes to td / th VNodes;
|
621
|
+
* which can be supplied by user defined templates
|
622
|
+
* @param children virtual / jsx node array
|
623
|
+
* @returns virtual / jsx node array
|
624
|
+
*/
|
625
|
+
const applyCellClasses = (children) => {
|
626
|
+
return utils.map(children, (cNode, i) => {
|
627
|
+
if (['td', 'th'].includes(cNode.vtag.toString())) {
|
628
|
+
cNode.vattrs = mergeProperties({
|
629
|
+
class: baseCellClasses(i, true),
|
630
|
+
}, cNode.vattrs);
|
631
|
+
}
|
632
|
+
return cNode;
|
633
|
+
});
|
634
|
+
};
|
675
635
|
if (tpl) {
|
676
636
|
let toRender = tpl(index.h, {
|
677
637
|
renderedRow: (index.h("tr", Object.assign({}, props, { key: rowModel.__uuid }), children)),
|
@@ -683,24 +643,9 @@ const TableRow = ({ rowRenderer, rowIndex, rowModel, onColumnPinned }, children,
|
|
683
643
|
if (node.vtag === 'tr') {
|
684
644
|
if (!node.vkey)
|
685
645
|
node.vkey = `${rowModel.__uuid}_${i}`;
|
686
|
-
node.vattrs = mergeProperties({ class: headerPinClasses('tr',
|
646
|
+
node.vattrs = mergeProperties({ class: headerPinClasses('tr', rowPinned, true) }, node.vattrs);
|
687
647
|
if (!!node.vchildren) {
|
688
|
-
node.vchildren =
|
689
|
-
if (['td', 'th'].includes(cNode.vtag.toString())) {
|
690
|
-
cNode.vattrs = mergeProperties({
|
691
|
-
class: headerPinClasses(cNode.vtag.toString(), pinned, true) + baseCellClasses(i, true),
|
692
|
-
ref: (th) => {
|
693
|
-
if ((!!th && pinned === 'top') || pinned === 'bottom')
|
694
|
-
addVObserver(th, pinned, onColumnPinned);
|
695
|
-
if (!!th && th.classList.contains('nano-tbl__pin--end'))
|
696
|
-
addHObserver(th, 'end', onColumnPinned);
|
697
|
-
if (!!th && th.classList.contains('nano-tbl__pin--start'))
|
698
|
-
addHObserver(th, 'start', onColumnPinned);
|
699
|
-
},
|
700
|
-
}, cNode.vattrs);
|
701
|
-
}
|
702
|
-
return cNode;
|
703
|
-
});
|
648
|
+
node.vchildren = applyCellClasses(node.vchildren);
|
704
649
|
}
|
705
650
|
}
|
706
651
|
return node;
|
@@ -708,28 +653,25 @@ const TableRow = ({ rowRenderer, rowIndex, rowModel, onColumnPinned }, children,
|
|
708
653
|
}
|
709
654
|
return toRender;
|
710
655
|
}
|
711
|
-
return (index.h("tr", Object.assign({}, props, { key: rowModel.__uuid }), children));
|
656
|
+
return (index.h("tr", Object.assign({}, props, { key: rowModel.__uuid }), applyCellClasses(children)));
|
712
657
|
};
|
713
|
-
const TableHeadFootRow = ({ rowRenderer
|
658
|
+
const TableHeadFootRow = ({ rowRenderer }, // onRowPinned, onColPinned
|
659
|
+
children, utils) => {
|
714
660
|
let extraProps = {};
|
715
661
|
if (rowRenderer.rowProperties) {
|
716
662
|
extraProps = rowRenderer.rowProperties() || {};
|
717
663
|
}
|
718
|
-
const
|
719
|
-
|
720
|
-
[`${CSSNAMESPACE}__cell-content`]: true,
|
721
|
-
[`${CSSNAMESPACE}__cell-content--wrap`]: wrap,
|
722
|
-
} }, children));
|
723
|
-
return header !== false ? index.h("th", { scope: "col" }, cell) : index.h("td", null, cell);
|
664
|
+
const TableHeadFootCell = ({ header, wrap, cellProps, wrapperProps }, children) => {
|
665
|
+
return tableCellContent({ header, wrap, cellProps, wrapperProps }, children, 'col');
|
724
666
|
};
|
725
667
|
const pinned = rowRenderer.pinned || null;
|
726
|
-
const baseProps = { class: headerPinClasses('tr',
|
668
|
+
const baseProps = { class: headerPinClasses('tr', pinned) };
|
727
669
|
const props = extraProps ? mergeProperties(baseProps, extraProps) : baseProps;
|
728
670
|
const tpl = rowRenderer === null || rowRenderer === void 0 ? void 0 : rowRenderer.template;
|
729
671
|
if (tpl) {
|
730
672
|
let toRender = tpl(index.h, {
|
731
673
|
renderedRow: index.h("tr", Object.assign({}, props), children),
|
732
|
-
},
|
674
|
+
}, TableHeadFootCell);
|
733
675
|
if (Array.isArray(toRender)) {
|
734
676
|
toRender = utils.map(toRender, (node) => {
|
735
677
|
if (node.vtag === 'tr') {
|
@@ -739,14 +681,6 @@ const TableHeadFootRow = ({ rowRenderer, onColumnPinned }, children, utils) => {
|
|
739
681
|
if (['td', 'th'].includes(cNode.vtag.toString())) {
|
740
682
|
cNode.vattrs = mergeProperties({
|
741
683
|
class: headerPinClasses(cNode.vtag.toString(), pinned, true),
|
742
|
-
ref: (th) => {
|
743
|
-
if ((!!th && pinned === 'top') || pinned === 'bottom')
|
744
|
-
addVObserver(th, pinned, onColumnPinned);
|
745
|
-
if (!!th && th.classList.contains('nano-tbl__pin--end'))
|
746
|
-
addHObserver(th, 'end', onColumnPinned);
|
747
|
-
if (!!th && th.classList.contains('nano-tbl__pin--start'))
|
748
|
-
addHObserver(th, 'start', onColumnPinned);
|
749
|
-
},
|
750
684
|
}, cNode.vattrs);
|
751
685
|
}
|
752
686
|
return cNode;
|
@@ -761,8 +695,399 @@ const TableHeadFootRow = ({ rowRenderer, onColumnPinned }, children, utils) => {
|
|
761
695
|
return index.h("tr", Object.assign({}, props), children);
|
762
696
|
};
|
763
697
|
|
764
|
-
|
698
|
+
function addStyleSheet(id, css) {
|
699
|
+
const styleSheet = document.getElementById(id) ||
|
700
|
+
document.createElement('style');
|
701
|
+
styleSheet.id = id;
|
702
|
+
styleSheet.innerHTML = css;
|
703
|
+
if (!styleSheet.isConnected)
|
704
|
+
document.head.append(styleSheet);
|
705
|
+
}
|
706
|
+
/**
|
707
|
+
* Manages the complex business of table 'pinning'; sticking columns and rows to the scrolling parent element.
|
708
|
+
*
|
709
|
+
* *knowing* when an element is pinned is tricky.
|
710
|
+
* Managing the display of multiple, side-by-side pinned elements is trickier still.
|
711
|
+
*
|
712
|
+
* Pinning table columns are very different from pinning table rows:
|
713
|
+
* - Rows are actual elements we can select, measure and apply styles to.
|
714
|
+
* - Columns are disparate collections of elements that are much harder to select, measure and apply styles to.
|
715
|
+
*
|
716
|
+
* With this in mind, how columns and rows are pinned is different:
|
717
|
+
* Rows can have changes applied directly, Columns have changes applied via dynamic stylesheets.
|
718
|
+
*
|
719
|
+
* The service is slightly opinionated on how it pins rows and columns (with some room for override):
|
720
|
+
* - Pinned columns are stuck consecutively, without overlapping.
|
721
|
+
* e.g. If column 'name' and 'surname' are both `pin: 'start'`; 'surname' will display **next** to name.
|
722
|
+
* Both columns are important for context
|
723
|
+
*
|
724
|
+
* - Pinned rows are set to overlap *when* they have the same ancestor,
|
725
|
+
* and stuck consecutively when they have a different ancestor.
|
726
|
+
* e.g. `tbody > tr.pin ~ tr.pin` the second row will **overlap** the first; it's unlikely both rows will be important for context.
|
727
|
+
* `thead > tr.pin`, `tbody > tr.pin`. Both rows are required for context so will require next to each other.
|
728
|
+
*
|
729
|
+
* Devs can override this behaviour by setting `--pin-start`, `--pin-end`, `--pin-top`, `--pin-bottom` custom vars.
|
730
|
+
*/
|
731
|
+
class TablePinService {
|
732
|
+
constructor(table, scrollElement) {
|
733
|
+
// Private state
|
734
|
+
this.cachedColMeta = new WeakMap();
|
735
|
+
this._pinnedStart = [];
|
736
|
+
this._pinnedEnd = [];
|
737
|
+
this._cssColDimensionCacheKey = '';
|
738
|
+
this.cacheX = 0;
|
739
|
+
this.cacheY = 0;
|
740
|
+
this.tableEle = table;
|
741
|
+
this.tableId = this.tableEle.id;
|
742
|
+
this.scrollElement = scrollElement;
|
743
|
+
// Secret sauce - `getElementsByClassName` is a live collection.
|
744
|
+
// An HTMLCollection will keep itself up-to-date as elements come and go
|
745
|
+
// So we can keep assessing on scroll
|
746
|
+
this.startColumns = table
|
747
|
+
.querySelector('thead')
|
748
|
+
.getElementsByClassName(`${CSSNAMESPACE}__pin--start`);
|
749
|
+
this.endColumns = table
|
750
|
+
.querySelector('thead')
|
751
|
+
.getElementsByClassName(`${CSSNAMESPACE}__pin--end`);
|
752
|
+
this.topRows = table.getElementsByClassName(`${CSSNAMESPACE}__pin--top`);
|
753
|
+
this.bottomRows = table.getElementsByClassName(`${CSSNAMESPACE}__pin--bottom`);
|
754
|
+
this.onResize();
|
755
|
+
}
|
756
|
+
// Pinned cols & change detection
|
757
|
+
get pinnedStart() {
|
758
|
+
return this._pinnedStart;
|
759
|
+
}
|
760
|
+
set pinnedStart(cols) {
|
761
|
+
this._pinnedStart = cols;
|
762
|
+
this.handlePinnedStartChange();
|
763
|
+
}
|
764
|
+
/**
|
765
|
+
* Called when columns are either pinned or unpinned.
|
766
|
+
* Attaches a tiny stylesheet to target the 'last' start column.
|
767
|
+
* (e.g. We only want to apply drop shadow on last pinned start column - not all pinned columns)
|
768
|
+
*/
|
769
|
+
handlePinnedStartChange() {
|
770
|
+
index.writeTask(() => {
|
771
|
+
if (this.pinnedStart.length) {
|
772
|
+
this.tableEle.classList.add(`${CSSNAMESPACE}__pinned--start`);
|
773
|
+
const lastActiveCol = this.cachedColMeta.get(this.pinnedStart[this.pinnedStart.length - 1]);
|
774
|
+
addStyleSheet(`${this.tableId}-col-start-active-style`,
|
775
|
+
/* css */ `
|
776
|
+
#${this.tableId} tr > :nth-child(${lastActiveCol.idx + 1}) {
|
777
|
+
--pin-start-active: 1;
|
778
|
+
}
|
779
|
+
`);
|
780
|
+
}
|
781
|
+
else {
|
782
|
+
this.tableEle.classList.remove(`${CSSNAMESPACE}__pinned--start`);
|
783
|
+
addStyleSheet(`${this.tableId}-col-start-active-style`, ``);
|
784
|
+
}
|
785
|
+
});
|
786
|
+
}
|
787
|
+
get pinnedEnd() {
|
788
|
+
return this._pinnedEnd;
|
789
|
+
}
|
790
|
+
set pinnedEnd(cols) {
|
791
|
+
this._pinnedEnd = cols;
|
792
|
+
this.handlePinnedEndChange();
|
793
|
+
}
|
794
|
+
/**
|
795
|
+
* Called when columns are either pinned or unpinned.
|
796
|
+
* Attaches a tiny stylesheet to target the 'first' end column.
|
797
|
+
* (e.g. We only want to apply drop shadow on first pinned end column - not all pinned columns)
|
798
|
+
*/
|
799
|
+
handlePinnedEndChange() {
|
800
|
+
index.writeTask(() => {
|
801
|
+
if (this.pinnedEnd.length) {
|
802
|
+
this.tableEle.classList.add(`${CSSNAMESPACE}__pinned--end`);
|
803
|
+
const firstActiveCol = this.cachedColMeta.get(this.pinnedEnd[0]);
|
804
|
+
addStyleSheet(`${this.tableId}-col-end-active-style`,
|
805
|
+
/* css */ `
|
806
|
+
#${this.tableId} tr > :nth-child(${firstActiveCol.idx + 1}) { --pin-end-active: 1; }
|
807
|
+
`);
|
808
|
+
}
|
809
|
+
else {
|
810
|
+
this.tableEle.classList.remove(`${CSSNAMESPACE}__pinned--end`);
|
811
|
+
addStyleSheet(`${this.tableId}-col-end-active-style`, ``);
|
812
|
+
}
|
813
|
+
});
|
814
|
+
}
|
815
|
+
get cssColDimensionCacheKey() {
|
816
|
+
return this._cssColDimensionCacheKey;
|
817
|
+
}
|
818
|
+
set cssColDimensionCacheKey(key) {
|
819
|
+
if (key === this._cssColDimensionCacheKey)
|
820
|
+
return;
|
821
|
+
this._cssColDimensionCacheKey = key;
|
822
|
+
this.createPinnedColDimensionStyles();
|
823
|
+
}
|
824
|
+
/**
|
825
|
+
* To only generate column dimension styles when necessary we
|
826
|
+
* maintain a cache key string via serialised column meta.
|
827
|
+
* Only when this key changes do we generate a new stylesheet
|
828
|
+
*/
|
829
|
+
generateCssCacheKey() {
|
830
|
+
let key = '';
|
831
|
+
for (const col of this.startColumns) {
|
832
|
+
const colMeta = this.cachedColMeta.get(col);
|
833
|
+
key += `${colMeta.idx}-start-${colMeta.width}`;
|
834
|
+
}
|
835
|
+
for (const col of this.endColumns) {
|
836
|
+
const colMeta = this.cachedColMeta.get(col);
|
837
|
+
key += `${colMeta.idx}-start-${colMeta.width}`;
|
838
|
+
}
|
839
|
+
this.cssColDimensionCacheKey = key;
|
840
|
+
}
|
841
|
+
/**
|
842
|
+
* Generates pinned column width offset styles
|
843
|
+
* so pinned columns can appear stuck together,
|
844
|
+
* then attaches a stylesheet.
|
845
|
+
*/
|
846
|
+
createPinnedColDimensionStyles() {
|
847
|
+
let widthS = 0;
|
848
|
+
let widthE = 0;
|
849
|
+
const startCols = Array.from(this.startColumns);
|
850
|
+
const endCols = Array.from(this.endColumns).reverse();
|
851
|
+
const css = /* css */ `
|
852
|
+
${startCols
|
853
|
+
.map((col) => {
|
854
|
+
const colMeta = this.cachedColMeta.get(col);
|
855
|
+
widthS += colMeta.width || 0;
|
856
|
+
return /* css */ `
|
857
|
+
#${this.tableId} tr > :nth-child(${colMeta.idx + 1}) ~ td,
|
858
|
+
#${this.tableId} tr > :nth-child(${colMeta.idx + 1}) ~ th {
|
859
|
+
--pin-start: ${widthS - 1}px;
|
860
|
+
}
|
861
|
+
`;
|
862
|
+
})
|
863
|
+
.join('')}
|
864
|
+
${endCols
|
865
|
+
.map((col) => {
|
866
|
+
const colMeta = this.cachedColMeta.get(col);
|
867
|
+
widthE += colMeta.width;
|
868
|
+
return /* css */ `
|
869
|
+
#${this.tableId} tr > td:has(~ :nth-child(${colMeta.idx + 1})),
|
870
|
+
#${this.tableId} tr > th:has(~ :nth-child(${colMeta.idx + 1})) {
|
871
|
+
--pin-end: ${widthE - 1}px;
|
872
|
+
}
|
873
|
+
`;
|
874
|
+
})
|
875
|
+
.join('')}
|
876
|
+
`;
|
877
|
+
addStyleSheet(`${this.tableId}-dimension-style`, css);
|
878
|
+
}
|
879
|
+
getParentOffsets() {
|
880
|
+
const { x, y } = this.scrollElement.getBoundingClientRect();
|
881
|
+
let offsetX = x;
|
882
|
+
let offsetY = y;
|
883
|
+
if (this.scrollElement === document.documentElement) {
|
884
|
+
offsetX = this.scrollElement.offsetLeft;
|
885
|
+
offsetY = this.scrollElement.offsetTop;
|
886
|
+
}
|
887
|
+
return { offsetX, offsetY };
|
888
|
+
}
|
889
|
+
/**
|
890
|
+
* Loops through all 'top' & 'bottom' rows (on scroll or resize)
|
891
|
+
* Manages their visual state by applying classes on stuck / unstuck
|
892
|
+
* And their pinned offset / distance
|
893
|
+
*/
|
894
|
+
assessRows() {
|
895
|
+
if (!this.topRows.length && !this.bottomRows.length)
|
896
|
+
return;
|
897
|
+
// top rows
|
898
|
+
if (this.topRows.length) {
|
899
|
+
index.readTask(async () => {
|
900
|
+
let heightAggregate = 0;
|
901
|
+
let cacheParent;
|
902
|
+
const { offsetY } = this.getParentOffsets();
|
903
|
+
for (const topRow of this.topRows) {
|
904
|
+
const { y, height } = topRow.getBoundingClientRect();
|
905
|
+
const currParent = topRow.parentElement;
|
906
|
+
// we'll use the applied `--pin-top` css var to decide row offset.
|
907
|
+
// This allows devs to override this behaviour through selector specificity
|
908
|
+
const pinTop = getComputedStyle(topRow).getPropertyValue('--pin-top');
|
909
|
+
const offset = pinTop !== '' ? parseFloat(pinTop) : heightAggregate;
|
910
|
+
// we need to wait for the row to finish sticking
|
911
|
+
// and generating it's offset (`--pin-top`) so we can see, on
|
912
|
+
// subsequent rows *if* the offset was applied
|
913
|
+
await new Promise((resolve) => index.writeTask(() => {
|
914
|
+
if (y - offsetY <= offset) {
|
915
|
+
topRow.classList.add(`${CSSNAMESPACE}__pinned`, `${CSSNAMESPACE}__pinned--top`);
|
916
|
+
}
|
917
|
+
else {
|
918
|
+
topRow.classList.remove(`${CSSNAMESPACE}__pinned`, `${CSSNAMESPACE}__pinned--top`);
|
919
|
+
}
|
920
|
+
// by default, we only want to stick one row from each parental block (thead, tbody, tfoot)
|
921
|
+
// so only aggregate height / offset when cacheParent is different from current parent.
|
922
|
+
// Devs can override this behaviour by manually setting `--pin-bottom` on the table row
|
923
|
+
if (cacheParent !== currParent) {
|
924
|
+
currParent.style.setProperty('--pin-top', `${heightAggregate}px`);
|
925
|
+
heightAggregate += height;
|
926
|
+
cacheParent = currParent;
|
927
|
+
}
|
928
|
+
resolve();
|
929
|
+
}));
|
930
|
+
}
|
931
|
+
});
|
932
|
+
}
|
933
|
+
// bottom rows
|
934
|
+
if (this.bottomRows.length) {
|
935
|
+
const bottomRows = Array.from(this.bottomRows).reverse();
|
936
|
+
index.readTask(async () => {
|
937
|
+
let cacheParent;
|
938
|
+
let heightAggregate = 0;
|
939
|
+
const { offsetY } = this.getParentOffsets();
|
940
|
+
for (const bottomRow of bottomRows) {
|
941
|
+
if (!bottomRow.isConnected)
|
942
|
+
continue;
|
943
|
+
const { y, height } = bottomRow.getBoundingClientRect();
|
944
|
+
const currParent = bottomRow.parentElement;
|
945
|
+
// we'll use the applied `--pin-bottom` css var to decide row offset.
|
946
|
+
// This allows devs to override this behaviour through selector specificity
|
947
|
+
const pinBottom = getComputedStyle(bottomRow).getPropertyValue('--pin-bottom');
|
948
|
+
const offset = pinBottom !== '' ? parseFloat(pinBottom) : heightAggregate;
|
949
|
+
// we need to wait for the row to finish sticking
|
950
|
+
// and generating it's offset (`--pin-bottom`) to we can see, on
|
951
|
+
// subsequent rows *if* the offset was applied
|
952
|
+
await new Promise((resolve) => index.writeTask(() => {
|
953
|
+
if (this.tableDims.height + offsetY - (y + height) <= offset) {
|
954
|
+
bottomRow.classList.add(`${CSSNAMESPACE}__pinned`, `${CSSNAMESPACE}__pinned--bottom`);
|
955
|
+
}
|
956
|
+
else {
|
957
|
+
bottomRow.classList.remove(`${CSSNAMESPACE}__pinned`, `${CSSNAMESPACE}__pinned--bottom`);
|
958
|
+
}
|
959
|
+
// by default, we only want to stick one row from each parental block (thead, tbody, tfoot)
|
960
|
+
// so only aggregate height / offset when cacheParent is different from current parent.
|
961
|
+
// Devs can override this behaviour by manually setting `--pin-bottom` on the table row
|
962
|
+
if (cacheParent !== currParent) {
|
963
|
+
currParent.style.setProperty('--pin-bottom', `${heightAggregate}px`);
|
964
|
+
heightAggregate += height;
|
965
|
+
cacheParent = currParent;
|
966
|
+
}
|
967
|
+
resolve();
|
968
|
+
}));
|
969
|
+
}
|
970
|
+
});
|
971
|
+
}
|
972
|
+
}
|
973
|
+
/**
|
974
|
+
* Loops through all 'start' & 'end' columns (on scroll or resize)
|
975
|
+
* Caches meta about each column (e.g. size, position-index)
|
976
|
+
* and decides which columns are pinned
|
977
|
+
*/
|
978
|
+
async assessCols() {
|
979
|
+
if (!this.startColumns.length && !this.endColumns.length)
|
980
|
+
return;
|
981
|
+
let boundBox;
|
982
|
+
let currPinned;
|
983
|
+
let parentEles;
|
984
|
+
const done = new Promise((resolve) => {
|
985
|
+
// start cols
|
986
|
+
if (this.startColumns.length) {
|
987
|
+
index.readTask(() => {
|
988
|
+
const { offsetX } = this.getParentOffsets();
|
989
|
+
// cumulatively add widths of columns together
|
990
|
+
// 'cos columns stick together
|
991
|
+
let widthAggregate = offsetX;
|
992
|
+
parentEles = Array.from(this.startColumns[0].parentElement.children);
|
993
|
+
for (const startCol of this.startColumns) {
|
994
|
+
boundBox = startCol.getBoundingClientRect();
|
995
|
+
// cache meta for later
|
996
|
+
this.cachedColMeta.set(startCol, {
|
997
|
+
width: boundBox.width,
|
998
|
+
idx: parentEles.indexOf(startCol),
|
999
|
+
});
|
1000
|
+
currPinned = this.pinnedStart.find((c) => c === startCol);
|
1001
|
+
if (boundBox.x < widthAggregate) {
|
1002
|
+
// this column is pinned
|
1003
|
+
if (!currPinned)
|
1004
|
+
this.pinnedStart = [
|
1005
|
+
...this.pinnedStart,
|
1006
|
+
startCol,
|
1007
|
+
];
|
1008
|
+
}
|
1009
|
+
else if (currPinned) {
|
1010
|
+
// this column is unpinned
|
1011
|
+
this.pinnedStart = this.pinnedStart.filter((c) => c !== startCol);
|
1012
|
+
}
|
1013
|
+
widthAggregate += boundBox.width;
|
1014
|
+
}
|
1015
|
+
if (!this.endColumns.length)
|
1016
|
+
resolve();
|
1017
|
+
});
|
1018
|
+
}
|
1019
|
+
// end cols
|
1020
|
+
if (this.endColumns.length) {
|
1021
|
+
index.readTask(() => {
|
1022
|
+
const endCols = Array.from(this.endColumns).reverse();
|
1023
|
+
parentEles = Array.from(this.endColumns[0].parentElement.children);
|
1024
|
+
const { offsetX } = this.getParentOffsets();
|
1025
|
+
// cumulatively add widths of columns together
|
1026
|
+
// 'cos columns stick together
|
1027
|
+
let widthAggregate = 0;
|
1028
|
+
for (const endCol of endCols) {
|
1029
|
+
boundBox = endCol.getBoundingClientRect();
|
1030
|
+
// cache meta for later
|
1031
|
+
this.cachedColMeta.set(endCol, {
|
1032
|
+
width: boundBox.width,
|
1033
|
+
idx: parentEles.indexOf(endCol),
|
1034
|
+
});
|
1035
|
+
currPinned = this.pinnedEnd.find((c) => c === endCol);
|
1036
|
+
if (this.tableDims.width + offsetX - boundBox.right <=
|
1037
|
+
widthAggregate) {
|
1038
|
+
// this column is pinned
|
1039
|
+
if (!currPinned)
|
1040
|
+
this.pinnedEnd = [endCol, ...this.pinnedEnd];
|
1041
|
+
}
|
1042
|
+
else if (currPinned) {
|
1043
|
+
// this column is unpinned
|
1044
|
+
this.pinnedEnd = this.pinnedEnd.filter((c) => c !== endCol);
|
1045
|
+
}
|
1046
|
+
widthAggregate += boundBox.width;
|
1047
|
+
}
|
1048
|
+
resolve();
|
1049
|
+
});
|
1050
|
+
}
|
1051
|
+
});
|
1052
|
+
await done;
|
1053
|
+
// potentially generate a new css stylesheet if anything changed
|
1054
|
+
this.generateCssCacheKey();
|
1055
|
+
}
|
1056
|
+
onScroll(pos) {
|
1057
|
+
if (this.cacheX !== pos.x) {
|
1058
|
+
this.cacheX = pos.x;
|
1059
|
+
this.assessCols();
|
1060
|
+
}
|
1061
|
+
if (this.cacheY !== pos.y) {
|
1062
|
+
this.cacheY = pos.y;
|
1063
|
+
this.assessRows();
|
1064
|
+
}
|
1065
|
+
}
|
1066
|
+
onResize() {
|
1067
|
+
const width = this.scrollElement.clientWidth;
|
1068
|
+
const height = this.scrollElement.clientHeight;
|
1069
|
+
this.tableDims = { width, height };
|
1070
|
+
this.assessCols();
|
1071
|
+
this.assessRows();
|
1072
|
+
}
|
1073
|
+
}
|
1074
|
+
|
1075
|
+
const tableCss = ":host{box-sizing:border-box}*,*::before,*::after{box-sizing:border-box}[hidden]{display:none !important}nano-table{display:block;width:100%;--max-col-width:clamp(200px, 500px, 50vw);--color:var(--nano-color-mediumgrey, #68767e);--font-size:0.87rem;--cell-line-height:1.5;--thead-font-size:0.95rem;--thead-color:#455560;--tfoot-color:#455560;--border-color:#dddbda;--border-style:thin solid var(--border-color);--border-tint-color:#0084a9;--border-tint-style:3px solid var(--border-tint-color);--cell-bg-rgb:var(--nano-color-white-rgb, 255 255 255);--head-bg-rgb:250 250 249;--foot-bg-rgb:var(--head-bg-rgb);--th-row-bg-rgb:var(--cell-bg-rgb);--ordered-bg-rgb:var(--nano-color-offwhite-rgb, 249 249 251);--td-padding-start:0.625rem;--td-padding-end:0.625rem;--td-padding-top:0.6rem;--td-padding-bottom:0.6125rem;--th-padding-start:0.725rem;--th-padding-end:0.625rem;--th-padding-top:0.875rem;--th-padding-bottom:0.6875rem;--td-padding-v:var(--td-padding-top) var(--td-padding-bottom);--td-padding-h:var(--td-padding-start) var(--td-padding-end);--th-padding-v:var(--th-padding-top) var(--th-padding-bottom);--th-padding-h:var(--th-padding-start) var(--th-padding-end);--foot-th-padding-v:var(--td-padding-top) var(--td-padding-bottom);--foot-th-padding-h:var(--td-padding-start) var(--td-padding-end);--head-th-padding-v:var(--th-padding-top) var(--th-padding-bottom);--head-th-padding-h:var(--th-padding-start) var(--th-padding-end);--bookend-col-padding:2rem}.nano-tbl{color:var(--color);text-align:start;width:100%;font-size:var(--font-size);border-spacing:0 0;border-collapse:separate;background:rgb(var(--cell-bg-rgb));-webkit-border-end:1px solid transparent;border-inline-end:1px solid transparent;-webkit-border-before:1px solid transparent;border-block-start:1px solid transparent;position:relative;z-index:1}.nano-tbl__wrap{display:table;min-width:100%}.nano-tbl__top-anchor{clip:rect(1px, 1px, 1px, 1px);-webkit-clip-path:inset(50%);clip-path:inset(50%);block-size:1px;inline-size:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;position:relative}.nano-tbl__ordered{background-color:var(--ordered-bg);-webkit-border-start:var(--border-style);border-inline-start:var(--border-style);-webkit-border-end:var(--border-style);border-inline-end:var(--border-style)}.nano-tbl__order-btn{padding:0;border:none;outline:none;font:inherit;background:none;-webkit-appearance:none;appearance:none;color:inherit;display:flex;gap:10px;align-items:center;width:100%}.nano-tbl__order-btn:focus-visible{outline:none;box-shadow:var(--nano-control-focus-shadow, 0 0 0 0.1875rem var(--nano-control-focus-color, rgba(144, 198, 231, 0.8))) inset}.nano-tbl__status-icons{margin-inline:auto 10px;display:flex;gap:10px}.nano-tbl__progress-bar{font-size:0.2rem;position:sticky;inset-block-start:0;inset-inline:0;z-index:10;transition:scale 0.25s;transform:scale(0);width:100%;height:0}.nano-tbl__progress-bar--show{transform:scale(1);height:auto}.nano-tbl__caption--hide{clip:rect(1px, 1px, 1px, 1px);-webkit-clip-path:inset(50%);clip-path:inset(50%);block-size:1px;inline-size:1px;margin:-1px;overflow:hidden;padding:0;position:absolute}.nano-tbl__td,.nano-tbl__th{line-height:var(--cell-line-height);text-align:start;-webkit-border-before:var(--border-style);border-block-start:var(--border-style);max-width:var(--max-col-width);background-color:rgb(var(--cell-bg-rgb))}tbody:first-of-type tr:first-child .nano-tbl__td,tbody:first-of-type tr:first-child .nano-tbl__th{-webkit-border-before:none;border-block-start:none}tbody:last-of-type tr:last-child .nano-tbl__td,tbody:last-of-type tr:last-child .nano-tbl__th{-webkit-border-after:var(--border-style);border-block-end:var(--border-style)}.md .nano-tbl__td:first-child .nano-tbl__cell-content,.md .nano-tbl__th:first-child .nano-tbl__cell-content{-webkit-padding-start:var(--bookend-col-padding);padding-inline-start:var(--bookend-col-padding)}.md .nano-tbl__td:last-child .nano-tbl__cell-content,.md .nano-tbl__th:last-child .nano-tbl__cell-content{-webkit-padding-end:var(--bookend-col-padding);padding-inline-end:var(--bookend-col-padding)}@media (max-width: 768px){.nano-tbl__td:first-child .nano-tbl__cell-content,.nano-tbl__th:first-child .nano-tbl__cell-content{-webkit-padding-start:var(--td-padding-start) !important;padding-inline-start:var(--td-padding-start) !important}.nano-tbl__td:last-child .nano-tbl__cell-content,.nano-tbl__th:last-child .nano-tbl__cell-content{-webkit-padding-end:var(--td-padding-end) !important;padding-inline-end:var(--td-padding-end) !important}}thead .nano-tbl__td,thead .nano-tbl__th{color:var(--thead-color);font-weight:800;background:rgb(var(--head-bg-rgb)/100%);font-size:var(--thead-font-size);-webkit-border-before:none !important;border-block-start:none !important}thead .nano-tbl__td .nano-tbl__cell-content,thead .nano-tbl__th .nano-tbl__cell-content{padding-block:var(--head-th-padding-v);padding-inline:var(--head-th-padding-h)}thead .nano-tbl__td .nano-sortable__keyboard-handle,thead .nano-tbl__th .nano-sortable__keyboard-handle{position:absolute;inset-inline-end:5px;inset-block-start:50%;transform:translateY(-50%);background:white;z-index:10}tfoot .nano-tbl__td,tfoot .nano-tbl__th{color:var(--tfoot-color);font-weight:800;-webkit-border-before:none;border-block-start:none;background:rgb(var(--foot-bg-rgb)/100%);font-size:var(--thead-font-size)}tfoot .nano-tbl__td .nano-tbl__cell-content,tfoot .nano-tbl__th .nano-tbl__cell-content{padding-block:var(--foot-th-padding-v);padding-inline:var(--foot-th-padding-h)}.nano-tbl__td.nano-tbl__ordered,.nano-tbl__th.nano-tbl__ordered{background-color:rgb(var(--ordered-bg-rgb)/80%) !important}.nano-tbl__cell-content{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;padding-block:var(--td-padding-v);padding-inline:var(--td-padding-h)}.nano-tbl__cell-content--no-result{padding-block:2rem}.nano-tbl__cell-content--wrap{white-space:normal;overflow:visible}.nano-tbl tbody{will-change:scroll-position;opacity:1;transition:0.1s ease opacity}.nano-tbl tbody.nano-tbl__loading{z-index:-1;position:relative}.nano-tbl tbody.nano-tbl__inactive{opacity:0}.nano-tbl tbody .nano-tbl__tr:has(~.nano-tbl__tr--placeholder){display:none}.nano-tbl tbody .nano-tbl__tr--placeholder~.nano-tbl__tr{display:none}.nano-tbl th[scope=row]{font-weight:800;margin:0}.nano-tbl__pin--start{position:sticky;inset-inline-start:var(--pin-start, -1px)}.nano-tbl__pin--start::after{content:\"\";position:absolute;inset:0;box-shadow:5px 0 4px -1px rgba(0, 0, 0, 0.2);opacity:var(--pin-start-active, 0);z-index:-1}.nano-tbl__pinned--start .nano-tbl__pin--start{z-index:2}.nano-tbl__pin--end{position:sticky}.nano-tbl__pin--start+.nano-tbl__pin--end{inset-inline-end:auto !important}.nano-tbl__pin--start+.nano-tbl__pin--end::after{display:none}.sm .nano-tbl__pin--end{inset-inline-end:var(--pin-end, -1px);max-width:min(50vw, 200px)}.sm .nano-tbl__pin--end::after{display:block !important;content:\"\";position:absolute;inset:0;box-shadow:-5px 1px 4px -1px rgba(0, 0, 0, 0.2);opacity:var(--pin-end-active, 0);z-index:-1}.sm .nano-tbl__pinned--end .nano-tbl__pin--end{z-index:3}.nano-tbl__pin--top .nano-tbl__th,.nano-tbl__pin--top .nano-tbl__td{position:sticky;inset-block-start:var(--pin-top, -1px)}.nano-tbl__pin--top.nano-tbl__pinned--top .nano-tbl__th,.nano-tbl__pin--top.nano-tbl__pinned--top .nano-tbl__td{z-index:4 !important}.nano-tbl__pinned--start .nano-tbl__pin--top.nano-tbl__pinned--top .nano-tbl__pin--start{z-index:6 !important}tbody .nano-tbl__pin--top.nano-tbl__pinned--top .nano-tbl__th,tbody .nano-tbl__pin--top.nano-tbl__pinned--top .nano-tbl__td{box-shadow:1px 3px 4px -1px rgba(0, 0, 0, 0.1)}.nano-tbl__pin--bottom .nano-tbl__th,.nano-tbl__pin--bottom .nano-tbl__td{position:sticky;inset-block-end:var(--pin-bottom, -1px)}.nano-tbl__pin--bottom.nano-tbl__pinned--bottom .nano-tbl__th,.nano-tbl__pin--bottom.nano-tbl__pinned--bottom .nano-tbl__td{z-index:5 !important}.nano-tbl__pin--bottom.nano-tbl__pinned--bottom:has(~.nano-tbl__pin--bottom.nano-tbl__pinned--bottom) .nano-tbl__th,.nano-tbl__pin--bottom.nano-tbl__pinned--bottom:has(~.nano-tbl__pin--bottom.nano-tbl__pinned--bottom) .nano-tbl__td{z-index:6 !important}.nano-tbl__pinned--start .nano-tbl__pin--bottom.nano-tbl__pinned--bottom .nano-tbl__pin--start{z-index:6 !important}tbody .nano-tbl__pin--bottom.nano-tbl__pinned--bottom .nano-tbl__th,tbody .nano-tbl__pin--bottom.nano-tbl__pinned--bottom .nano-tbl__td{box-shadow:1px -3px 4px -1px rgba(0, 0, 0, 0.07)}.nano-tbl thead tr:last-of-type td,.nano-tbl thead tr:last-of-type th{-webkit-border-after:var(--border-tint-style);border-block-end:var(--border-tint-style)}.nano-tbl tfoot tr:first-of-type td,.nano-tbl tfoot tr:first-of-type th{-webkit-border-before:none;border-block-start:none}.nano-tbl tfoot tr:last-of-type td,.nano-tbl tfoot tr:last-of-type th{-webkit-border-before:var(--border-style);border-block-start:var(--border-style);-webkit-border-after:var(--border-tint-style);border-block-end:var(--border-tint-style)}.nano-tbl__pinned--bottom .nano-tbl tfoot tr.nano-tbl__pin--bottom:first-of-type td,.nano-tbl__pinned--bottom .nano-tbl tfoot tr.nano-tbl__pin--bottom:first-of-type th{-webkit-border-before:var(--border-tint-style) !important;border-block-start:var(--border-tint-style) !important}.nano-tbl__pinned--bottom .nano-tbl tfoot tr.nano-tbl__pin--bottom:last-of-type td,.nano-tbl__pinned--bottom .nano-tbl tfoot tr.nano-tbl__pin--bottom:last-of-type th{-webkit-border-after:none !important;border-block-end:none !important}.nano-tbl .unlimited-width{max-width:none}.nano-tbl__spinner{font-size:1.5rem;transition:scale 0.25s;scale:0;padding:0.5rem;position:absolute;inset-block-end:0;inset-inline-start:calc(50% - 0.75rem);z-index:0}.nano-tbl__spinner--show{scale:1;position:sticky}.nano-tbl nano-skeleton{line-height:var(--cell-line-height)}";
|
765
1076
|
|
1077
|
+
const measurePerf = false;
|
1078
|
+
function perMark(name, end = false) {
|
1079
|
+
if (!performance || !measurePerf)
|
1080
|
+
return;
|
1081
|
+
if (end) {
|
1082
|
+
performance === null || performance === void 0 ? void 0 : performance.mark('end' + name);
|
1083
|
+
performance === null || performance === void 0 ? void 0 : performance.measure(name, 'start' + name, 'end' + name);
|
1084
|
+
const entries = performance === null || performance === void 0 ? void 0 : performance.getEntriesByName(name);
|
1085
|
+
console.log(entries[entries.length ? entries.length - 1 : 0]);
|
1086
|
+
}
|
1087
|
+
else {
|
1088
|
+
performance === null || performance === void 0 ? void 0 : performance.mark('start' + name);
|
1089
|
+
}
|
1090
|
+
}
|
766
1091
|
let id = 0;
|
767
1092
|
const Table = class {
|
768
1093
|
constructor(hostRef) {
|
@@ -780,7 +1105,6 @@ const Table = class {
|
|
780
1105
|
this.filters = [];
|
781
1106
|
this.currentFilters = '[]';
|
782
1107
|
this.currentSort = '';
|
783
|
-
this.cacheScrollPosition = 0;
|
784
1108
|
this.measureHeight = 0;
|
785
1109
|
this.blockHeights = [];
|
786
1110
|
this.unitHeight = 0;
|
@@ -799,6 +1123,7 @@ const Table = class {
|
|
799
1123
|
const sortEvent = this.nanoTblBeforeSort.emit({ column: column, order });
|
800
1124
|
if (sortEvent.defaultPrevented)
|
801
1125
|
return;
|
1126
|
+
perMark('sort');
|
802
1127
|
this.currentSort = order + ':' + column;
|
803
1128
|
// doesn't make sense to leave user in place for a sort
|
804
1129
|
this.scrollToTop(element);
|
@@ -842,25 +1167,40 @@ const Table = class {
|
|
842
1167
|
* stop loop - it's on the current active block.
|
843
1168
|
*/
|
844
1169
|
this.scrollHandler = () => {
|
1170
|
+
var _a;
|
1171
|
+
let scrollPos = 0;
|
1172
|
+
perMark('scrollHandler');
|
845
1173
|
// don't listen if this table isn't in the viewport
|
846
|
-
if (!this.store.general.state.isActive || !this.rows)
|
1174
|
+
if (!((_a = this.store) === null || _a === void 0 ? void 0 : _a.general.state.isActive) || !this.rows)
|
847
1175
|
return;
|
848
1176
|
if (this.primaryBlockIndex === undefined)
|
849
1177
|
this.primaryBlockIndex = 0;
|
850
1178
|
index.readTask(() => {
|
851
|
-
|
1179
|
+
scrollPos =
|
1180
|
+
typeof this.scrollParent.scrollTop !== 'undefined'
|
1181
|
+
? this.scrollParent.scrollTop
|
1182
|
+
: window.scrollY;
|
1183
|
+
scrollPos += this.host.offsetTop;
|
1184
|
+
if (this.tablePinnedService) {
|
1185
|
+
this.tablePinnedService.onScroll({
|
1186
|
+
x: typeof this.scrollParent.scrollLeft !== 'undefined'
|
1187
|
+
? this.scrollParent.scrollLeft
|
1188
|
+
: window.scrollX,
|
1189
|
+
y: scrollPos,
|
1190
|
+
});
|
1191
|
+
}
|
852
1192
|
let cumulativeHeight = this.host.offsetTop;
|
853
1193
|
let blockIndex = 0;
|
854
1194
|
const blockLen = this.blocks.length;
|
855
|
-
while (blockIndex < blockLen &&
|
856
|
-
this.cacheScrollPosition >= cumulativeHeight) {
|
1195
|
+
while (blockIndex < blockLen && scrollPos >= cumulativeHeight) {
|
857
1196
|
cumulativeHeight += this.getBlockHeight(blockIndex);
|
858
|
-
if (
|
1197
|
+
if (scrollPos < cumulativeHeight) {
|
859
1198
|
const potentialBlocks = [
|
860
1199
|
blockIndex,
|
861
1200
|
blockIndex + 1,
|
862
|
-
Math.max(0, blockIndex - 1),
|
1201
|
+
// Math.max(0, blockIndex - 1),
|
863
1202
|
];
|
1203
|
+
console.log(potentialBlocks);
|
864
1204
|
if (potentialBlocks.toString() !== this.activeBlocks.toString()) {
|
865
1205
|
this.activeBlocks = potentialBlocks;
|
866
1206
|
}
|
@@ -868,11 +1208,7 @@ const Table = class {
|
|
868
1208
|
}
|
869
1209
|
blockIndex++;
|
870
1210
|
}
|
871
|
-
|
872
|
-
};
|
873
|
-
this.handleColumnPinned = (positions) => {
|
874
|
-
Object.entries(positions).forEach(([key, applied]) => {
|
875
|
-
this.tableEle.classList.toggle(`${CSSNAMESPACE}__pinned--${key}`, applied);
|
1211
|
+
perMark('scrollHandler', true);
|
876
1212
|
});
|
877
1213
|
};
|
878
1214
|
this.handleResizeChange = (e) => {
|
@@ -883,12 +1219,12 @@ const Table = class {
|
|
883
1219
|
classes = [...e.target.className.split(' '), ...classes];
|
884
1220
|
this.tableWrapperEle.classList.add(...classes.filter((cl) => !!cl));
|
885
1221
|
};
|
886
|
-
this.
|
1222
|
+
this.customRenderer = undefined;
|
887
1223
|
this.type = 'table';
|
888
1224
|
this.caption = undefined;
|
889
1225
|
this.showCaption = false;
|
890
1226
|
this.loading = undefined;
|
891
|
-
this.internalLoading =
|
1227
|
+
this.internalLoading = true;
|
892
1228
|
this.placeholderSize = 5;
|
893
1229
|
this.rows = undefined;
|
894
1230
|
this.columns = [];
|
@@ -896,14 +1232,14 @@ const Table = class {
|
|
896
1232
|
this.rowRender = undefined;
|
897
1233
|
this.footRender = { pinned: 'bottom' };
|
898
1234
|
this.showFooter = false;
|
899
|
-
this.perBlock =
|
1235
|
+
this.perBlock = 50;
|
900
1236
|
this.searchTerm = undefined;
|
901
1237
|
this.customFilterFn = undefined;
|
902
1238
|
this.customSortFn = undefined;
|
903
1239
|
this.defaultSort = true;
|
904
1240
|
this.virtualTotalItems = 0;
|
905
1241
|
this.blocks = [];
|
906
|
-
this.activeBlocks = [0, 1
|
1242
|
+
this.activeBlocks = [0, 1];
|
907
1243
|
this.debounceSetLoading = throttle.debounce(this.debounceSetLoading.bind(this), 50);
|
908
1244
|
}
|
909
1245
|
get _loading() {
|
@@ -932,6 +1268,8 @@ const Table = class {
|
|
932
1268
|
if (!this.isReady)
|
933
1269
|
requestAnimationFrame(() => this.setInitialBlockDimension());
|
934
1270
|
this._loading = false;
|
1271
|
+
if (this.tablePinnedService)
|
1272
|
+
this.tablePinnedService.assessRows();
|
935
1273
|
});
|
936
1274
|
}
|
937
1275
|
async handleColsChange() {
|
@@ -949,6 +1287,10 @@ const Table = class {
|
|
949
1287
|
virtualTotalItemsChangeHandler() {
|
950
1288
|
this.setBlocks();
|
951
1289
|
}
|
1290
|
+
/** @readonly - shows the currently applied filters */
|
1291
|
+
get appliedFilters() {
|
1292
|
+
return this.filters;
|
1293
|
+
}
|
952
1294
|
/** Remove any column sorts currently applied
|
953
1295
|
* @returns a promise which resolves when complete */
|
954
1296
|
async resetSorting() {
|
@@ -991,8 +1333,6 @@ const Table = class {
|
|
991
1333
|
}
|
992
1334
|
/** Updates a row model at a given index
|
993
1335
|
* @param row - the row to update.
|
994
|
-
* *Note* - this should come from the `col.cellTemplate` or `row.rowRender.template` `rowModel` property
|
995
|
-
* - rows are augmented with certain properties to aid with efficient rendering
|
996
1336
|
* @param rowIndex - the row index to insert this row
|
997
1337
|
*/
|
998
1338
|
async updateRow(row, rowIndex) {
|
@@ -1023,7 +1363,9 @@ const Table = class {
|
|
1023
1363
|
? document
|
1024
1364
|
: this._scrollParent).removeEventListener('scroll', this.scrollHandler);
|
1025
1365
|
}
|
1026
|
-
(ele === document.documentElement ? document : ele).addEventListener('scroll', this.scrollHandler
|
1366
|
+
(ele === document.documentElement ? document : ele).addEventListener('scroll', this.scrollHandler
|
1367
|
+
// {passive: true}
|
1368
|
+
);
|
1027
1369
|
this._scrollParent = ele;
|
1028
1370
|
}
|
1029
1371
|
// used to fire `nanoTblBlockRendered` on block render change
|
@@ -1077,17 +1419,20 @@ const Table = class {
|
|
1077
1419
|
return Object.assign(Object.assign({}, c), { order: null });
|
1078
1420
|
});
|
1079
1421
|
this.nanoTblAfterSort.emit({ column: column, order });
|
1422
|
+
perMark('sort', true);
|
1080
1423
|
}
|
1081
1424
|
async searchStart() {
|
1082
1425
|
this._loading = true;
|
1083
1426
|
const sortEvent = this.nanoTblBeforeSearch.emit({ term: this.searchTerm });
|
1084
1427
|
if (sortEvent.defaultPrevented)
|
1085
1428
|
return;
|
1429
|
+
perMark('search');
|
1086
1430
|
// doesn't make sense to leave user in place for a search
|
1087
1431
|
this.scrollToTop();
|
1088
1432
|
try {
|
1089
1433
|
await storeSearch(this.host, this.searchTerm);
|
1090
1434
|
this.nanoTblAfterSearch.emit({ term: this.searchTerm });
|
1435
|
+
perMark('search', true);
|
1091
1436
|
}
|
1092
1437
|
catch (e) {
|
1093
1438
|
console.warn('search failed', e);
|
@@ -1114,6 +1459,7 @@ const Table = class {
|
|
1114
1459
|
const sortEvent = this.nanoTblBeforeFilter.emit({ filters: this.filters });
|
1115
1460
|
if (sortEvent.defaultPrevented)
|
1116
1461
|
return;
|
1462
|
+
perMark('filter');
|
1117
1463
|
this.currentFilters = JSON.stringify(this.filters);
|
1118
1464
|
// doesn't make sense to leave user in place for a search
|
1119
1465
|
this.scrollToTop();
|
@@ -1122,10 +1468,11 @@ const Table = class {
|
|
1122
1468
|
const res = await this.customFilterFn(this.filters);
|
1123
1469
|
// if the response is 'true', the custom filter did it's thing
|
1124
1470
|
// handover to finish and stop loading state.
|
1125
|
-
// if response is
|
1471
|
+
// if response is falsy, carry on to do a FE filter
|
1126
1472
|
if (res === true) {
|
1127
1473
|
this.filterComplete();
|
1128
1474
|
this._loading = false;
|
1475
|
+
return;
|
1129
1476
|
}
|
1130
1477
|
}
|
1131
1478
|
catch (e) {
|
@@ -1134,8 +1481,8 @@ const Table = class {
|
|
1134
1481
|
console.warn('custom filter failed', e);
|
1135
1482
|
this.currentFilters = '';
|
1136
1483
|
this._loading = false;
|
1484
|
+
return;
|
1137
1485
|
}
|
1138
|
-
return;
|
1139
1486
|
}
|
1140
1487
|
try {
|
1141
1488
|
await storeFilter(this.host, this.filters);
|
@@ -1151,13 +1498,22 @@ const Table = class {
|
|
1151
1498
|
filterComplete() {
|
1152
1499
|
this.columns = this.columns.map((c) => {
|
1153
1500
|
const cFilter = this.filters.find((f) => f.prop === c.prop);
|
1154
|
-
if
|
1501
|
+
// if we found a filter AND
|
1502
|
+
// it isn't true / false and has a length OR
|
1503
|
+
// it is true or false
|
1504
|
+
if (cFilter &&
|
1505
|
+
((typeof cFilter.filter !== 'boolean' && cFilter.filter.length) ||
|
1506
|
+
typeof cFilter.filter === 'boolean'))
|
1155
1507
|
c.filter = cFilter.filter;
|
1156
|
-
|
1508
|
+
// if a filter value is not set OR
|
1509
|
+
// it isn't true / false and has no length
|
1510
|
+
else if ((c.filter !== null && c.filter !== undefined) ||
|
1511
|
+
(!!c.filter && typeof c.filter !== 'boolean' && !c.filter.length))
|
1157
1512
|
c.filter = undefined;
|
1158
1513
|
return c;
|
1159
1514
|
});
|
1160
1515
|
this.nanoTblAfterFilter.emit({ filters: this.filters });
|
1516
|
+
perMark('filter', true);
|
1161
1517
|
}
|
1162
1518
|
/** Scrolls to the top immediately - used whilst sorting / filtering */
|
1163
1519
|
scrollToTop(element) {
|
@@ -1193,6 +1549,7 @@ const Table = class {
|
|
1193
1549
|
var _a;
|
1194
1550
|
if (!((_a = this.blockElements) === null || _a === void 0 ? void 0 : _a.length))
|
1195
1551
|
return;
|
1552
|
+
perMark('blockDims');
|
1196
1553
|
const testForDimensions = async () => {
|
1197
1554
|
await this.setMeasureElement();
|
1198
1555
|
if (this.unitHeight)
|
@@ -1216,6 +1573,8 @@ const Table = class {
|
|
1216
1573
|
});
|
1217
1574
|
// we're all finished.
|
1218
1575
|
dimensionsReady.then(() => {
|
1576
|
+
perMark('blockDims', true);
|
1577
|
+
perMark('init', true);
|
1219
1578
|
requestAnimationFrame(() => (this.isReady = true));
|
1220
1579
|
});
|
1221
1580
|
}
|
@@ -1238,6 +1597,8 @@ const Table = class {
|
|
1238
1597
|
if (!!col) {
|
1239
1598
|
await this.sortStart(col.order, col.prop);
|
1240
1599
|
}
|
1600
|
+
if (this.tablePinnedService)
|
1601
|
+
this.tablePinnedService.assessCols();
|
1241
1602
|
}
|
1242
1603
|
/** Split up all incoming rows into 'blocks' split amongst tbody elements.
|
1243
1604
|
* These can then be hidden / shown to improve performance.
|
@@ -1248,6 +1609,7 @@ const Table = class {
|
|
1248
1609
|
this.blocks = [];
|
1249
1610
|
return;
|
1250
1611
|
}
|
1612
|
+
perMark('setBlocks');
|
1251
1613
|
// this.ignoreIO = true;
|
1252
1614
|
let i = 1;
|
1253
1615
|
const l = this.virtualTotalItems > dRows.length
|
@@ -1270,6 +1632,7 @@ const Table = class {
|
|
1270
1632
|
blocks.push({ rows, __uuid: math.cyrb53(rows.map((b) => b.__uuid).join()) });
|
1271
1633
|
}
|
1272
1634
|
this.blocks = blocks;
|
1635
|
+
perMark('setBlocks', true);
|
1273
1636
|
}
|
1274
1637
|
/**
|
1275
1638
|
* Returns a block render height.
|
@@ -1338,6 +1701,7 @@ const Table = class {
|
|
1338
1701
|
}
|
1339
1702
|
// Component lifecycle
|
1340
1703
|
async componentWillLoad() {
|
1704
|
+
perMark('init');
|
1341
1705
|
// setup stores
|
1342
1706
|
this.store = await generateStore(this.host, this.columns, this.scrollParent, this.isReady);
|
1343
1707
|
await this.handleRowsChange();
|
@@ -1357,6 +1721,9 @@ const Table = class {
|
|
1357
1721
|
}
|
1358
1722
|
componentDidLoad() {
|
1359
1723
|
this.setInitialBlockDimension();
|
1724
|
+
if (!this.tablePinnedService) {
|
1725
|
+
this.tablePinnedService = new TablePinService(this.tableEle, this.scrollParent);
|
1726
|
+
}
|
1360
1727
|
}
|
1361
1728
|
componentShouldUpdate(_newVal, _oldVal, stateName) {
|
1362
1729
|
// stop double rendering - we use the store for rendering internally
|
@@ -1366,9 +1733,11 @@ const Table = class {
|
|
1366
1733
|
return false;
|
1367
1734
|
}
|
1368
1735
|
componentWillRender() {
|
1736
|
+
perMark('render');
|
1369
1737
|
}
|
1370
1738
|
componentDidRender() {
|
1371
1739
|
this.setMeasureElement().then(() => this.setBlockHeight());
|
1740
|
+
perMark('render', true);
|
1372
1741
|
}
|
1373
1742
|
disconnectedCallback() {
|
1374
1743
|
if (!this.activeWatcherIo)
|
@@ -1381,28 +1750,31 @@ const Table = class {
|
|
1381
1750
|
}
|
1382
1751
|
render() {
|
1383
1752
|
this.blockElements = [];
|
1384
|
-
return (index.h(index.Host, null, index.h("div", { class: `${CSSNAMESPACE}__top-anchor`, ref: (a) => (this.topAnchorEle = a) }, "\u00A0"), index.h("nano-resize-observe", { states: "576w sm, 768w md", class: "sm md", onNanoResizeStateChange: this.handleResizeChange
|
1753
|
+
return (index.h(index.Host, null, index.h("div", { class: `${CSSNAMESPACE}__top-anchor`, ref: (a) => (this.topAnchorEle = a) }, "\u00A0"), index.h("nano-resize-observe", { states: "576w sm, 768w md", class: "sm md", onNanoResizeStateChange: this.handleResizeChange, onNanoResize: () => {
|
1754
|
+
if (this.tablePinnedService)
|
1755
|
+
this.tablePinnedService.onResize();
|
1756
|
+
} }), index.h("div", { class: `${CSSNAMESPACE}__wrap sm md`, ref: (div) => (this.tableWrapperEle = div), "aria-labelledby": 'nano-table-caption-' + this.renderId, tabindex: this.type === 'grid' ? '0' : undefined }, index.h("nano-progress-bar", { indeterminate: true, class: {
|
1385
1757
|
[`${CSSNAMESPACE}__progress-bar`]: true,
|
1386
1758
|
[`${CSSNAMESPACE}__progress-bar--show`]: this._loading,
|
1387
|
-
} }), index.h("table", { role: this.type === 'grid' ? 'grid' : undefined, "aria-rowcount": this.store.data.state.rows.length, "aria-colcount": this.store.config.state.columns.length, class: `${CSSNAMESPACE}`, ref: (tbl) => (this.tableEle = tbl) }, index.h("caption", { class: {
|
1759
|
+
} }), index.h("table", { role: this.type === 'grid' ? 'grid' : undefined, "aria-rowcount": this.store.data.state.rows.length, "aria-colcount": this.store.config.state.columns.length, class: `${CSSNAMESPACE}`, ref: (tbl) => (this.tableEle = tbl), id: 'nano-table-' + this.renderId }, index.h("caption", { class: {
|
1388
1760
|
[`${CSSNAMESPACE}__caption`]: true,
|
1389
1761
|
[`${CSSNAMESPACE}__caption--hide`]: !this.showCaption,
|
1390
|
-
}, id: 'table-caption-' + this.renderId }, index.h("slot", { name: "caption" }, this.caption)), index.h("thead", null, index.h(TableHeadFootRow, { rowRenderer: this.headRender
|
1391
|
-
index.h(TableColHead, { column: colModel, headRenderer: this.headRender, onColumnSortClick: this.sortStart,
|
1762
|
+
}, id: 'nano-table-caption-' + this.renderId }, index.h("slot", { name: "caption" }, this.caption)), index.h("thead", null, index.h(TableHeadFootRow, { rowRenderer: this.headRender }, this.store.config.state.columns.map((colModel) => [
|
1763
|
+
index.h(TableColHead, { column: colModel, headRenderer: this.headRender, onColumnSortClick: this.sortStart, defaults: {
|
1392
1764
|
sortable: this.defaultSort,
|
1393
1765
|
} }),
|
1394
|
-
]))), this._loading && !this.blocks.length && (index.h("tbody", { class: `${CSSNAMESPACE}__active` }, [...Array(10).keys()].map((rowIndex) => (index.h("tr", null, this.store.config.state.columns.map((_colModel, colIndex) => (index.h(TableCell
|
1766
|
+
]))), this._loading && !this.blocks.length && (index.h("tbody", { class: `${CSSNAMESPACE}__active ${CSSNAMESPACE}__loading` }, [...Array(10).keys()].map((rowIndex) => (index.h("tr", null, this.store.config.state.columns.map((_colModel, colIndex) => (index.h(TableCell, { rowIndex: rowIndex, colIndex: colIndex, nestedContent: () => index.h("nano-skeleton", null) })))))))), index.h("tr", { hidden: !!this._loading || !!this.blocks.length }, index.h("th", { class: `${CSSNAMESPACE}__th`, colSpan: this.store.config.state.columns.length }, index.h("div", { class: "nano-tbl__cell-content nano-tbl__cell-content--no-result" }, index.h("slot", { name: "no-results" }, "No results found")))), this.blocks.map((block, blockIndex) => (index.h("tbody", { key: block.__uuid, id: `tbody-${this.renderId}-${blockIndex}`, ref: (tb) => {
|
1395
1767
|
this.blockElements.push(tb);
|
1396
1768
|
}, class: {
|
1397
1769
|
[`${CSSNAMESPACE}__inactive`]: !this.activeBlocks.includes(blockIndex),
|
1398
1770
|
[`${CSSNAMESPACE}__active`]: this.activeBlocks.includes(blockIndex),
|
1399
1771
|
} }, this.activeBlocks.includes(blockIndex) ? (block.rows.map((row, i) => {
|
1400
1772
|
const rowIndex = blockIndex > 0 ? blockIndex * this.perBlock + i : i;
|
1401
|
-
return (index.h(TableRow, { rowRenderer: this.rowRender, rowModel: row, rowIndex: rowIndex }, this.store.config.state.columns.map((_colModel, colIndex) => (index.h(TableCell
|
1402
|
-
})) : (index.h("tr",
|
1773
|
+
return (index.h(TableRow, { rowRenderer: this.rowRender, rowModel: row, rowIndex: rowIndex }, this.store.config.state.columns.map((_colModel, colIndex) => (index.h(TableCell, { rowIndex: rowIndex, colIndex: colIndex })))));
|
1774
|
+
})) : (index.h("tr", { class: `${CSSNAMESPACE}__tr--placeholder` }, index.h("td", { colSpan: this.store.config.state.columns.length, style: {
|
1403
1775
|
height: this.getBlockHeight(blockIndex) + 'px',
|
1404
|
-
} })))))), this.showFooter && (index.h("tfoot", null, index.h(TableHeadFootRow, { rowRenderer: this.footRender
|
1405
|
-
index.h(TableColHead, { column: colModel, headRenderer: this.footRender,
|
1776
|
+
} })))))), this.showFooter && (index.h("tfoot", null, index.h(TableHeadFootRow, { rowRenderer: this.footRender }, this.store.config.state.columns.map((colModel) => [
|
1777
|
+
index.h(TableColHead, { column: colModel, headRenderer: this.footRender, onColumnSortClick: this.sortStart, defaults: {
|
1406
1778
|
sortable: this.defaultSort,
|
1407
1779
|
} }),
|
1408
1780
|
]))))), !!this.blocks.length && (index.h("nano-spinner", { type: "circle", class: {
|
@@ -1423,4 +1795,4 @@ Table.style = tableCss;
|
|
1423
1795
|
exports.Table = Table;
|
1424
1796
|
exports.createWorker = createWorker;
|
1425
1797
|
|
1426
|
-
//# sourceMappingURL=nano-table-
|
1798
|
+
//# sourceMappingURL=nano-table-10a40ab3.js.map
|