@nanoporetech-digital/components 3.4.0 → 3.5.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.
Files changed (101) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/dist/cjs/index-41582c2a.js +16 -12
  3. package/dist/cjs/index.cjs.js.map +1 -1
  4. package/dist/cjs/loader.cjs.js +1 -1
  5. package/dist/cjs/nano-components.cjs.js +1 -1
  6. package/dist/cjs/nano-demo.cjs.entry.js +291 -0
  7. package/dist/cjs/nano-demo.cjs.entry.js.map +1 -0
  8. package/dist/cjs/{nano-table-b9cdafab.js → nano-table-067e0c12.js} +486 -202
  9. package/dist/cjs/nano-table-067e0c12.js.map +1 -0
  10. package/dist/cjs/nano-table.cjs.entry.js +1 -1
  11. package/dist/cjs/{table.worker-291904c9.js → table.worker-a4d75c46.js} +3 -3
  12. package/dist/cjs/table.worker-a4d75c46.js.map +1 -0
  13. package/dist/cjs/table.worker-e9fb087e.js +4 -0
  14. package/dist/collection/collection-manifest.json +1 -0
  15. package/dist/collection/components/alert/alert.helpers.js.map +1 -1
  16. package/dist/collection/components/demo/demo.js +284 -0
  17. package/dist/collection/components/demo/demo.js.map +1 -0
  18. package/dist/collection/components/dialog/dialog.helpers.js.map +1 -1
  19. package/dist/collection/components/table/table-interface.js.map +1 -1
  20. package/dist/collection/components/table/table.cell.js +65 -0
  21. package/dist/collection/components/table/table.cell.js.map +1 -0
  22. package/dist/collection/components/table/table.css +98 -20
  23. package/dist/collection/components/table/table.header.js +156 -0
  24. package/dist/collection/components/table/table.header.js.map +1 -0
  25. package/dist/collection/components/table/table.js +170 -18
  26. package/dist/collection/components/table/table.js.map +1 -1
  27. package/dist/collection/components/table/table.row.js +113 -0
  28. package/dist/collection/components/table/table.row.js.map +1 -0
  29. package/dist/collection/components/table/table.store.js +46 -9
  30. package/dist/collection/components/table/table.store.js.map +1 -1
  31. package/dist/collection/components/table/table.utils.js +230 -0
  32. package/dist/collection/components/table/table.utils.js.map +1 -1
  33. package/dist/collection/components/table/table.worker.js +1 -0
  34. package/dist/collection/components/table/table.worker.js.map +1 -1
  35. package/dist/components/index.d.ts +1 -0
  36. package/dist/components/index.js +1 -0
  37. package/dist/components/index.js.map +1 -1
  38. package/dist/components/nano-demo.d.ts +11 -0
  39. package/dist/components/nano-demo.js +341 -0
  40. package/dist/components/nano-demo.js.map +1 -0
  41. package/dist/components/nano-table.js +2 -1247
  42. package/dist/components/nano-table.js.map +1 -1
  43. package/dist/components/table.js +1539 -0
  44. package/dist/components/table.js.map +1 -0
  45. package/dist/components/table.worker.js +2 -2
  46. package/dist/custom-elements/index.d.ts +6 -0
  47. package/dist/custom-elements/index.js +772 -204
  48. package/dist/custom-elements/index.js.map +1 -1
  49. package/dist/esm/index-3c280603.js +16 -12
  50. package/dist/esm/index.js.map +1 -1
  51. package/dist/esm/loader.js +1 -1
  52. package/dist/esm/nano-components.js +1 -1
  53. package/dist/esm/nano-demo.entry.js +287 -0
  54. package/dist/esm/nano-demo.entry.js.map +1 -0
  55. package/dist/esm/{nano-table-c8ef2276.js → nano-table-95921f46.js} +487 -203
  56. package/dist/esm/nano-table-95921f46.js.map +1 -0
  57. package/dist/esm/nano-table.entry.js +1 -1
  58. package/dist/esm/{table.worker-65438fa0.js → table.worker-769f1441.js} +3 -3
  59. package/dist/esm/table.worker-769f1441.js.map +1 -0
  60. package/dist/esm/table.worker-e9fb087e.js +4 -0
  61. package/dist/nano-components/index.esm.js.map +1 -1
  62. package/dist/nano-components/nano-components.esm.js +1 -1
  63. package/dist/nano-components/nano-components.esm.js.map +1 -1
  64. package/dist/nano-components/p-26905bca.js +5 -0
  65. package/dist/nano-components/{p-14218d23.entry.js.map → p-26905bca.js.map} +0 -0
  66. package/dist/nano-components/p-85cfb0af.entry.js +5 -0
  67. package/dist/nano-components/p-85cfb0af.entry.js.map +1 -0
  68. package/dist/nano-components/p-8fc2a38d.js +5 -0
  69. package/dist/nano-components/p-8fc2a38d.js.map +1 -0
  70. package/dist/nano-components/p-e9fb087e.js +4 -0
  71. package/dist/nano-components/{p-14218d23.entry.js → p-fb12a45d.entry.js} +2 -2
  72. package/dist/nano-components/{p-fe1f8360.js.map → p-fb12a45d.entry.js.map} +0 -0
  73. package/dist/types/components/alert/alert.helpers.d.ts +1 -1
  74. package/dist/types/components/demo/demo.d.ts +6 -0
  75. package/dist/types/components/dialog/dialog.helpers.d.ts +1 -1
  76. package/dist/types/components/table/table-interface.d.ts +38 -23
  77. package/dist/types/components/table/table.cell.d.ts +18 -0
  78. package/dist/types/components/table/table.d.ts +36 -1
  79. package/dist/types/components/table/table.header.d.ts +16 -0
  80. package/dist/types/components/table/table.row.d.ts +15 -0
  81. package/dist/types/components/table/table.utils.d.ts +99 -0
  82. package/dist/types/components.d.ts +50 -0
  83. package/docs-json.json +124 -3
  84. package/docs-vscode.json +17 -1
  85. package/package.json +3 -3
  86. package/dist/cjs/nano-table-b9cdafab.js.map +0 -1
  87. package/dist/cjs/table.worker-1fd13775.js +0 -4
  88. package/dist/cjs/table.worker-291904c9.js.map +0 -1
  89. package/dist/collection/components/table/table.children.js +0 -224
  90. package/dist/collection/components/table/table.children.js.map +0 -1
  91. package/dist/collection/components/table/table.service.js +0 -121
  92. package/dist/collection/components/table/table.service.js.map +0 -1
  93. package/dist/esm/nano-table-c8ef2276.js.map +0 -1
  94. package/dist/esm/table.worker-1fd13775.js +0 -4
  95. package/dist/esm/table.worker-65438fa0.js.map +0 -1
  96. package/dist/nano-components/p-1fd13775.js +0 -4
  97. package/dist/nano-components/p-f9349146.js +0 -5
  98. package/dist/nano-components/p-f9349146.js.map +0 -1
  99. package/dist/nano-components/p-fe1f8360.js +0 -5
  100. package/dist/types/components/table/table.children.d.ts +0 -30
  101. package/dist/types/components/table/table.service.d.ts +0 -42
