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