@timlassiter11/yatl 1.0.3 → 1.0.5

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/dist/index.mjs CHANGED
@@ -193,11 +193,8 @@ function widthsToGridTemplates(widths, defaultWidth = "1fr") {
193
193
  function isCompareable(value) {
194
194
  return typeof value === "string" || typeof value === "number" || typeof value === "boolean" || value instanceof Date;
195
195
  }
196
- function isInternalColumn(col) {
197
- return col.role === "internal";
198
- }
199
196
  function isDisplayColumn(col) {
200
- return col.role !== "internal";
197
+ return col?.role !== "internal";
201
198
  }
202
199
 
203
200
  // src/yatl-table.ts
@@ -314,7 +311,8 @@ var yatl_table_styles_default = css`
314
311
  border-bottom: none;
315
312
  }
316
313
 
317
- .header .cell::after,
314
+ .header.reorderable .cell::after,
315
+ .header .cell.sortable::after,
318
316
  .row:not(.header)::after {
319
317
  content: '';
320
318
  position: absolute;
@@ -471,7 +469,7 @@ var yatl_table_styles_default = css`
471
469
  flex-shrink: 0;
472
470
 
473
471
  position: sticky;
474
- bottom: 0;
472
+ inset: 0;
475
473
  z-index: var(--header-z-index);
476
474
  }
477
475
 
