@nanoporetech-digital/components 5.1.3 → 5.2.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 +15 -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-04993bb4.js} +552 -181
- package/dist/cjs/nano-table-04993bb4.js.map +1 -0
- package/dist/cjs/nano-table.cjs.entry.js +2 -2
- package/dist/cjs/{table.worker-77e56070.js → table.worker-85877b23.js} +4 -4
- package/dist/cjs/table.worker-85877b23.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 +96 -43
- 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 +525 -183
- 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-91f09583.js} +553 -182
- package/dist/esm/nano-table-91f09583.js.map +1 -0
- package/dist/esm/nano-table.entry.js +2 -2
- package/dist/esm/{table.worker-c17a27ed.js → table.worker-625475ba.js} +4 -4
- package/dist/esm/table.worker-625475ba.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-17ee0c07.entry.js +5 -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-3de3449e.js +5 -0
- package/dist/nano-components/p-3de3449e.js.map +1 -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-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-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-2e63676f.js → p-dfbf0d56.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 -7
- 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 +575 -190
- 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-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-2e63676f.js.map → p-17ee0c07.entry.js.map} +0 -0
- /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-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-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
- /package/dist/nano-components/{p-30cc21c2.entry.js.map → p-dfbf0d56.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-85877b23.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) {
|
@@ -799,6 +1124,7 @@ const Table = class {
|
|
799
1124
|
const sortEvent = this.nanoTblBeforeSort.emit({ column: column, order });
|
800
1125
|
if (sortEvent.defaultPrevented)
|
801
1126
|
return;
|
1127
|
+
perMark('sort');
|
802
1128
|
this.currentSort = order + ':' + column;
|
803
1129
|
// doesn't make sense to leave user in place for a sort
|
804
1130
|
this.scrollToTop(element);
|
@@ -842,13 +1168,24 @@ const Table = class {
|
|
842
1168
|
* stop loop - it's on the current active block.
|
843
1169
|
*/
|
844
1170
|
this.scrollHandler = () => {
|
1171
|
+
var _a;
|
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
|
-
this.cacheScrollPosition =
|
1179
|
+
this.cacheScrollPosition =
|
1180
|
+
typeof this.scrollParent.scrollTop !== 'undefined'
|
1181
|
+
? this.scrollParent.scrollTop
|
1182
|
+
: window.scrollY;
|
1183
|
+
if (this.tablePinnedService) {
|
1184
|
+
this.tablePinnedService.onScroll({
|
1185
|
+
x: this.scrollParent.scrollLeft || window.scrollX,
|
1186
|
+
y: this.cacheScrollPosition,
|
1187
|
+
});
|
1188
|
+
}
|
852
1189
|
let cumulativeHeight = this.host.offsetTop;
|
853
1190
|
let blockIndex = 0;
|
854
1191
|
const blockLen = this.blocks.length;
|
@@ -859,7 +1196,9 @@ const Table = class {
|
|
859
1196
|
const potentialBlocks = [
|
860
1197
|
blockIndex,
|
861
1198
|
blockIndex + 1,
|
862
|
-
|
1199
|
+
this.cacheScrollPosition,
|
1200
|
+
cumulativeHeight,
|
1201
|
+
// Math.max(0, blockIndex - 1),
|
863
1202
|
];
|
864
1203
|
if (potentialBlocks.toString() !== this.activeBlocks.toString()) {
|
865
1204
|
this.activeBlocks = potentialBlocks;
|
@@ -868,11 +1207,7 @@ const Table = class {
|
|
868
1207
|
}
|
869
1208
|
blockIndex++;
|
870
1209
|
}
|
871
|
-
|
872
|
-
};
|
873
|
-
this.handleColumnPinned = (positions) => {
|
874
|
-
Object.entries(positions).forEach(([key, applied]) => {
|
875
|
-
this.tableEle.classList.toggle(`${CSSNAMESPACE}__pinned--${key}`, applied);
|
1210
|
+
perMark('scrollHandler', true);
|
876
1211
|
});
|
877
1212
|
};
|
878
1213
|
this.handleResizeChange = (e) => {
|
@@ -883,12 +1218,12 @@ const Table = class {
|
|
883
1218
|
classes = [...e.target.className.split(' '), ...classes];
|
884
1219
|
this.tableWrapperEle.classList.add(...classes.filter((cl) => !!cl));
|
885
1220
|
};
|
886
|
-
this.
|
1221
|
+
this.customRenderer = undefined;
|
887
1222
|
this.type = 'table';
|
888
1223
|
this.caption = undefined;
|
889
1224
|
this.showCaption = false;
|
890
1225
|
this.loading = undefined;
|
891
|
-
this.internalLoading =
|
1226
|
+
this.internalLoading = true;
|
892
1227
|
this.placeholderSize = 5;
|
893
1228
|
this.rows = undefined;
|
894
1229
|
this.columns = [];
|
@@ -896,14 +1231,14 @@ const Table = class {
|
|
896
1231
|
this.rowRender = undefined;
|
897
1232
|
this.footRender = { pinned: 'bottom' };
|
898
1233
|
this.showFooter = false;
|
899
|
-
this.perBlock =
|
1234
|
+
this.perBlock = 50;
|
900
1235
|
this.searchTerm = undefined;
|
901
1236
|
this.customFilterFn = undefined;
|
902
1237
|
this.customSortFn = undefined;
|
903
1238
|
this.defaultSort = true;
|
904
1239
|
this.virtualTotalItems = 0;
|
905
1240
|
this.blocks = [];
|
906
|
-
this.activeBlocks = [0, 1
|
1241
|
+
this.activeBlocks = [0, 1];
|
907
1242
|
this.debounceSetLoading = throttle.debounce(this.debounceSetLoading.bind(this), 50);
|
908
1243
|
}
|
909
1244
|
get _loading() {
|
@@ -932,6 +1267,8 @@ const Table = class {
|
|
932
1267
|
if (!this.isReady)
|
933
1268
|
requestAnimationFrame(() => this.setInitialBlockDimension());
|
934
1269
|
this._loading = false;
|
1270
|
+
if (this.tablePinnedService)
|
1271
|
+
this.tablePinnedService.assessRows();
|
935
1272
|
});
|
936
1273
|
}
|
937
1274
|
async handleColsChange() {
|
@@ -949,6 +1286,10 @@ const Table = class {
|
|
949
1286
|
virtualTotalItemsChangeHandler() {
|
950
1287
|
this.setBlocks();
|
951
1288
|
}
|
1289
|
+
/** @readonly - shows the currently applied filters */
|
1290
|
+
get appliedFilters() {
|
1291
|
+
return this.filters;
|
1292
|
+
}
|
952
1293
|
/** Remove any column sorts currently applied
|
953
1294
|
* @returns a promise which resolves when complete */
|
954
1295
|
async resetSorting() {
|
@@ -991,8 +1332,6 @@ const Table = class {
|
|
991
1332
|
}
|
992
1333
|
/** Updates a row model at a given index
|
993
1334
|
* @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
1335
|
* @param rowIndex - the row index to insert this row
|
997
1336
|
*/
|
998
1337
|
async updateRow(row, rowIndex) {
|
@@ -1023,7 +1362,9 @@ const Table = class {
|
|
1023
1362
|
? document
|
1024
1363
|
: this._scrollParent).removeEventListener('scroll', this.scrollHandler);
|
1025
1364
|
}
|
1026
|
-
(ele === document.documentElement ? document : ele).addEventListener('scroll', this.scrollHandler
|
1365
|
+
(ele === document.documentElement ? document : ele).addEventListener('scroll', this.scrollHandler
|
1366
|
+
// {passive: true}
|
1367
|
+
);
|
1027
1368
|
this._scrollParent = ele;
|
1028
1369
|
}
|
1029
1370
|
// used to fire `nanoTblBlockRendered` on block render change
|
@@ -1077,17 +1418,20 @@ const Table = class {
|
|
1077
1418
|
return Object.assign(Object.assign({}, c), { order: null });
|
1078
1419
|
});
|
1079
1420
|
this.nanoTblAfterSort.emit({ column: column, order });
|
1421
|
+
perMark('sort', true);
|
1080
1422
|
}
|
1081
1423
|
async searchStart() {
|
1082
1424
|
this._loading = true;
|
1083
1425
|
const sortEvent = this.nanoTblBeforeSearch.emit({ term: this.searchTerm });
|
1084
1426
|
if (sortEvent.defaultPrevented)
|
1085
1427
|
return;
|
1428
|
+
perMark('search');
|
1086
1429
|
// doesn't make sense to leave user in place for a search
|
1087
1430
|
this.scrollToTop();
|
1088
1431
|
try {
|
1089
1432
|
await storeSearch(this.host, this.searchTerm);
|
1090
1433
|
this.nanoTblAfterSearch.emit({ term: this.searchTerm });
|
1434
|
+
perMark('search', true);
|
1091
1435
|
}
|
1092
1436
|
catch (e) {
|
1093
1437
|
console.warn('search failed', e);
|
@@ -1114,6 +1458,7 @@ const Table = class {
|
|
1114
1458
|
const sortEvent = this.nanoTblBeforeFilter.emit({ filters: this.filters });
|
1115
1459
|
if (sortEvent.defaultPrevented)
|
1116
1460
|
return;
|
1461
|
+
perMark('filter');
|
1117
1462
|
this.currentFilters = JSON.stringify(this.filters);
|
1118
1463
|
// doesn't make sense to leave user in place for a search
|
1119
1464
|
this.scrollToTop();
|
@@ -1122,10 +1467,11 @@ const Table = class {
|
|
1122
1467
|
const res = await this.customFilterFn(this.filters);
|
1123
1468
|
// if the response is 'true', the custom filter did it's thing
|
1124
1469
|
// handover to finish and stop loading state.
|
1125
|
-
// if response is
|
1470
|
+
// if response is falsy, carry on to do a FE filter
|
1126
1471
|
if (res === true) {
|
1127
1472
|
this.filterComplete();
|
1128
1473
|
this._loading = false;
|
1474
|
+
return;
|
1129
1475
|
}
|
1130
1476
|
}
|
1131
1477
|
catch (e) {
|
@@ -1134,8 +1480,8 @@ const Table = class {
|
|
1134
1480
|
console.warn('custom filter failed', e);
|
1135
1481
|
this.currentFilters = '';
|
1136
1482
|
this._loading = false;
|
1483
|
+
return;
|
1137
1484
|
}
|
1138
|
-
return;
|
1139
1485
|
}
|
1140
1486
|
try {
|
1141
1487
|
await storeFilter(this.host, this.filters);
|
@@ -1151,13 +1497,22 @@ const Table = class {
|
|
1151
1497
|
filterComplete() {
|
1152
1498
|
this.columns = this.columns.map((c) => {
|
1153
1499
|
const cFilter = this.filters.find((f) => f.prop === c.prop);
|
1154
|
-
if
|
1500
|
+
// if we found a filter AND
|
1501
|
+
// it isn't true / false and has a length OR
|
1502
|
+
// it is true or false
|
1503
|
+
if (cFilter &&
|
1504
|
+
((typeof cFilter.filter !== 'boolean' && cFilter.filter.length) ||
|
1505
|
+
typeof cFilter.filter === 'boolean'))
|
1155
1506
|
c.filter = cFilter.filter;
|
1156
|
-
|
1507
|
+
// if a filter value is not set OR
|
1508
|
+
// it isn't true / false and has no length
|
1509
|
+
else if ((c.filter !== null && c.filter !== undefined) ||
|
1510
|
+
(!!c.filter && typeof c.filter !== 'boolean' && !c.filter.length))
|
1157
1511
|
c.filter = undefined;
|
1158
1512
|
return c;
|
1159
1513
|
});
|
1160
1514
|
this.nanoTblAfterFilter.emit({ filters: this.filters });
|
1515
|
+
perMark('filter', true);
|
1161
1516
|
}
|
1162
1517
|
/** Scrolls to the top immediately - used whilst sorting / filtering */
|
1163
1518
|
scrollToTop(element) {
|
@@ -1193,6 +1548,7 @@ const Table = class {
|
|
1193
1548
|
var _a;
|
1194
1549
|
if (!((_a = this.blockElements) === null || _a === void 0 ? void 0 : _a.length))
|
1195
1550
|
return;
|
1551
|
+
perMark('blockDims');
|
1196
1552
|
const testForDimensions = async () => {
|
1197
1553
|
await this.setMeasureElement();
|
1198
1554
|
if (this.unitHeight)
|
@@ -1216,6 +1572,8 @@ const Table = class {
|
|
1216
1572
|
});
|
1217
1573
|
// we're all finished.
|
1218
1574
|
dimensionsReady.then(() => {
|
1575
|
+
perMark('blockDims', true);
|
1576
|
+
perMark('init', true);
|
1219
1577
|
requestAnimationFrame(() => (this.isReady = true));
|
1220
1578
|
});
|
1221
1579
|
}
|
@@ -1238,6 +1596,8 @@ const Table = class {
|
|
1238
1596
|
if (!!col) {
|
1239
1597
|
await this.sortStart(col.order, col.prop);
|
1240
1598
|
}
|
1599
|
+
if (this.tablePinnedService)
|
1600
|
+
this.tablePinnedService.assessCols();
|
1241
1601
|
}
|
1242
1602
|
/** Split up all incoming rows into 'blocks' split amongst tbody elements.
|
1243
1603
|
* These can then be hidden / shown to improve performance.
|
@@ -1248,6 +1608,7 @@ const Table = class {
|
|
1248
1608
|
this.blocks = [];
|
1249
1609
|
return;
|
1250
1610
|
}
|
1611
|
+
perMark('setBlocks');
|
1251
1612
|
// this.ignoreIO = true;
|
1252
1613
|
let i = 1;
|
1253
1614
|
const l = this.virtualTotalItems > dRows.length
|
@@ -1270,6 +1631,7 @@ const Table = class {
|
|
1270
1631
|
blocks.push({ rows, __uuid: math.cyrb53(rows.map((b) => b.__uuid).join()) });
|
1271
1632
|
}
|
1272
1633
|
this.blocks = blocks;
|
1634
|
+
perMark('setBlocks', true);
|
1273
1635
|
}
|
1274
1636
|
/**
|
1275
1637
|
* Returns a block render height.
|
@@ -1338,6 +1700,7 @@ const Table = class {
|
|
1338
1700
|
}
|
1339
1701
|
// Component lifecycle
|
1340
1702
|
async componentWillLoad() {
|
1703
|
+
perMark('init');
|
1341
1704
|
// setup stores
|
1342
1705
|
this.store = await generateStore(this.host, this.columns, this.scrollParent, this.isReady);
|
1343
1706
|
await this.handleRowsChange();
|
@@ -1357,6 +1720,9 @@ const Table = class {
|
|
1357
1720
|
}
|
1358
1721
|
componentDidLoad() {
|
1359
1722
|
this.setInitialBlockDimension();
|
1723
|
+
if (!this.tablePinnedService) {
|
1724
|
+
this.tablePinnedService = new TablePinService(this.tableEle, this.scrollParent);
|
1725
|
+
}
|
1360
1726
|
}
|
1361
1727
|
componentShouldUpdate(_newVal, _oldVal, stateName) {
|
1362
1728
|
// stop double rendering - we use the store for rendering internally
|
@@ -1366,9 +1732,11 @@ const Table = class {
|
|
1366
1732
|
return false;
|
1367
1733
|
}
|
1368
1734
|
componentWillRender() {
|
1735
|
+
perMark('render');
|
1369
1736
|
}
|
1370
1737
|
componentDidRender() {
|
1371
1738
|
this.setMeasureElement().then(() => this.setBlockHeight());
|
1739
|
+
perMark('render', true);
|
1372
1740
|
}
|
1373
1741
|
disconnectedCallback() {
|
1374
1742
|
if (!this.activeWatcherIo)
|
@@ -1381,28 +1749,31 @@ const Table = class {
|
|
1381
1749
|
}
|
1382
1750
|
render() {
|
1383
1751
|
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
|
1752
|
+
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: () => {
|
1753
|
+
if (this.tablePinnedService)
|
1754
|
+
this.tablePinnedService.onResize();
|
1755
|
+
} }), 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
1756
|
[`${CSSNAMESPACE}__progress-bar`]: true,
|
1386
1757
|
[`${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: {
|
1758
|
+
} }), 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
1759
|
[`${CSSNAMESPACE}__caption`]: true,
|
1389
1760
|
[`${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,
|
1761
|
+
}, 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) => [
|
1762
|
+
index.h(TableColHead, { column: colModel, headRenderer: this.headRender, onColumnSortClick: this.sortStart, defaults: {
|
1392
1763
|
sortable: this.defaultSort,
|
1393
1764
|
} }),
|
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
|
1765
|
+
]))), 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
1766
|
this.blockElements.push(tb);
|
1396
1767
|
}, class: {
|
1397
1768
|
[`${CSSNAMESPACE}__inactive`]: !this.activeBlocks.includes(blockIndex),
|
1398
1769
|
[`${CSSNAMESPACE}__active`]: this.activeBlocks.includes(blockIndex),
|
1399
1770
|
} }, this.activeBlocks.includes(blockIndex) ? (block.rows.map((row, i) => {
|
1400
1771
|
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",
|
1772
|
+
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 })))));
|
1773
|
+
})) : (index.h("tr", { class: `${CSSNAMESPACE}__tr--placeholder` }, index.h("td", { colSpan: this.store.config.state.columns.length, style: {
|
1403
1774
|
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,
|
1775
|
+
} })))))), this.showFooter && (index.h("tfoot", null, index.h(TableHeadFootRow, { rowRenderer: this.footRender }, this.store.config.state.columns.map((colModel) => [
|
1776
|
+
index.h(TableColHead, { column: colModel, headRenderer: this.footRender, onColumnSortClick: this.sortStart, defaults: {
|
1406
1777
|
sortable: this.defaultSort,
|
1407
1778
|
} }),
|
1408
1779
|
]))))), !!this.blocks.length && (index.h("nano-spinner", { type: "circle", class: {
|
@@ -1423,4 +1794,4 @@ Table.style = tableCss;
|
|
1423
1794
|
exports.Table = Table;
|
1424
1795
|
exports.createWorker = createWorker;
|
1425
1796
|
|
1426
|
-
//# sourceMappingURL=nano-table-
|
1797
|
+
//# sourceMappingURL=nano-table-04993bb4.js.map
|