@@ -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-291904c9.js'); }).then(m => m.worker);
115
+ const workerPromise = Promise.resolve().then(function () { return require('./table.worker-a4d75c46.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');
@@ -166,16 +166,53 @@ async function generateStore(host, columns, scrollParent) {
166
166
  function getStore(host) {
167
167
  return stores.get(host);
168
168
  }
169
+ function getDataType(value) {
170
+ if (value instanceof Date) {
171
+ return 'date';
172
+ }
173
+ if (['number', 'string'].includes(typeof value)) {
174
+ return typeof value;
175
+ }
176
+ return 'unknown';
177
+ }
169
178
  function storeSetData(host, rows) {
170
179
  const store = stores.get(host);
171
180
  if (!store)
172
181
  return;
173
- // augment data with some internal props
174
- rows = rows.map((row, i) => ({
175
- ...row,
176
- __index: i,
177
- __uuid: math.cyrb53(Object.values(row).join()),
178
- }));
182
+ const cols = store.config.state.columns;
183
+ const dateCols = cols
184
+ .filter((col) => col.type === 'date')
185
+ .reduce((prev, curr) => {
186
+ return [...prev, curr.prop];
187
+ }, []);
188
+ const unknownCols = cols.filter((col) => !col.type);
189
+ // augments data with some internal.
190
+ // discern unknown column types
191
+ // convert dates to numbers for worker
192
+ rows = rows.map((row, i) => {
193
+ // try our best to discern the column type (from first row) if unset
194
+ if (unknownCols.length && i === 0) {
195
+ store.config.state.columns = cols.map((col) => {
196
+ if (unknownCols.includes(col) && row[col.prop] && !col.type) {
197
+ col.type = getDataType(row[col.prop]);
198
+ if (col.type === 'date')
199
+ dateCols.push(col.prop);
200
+ }
201
+ return col;
202
+ });
203
+ }
204
+ // convert date columns into numbers to send to our worker
205
+ dateCols.forEach((colName) => {
206
+ // coerce any date type;
207
+ // Date(), timestamp, valid date string
208
+ const coerceDate = new Date(row[colName]) ?? null;
209
+ if (!!coerceDate && Number(coerceDate))
210
+ row[colName] = Number(coerceDate);
211
+ });
212
+ row['__index'] = i;
213
+ row['__uuid'] = math.cyrb53(Object.values(row).join());
214
+ return row;
215
+ });
179
216
  store.data.state.rows = rows;
180
217
  if (store.general.state.workerId)
181
218
  return syncDataToWorker(store.general.state.workerId, rows);
@@ -196,7 +233,7 @@ async function storeSearch(host, term) {
196
233
  store.data.state.rows = await workerSearch(store.general.state.workerId, term);
197
234
  }
198
235
  catch (e) {
199
- console.log(e);
236
+ console.warn(e);
200
237
  }
201
238
  }
202
239
  async function storeFilter(host, filters) {
@@ -207,7 +244,7 @@ async function storeFilter(host, filters) {
207
244
  store.data.state.rows = await workerFilter(store.general.state.workerId, filters);
208
245
  }
209
246
  catch (e) {
210
- console.log(e);
247
+ console.warn(e);
211
248
  }
212
249
  }
213
250
  async function storeSort(host, prop, order) {
@@ -218,7 +255,7 @@ async function storeSort(host, prop, order) {
218
255
  store.data.state.rows = await workerSort(store.general.state.workerId, prop, order);
219
256
  }
220
257
  catch (e) {
221
- console.log(e);
258
+ console.warn(e);
222
259
  }
223
260
  }
224
261
 
@@ -315,19 +352,6 @@ function mergeCellProperties(rowIndex, colIndex, defaultProps) {
315
352
  return props;
316
353
  return mergeProperties(props, extra);
317
354
  }
318
- /**
319
- * Renders a cell using a custom renderer if set.
320
- * @param rowIndex - the current row index being rendered
321
- * @param colIndex - the current column index being rendered
322
- * @returns - a JSX node
323
- */
324
- function cellRender(rowIndex, colIndex) {
325
- const store = fetchStores();
326
- const columns = store.config.state.columns;
327
- const tpl = columns[colIndex]?.cellTemplate;
328
- const model = colDataModel(rowIndex, colIndex);
329
- return tpl ? (tpl(index.h, model)) : (index.h(index.Fragment, null, model.cellModel.toString()));
330
- }
331
355
  /**
332
356
  * Renders a table header (within a thead) using a custom template if set.
333
357
  * @param col - the current column config object
@@ -337,26 +361,14 @@ function colheadFootRender(col) {
337
361
  const tpl = col?.colTemplate;
338
362
  return tpl ? (tpl(index.h, col)) : (index.h(index.Fragment, null, col.title));
339
363
  }
340
-
341
- function baseClasses(type, vPinned, toString = false) {
342
- const classes = {
343
- [`${CSSNAMESPACE}__${type}`]: true,
344
- [`${CSSNAMESPACE}__pin`]: !!vPinned,
345
- [`${CSSNAMESPACE}__pin--top`]: vPinned === 'top',
346
- [`${CSSNAMESPACE}__pin--bottom`]: vPinned === 'bottom',
347
- };
348
- if (toString) {
349
- let classString = '';
350
- Object.entries(classes).forEach(([className, on]) => {
351
- if (on)
352
- classString += className + ' ';
353
- });
354
- return classString;
355
- }
356
- return classes;
357
- }
358
364
  const stickyHIOs = new WeakMap();
359
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
+ */
360
372
  function addHObserver(el, pos, cb) {
361
373
  if (stickyHIOs.get(el))
362
374
  return;
@@ -371,13 +383,13 @@ function addHObserver(el, pos, cb) {
371
383
  !e.isIntersecting;
372
384
  }
373
385
  if (pos === 'end') {
374
- // console.log('refe', store.general.state.host)
375
386
  // TODO - sort these out for RtL
376
387
  positions.end =
377
388
  e.boundingClientRect.right > e.boundingClientRect.width &&
378
389
  !e.isIntersecting;
379
390
  }
380
- cb(positions);
391
+ if (!!cb)
392
+ cb(positions);
381
393
  }, {
382
394
  threshold: [1],
383
395
  rootMargin: '1px 0px 100px 0px',
@@ -387,6 +399,12 @@ function addHObserver(el, pos, cb) {
387
399
  // dirty fix - wait a tick 'cos nano-size-observer isn't always ready in-time
388
400
  setTimeout(() => observer.observe(el), 300);
389
401
  }
402
+ /**
403
+ * Adds element to Intersection Observer. Fires when element changes on the y axis
404
+ * @param el - an element to observe
405
+ * @param pos - the edge to watch (start or end)
406
+ * @param cb - callback when an intersection state changes.
407
+ */
390
408
  function addVObserver(el, pos, cb) {
391
409
  if (stickyVIOs.get(el))
392
410
  return;
@@ -400,11 +418,14 @@ function addVObserver(el, pos, cb) {
400
418
  e.boundingClientRect.y - (rootBounds.y + root.scrollTop) < 0 &&
401
419
  !e.isIntersecting;
402
420
  }
403
- if (pos === 'bottom')
421
+ if (pos === 'bottom') {
422
+ const boundingClientRect = e.target.getBoundingClientRect();
404
423
  positions.bottom =
405
- e.boundingClientRect.height > e.intersectionRect.height &&
406
- !e.isIntersecting;
407
- cb(positions);
424
+ boundingClientRect.height + boundingClientRect.y >
425
+ rootBounds.height && !e.isIntersecting;
426
+ }
427
+ if (!!cb)
428
+ cb(positions);
408
429
  }, {
409
430
  threshold: [1],
410
431
  rootMargin: '0px 100px 0px 100px',
@@ -413,64 +434,183 @@ function addVObserver(el, pos, cb) {
413
434
  stickyVIOs.set(el, observer);
414
435
  requestAnimationFrame(() => observer.observe(el));
415
436
  }
416
- const TableRow = ({ rowRenderer, rowIndex, row }, children) => {
417
- let extraProps = {};
418
- if (!row) {
419
- const model = rowDataModel(rowIndex);
420
- row = model.row;
421
- }
422
- if (rowRenderer?.rowProperties) {
423
- extraProps =
424
- rowRenderer.rowProperties({ row: row, rowIndex }) || extraProps;
437
+ function headerPinClasses(type, vPinned, toString = false) {
438
+ const classes = {
439
+ [`${CSSNAMESPACE}__${type}`]: true,
440
+ [`${CSSNAMESPACE}__pin`]: !!vPinned,
441
+ [`${CSSNAMESPACE}__pin--top`]: vPinned === 'top',
442
+ [`${CSSNAMESPACE}__pin--bottom`]: vPinned === 'bottom',
443
+ };
444
+ if (toString)
445
+ return classListToStr(classes);
446
+ return classes;
447
+ }
448
+ /**
449
+ * Turns a class map {'string': boolean} to class string
450
+ * @param classes - the class map to convert
451
+ * @returns a class string
452
+ */
453
+ function classListToStr(classes) {
454
+ let classString = '';
455
+ Object.entries(classes).forEach(([className, on]) => {
456
+ if (on)
457
+ classString += className + ' ';
458
+ });
459
+ return classString;
460
+ }
461
+ /**
462
+ * Detects the current scroll speed as a number.
463
+ * Use within a scroll listener
464
+ */
465
+ const detectScrollSpeed = (() => {
466
+ let lastPos;
467
+ let newPos;
468
+ let timer;
469
+ let delta;
470
+ const delay = 60; // in "ms" (higher means lower fidelity )
471
+ const clear = () => {
472
+ lastPos = null;
473
+ delta = 0;
474
+ };
475
+ clear();
476
+ return () => {
477
+ newPos = window.scrollY;
478
+ if (lastPos != null)
479
+ delta = newPos - lastPos;
480
+ lastPos = newPos;
481
+ window.clearTimeout(timer);
482
+ timer = window.setTimeout(clear, delay);
483
+ return delta;
484
+ };
485
+ })();
486
+ /**
487
+ * Attempts to find the closes scrolling parental element
488
+ * @param element - the element from which to traverse up the DOM
489
+ * @returns - the closest scrolling parental element
490
+ */
491
+ function findScrollParent(element) {
492
+ let style = getComputedStyle(element);
493
+ const excludeStaticParent = style.position === 'absolute';
494
+ const overflowRegex = /(auto|scroll)/;
495
+ if (style.position === 'fixed')
496
+ return document.documentElement;
497
+ for (let parent = element; (parent = parent.parentElement);) {
498
+ style = getComputedStyle(parent);
499
+ if (excludeStaticParent && style.position === 'static') {
500
+ continue;
501
+ }
502
+ if (overflowRegex.test(style.overflow + style.overflowY + style.overflowX))
503
+ return parent;
425
504
  }
426
- let pinned;
427
- if (rowRenderer?.pinned && typeof rowRenderer.pinned === 'function') {
428
- pinned = rowRenderer.pinned();
505
+ return document.documentElement;
506
+ }
507
+ /**
508
+ * Checks whether an element is currently viewable within the viewport
509
+ * @param el - element to check
510
+ * @param percentVisible - the percentage of the element that should be within the viewport
511
+ * @returns true if the element's area percentage is visible
512
+ */
513
+ function isInViewport(el, percentVisible = 100) {
514
+ const r = el.getBoundingClientRect();
515
+ const windowHeight = window.innerHeight || document.documentElement.clientHeight;
516
+ if (!r.bottom &&
517
+ !r.top &&
518
+ !r.left &&
519
+ !r.right &&
520
+ !r.height &&
521
+ !r.width &&
522
+ !r.x &&
523
+ !r.y)
524
+ return false;
525
+ return !(Math.floor(100 - ((r.top >= 0 ? 0 : r.top) / +-r.height) * 100) <
526
+ percentVisible ||
527
+ Math.floor(100 - ((r.bottom - windowHeight) / r.height) * 100) <
528
+ percentVisible);
529
+ }
530
+ /**
531
+ * Immutable array re-order
532
+ * @param from - the index to move from
533
+ * @param to - the index to move to
534
+ * @param arr - the array to re-order
535
+ * @returns - a new, re-orderd array
536
+ */
537
+ function arrMove(from, to, arr) {
538
+ const newArr = [...arr];
539
+ const item = newArr.splice(from, 1)[0];
540
+ newArr.splice(to, 0, item);
541
+ return newArr;
542
+ }
543
+
544
+ // TABLE HEADERS
545
+ // (thead > tr > th, tfoot > tr > th)
546
+ let draggingCol;
547
+ let draggingColEle;
548
+ let dragEnterEle;
549
+ let draggingParent;
550
+ const TableColHead = ({ column, headRenderer, onColumnSortClick, onColumnPinned, onColumnDrag, onColumnDrop, defaults, }) => {
551
+ const store = fetchStores();
552
+ // Drag to re-order columns handling
553
+ function handleDragStart(e, column) {
554
+ draggingCol = column;
555
+ draggingColEle = dragEnterEle = e.target;
556
+ draggingParent = draggingColEle.closest('.' + `${CSSNAMESPACE}__tr`);
557
+ draggingParent.classList.add(`${CSSNAMESPACE}__dragging`);
558
+ draggingColEle.classList.add(`${CSSNAMESPACE}__drag--start`);
559
+ e.dataTransfer.effectAllowed = 'move';
560
+ e.dataTransfer.setData('text/html', draggingColEle.innerHTML);
561
+ onColumnDrag(column.prop, draggingColEle);
429
562
  }
430
- const baseProps = { class: baseClasses('tr', pinned) };
431
- const props = extraProps ? mergeProperties(baseProps, extraProps) : baseProps;
432
- return (index.h("tr", { ...props, key: row.__uuid }, children));
433
- };
434
- const TableHeadFootRow = ({ rowRenderer, onColumnPinned }, children, utils) => {
435
- let extraProps = {};
436
- if (rowRenderer.rowProperties) {
437
- extraProps = rowRenderer.rowProperties() || {};
563
+ function handleDragEnd() {
564
+ draggingParent.classList.remove(`${CSSNAMESPACE}__dragging`);
565
+ draggingColEle.classList.remove(`${CSSNAMESPACE}__drag--start`);
566
+ draggingParent
567
+ .querySelectorAll(`.${CSSNAMESPACE}__drag-mask--active`)
568
+ .forEach((el) => {
569
+ el.classList.remove(`${CSSNAMESPACE}__drag-mask--active`);
570
+ });
571
+ draggingColEle = null;
572
+ draggingCol = null;
573
+ draggingParent = null;
574
+ dragEnterEle = null;
438
575
  }
439
- const pinned = rowRenderer.pinned || null;
440
- const baseProps = { class: baseClasses('tr', null) };
441
- const props = extraProps ? mergeProperties(baseProps, extraProps) : baseProps;
442
- const tpl = rowRenderer?.template;
443
- if (tpl) {
444
- let toRender = tpl(index.h, {
445
- renderedRow: index.h("tr", { ...props }, children),
576
+ function handleDragEnter(e) {
577
+ if (dragEnterEle === e.target)
578
+ return;
579
+ e.preventDefault();
580
+ e.stopImmediatePropagation();
581
+ e.dataTransfer.dropEffect = 'move';
582
+ draggingParent
583
+ .querySelectorAll(`.${CSSNAMESPACE}__drag-mask--active`)
584
+ .forEach((el) => {
585
+ el.classList.remove(`${CSSNAMESPACE}__drag-mask--active`);
446
586
  });
447
- if (Array.isArray(toRender)) {
448
- toRender = utils.map(toRender, (node) => {
449
- if (node.vtag === 'tr') {
450
- node.vattrs = mergeProperties({ class: baseClasses('tr', null, true) }, node.vattrs);
451
- if (!!node.vchildren) {
452
- node.vchildren = utils.map(node.vchildren, (cNode) => {
453
- if (['td', 'th'].includes(cNode.vtag.toString())) {
454
- cNode.vattrs = mergeProperties({
455
- class: baseClasses(cNode.vtag.toString(), pinned, true),
456
- ref: (th) => {
457
- addVObserver(th, pinned, onColumnPinned);
458
- },
459
- }, cNode.vattrs);
460
- }
461
- return cNode;
462
- });
463
- }
464
- }
465
- return node;
466
- });
587
+ dragEnterEle = e.target;
588
+ if (!dragEnterEle.classList.contains(`${CSSNAMESPACE}__drag-mask`)) {
589
+ e.dataTransfer.dropEffect = 'none';
590
+ return;
467
591
  }
468
- return toRender;
592
+ dragEnterEle.classList.add(`${CSSNAMESPACE}__drag-mask--active`);
469
593
  }
470
- return index.h("tr", { ...props }, children);
471
- };
472
- const TableColHead = ({ column, headRenderer, onColumnOrderClick, onColumnPinned, }) => {
473
- function handleColumnOrderClick(e) {
594
+ function handleDrop(e) {
595
+ e.stopPropagation();
596
+ const { colName } = this.dataset;
597
+ if (colName === draggingCol.prop)
598
+ return;
599
+ const cols = store.config.state.columns;
600
+ let toIndex = cols.findIndex((col) => col.prop === colName);
601
+ const fromIndex = cols.findIndex((col) => col === draggingCol);
602
+ if (toIndex < fromIndex &&
603
+ this.classList.contains(`${CSSNAMESPACE}__drag-mask--end`))
604
+ toIndex++;
605
+ if (toIndex > fromIndex &&
606
+ this.classList.contains(`${CSSNAMESPACE}__drag-mask--start`))
607
+ toIndex--;
608
+ if (toIndex === fromIndex)
609
+ return;
610
+ onColumnDrop(draggingCol.prop, store.config.state.columns[toIndex].prop, draggingColEle);
611
+ }
612
+ // Sort handling
613
+ function handleColumnSortClick(e) {
474
614
  let order;
475
615
  switch (column.order) {
476
616
  case 'asc':
@@ -482,7 +622,15 @@ const TableColHead = ({ column, headRenderer, onColumnOrderClick, onColumnPinned
482
622
  default:
483
623
  order = 'asc';
484
624
  }
485
- onColumnOrderClick(order, column.prop, e.target.closest('th'));
625
+ onColumnSortClick(order, column.prop, e.target.closest('th'));
626
+ }
627
+ function isSortable() {
628
+ return ((!!defaults.sortable && column.sortable !== false) ||
629
+ (!defaults.sortable && column.sortable === true));
630
+ }
631
+ function isDraggable() {
632
+ return ((!!defaults.draggable && column.draggable !== false) ||
633
+ (!defaults.draggable && column.draggable === true));
486
634
  }
487
635
  let extraProps = {};
488
636
  if (column.columnProperties) {
@@ -490,7 +638,7 @@ const TableColHead = ({ column, headRenderer, onColumnOrderClick, onColumnPinned
490
638
  }
491
639
  const baseProps = {
492
640
  class: {
493
- ...baseClasses('th', headRenderer?.pinned),
641
+ ...headerPinClasses('th', headRenderer?.pinned),
494
642
  [`${CSSNAMESPACE}__pin--start`]: column.pinned === 'start',
495
643
  [`${CSSNAMESPACE}__pin--end`]: column.pinned === 'end',
496
644
  [`${CSSNAMESPACE}__ordered`]: !!column.order,
@@ -502,60 +650,106 @@ const TableColHead = ({ column, headRenderer, onColumnOrderClick, onColumnPinned
502
650
  if (!content)
503
651
  return index.h(index.Fragment, null);
504
652
  props =
505
- Number(props.colspan) > 1
653
+ Number(props.colSpan) > 1
506
654
  ? { ...props, scope: 'colgroup' }
507
655
  : { ...props, scope: 'col' };
508
- if (column.sortable !== false) {
509
- return (index.h("th", { ...props, "aria-sort": column.order
510
- ? column.order === 'asc'
511
- ? 'ascending'
512
- : 'descending'
513
- : 'none', ref: (th) => {
514
- if (['end', 'start'].includes(column.pinned))
515
- addHObserver(th, column.pinned, onColumnPinned);
516
- if (['top', 'bottom'].includes(headRenderer.pinned))
517
- addVObserver(th, headRenderer.pinned, onColumnPinned);
518
- } },
519
- index.h("button", { class: {
520
- [`${CSSNAMESPACE}__order-btn`]: true,
521
- [`${CSSNAMESPACE}__cell-content`]: true,
522
- }, onClick: handleColumnOrderClick },
523
- colheadFootRender(column),
524
- !!column.filter && index.h("nano-icon", { name: "light/filter" }),
525
- !!column.order &&
526
- (column.order === 'desc' ? (index.h("nano-icon", { name: "solid/long-arrow-down" })) : (index.h("nano-icon", { name: "solid/long-arrow-up" }))),
527
- index.h("div", { class: `${CSSNAMESPACE}__status-icons` },
528
- index.h("nano-icon", { name: "light/chevron-down" })))));
656
+ if (isSortable()) {
657
+ const sort = column.order
658
+ ? column.order === 'asc'
659
+ ? 'ascending'
660
+ : 'descending'
661
+ : 'none';
662
+ props = { ...props, 'aria-sort': sort };
663
+ }
664
+ if (isDraggable()) {
665
+ props = {
666
+ ...props,
667
+ draggable: true,
668
+ onDragStart: (e) => handleDragStart(e, column),
669
+ onDragOver: (e) => e.preventDefault(),
670
+ onDragEnd: () => handleDragEnd(),
671
+ };
529
672
  }
530
673
  return (index.h("th", { ...props, ref: (th) => {
531
674
  if (['end', 'start'].includes(column.pinned))
532
675
  addHObserver(th, column.pinned, onColumnPinned);
533
676
  if (['top', 'bottom'].includes(headRenderer.pinned))
534
677
  addVObserver(th, headRenderer.pinned, onColumnPinned);
535
- } },
536
- index.h("div", { class: `${CSSNAMESPACE}__cell-content` },
678
+ }, key: column.prop },
679
+ isDraggable() && [
680
+ index.h("div", { class: {
681
+ [`${CSSNAMESPACE}__drag-mask`]: true,
682
+ [`${CSSNAMESPACE}__drag-mask--start`]: true,
683
+ }, "data-col-name": column.prop, onDragEnter: handleDragEnter, onDrop: handleDrop, onDragOver: (e) => e.preventDefault() }),
684
+ index.h("div", { class: {
685
+ [`${CSSNAMESPACE}__drag-mask`]: true,
686
+ [`${CSSNAMESPACE}__drag-mask--end`]: true,
687
+ }, "data-col-name": column.prop, onDragEnter: handleDragEnter, onDrop: handleDrop, onDragOver: (e) => e.preventDefault() }),
688
+ ],
689
+ isSortable() ? (index.h("button", { class: {
690
+ [`${CSSNAMESPACE}__order-btn`]: true,
691
+ [`${CSSNAMESPACE}__cell-content`]: true,
692
+ }, onClick: handleColumnSortClick },
693
+ colheadFootRender(column),
694
+ !!column.filter && index.h("nano-icon", { name: "light/filter" }),
695
+ !!column.order &&
696
+ (column.order === 'desc' ? (index.h("nano-icon", { name: "solid/long-arrow-down" })) : (index.h("nano-icon", { name: "solid/long-arrow-up" }))),
697
+ index.h("div", { class: `${CSSNAMESPACE}__status-icons` },
698
+ index.h("nano-icon", { name: "light/chevron-down" })))) : (index.h("div", { class: `${CSSNAMESPACE}__cell-content` },
537
699
  colheadFootRender(column),
538
- !!column.filter && index.h("nano-icon", { name: "light/bars-filter" }))));
700
+ !!column.filter && index.h("nano-icon", { name: "light/bars-filter" })))));
701
+ };
702
+
703
+ // TABLE CELL
704
+ // (tbody > tr > td, tbody > tr > th)
705
+ /**
706
+ * Renders a cell using a custom renderer if set.
707
+ * @param rowIndex - the current row index being rendered
708
+ * @param colIndex - the current column index being rendered
709
+ * @returns - a JSX node
710
+ */
711
+ function cellRender(rowIndex, colIndex) {
712
+ const store = fetchStores();
713
+ const columns = store.config.state.columns;
714
+ const tpl = columns[colIndex]?.cellTemplate;
715
+ const model = colDataModel(rowIndex, colIndex);
716
+ if (!!model.cellModel && columns[colIndex].type === 'date') {
717
+ const d = new Date(model.cellModel);
718
+ if (d instanceof Date && !isNaN(d)) {
719
+ model.cellModel = !tpl
720
+ ? `${new Date(model.cellModel).toLocaleDateString()} ${new Date(model.cellModel).toLocaleTimeString()}`
721
+ : d;
722
+ }
723
+ }
724
+ return tpl ? (tpl(index.h, model)) : (index.h(index.Fragment, null, model.cellModel?.toString()));
725
+ }
726
+ const baseCellClasses = (colIndex, toString = false) => {
727
+ const store = fetchStores();
728
+ const column = store.config.state.columns[colIndex];
729
+ const classes = {
730
+ [`${CSSNAMESPACE}__td`]: true,
731
+ [`${CSSNAMESPACE}__ordered`]: !!column.order,
732
+ [`${CSSNAMESPACE}__pin`]: !!column.pinned,
733
+ [`${CSSNAMESPACE}__pin--start`]: column.pinned === 'start',
734
+ [`${CSSNAMESPACE}__pin--end`]: column.pinned === 'end',
735
+ };
736
+ if (toString)
737
+ return classListToStr(classes);
738
+ return classes;
539
739
  };
540
740
  const TableCell = ({ rowIndex, colIndex, nestedContent, }) => {
541
741
  const content = nestedContent || cellRender(rowIndex, colIndex);
542
742
  if (!content)
543
743
  return index.h(index.Fragment, null);
744
+ let CellType = 'td';
544
745
  const store = fetchStores();
545
746
  const column = store.config.state.columns[colIndex];
546
- let CellType = 'td';
547
747
  let props = mergeCellProperties(rowIndex, colIndex, {
548
- class: {
549
- [`${CSSNAMESPACE}__td`]: true,
550
- [`${CSSNAMESPACE}__ordered`]: !!column.order,
551
- [`${CSSNAMESPACE}__pin`]: !!column.pinned,
552
- [`${CSSNAMESPACE}__pin--start`]: column.pinned === 'start',
553
- [`${CSSNAMESPACE}__pin--end`]: column.pinned === 'end',
554
- },
748
+ class: baseCellClasses(colIndex),
555
749
  });
556
750
  if (column.rowHeader) {
557
751
  props =
558
- Number(props.rowspan) > 1
752
+ Number(props.rowSpan) > 1
559
753
  ? { ...props, scope: 'rowgroup' }
560
754
  : { ...props, scope: 'row' };
561
755
  CellType = 'th';
@@ -566,62 +760,113 @@ const TableCell = ({ rowIndex, colIndex, nestedContent, }) => {
566
760
  index.h("div", { class: `${CSSNAMESPACE}__cell-content` }, content)));
567
761
  };
568
762
 
569
- const detectScrollSpeed = (() => {
570
- let lastPos;
571
- let newPos;
572
- let timer;
573
- let delta;
574
- const delay = 60; // in "ms" (higher means lower fidelity )
575
- const clear = () => {
576
- lastPos = null;
577
- delta = 0;
763
+ const TableRow = ({ rowRenderer, rowIndex, row, onColumnPinned }, children, utils) => {
764
+ let extraProps = {};
765
+ const TableCell = ({ header }, children) => {
766
+ const cell = index.h("div", { class: CSSNAMESPACE + '__cell-content' }, children);
767
+ return header ? index.h("th", { scope: "row" }, cell) : index.h("td", null, cell);
578
768
  };
579
- clear();
580
- return () => {
581
- newPos = window.scrollY;
582
- if (lastPos != null)
583
- delta = newPos - lastPos;
584
- lastPos = newPos;
585
- window.clearTimeout(timer);
586
- timer = window.setTimeout(clear, delay);
587
- return delta;
769
+ if (!row) {
770
+ const model = rowDataModel(rowIndex);
771
+ row = model.row;
772
+ }
773
+ if (rowRenderer?.rowProperties) {
774
+ extraProps = rowRenderer.rowProperties({ row, rowIndex }) || extraProps;
775
+ }
776
+ let pinned;
777
+ if (rowRenderer?.pinned && typeof rowRenderer.pinned === 'function') {
778
+ pinned = rowRenderer.pinned();
779
+ }
780
+ const baseProps = { class: headerPinClasses('tr', pinned) };
781
+ const props = extraProps ? mergeProperties(baseProps, extraProps) : baseProps;
782
+ const tpl = rowRenderer?.template;
783
+ if (tpl) {
784
+ let toRender = tpl(index.h, {
785
+ renderedRow: (index.h("tr", { ...props, key: row.__uuid }, children)),
786
+ row,
787
+ rowIndex,
788
+ }, TableCell);
789
+ if (Array.isArray(toRender)) {
790
+ toRender = utils.map(toRender, (node, i) => {
791
+ if (node.vtag === 'tr') {
792
+ if (!node.vkey)
793
+ node.vkey = `${row.__uuid}_${i}`;
794
+ node.vattrs = mergeProperties({ class: headerPinClasses('tr', pinned, true) }, node.vattrs);
795
+ if (!!node.vchildren) {
796
+ node.vchildren = utils.map(node.vchildren, (cNode, i) => {
797
+ if (['td', 'th'].includes(cNode.vtag.toString())) {
798
+ cNode.vattrs = mergeProperties({
799
+ class: headerPinClasses(cNode.vtag.toString(), pinned, true) + baseCellClasses(i, true),
800
+ ref: (th) => {
801
+ if ((!!th && pinned === 'top') || pinned === 'bottom')
802
+ addVObserver(th, pinned, onColumnPinned);
803
+ if (!!th && th.classList.contains('nano-tbl__pin--end'))
804
+ addHObserver(th, 'end', onColumnPinned);
805
+ if (!!th && th.classList.contains('nano-tbl__pin--start'))
806
+ addHObserver(th, 'start', onColumnPinned);
807
+ },
808
+ }, cNode.vattrs);
809
+ }
810
+ return cNode;
811
+ });
812
+ }
813
+ }
814
+ return node;
815
+ });
816
+ }
817
+ return toRender;
818
+ }
819
+ return (index.h("tr", { ...props, key: row.__uuid }, children));
820
+ };
821
+ const TableHeadFootRow = ({ rowRenderer, onColumnPinned }, children, utils) => {
822
+ let extraProps = {};
823
+ if (rowRenderer.rowProperties) {
824
+ extraProps = rowRenderer.rowProperties() || {};
825
+ }
826
+ const TableCell = ({ header }, children) => {
827
+ const cell = index.h("div", { class: CSSNAMESPACE + '__cell-content' }, children);
828
+ return header !== false ? index.h("th", { scope: "col" }, cell) : index.h("td", null, cell);
588
829
  };
589
- })();
590
- function findScrollParent(element) {
591
- let style = getComputedStyle(element);
592
- const excludeStaticParent = style.position === 'absolute';
593
- const overflowRegex = /(auto|scroll)/;
594
- if (style.position === 'fixed')
595
- return document.documentElement;
596
- for (let parent = element; (parent = parent.parentElement);) {
597
- style = getComputedStyle(parent);
598
- if (excludeStaticParent && style.position === 'static') {
599
- continue;
830
+ const pinned = rowRenderer.pinned || null;
831
+ const baseProps = { class: headerPinClasses('tr', null) };
832
+ const props = extraProps ? mergeProperties(baseProps, extraProps) : baseProps;
833
+ const tpl = rowRenderer?.template;
834
+ if (tpl) {
835
+ let toRender = tpl(index.h, {
836
+ renderedRow: index.h("tr", { ...props }, children),
837
+ }, TableCell);
838
+ if (Array.isArray(toRender)) {
839
+ toRender = utils.map(toRender, (node) => {
840
+ if (node.vtag === 'tr') {
841
+ node.vattrs = mergeProperties({ class: headerPinClasses('tr', pinned, true) }, node.vattrs);
842
+ if (!!node.vchildren) {
843
+ node.vchildren = utils.map(node.vchildren, (cNode) => {
844
+ if (['td', 'th'].includes(cNode.vtag.toString())) {
845
+ cNode.vattrs = mergeProperties({
846
+ class: headerPinClasses(cNode.vtag.toString(), pinned, true),
847
+ ref: (th) => {
848
+ if ((!!th && pinned === 'top') || pinned === 'bottom')
849
+ addVObserver(th, pinned, onColumnPinned);
850
+ if (!!th && th.classList.contains('nano-tbl__pin--end'))
851
+ addHObserver(th, 'end', onColumnPinned);
852
+ if (!!th && th.classList.contains('nano-tbl__pin--start'))
853
+ addHObserver(th, 'start', onColumnPinned);
854
+ },
855
+ }, cNode.vattrs);
856
+ }
857
+ return cNode;
858
+ });
859
+ }
860
+ }
861
+ return node;
862
+ });
600
863
  }
601
- if (overflowRegex.test(style.overflow + style.overflowY + style.overflowX))
602
- return parent;
864
+ return toRender;
603
865
  }
604
- return document.documentElement;
605
- }
606
- function isInViewport(el, percentVisible = 100) {
607
- const r = el.getBoundingClientRect();
608
- const windowHeight = window.innerHeight || document.documentElement.clientHeight;
609
- if (!r.bottom &&
610
- !r.top &&
611
- !r.left &&
612
- !r.right &&
613
- !r.height &&
614
- !r.width &&
615
- !r.x &&
616
- !r.y)
617
- return false;
618
- return !(Math.floor(100 - ((r.top >= 0 ? 0 : r.top) / +-r.height) * 100) <
619
- percentVisible ||
620
- Math.floor(100 - ((r.bottom - windowHeight) / r.height) * 100) <
621
- percentVisible);
622
- }
866
+ return index.h("tr", { ...props }, children);
867
+ };
623
868
 
624
- const tableCss = ":host{box-sizing:border-box}*,*::before,*::after{box-sizing:border-box}[hidden]{display:none !important}@charset \"UTF-8\";nano-table{display:block;width:100%;--max-col-width:200px;--color:var(--nano-color-mediumgrey, #68767e);--font-size:0.87rem;--cell-line-height:1.5;--thead-font-size:0.95rem;--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.5rem;--td-padding-bottom:0.4125rem;--th-padding-start:0.625rem;--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(--th-padding-top) var(--th-padding-bottom);--foot-th-padding-h:var(--th-padding-start) var(--th-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));border-inline-end: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);border-inline-start: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__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;scale:0;width:100%;height:0}.nano-tbl__progress-bar--show{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;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{border-block-start:none}tbody:last-of-type tr:last-child .nano-tbl__td,tbody:last-of-type tr:last-child .nano-tbl__th{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{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{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{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{padding-inline-end:var(--td-padding-end) !important}}thead .nano-tbl__td,thead .nano-tbl__th{font-weight:800;background:rgba(var(--head-bg-rgb), 90%);font-size:var(--thead-font-size);border-block-start:none}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)}tfoot .nano-tbl__td,tfoot .nano-tbl__th{font-weight:800;border-block-end:none;background:rgba(var(--foot-bg-rgb), 90%);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:rgba(var(--ordered-bg-rgb), 0.8) !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 tbody{will-change:scroll-position;visibility:visible}.nano-tbl tbody.nano-tbl__inactive{visibility:hidden}.nano-tbl th[scope=row]{font-weight:800;margin:0}.sm .nano-tbl th[scope=row]{max-width:65vw !important}.nano-tbl__pin{position:sticky;z-index:1}.nano-tbl__pin--start{inset-inline:-1px auto;transition:max-width 0.25s}.nano-tbl__pin--start::after{content:\"\";position:absolute;inset:0;box-shadow:5px 1px 4px 0 rgba(0, 0, 0, 0.2);opacity:0;z-index:-1}.nano-tbl__pinned--start .nano-tbl__pin--start{z-index:2;max-width:125px}.sm .nano-tbl__pinned--start .nano-tbl__pin--start{max-width:var(--max-col-width)}.nano-tbl__pinned--start .nano-tbl__pin--start::after{opacity:1}.nano-tbl__pin--end{}.nano-tbl__pin--start+.nano-tbl__pin--end{inset-inline:auto auto}.nano-tbl__pin--start+.nano-tbl__pin--end::after{display:none}.sm .nano-tbl__pin--end{inset-inline:auto -1px !important;max-width:min(50vw, 200px)}.sm .nano-tbl__pin--end::after{display:block !important;content:\"\";position:absolute;inset:0;box-shadow:-5px 1px 4px 0 rgba(0, 0, 0, 0.2);opacity:0;z-index:-1}.sm .nano-tbl__pinned--end .nano-tbl__pin--end{z-index:3}.sm .nano-tbl__pinned--end .nano-tbl__pin--end::after{opacity:1}.nano-tbl__pin--top{inset-block:-1px auto}.nano-tbl__pinned--top .nano-tbl__pin--top{z-index:4}.nano-tbl__pin--bottom{inset-block:auto -1px}.nano-tbl__pinned--bottom .nano-tbl__pin--bottom{z-index:5;border-block-start:var(--border-tint-style) !important}.nano-tbl__pinned--top.nano-tbl__pinned--start .nano-tbl__pin--top.nano-tbl__pin--start{z-index:6}.nano-tbl__pinned--top.nano-tbl__pinned--end .nano-tbl__pin--top.nano-tbl__pin--end{z-index:6}.nano-tbl__pinned--bottom.nano-tbl__pinned--start .nano-tbl__pin--bottom.nano-tbl__pin--start{z-index:6}.nano-tbl__pinned--bottom.nano-tbl__pinned--end .nano-tbl__pin--bottom.nano-tbl__pin--end{z-index:6}.nano-tbl thead tr:last-of-type td,.nano-tbl thead tr:last-of-type th{border-block-end:var(--border-tint-style)}.nano-tbl tfoot tr:first-of-type td,.nano-tbl tfoot tr:first-of-type th{border-block-start:none}.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)}";
869
+ 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, 30%, 20vw);--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.5rem;--td-padding-bottom:0.4125rem;--th-padding-start:0.625rem;--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));border-inline-end: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);border-inline-start:var(--border-style);border-inline-end:var(--border-style)}.nano-tbl__drag-mask{display:none;position:absolute;inset-block:-2px -2px;z-index:10;opacity:0;transition:0.2s ease opacity}.nano-tbl__drag-mask--start{width:calc(50% + 2px);inset-inline-start:-2px;border-inline-start:2px dashed var(--border-tint-color)}.nano-tbl__drag-mask--end{width:50%;inset-inline-end:0;border-inline-end:2px dashed var(--border-tint-color)}.nano-tbl__drag-mask--active{opacity:1}.nano-tbl__dragging .nano-tbl__drag-mask{display:block}.nano-tbl__drag--start{opacity:0.4}.nano-tbl__dragging .nano-tbl__td,.nano-tbl__dragging .nano-tbl__th{cursor:no-drop}.nano-tbl__dragging .nano-tbl__td .nano-tbl__cell-content,.nano-tbl__dragging .nano-tbl__th .nano-tbl__cell-content{pointer-events:none}.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__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;scale:0;width:100%;height:0}.nano-tbl__progress-bar--show{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;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{border-block-start:none}tbody:last-of-type tr:last-child .nano-tbl__td,tbody:last-of-type tr:last-child .nano-tbl__th{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{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{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{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{padding-inline-end:var(--td-padding-end) !important}}thead .nano-tbl__td,thead .nano-tbl__th{color:var(--thead-color);font-weight:800;background:rgba(var(--head-bg-rgb), 90%);font-size:var(--thead-font-size);border-block-start:none !important;transition:all 0.2s ease}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)}tfoot .nano-tbl__td,tfoot .nano-tbl__th{color:var(--tfoot-color);font-weight:800;border-block-start:none;background:rgba(var(--foot-bg-rgb), 90%);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:rgba(var(--ordered-bg-rgb), 0.8) !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 tbody{will-change:scroll-position;visibility:visible}.nano-tbl tbody.nano-tbl__inactive{visibility:hidden}.nano-tbl th[scope=row]{font-weight:800;margin:0}.nano-tbl__pin{position:sticky;z-index:1}.nano-tbl__pin--start{inset-inline:-1px auto;transition:max-width 0.25s ease;z-index:2}.nano-tbl__pin--start::after{content:\"\";position:absolute;inset:0;box-shadow:5px 1px 4px 0 rgba(0, 0, 0, 0.2);opacity:0;z-index:-1}.nano-tbl__pinned--start .nano-tbl__pin--start{z-index:2;max-width:125px !important}.sm .nano-tbl__pinned--start .nano-tbl__pin--start{max-width:var(--max-col-width) !important}.nano-tbl__pinned--start .nano-tbl__pin--start::after{opacity:1}.nano-tbl__pin--end{z-index:2;}.nano-tbl__pin--start+.nano-tbl__pin--end{inset-inline:auto auto}.nano-tbl__pin--start+.nano-tbl__pin--end::after{display:none}.sm .nano-tbl__pin--end{inset-inline:auto -1px !important;max-width:min(50vw, 200px)}.sm .nano-tbl__pin--end::after{display:block !important;content:\"\";position:absolute;inset:0;box-shadow:-5px 1px 4px 0 rgba(0, 0, 0, 0.2);opacity:0;z-index:-1}.sm .nano-tbl__pinned--end .nano-tbl__pin--end{z-index:3}.sm .nano-tbl__pinned--end .nano-tbl__pin--end::after{opacity:1}.nano-tbl__pin--top{inset-block:-1px auto;z-index:3}.nano-tbl__pinned--top .nano-tbl__pin--top{z-index:4 !important}.nano-tbl__pin--bottom{inset-block:auto -1px;z-index:3}.nano-tbl__pinned--bottom .nano-tbl__pin--bottom{z-index:5 !important}.nano-tbl__pin--top.nano-tbl__pin--start{z-index:4}.nano-tbl__pinned--start .nano-tbl__pin--top.nano-tbl__pin--start{z-index:5 !important}.nano-tbl__pinned--top.nano-tbl__pinned--start .nano-tbl__pin--top.nano-tbl__pin--start{z-index:6 !important}.nano-tbl__pin--top.nano-tbl__pin--end{z-index:4}.nano-tbl__pinned--end .nano-tbl__pin--top.nano-tbl__pin--end{z-index:5 !important}.nano-tbl__pinned--top.nano-tbl__pinned--end .nano-tbl__pin--top.nano-tbl__pin--end{z-index:6 !important}.nano-tbl__pin--bottom.nano-tbl__pin--start{z-index:4}.nano-tbl__pinned--start .nano-tbl__pin--bottom.nano-tbl__pin--start{z-index:5 !important}.nano-tbl__pinned--bottom.nano-tbl__pinned--start .nano-tbl__pin--bottom.nano-tbl__pin--start{z-index:6 !important}.nano-tbl__pin--bottom.nano-tbl__pin--end{z-index:4}.nano-tbl__pinned--end .nano-tbl__pin--bottom.nano-tbl__pin--end{z-index:5 !important}.nano-tbl__pinned--bottom.nano-tbl__pinned--end .nano-tbl__pin--bottom.nano-tbl__pin--end{z-index:6 !important}.nano-tbl thead tr:last-of-type td,.nano-tbl thead tr:last-of-type th{border-block-end:var(--border-tint-style)}.nano-tbl tfoot tr:first-of-type td,.nano-tbl tfoot tr:first-of-type th{border-block-start:none}.nano-tbl tfoot tr:last-of-type td,.nano-tbl tfoot tr:last-of-type th{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{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{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)}";
625
870
 
626
871
  let id = 0;
627
872
  const Table = class {
@@ -631,16 +876,18 @@ const Table = class {
631
876
  this.nanoTblReady = index.createEvent(this, "nanoTblReady", 7);
632
877
  this.nanoTblBeforeSort = index.createEvent(this, "nanoTblBeforeSort", 7);
633
878
  this.nanoTblAfterSort = index.createEvent(this, "nanoTblAfterSort", 7);
879
+ this.nanoTblColDrag = index.createEvent(this, "nanoTblColDrag", 7);
880
+ this.nanoTblColDrop = index.createEvent(this, "nanoTblColDrop", 7);
634
881
  this.nanoTblBeforeFilter = index.createEvent(this, "nanoTblBeforeFilter", 7);
635
882
  this.nanoTblAfterFilter = index.createEvent(this, "nanoTblAfterFilter", 7);
636
883
  this.nanoTblBeforeSearch = index.createEvent(this, "nanoTblBeforeSearch", 7);
637
884
  this.nanoTblAfterSearch = index.createEvent(this, "nanoTblAfterSearch", 7);
638
885
  this.debounceSetLoading = (l) => {
639
- this._loading = !!this.store.data.state.rows.length ? l : true;
886
+ this._loading = l;
640
887
  };
641
888
  this.renderId = 'tbl-' + id++;
642
889
  this.filters = [];
643
- this.currentFilters = '';
890
+ this.currentFilters = '[]';
644
891
  this.currentSort = '';
645
892
  this.blockIos = new WeakMap();
646
893
  this.blockHeights = [];
@@ -648,6 +895,23 @@ const Table = class {
648
895
  // Scroll / IO used for hiding / showing blocks
649
896
  this.ignoreIO = true;
650
897
  this._isReady = false;
898
+ this.colDrag = (column) => {
899
+ this.nanoTblColDrag.emit({ column });
900
+ };
901
+ this.colDrop = (fromCol, toCol) => {
902
+ const cols = this.store.config.state.columns;
903
+ const toIndex = cols.findIndex((col) => col.prop === toCol);
904
+ const fromIndex = cols.findIndex((col) => col.prop === fromCol);
905
+ const dropEvent = this.nanoTblColDrop.emit({
906
+ fromCol,
907
+ toCol,
908
+ fromIndex,
909
+ toIndex,
910
+ });
911
+ if (dropEvent.defaultPrevented)
912
+ return;
913
+ this.store.config.state.columns = arrMove(fromIndex, toIndex, cols);
914
+ };
651
915
  /**
652
916
  * Start a sort - can be cancelled by `preventDefault`
653
917
  * @param order - column order
@@ -703,7 +967,7 @@ const Table = class {
703
967
  // This is a bit gross
704
968
  // The Intersection Observer (IO) fires in an incorrect order when the scrolling is very fast
705
969
  // i.e. we go past blocks 3, 2, 1 and land on 0, but 3 can fire as 'intersecting' after 0.
706
- // To fix that, we check - for realsies - if the block IS visible.
970
+ // To fix that, we check - for realzies - if the block IS visible.
707
971
  // BUT that test is not as sensitive to a block being visible via the IO,
708
972
  // so doesn't always fire if scrolling slowly
709
973
  // *sigh*
@@ -736,6 +1000,10 @@ const Table = class {
736
1000
  this.tableEle.classList.toggle(`${CSSNAMESPACE}__pinned--${key}`, applied);
737
1001
  });
738
1002
  };
1003
+ this.handleResizeChange = (e) => {
1004
+ this.tableWrapperEle.className = '';
1005
+ this.tableWrapperEle.classList.add(...(e.target.className + ' ' + `${CSSNAMESPACE}__wrap`).split(' '));
1006
+ };
739
1007
  this.type = 'table';
740
1008
  this.caption = undefined;
741
1009
  this.showCaption = false;
@@ -751,6 +1019,8 @@ const Table = class {
751
1019
  this.searchTerm = undefined;
752
1020
  this.customFilterFn = undefined;
753
1021
  this.customSortFn = undefined;
1022
+ this.defaultSort = true;
1023
+ this.defaultColDraggable = false;
754
1024
  this.blocks = [];
755
1025
  this.activeBlocks = [0, 1, 2];
756
1026
  this.measureHeight = 0;
@@ -777,9 +1047,8 @@ const Table = class {
777
1047
  this.currentFilters = '';
778
1048
  this.currentSort = '';
779
1049
  await this.columnInit();
780
- if (!this.isReady) {
1050
+ if (!this.isReady)
781
1051
  this.setInitialBlockDimension();
782
- }
783
1052
  this.loading = false;
784
1053
  });
785
1054
  }
@@ -827,6 +1096,14 @@ const Table = class {
827
1096
  this.filters = [];
828
1097
  return this.filterStart(filters, additive);
829
1098
  }
1099
+ /** Remove filters from a column
1100
+ * @param columnNames - the filters to apply
1101
+ * @returns a promise which resolves when complete
1102
+ */
1103
+ async removeFilters(columnNames) {
1104
+ this.filters = this.filters.filter((f) => !columnNames.includes(f.prop));
1105
+ return this.filterStart();
1106
+ }
830
1107
  // uses the first 'tr' of an active block as our yard stick
831
1108
  set measureEle(el) {
832
1109
  if (!el)
@@ -846,13 +1123,13 @@ const Table = class {
846
1123
  if (this.isReady)
847
1124
  requestAnimationFrame(() => this.handleReady());
848
1125
  }
1126
+ // Private Logic
849
1127
  // Listeners
850
1128
  scrollListener() {
851
1129
  // see explanation in `setupBlockIO`
852
1130
  const speed = detectScrollSpeed();
853
1131
  this.scrollSpeed = speed < 0 ? speed * -1 : speed;
854
1132
  }
855
- // Logic
856
1133
  handleReady() {
857
1134
  const hash = window.location.hash;
858
1135
  if (hash.length > 1) {
@@ -1086,19 +1363,20 @@ const Table = class {
1086
1363
  processSlots() {
1087
1364
  // see if we have slot content
1088
1365
  if (!this.caption && !this.host.querySelector('[slot="caption"]')) {
1089
- console.error('For accessibility you must set a `title` prop or use the `caption` slot');
1366
+ console.error('For accessibility you must set a `caption` prop or use the `caption` slot');
1090
1367
  }
1091
1368
  }
1092
1369
  // Component lifecycle
1093
1370
  async componentWillLoad() {
1371
+ this.scrollParent = findScrollParent(this.host);
1094
1372
  this.store = await generateStore(this.host, this.columns, this.scrollParent);
1095
1373
  await this.handleRowsChange();
1096
1374
  this.processSlots();
1097
- this.setBlocks();
1098
1375
  this.store.data.onChange('rows', () => this.setBlocks());
1376
+ this.setBlocks();
1099
1377
  }
1100
1378
  connectedCallback() {
1101
- index.readTask(() => (this.scrollParent = findScrollParent(this.host)));
1379
+ this.scrollParent = findScrollParent(this.host);
1102
1380
  }
1103
1381
  componentDidLoad() {
1104
1382
  this.setInitialBlockDimension();
@@ -1118,15 +1396,18 @@ const Table = class {
1118
1396
  }
1119
1397
  render() {
1120
1398
  this.blockElements = [];
1121
- return (index.h(index.Host, null, index.h("div", { class: `${CSSNAMESPACE}__top-anchor`, ref: (a) => (this.topAnchorEle = a) }, "\u00A0"), index.h("nano-resize-observe", { "aria-labelledby": 'table-caption-' + this.renderId, tabindex: this.type === 'grid' ? '0' : undefined, states: "576w sm, 768w md", class: "sm md" }, index.h("div", { class: `${CSSNAMESPACE}__wrap` }, index.h("nano-progress-bar", { indeterminate: true, class: {
1399
+ return (index.h(index.Host, null, index.h("div", { class: `${CSSNAMESPACE}__top-anchor`, ref: (a) => (this.topAnchorEle = a) }, "\u00A0"), index.h("nano-resize-observe", { "aria-labelledby": 'table-caption-' + this.renderId, tabindex: this.type === 'grid' ? '0' : undefined, states: "576w sm, 768w md", class: "sm md", onNanoResizeStateChange: this.handleResizeChange }), index.h("div", { class: `${CSSNAMESPACE}__wrap sm md`, ref: (div) => (this.tableWrapperEle = div) }, index.h("nano-progress-bar", { indeterminate: true, class: {
1122
1400
  [`${CSSNAMESPACE}__progress-bar`]: true,
1123
1401
  [`${CSSNAMESPACE}__progress-bar--show`]: this._loading,
1124
1402
  } }), index.h("table", { role: this.type === 'grid' ? 'grid' : undefined, "aria-readonly": this.type === 'table' ? 'true' : 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: {
1125
1403
  [`${CSSNAMESPACE}__caption`]: true,
1126
1404
  [`${CSSNAMESPACE}__caption--hide`]: !this.showCaption,
1127
1405
  }, id: 'table-caption-' + this.renderId }, index.h("slot", { name: "caption" }, this.caption)), index.h("thead", null, index.h(TableHeadFootRow, { rowRenderer: this.headRender, onColumnPinned: this.handleColumnPinned }, this.store.config.state.columns.map((colModel) => [
1128
- index.h(TableColHead, { column: colModel, headRenderer: this.headRender, onColumnOrderClick: this.sortStart, onColumnPinned: this.handleColumnPinned }),
1129
- ]))), 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, { rowIndex: rowIndex, colIndex: colIndex, nestedContent: index.h("nano-skeleton", null) })))))))), this.blocks.map((block, blockIndex) => (index.h("tbody", { key: block.__uuid, id: `tbody-${this.renderId}-${blockIndex}`, ref: (tb) => {
1406
+ index.h(TableColHead, { column: colModel, headRenderer: this.headRender, onColumnSortClick: this.sortStart, onColumnPinned: this.handleColumnPinned, onColumnDrag: this.colDrag, onColumnDrop: this.colDrop, defaults: {
1407
+ sortable: this.defaultSort,
1408
+ draggable: this.defaultColDraggable,
1409
+ } }),
1410
+ ]))), 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, { rowIndex: rowIndex, colIndex: colIndex, nestedContent: index.h("nano-skeleton", null) })))))))), !this._loading && !this.blocks.length && (index.h("tr", null, 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) => {
1130
1411
  this.blockElements.push(tb);
1131
1412
  this.setupBlockIO(tb, blockIndex);
1132
1413
  }, class: {
@@ -1134,15 +1415,18 @@ const Table = class {
1134
1415
  [`${CSSNAMESPACE}__active`]: this.activeBlocks.includes(blockIndex),
1135
1416
  } }, this.activeBlocks.includes(blockIndex) ? (block.rows.map((row, i) => {
1136
1417
  const rowIndex = blockIndex > 0 ? blockIndex * this.perBlock + i : i;
1137
- return (index.h(TableRow, { rowRenderer: this.rowRender, row: row }, this.store.config.state.columns.map((_colModel, colIndex) => (index.h(TableCell, { rowIndex: rowIndex, colIndex: colIndex })))));
1418
+ return (index.h(TableRow, { rowRenderer: this.rowRender, row: row, rowIndex: rowIndex }, this.store.config.state.columns.map((_colModel, colIndex) => (index.h(TableCell, { rowIndex: rowIndex, colIndex: colIndex })))));
1138
1419
  })) : (index.h("td", { colSpan: this.store.config.state.columns.length, style: {
1139
1420
  height: this.getBlockHeight(blockIndex),
1140
1421
  } }))))), this.showFooter && (index.h("tfoot", null, index.h(TableHeadFootRow, { rowRenderer: this.footRender, onColumnPinned: this.handleColumnPinned }, this.store.config.state.columns.map((colModel) => [
1141
- index.h(TableColHead, { column: colModel, headRenderer: this.footRender, onColumnPinned: this.handleColumnPinned, onColumnOrderClick: this.sortStart }),
1422
+ index.h(TableColHead, { column: colModel, headRenderer: this.footRender, onColumnPinned: this.handleColumnPinned, onColumnSortClick: this.sortStart, defaults: {
1423
+ sortable: this.defaultSort,
1424
+ draggable: this.defaultColDraggable,
1425
+ } }),
1142
1426
  ]))))), !!this.blocks.length && (index.h("nano-spinner", { type: "circle", class: {
1143
1427
  [`${CSSNAMESPACE}__spinner`]: true,
1144
1428
  [`${CSSNAMESPACE}__spinner--show`]: this._loading,
1145
- } }))))));
1429
+ } })))));
1146
1430
  }
1147
1431
  get host() { return index.getElement(this); }
1148
1432
  static get watchers() { return {
@@ -1156,4 +1440,4 @@ Table.style = tableCss;
1156
1440
  exports.Table = Table;
1157
1441
  exports.createWorker = createWorker;
1158
1442
 
1159
- //# sourceMappingURL=nano-table-b9cdafab.js.map
1443
+ //# sourceMappingURL=nano-table-067e0c12.js.map