@@ -542,7 +540,8 @@ var YatlTable = class extends LitElement {
542
540
  this._enableSearchTokenization = false;
543
541
  this._enableSearchScoring = false;
544
542
  this._columns = [];
545
- this._columnStates = [];
543
+ this._columnDefinitionMap = /* @__PURE__ */ new Map();
544
+ this._columnStateMap = /* @__PURE__ */ new Map();
546
545
  this._columnOrder = [];
547
546
  this._storageOptions = null;
548
547
  this._data = [];
@@ -582,13 +581,11 @@ var YatlTable = class extends LitElement {
582
581
  // #endregion
583
582
  // #region --- Event Handlers ---
584
583
  this.handleHeaderClicked = (event, column) => {
585
- const target = event.target;
586
- const currentTarget = event.currentTarget;
587
- if (!currentTarget.classList.contains("sortable") || target.classList.contains("resizer")) {
584
+ if (this.resizeState) {
588
585
  return;
589
586
  }
590
587
  const multiSort = event.shiftKey;
591
- const state2 = this.getColumnState(column.field);
588
+ const state2 = this.getOrCreateColumnState(column.field);
592
589
  if (!state2?.sort) {
593
590
  this.sort(column.field, "asc", !multiSort);
594
591
  } else if (state2.sort.order === "asc") {
@@ -615,11 +612,13 @@ var YatlTable = class extends LitElement {
615
612
  );
616
613
  });
617
614
  };
618
- this.handleResizeMouseUp = (_event) => {
615
+ this.handleResizeMouseUp = (event) => {
619
616
  window.removeEventListener("mousemove", this.handleResizeMouseMove);
620
617
  window.removeEventListener("mouseup", this.handleResizeMouseUp);
621
618
  document.body.style.cursor = "";
622
619
  if (this.resizeState?.active) {
620
+ event.preventDefault();
621
+ event.stopPropagation();
623
622
  const finalWidth = parseFloat(
624
623
  this.resizeState.currentWidths[this.resizeState.columnIndex]
625
624
  );
@@ -629,7 +628,9 @@ var YatlTable = class extends LitElement {
629
628
  this.columnWidths = columnWidths;
630
629
  this.dispatchEvent(new YatlColumnResizeEvent(state2.field, state2.width));
631
630
  }
632
- this.resizeState = null;
631
+ setTimeout(() => {
632
+ this.resizeState = null;
633
+ });
633
634
  };
634
635
  this.handleDragColumnStart = (event, field) => {
635
636
  const target = event.target;
@@ -672,7 +673,7 @@ var YatlTable = class extends LitElement {
672
673
  const dropIndex = newColumnOrder.findIndex((col) => col === field);
673
674
  if (dragIndex > -1 && dropIndex > -1) {
674
675
  const [draggedColumn] = newColumnOrder.splice(dragIndex, 1);
675
- const droppedColumn = findColumn(field, this.columns);
676
+ const droppedColumn = this.getColumn(field);
676
677
  if (!droppedColumn) return;
677
678
  newColumnOrder.splice(dropIndex, 0, draggedColumn);
678
679
  const reorderEvent = new YatlColumnReorderEvent(
@@ -726,17 +727,24 @@ var YatlTable = class extends LitElement {
726
727
  const oldValue = this._columns;
727
728
  this._columns = columns;
728
729
  this.filterDirty = true;
730
+ this._columnDefinitionMap = /* @__PURE__ */ new Map();
731
+ for (const column of this.columns) {
732
+ this._columnDefinitionMap.set(column.field, column);
733
+ }
729
734
  this.requestUpdate("columns", oldValue);
730
735
  }
736
+ get displayColumns() {
737
+ return this._columns.filter(isDisplayColumn);
738
+ }
731
739
  get columnOrder() {
732
740
  const finalOrder = /* @__PURE__ */ new Set();
733
741
  for (const field of this._columnOrder) {
734
- const col = findColumn(field, this.getColumns("display"));
742
+ const col = this.getDisplayColumn(field);
735
743
  if (col) {
736
744
  finalOrder.add(field);
737
745
  }
738
746
  }
739
- for (const col of this.getColumns("display")) {
747
+ for (const col of this.displayColumns) {
740
748
  if (!finalOrder.has(col.field)) {
741
749
  finalOrder.add(col.field);
742
750
  }
@@ -754,15 +762,15 @@ var YatlTable = class extends LitElement {
754
762
  get columnVisibility() {
755
763
  return this.columnOrder.map((field) => ({
756
764
  field,
757
- visible: this.getColumnState(field).visible
765
+ visible: this.getOrCreateColumnState(field).visible
758
766
  }));
759
767
  }
760
768
  set columnVisibility(columns) {
761
769
  const oldValue = this.columnVisibility;
762
770
  let changed = false;
763
771
  for (const column of columns) {
764
- const columnState = this.getColumnState(column.field);
765
- if (columnState && columnState.visible !== column.visible) {
772
+ const columnState = this.getOrCreateColumnState(column.field);
773
+ if (columnState.visible !== column.visible) {
766
774
  changed = true;
767
775
  columnState.visible = column.visible;
768
776
  }
@@ -774,7 +782,7 @@ var YatlTable = class extends LitElement {
774
782
  }
775
783
  get columnSort() {
776
784
  return this.columnOrder.map((field) => {
777
- const sortState = this.getColumnState(field).sort;
785
+ const sortState = this.getOrCreateColumnState(field).sort;
778
786
  return {
779
787
  field,
780
788
  // We need to make a copy of sort state so
@@ -787,7 +795,7 @@ var YatlTable = class extends LitElement {
787
795
  const oldValue = this.columnSort;
788
796
  let changed = false;
789
797
  for (const column of columns) {
790
- const columnState = this.getColumnState(column.field);
798
+ const columnState = this.getOrCreateColumnState(column.field);
791
799
  if (columnState && (columnState.sort?.order !== column.sort?.order || columnState.sort?.priority !== column.sort?.priority)) {
792
800
  changed = true;
793
801
  columnState.sort = column.sort;
@@ -802,15 +810,15 @@ var YatlTable = class extends LitElement {
802
810
  get columnWidths() {
803
811
  return this.columnOrder.map((field) => ({
804
812
  field,
805
- width: this.getColumnState(field).width
813
+ width: this.getOrCreateColumnState(field).width
806
814
  }));
807
815
  }
808
816
  set columnWidths(columns) {
809
817
  const oldValue = this.columnWidths;
810
818
  let changed = false;
811
819
  for (const column of columns) {
812
- const columnState = this.getColumnState(column.field);
813
- if (columnState && columnState.width !== column.width) {
820
+ const columnState = this.getOrCreateColumnState(column.field);
821
+ if (columnState.width !== column.width) {
814
822
  changed = true;
815
823
  columnState.width = column.width;
816
824
  }
@@ -894,6 +902,15 @@ var YatlTable = class extends LitElement {
894
902
  }
895
903
  // #endregion
896
904
  // #region --- Public Methods ---
905
+ getColumn(field) {
906
+ return this._columnDefinitionMap.get(field);
907
+ }
908
+ getDisplayColumn(field) {
909
+ const column = this._columnDefinitionMap.get(field);
910
+ if (column && isDisplayColumn(column)) {
911
+ return column;
912
+ }
913
+ }
897
914
  /**
898
915
  * Gets a copy of the current state of the table.
899
916
  */
@@ -903,7 +920,7 @@ var YatlTable = class extends LitElement {
903
920
  filters: this.filters,
904
921
  columnOrder: this.columnOrder,
905
922
  columns: this.columns.map((column) => {
906
- const state2 = this.getColumnState(column.field);
923
+ const state2 = this.getOrCreateColumnState(column.field);
907
924
  return {
908
925
  field: column.field,
909
926
  visible: state2.visible,
@@ -928,10 +945,8 @@ var YatlTable = class extends LitElement {
928
945
  this.columnOrder = state2.columnOrder;
929
946
  }
930
947
  if ("columns" in state2 && state2.columns !== void 0) {
931
- const newColumnStates = [];
932
948
  for (const newState of state2.columns) {
933
- const currentState = this.getColumnState(newState.field);
934
- newColumnStates.push(currentState);
949
+ const currentState = this.getOrCreateColumnState(newState.field);
935
950
  if (!newState) {
936
951
  continue;
937
952
  }
@@ -945,7 +960,6 @@ var YatlTable = class extends LitElement {
945
960
  currentState.width = newState.width;
946
961
  }
947
962
  }
948
- this._columnStates = newColumnStates;
949
963
  this.requestUpdate();
950
964
  }
951
965
  }
@@ -1005,15 +1019,15 @@ var YatlTable = class extends LitElement {
1005
1019
  return;
1006
1020
  }
1007
1021
  state2.visible = visible;
1008
- this.columnVisibility = visibilityStates;
1022
+ this.columnVisibility = [...visibilityStates];
1009
1023
  }
1010
1024
  /**
1011
1025
  * Toggles the visibility of hte specified column
1012
1026
  * @param field - The field name of the column to toggle.
1013
1027
  */
1014
1028
  toggleColumnVisibility(field) {
1015
- const state2 = this.getColumnState(field);
1016
- this.setColumnVisibility(field, !state2);
1029
+ const state2 = this.getOrCreateColumnState(field);
1030
+ this.setColumnVisibility(field, !state2.visible);
1017
1031
  }
1018
1032
  /**
1019
1033
  * Shows the specified column
@@ -1036,18 +1050,16 @@ var YatlTable = class extends LitElement {
1036
1050
  */
1037
1051
  export(filename, all = false) {
1038
1052
  const data = all ? this.data : this.filteredData;
1039
- const rows = [...data.values()];
1040
- const columnData = this.getColumnData(this.getColumns("display"));
1041
- const csvHeaders = columnData.filter(
1042
- (col) => all || isDisplayColumn(col.options) && col.state?.visible
1043
- ).map((col) => `"${col.options.title}"`).join(",");
1044
- const csvRows = rows.map((row) => {
1053
+ const columnData = this.displayColumns;
1054
+ const csvHeaders = columnData.filter((column) => all || this.getOrCreateColumnState(column.field).visible).map((column) => `"${column.title}"`).join(",");
1055
+ const csvRows = data.map((row) => {
1045
1056
  const list = [];
1046
- for (const col of columnData) {
1047
- let value = getNestedValue(row, col.field);
1048
- if (all || col.state.visible) {
1049
- if (typeof col.options.valueFormatter === "function") {
1050
- value = col.options.valueFormatter(value, row);
1057
+ for (const column of columnData) {
1058
+ const state2 = this.getOrCreateColumnState(column.field);
1059
+ let value = getNestedValue(row, column.field);
1060
+ if (all || state2.visible) {
1061
+ if (typeof column.valueFormatter === "function") {
1062
+ value = column.valueFormatter(value, row);
1051
1063
  }
1052
1064
  value = String(value).replace('"', '""');
1053
1065
  list.push(`"${value}"`);
@@ -1200,9 +1212,12 @@ var YatlTable = class extends LitElement {
1200
1212
  ></div>` : nothing;
1201
1213
  }
1202
1214
  renderHeaderCell(field) {
1203
- const column = findColumn(field, this.getColumns("display"));
1204
- const state2 = this.getColumnState(column.field);
1205
- if (state2.visible == false) {
1215
+ const column = this.getDisplayColumn(field);
1216
+ if (!column) {
1217
+ return nothing;
1218
+ }
1219
+ const state2 = this.getOrCreateColumnState(field);
1220
+ if (!state2.visible) {
1206
1221
  return nothing;
1207
1222
  }
1208
1223
  return html2`
@@ -1234,8 +1249,13 @@ var YatlTable = class extends LitElement {
1234
1249
  `;
1235
1250
  }
1236
1251
  renderHeader() {
1252
+ const classes = {
1253
+ "header": true,
1254
+ "row": true,
1255
+ "reorderable": this.enableColumnReorder
1256
+ };
1237
1257
  return html2`
1238
- <div part="header" class="header row">
1258
+ <div part="header" class=${classMap(classes)}>
1239
1259
  ${this.columnOrder.map((field) => this.renderHeaderCell(field))}
1240
1260
  </div>
1241
1261
  `;
@@ -1251,11 +1271,14 @@ var YatlTable = class extends LitElement {
1251
1271
  return this.enableSearchHighlight && indices ? highlightText(String(value), indices[column.field]) : value;
1252
1272
  }
1253
1273
  renderCell(field, row) {
1254
- const column = findColumn(field, this.getColumns("display"));
1255
- const state2 = this.getColumnState(column.field);
1256
- if (!state2.visible) {
1274
+ const column = this.getDisplayColumn(field);
1275
+ if (!column) {
1257
1276
  return nothing;
1258
1277
  }
1278
+ const state2 = this.getOrCreateColumnState(field);
1279
+ if (!state2.visible) {
1280
+ return;
1281
+ }
1259
1282
  let value = getNestedValue(row, column.field);
1260
1283
  let userParts = column.cellParts?.call(this, value, column.field, row);
1261
1284
  if (Array.isArray(userParts)) {
@@ -1529,8 +1552,8 @@ var YatlTable = class extends LitElement {
1529
1552
  return false;
1530
1553
  }
1531
1554
  } else {
1532
- const col = findColumn(field, this.columns);
1533
- const filterCallback = col ? col.filter : void 0;
1555
+ const column = this.getColumn(field);
1556
+ const filterCallback = column ? column.filter : void 0;
1534
1557
  if (!this.filterField(value, filter, filterCallback)) {
1535
1558
  return false;
1536
1559
  }
@@ -1539,8 +1562,8 @@ var YatlTable = class extends LitElement {
1539
1562
  return true;
1540
1563
  }
1541
1564
  filterRows() {
1542
- const columnData = this.getColumnData(this.columns);
1543
- const fields = columnData.filter((col) => col.options.searchable).map((c) => c.field);
1565
+ const columnData = [...this.columns];
1566
+ const fields = columnData.filter((column) => column.searchable).map((column) => column.field);
1544
1567
  this._filteredData = this.data.filter((row, index) => {
1545
1568
  const metadata = this.rowMetadata.get(row);
1546
1569
  metadata.searchScore = 0;
@@ -1579,25 +1602,18 @@ var YatlTable = class extends LitElement {
1579
1602
  // #region --- Sort Methods ---
1580
1603
  compareRows(a, b, field) {
1581
1604
  let aValue, bValue;
1582
- const columnData = findColumn(
1583
- field,
1584
- this.getColumnData(this.getColumns("display"))
1585
- );
1586
- if (!columnData.state.sort) {
1605
+ const state2 = this.getOrCreateColumnState(field);
1606
+ if (!state2.sort) {
1587
1607
  return 0;
1588
1608
  }
1589
1609
  const aMetadata = this.rowMetadata.get(a);
1590
1610
  const bMetadata = this.rowMetadata.get(b);
1591
- if (columnData.state.sort?.order === "asc") {
1592
- aValue = aMetadata.sortValues[columnData.field];
1593
- bValue = bMetadata.sortValues[columnData.field];
1611
+ if (state2.sort?.order === "asc") {
1612
+ aValue = aMetadata.sortValues[field];
1613
+ bValue = bMetadata.sortValues[field];
1594
1614
  } else {
1595
- aValue = bMetadata.sortValues[columnData.field];
1596
- bValue = aMetadata.sortValues[columnData.field];
1597
- }
1598
- if (typeof columnData.options.sorter === "function") {
1599
- const ret = columnData.options.sorter(aValue, bValue);
1600
- if (ret !== 0) return ret;
1615
+ aValue = bMetadata.sortValues[field];
1616
+ bValue = aMetadata.sortValues[field];
1601
1617
  }
1602
1618
  const aIsNull = aValue == null;
1603
1619
  const bIsNull = bValue == null;
@@ -1612,7 +1628,7 @@ var YatlTable = class extends LitElement {
1612
1628
  this.filterRows();
1613
1629
  return;
1614
1630
  }
1615
- const sortedColumns = this.getColumnData(this.columns).filter((col) => col.state.visible && col.state.sort).sort((a, b) => b.state.sort.priority - a.state.sort.priority);
1631
+ const sortedStates = [...this._columnStateMap.values()].filter((state2) => state2.visible && state2.sort).sort((a, b) => b.sort.priority - a.sort.priority);
1616
1632
  this._filteredData = this._filteredData.toSorted((a, b) => {
1617
1633
  const aMetadata = this.rowMetadata.get(a);
1618
1634
  const bMetadata = this.rowMetadata.get(b);
@@ -1622,8 +1638,8 @@ var YatlTable = class extends LitElement {
1622
1638
  if (aValue > bValue) return -1;
1623
1639
  if (aValue < bValue) return 1;
1624
1640
  }
1625
- for (const col of sortedColumns) {
1626
- const comp = this.compareRows(a, b, col.field);
1641
+ for (const state2 of sortedStates) {
1642
+ const comp = this.compareRows(a, b, state2.field);
1627
1643
  if (comp !== 0) {
1628
1644
  return comp;
1629
1645
  }
@@ -1647,16 +1663,14 @@ var YatlTable = class extends LitElement {
1647
1663
  this.rowMetadata.set(row, metadata);
1648
1664
  for (const column of this.columns) {
1649
1665
  const value = getNestedValue(row, column.field);
1650
- if (isDisplayColumn(column)) {
1651
- if (typeof column.sortValue === "function") {
1652
- metadata.sortValues[column.field] = column.sortValue(value);
1653
- } else if (typeof value === "string") {
1654
- metadata.sortValues[column.field] = value.toLocaleLowerCase();
1655
- } else if (isCompareable(value)) {
1656
- metadata.sortValues[column.field] = value;
1657
- } else {
1658
- metadata.sortValues[column.field] = String(value);
1659
- }
1666
+ if (typeof column.sorter === "function") {
1667
+ metadata.sortValues[column.field] = column.sorter(value);
1668
+ } else if (typeof value === "string") {
1669
+ metadata.sortValues[column.field] = value.toLocaleLowerCase();
1670
+ } else if (isCompareable(value)) {
1671
+ metadata.sortValues[column.field] = value;
1672
+ } else {
1673
+ metadata.sortValues[column.field] = String(value);
1660
1674
  }
1661
1675
  if (typeof value === "string") {
1662
1676
  metadata.searchValues[column.field] = value.toLocaleLowerCase();
@@ -1682,29 +1696,12 @@ var YatlTable = class extends LitElement {
1682
1696
  this.queryTokens.push(...this.searchTokenizer(this.searchQuery));
1683
1697
  }
1684
1698
  }
1685
- getColumns(kind = "all") {
1686
- switch (kind) {
1687
- case "display":
1688
- return this.columns.filter(isDisplayColumn);
1689
- case "internal":
1690
- return this.columns.filter(isInternalColumn);
1691
- case "all":
1692
- return this.columns;
1693
- }
1694
- }
1695
- getColumnData(columns) {
1696
- return columns.map((column) => ({
1697
- field: column.field,
1698
- options: column,
1699
- state: this.getColumnState(column.field)
1700
- }));
1701
- }
1702
1699
  /**
1703
1700
  * Gets the width of each column in the
1704
1701
  * order they will appear in the grid.
1705
1702
  */
1706
1703
  getGridWidths() {
1707
- return this.columnOrder.map((field) => this.getColumnState(field)).filter((state2) => state2.visible).map((state2) => state2.width);
1704
+ return this.columnOrder.map((field) => this.getOrCreateColumnState(field)).filter((state2) => state2.visible).map((state2) => state2.width);
1708
1705
  }
1709
1706
  scheduleSave() {
1710
1707
  window.clearTimeout(this.saveTimer);
@@ -1712,16 +1709,20 @@ var YatlTable = class extends LitElement {
1712
1709
  this.saveStateToStorage();
1713
1710
  }, STATE_SAVE_DEBOUNCE);
1714
1711
  }
1715
- getColumnState(field) {
1716
- let state2 = findColumn(field, this._columnStates);
1712
+ /**
1713
+ * Gets the column state associated with the given field.
1714
+ * If the state doesn't exist, a default state will be created.
1715
+ */
1716
+ getOrCreateColumnState(field) {
1717
+ let state2 = this._columnStateMap.get(field);
1717
1718
  if (!state2) {
1718
1719
  state2 = {
1719
1720
  field,
1720
1721
  visible: true,
1721
- sort: null,
1722
- width: null
1722
+ width: null,
1723
+ sort: null
1723
1724
  };
1724
- this._columnStates.push(state2);
1725
+ this._columnStateMap.set(field, state2);
1725
1726
  }
1726
1727
  return state2;
1727
1728
  }
@@ -1815,7 +1816,7 @@ var YatlTable = class extends LitElement {
1815
1816
  this.tableElement.querySelectorAll(".header .cell").forEach((element) => {
1816
1817
  const field2 = element.dataset.field;
1817
1818
  if (field2) {
1818
- const state2 = this.getColumnState(field2);
1819
+ const state2 = this.getOrCreateColumnState(field2);
1819
1820
  if (state2) {
1820
1821
  state2.width = element.getBoundingClientRect().width;
1821
1822
  }
@@ -1943,7 +1944,6 @@ export {
1943
1944
  YatlStateChangeEvent,
1944
1945
  YatlTable,
1945
1946
  createRegexTokenizer,
1946
- findColumn,
1947
1947
  whitespaceTokenizer
1948
1948
  };
1949
1949
  //# sourceMappingURL=index.mjs.map