lightning-base-components 1.14.2-alpha → 1.14.6-alpha

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 (82) hide show
  1. package/metadata/raptor.json +33 -1
  2. package/package.json +20 -4
  3. package/scopedImports/@salesforce-label-LightningDualListbox.movedOptionsPlural.js +1 -0
  4. package/scopedImports/@salesforce-label-LightningDualListbox.movedOptionsSingular.js +1 -0
  5. package/scopedImports/@salesforce-label-LightningErrorMessage.validitySelectAtleastOne.js +1 -0
  6. package/scopedImports/@salesforce-label-LightningMap.titleWithAddress.js +1 -0
  7. package/scopedImports/@salesforce-label-LightningModalBase.cancelandclose.js +1 -0
  8. package/src/lightning/ariaObserver/__component__/ariaObserver.spec.js +9 -0
  9. package/src/lightning/ariaObserver/__docs__/ariaObserver.md +142 -0
  10. package/src/lightning/ariaObserver/ariaObserver.js +24 -35
  11. package/src/lightning/baseFormattedText/baseFormattedText.html +6 -1
  12. package/src/lightning/baseFormattedText/baseFormattedText.js +5 -0
  13. package/src/lightning/buttonMenu/keyboard.js +0 -10
  14. package/src/lightning/card/card.html +6 -0
  15. package/src/lightning/checkboxGroup/checkboxGroup.html +2 -2
  16. package/src/lightning/checkboxGroup/checkboxGroup.js +6 -1
  17. package/src/lightning/colorPickerCustom/colorPickerCustom.js +20 -1
  18. package/src/lightning/datatable/__docs__/datatable.md +55 -0
  19. package/src/lightning/datatable/__examples__/basic/basic.html +1 -1
  20. package/src/lightning/datatable/__examples__/withInfiniteLoading/fetchDataHelper.js +21 -0
  21. package/src/lightning/datatable/__examples__/withInfiniteLoading/withInfiniteLoading.html +13 -0
  22. package/src/lightning/datatable/__examples__/withInfiniteLoading/withInfiniteLoading.js +42 -0
  23. package/src/lightning/datatable/autoWidthStrategy.js +170 -61
  24. package/src/lightning/datatable/{resizer.js → columnResizer.js} +0 -0
  25. package/src/lightning/datatable/columnWidthManager.js +226 -44
  26. package/src/lightning/datatable/columns-shared.js +1 -1
  27. package/src/lightning/datatable/datatable.js +104 -33
  28. package/src/lightning/datatable/errors.js +20 -9
  29. package/src/lightning/datatable/fixedWidthStrategy.js +43 -8
  30. package/src/lightning/datatable/headerActions.js +77 -49
  31. package/src/lightning/datatable/infiniteLoading.js +100 -28
  32. package/src/lightning/datatable/inlineEdit.js +505 -379
  33. package/src/lightning/datatable/inlineEditShared.js +24 -0
  34. package/src/lightning/datatable/keyboard.js +162 -127
  35. package/src/lightning/datatable/renderManager.js +208 -133
  36. package/src/lightning/datatable/{datatableResizeObserver.js → resizeObserver.js} +46 -29
  37. package/src/lightning/datatable/resizeSensor.js +8 -0
  38. package/src/lightning/datatable/rowLevelActions.js +17 -13
  39. package/src/lightning/datatable/rowNumber.js +54 -20
  40. package/src/lightning/datatable/rowSelection.js +760 -0
  41. package/src/lightning/datatable/rowSelectionShared.js +79 -0
  42. package/src/lightning/datatable/rows.js +17 -6
  43. package/src/lightning/datatable/state.js +16 -2
  44. package/src/lightning/datatable/templates/div/div.css +4 -0
  45. package/src/lightning/datatable/templates/div/div.html +128 -117
  46. package/src/lightning/datatable/templates/table/table.html +5 -0
  47. package/src/lightning/datatable/utils.js +14 -0
  48. package/src/lightning/datatable/widthManagerShared.js +27 -3
  49. package/src/lightning/datatable/wrapText.js +77 -47
  50. package/src/lightning/dualListbox/dualListbox.html +1 -1
  51. package/src/lightning/dualListbox/dualListbox.js +42 -0
  52. package/src/lightning/formattedDateTime/__docs__/formattedDateTime.md +36 -3
  53. package/src/lightning/formattedDateTime/__examples__/datetime/datetime.html +2 -2
  54. package/src/lightning/formattedDateTime/__examples__/datetime/datetime.js +3 -1
  55. package/src/lightning/formattedDateTime/__examples__/time/time.html +1 -1
  56. package/src/lightning/formattedDateTime/__examples__/time/time.js +3 -1
  57. package/src/lightning/formattedDateTime/formattedDateTime.js +1 -0
  58. package/src/lightning/input/input.html +2 -5
  59. package/src/lightning/inputUtils/validity.js +12 -1
  60. package/src/lightning/pillContainer/__docs__/pillContainer.md +45 -1
  61. package/src/lightning/positionLibrary/positionLibrary.js +31 -43
  62. package/src/lightning/primitiveCellActions/primitiveCellActions.js +69 -12
  63. package/src/lightning/primitiveCellFactory/cellWithStandardLayout.html +13 -11
  64. package/src/lightning/primitiveCellFactory/primitiveCellFactory.js +13 -8
  65. package/src/lightning/primitiveDatatableIeditPanel/primitiveDatatableIeditPanel.html +17 -14
  66. package/src/lightning/primitiveDatatableIeditPanel/primitiveDatatableIeditPanel.js +167 -98
  67. package/src/lightning/primitiveDatatableIeditTypeFactory/primitiveDatatableIeditTypeFactory.js +94 -69
  68. package/src/lightning/primitiveDatatableStatusBar/primitiveDatatableStatusBar.html +4 -4
  69. package/src/lightning/primitiveDatatableStatusBar/primitiveDatatableStatusBar.js +4 -4
  70. package/src/lightning/primitiveHeaderActions/primitiveHeaderActions.js +99 -37
  71. package/src/lightning/progressIndicator/progressIndicator.js +1 -1
  72. package/src/lightning/progressStep/progressStep.js +1 -1
  73. package/src/lightning/spinner/spinner.html +1 -1
  74. package/src/lightning/spinner/spinner.js +12 -0
  75. package/src/lightning/staticMap/staticMap.html +1 -0
  76. package/src/lightning/staticMap/staticMap.js +39 -2
  77. package/src/lightning/utils/classSet.js +4 -1
  78. package/src/lightning/utilsPrivate/phonify.js +1 -1
  79. package/scopedImports/@salesforce-label-LightningModalBase.close.js +0 -1
  80. package/src/lightning/datatable/inlineEdit-shared.js +0 -14
  81. package/src/lightning/datatable/selector-shared.js +0 -38
  82. package/src/lightning/datatable/selector.js +0 -527
@@ -9,7 +9,7 @@ import {
9
9
  isSafari,
10
10
  synchronizeAttrs,
11
11
  } from 'lightning/utilsPrivate';
12
- import { LightningDatatableResizeObserver } from './datatableResizeObserver';
12
+ import { LightningDatatableResizeObserver } from './resizeObserver';
13
13
  import { ColumnWidthManager } from './columnWidthManager';
14
14
  import { getDefaultState } from './state';
15
15
  import { getColumns, normalizeColumns, generateHeaderIndexes } from './columns';
@@ -38,11 +38,11 @@ import {
38
38
  getCSSWidthStyleOfTable,
39
39
  updateColumnWidthsMetadata,
40
40
  getResizerDefaultState,
41
- } from './resizer';
41
+ } from './columnResizer';
42
42
  import {
43
43
  syncSelectedRowsKeys,
44
44
  handleRowSelectionChange,
45
- updateSelectionState,
45
+ updateBulkSelectionState,
46
46
  getMaxRowSelection,
47
47
  setMaxRowSelection,
48
48
  getSelectedRowsKeys,
@@ -53,7 +53,7 @@ import {
53
53
  handleDeselectRow,
54
54
  getHideSelectAllCheckbox,
55
55
  getCurrentSelectionLength,
56
- } from './selector';
56
+ } from './rowSelection';
57
57
  import {
58
58
  syncActiveCell,
59
59
  handleKeydownOnCell,
@@ -80,6 +80,9 @@ import {
80
80
  handleKeydownOnTable,
81
81
  addFocusStylesToActiveCell,
82
82
  refocusCellElement,
83
+ isCellElement,
84
+ getActiveCellElement,
85
+ FOCUS_CLASS,
83
86
  } from './keyboard';
84
87
  import {
85
88
  getRowNumberOffset,
@@ -134,6 +137,9 @@ import {
134
137
  import {
135
138
  isViewportRenderingEnabled,
136
139
  setViewportRendering,
140
+ getDTWrapperHeight,
141
+ setFirstVisibleIndex,
142
+ setVirtualize,
137
143
  RenderManager,
138
144
  } from './renderManager';
139
145
 
@@ -144,6 +150,7 @@ import { generateUniqueId } from 'lightning/inputUtils';
144
150
  import DatatableTypes from './types';
145
151
  import labelAriaLiveNavigationMode from '@salesforce/label/LightningDatatable.ariaLiveNavigationMode';
146
152
  import labelAriaLiveActionMode from '@salesforce/label/LightningDatatable.ariaLiveActionMode';
153
+ import { styleToString } from './utils';
147
154
 
148
155
  const i18n = {
149
156
  ariaLiveNavigationMode: labelAriaLiveNavigationMode,
@@ -196,7 +203,6 @@ export default class LightningDatatable extends LightningElement {
196
203
  _privateTypes = {};
197
204
  _privateWidthObserver = null; // Instance of LightningDatatableResizeObserver
198
205
  _renderMode = 'table';
199
- _renderedRowCount = 0;
200
206
  _suppressBottomBar = false;
201
207
 
202
208
  /************************* PUBLIC PROPERTIES *************************/
@@ -332,6 +338,7 @@ export default class LightningDatatable extends LightningElement {
332
338
 
333
339
  set enableInfiniteLoading(value) {
334
340
  setInfiniteLoading(this.state, value);
341
+ handlePrefetch.call(this, this.template, this.state);
335
342
  }
336
343
 
337
344
  /**
@@ -493,6 +500,7 @@ export default class LightningDatatable extends LightningElement {
493
500
  * @type {object}
494
501
  * @property {boolean} viewportRendering - Specifies whether to defer rendering of rows outside the viewport until the user begins scrolling. To use this feature, create a fixed-height container element for lightning-datatable.
495
502
  * @property {number} rowHeight - Specifies the height of a row, in px
503
+ * @property {string} virtualize - specifies whether to enable virtualization. This requires the "role-based" render mode and a fixed-height container for lightning-datatable
496
504
  */
497
505
 
498
506
  /**
@@ -508,10 +516,21 @@ export default class LightningDatatable extends LightningElement {
508
516
 
509
517
  set renderConfig(value) {
510
518
  if (typeof value === 'object' && !isIE11) {
511
- const enableViewportRendering = value.viewportRendering;
512
- setViewportRendering(this.state, enableViewportRendering);
519
+ setViewportRendering(this.state, value.viewportRendering);
513
520
 
514
- this._renderManager.configure(this, value);
521
+ this._renderManager.configure(
522
+ this.state,
523
+ this.getWrapperHeight,
524
+ value
525
+ );
526
+ // if renderConfig already exists, update rendering
527
+ if (this._renderConfig) {
528
+ this._renderManager.updateViewportRendering(
529
+ this.state,
530
+ this.gridContainer,
531
+ true
532
+ );
533
+ }
515
534
  this._renderConfig = value;
516
535
  }
517
536
  }
@@ -536,6 +555,10 @@ export default class LightningDatatable extends LightningElement {
536
555
  validValues: ['default', 'role-based'],
537
556
  });
538
557
  this.state.renderModeRoleBased = this._renderMode === 'role-based';
558
+ this._columnWidthManager.setRenderMode(this.renderMode);
559
+ if (this._renderConfig) {
560
+ setVirtualize(this.state, this._renderConfig.virtualize);
561
+ }
539
562
  updateCellClassForRoleBasedMode(this.state);
540
563
  }
541
564
 
@@ -759,24 +782,40 @@ export default class LightningDatatable extends LightningElement {
759
782
 
760
783
  get computedTableStyle() {
761
784
  if (this._columnWidthManager.isAutoResizingUpdateQueued()) {
762
- return ['table-layout:auto'].join(';');
785
+ return styleToString(['table-layout:auto']);
763
786
  }
764
- return [
787
+ return styleToString([
765
788
  'table-layout:fixed',
766
789
  getCSSWidthStyleOfTable(this.widthsData),
767
- ].join(';');
790
+ ]);
768
791
  }
769
792
 
793
+ /**
794
+ * Resets row-number counter to offset to show
795
+ * correct value when row number column is present
796
+ * and adds necessary position and height styles when
797
+ * virtualization is enabled
798
+ */
770
799
  get computedTbodyStyle() {
800
+ const style = [];
801
+ const { firstVisibleIndex, bufferSize, virtualize, rows, rowHeight } =
802
+ this.state;
771
803
  if (
772
804
  hasRowNumberColumn(this.state) &&
773
805
  getRowNumberOffset(this.state) >= 0
774
806
  ) {
775
- return (
776
- 'counter-reset: row-number ' + getRowNumberOffset(this.state)
807
+ const firstRenderedRow = Math.max(
808
+ firstVisibleIndex - bufferSize,
809
+ 0
777
810
  );
811
+ const rowNumber = firstRenderedRow + getRowNumberOffset(this.state);
812
+ style.push(`counter-reset: row-number ${rowNumber}`);
813
+ }
814
+ if (virtualize) {
815
+ const length = rows.length;
816
+ style.push('position: relative', `height:${length * rowHeight}px`);
778
817
  }
779
- return '';
818
+ return styleToString(style);
780
819
  }
781
820
 
782
821
  /**
@@ -812,9 +851,7 @@ export default class LightningDatatable extends LightningElement {
812
851
  styles['overflow-x'] = 'auto';
813
852
  }
814
853
 
815
- return Object.entries(styles)
816
- .map(([key, value]) => key + ':' + value)
817
- .join(';');
854
+ return styleToString(styles);
818
855
  }
819
856
 
820
857
  /**
@@ -897,10 +934,16 @@ export default class LightningDatatable extends LightningElement {
897
934
  }
898
935
 
899
936
  get renderedRows() {
937
+ const { virtualize, rows, renderedRowCount } = this.state;
938
+ if (virtualize) {
939
+ const { firstIndex, lastIndex } =
940
+ this._renderManager.getRenderedRange(this.state);
941
+ return rows.slice(firstIndex, lastIndex);
942
+ }
900
943
  if (this.viewportRendering && !isIE11) {
901
- return this.state.rows.slice(0, this._renderedRowCount);
944
+ return rows.slice(0, renderedRowCount);
902
945
  }
903
- return this.state.rows;
946
+ return rows;
904
947
  }
905
948
 
906
949
  get showSelectAllCheckbox() {
@@ -931,11 +974,11 @@ export default class LightningDatatable extends LightningElement {
931
974
  super();
932
975
 
933
976
  this._privateTypes = new DatatableTypes(this.constructor.customTypes);
934
-
935
977
  this._columnWidthManager = new ColumnWidthManager(this.widthsData);
936
978
  this.updateRowsAndCellIndexes = updateRowsAndCellIndexes.bind(this);
937
979
 
938
980
  this._renderManager = new RenderManager();
981
+ this.getWrapperHeight = getDTWrapperHeight.bind(this);
939
982
  }
940
983
 
941
984
  /**
@@ -1081,6 +1124,10 @@ export default class LightningDatatable extends LightningElement {
1081
1124
  if (fireResizeEvent) {
1082
1125
  this.fireOnResize(false);
1083
1126
  }
1127
+
1128
+ const role = '[role="' + this.computedTableRole + '"]';
1129
+
1130
+ this.template.querySelector(role).style = this.computedTableStyle;
1084
1131
  }
1085
1132
 
1086
1133
  // Managing the cell widths is only required for the role-based table
@@ -1094,17 +1141,35 @@ export default class LightningDatatable extends LightningElement {
1094
1141
  this._customerSelectedRows = null;
1095
1142
  // set the previous focused cell to null after render is done
1096
1143
  resetCellToFocusFromPrev(state);
1144
+ // reset focus styles on re-render
1145
+ if (state.activeCell && state.activeCell.focused) {
1146
+ const cellElement = getActiveCellElement(template, state);
1147
+ if (
1148
+ cellElement &&
1149
+ cellElement.parentElement &&
1150
+ !cellElement.parentElement.classList.contains(FOCUS_CLASS)
1151
+ ) {
1152
+ setFocusActiveCell(template, state, null, null, false);
1153
+ }
1154
+ }
1097
1155
 
1098
- if (this.viewportRendering) {
1099
- this._renderManager.connectResizeObserver(this);
1156
+ if (this.viewportRendering || state.virtualize) {
1157
+ const resizeTarget = this.template.querySelector(
1158
+ 'div.dt-outer-container'
1159
+ );
1160
+ this._renderManager.connectResizeObserver(resizeTarget);
1100
1161
  if (!this._renderManager.hasWrapperHeight()) {
1101
- this._renderManager.updateWrapperHeight(this);
1162
+ this._renderManager.updateWrapperHeight(this.getWrapperHeight);
1102
1163
 
1103
1164
  // Reset the row count if we already had one before updating the wrapper height.
1104
1165
  // This can happen if the number of rows was calculated before the datatable
1105
1166
  // was rendered.
1106
- if (this._renderedRowCount) {
1107
- this._renderManager.updateViewportRendering(this, true);
1167
+ if (this.state.renderedRowCount) {
1168
+ this._renderManager.updateViewportRendering(
1169
+ this.state,
1170
+ this.gridContainer,
1171
+ true
1172
+ );
1108
1173
  }
1109
1174
  }
1110
1175
  }
@@ -1187,9 +1252,10 @@ export default class LightningDatatable extends LightningElement {
1187
1252
  }
1188
1253
 
1189
1254
  handleInlineEditPanelScroll.call(this, event);
1190
-
1191
- if (this.viewportRendering) {
1192
- this._renderManager.handleScroll(this, event);
1255
+ if (this.state.virtualize) {
1256
+ setFirstVisibleIndex(this.state, event.target.scrollTop);
1257
+ } else if (this.viewportRendering) {
1258
+ this._renderManager.handleScroll(this.state, event);
1193
1259
  }
1194
1260
  }
1195
1261
 
@@ -1202,8 +1268,9 @@ export default class LightningDatatable extends LightningElement {
1202
1268
  handleCellClick(event) {
1203
1269
  // handles the case when clicking on the margin/pading of the td/th
1204
1270
  const targetTagName = event.target.tagName.toLowerCase();
1271
+ const targetRole = event.target.getAttribute('role');
1205
1272
 
1206
- if (targetTagName === 'td' || targetTagName === 'th') {
1273
+ if (isCellElement(targetTagName, targetRole)) {
1207
1274
  // get the row/col key value from the primitive cell.
1208
1275
  const { rowKeyValue, colKeyValue } =
1209
1276
  event.target.querySelector(':first-child');
@@ -1464,8 +1531,12 @@ export default class LightningDatatable extends LightningElement {
1464
1531
 
1465
1532
  this.updateRowsAndCellIndexes(state);
1466
1533
 
1467
- if (this.viewportRendering) {
1468
- this._renderManager.updateViewportRendering(this);
1534
+ if (this.viewportRendering || state.virtualize) {
1535
+ this._renderManager.updateViewportRendering(
1536
+ this.state,
1537
+ this.gridContainer,
1538
+ !!state.virtualize
1539
+ );
1469
1540
  }
1470
1541
 
1471
1542
  this._columnWidthManager.handleRowNumberOffsetChange(state, widthsData);
@@ -1505,10 +1576,10 @@ export default class LightningDatatable extends LightningElement {
1505
1576
  setDirtyValues(state, this._draftValues);
1506
1577
  updateRowNavigationMode(hadTreeDataTypePreviously, state);
1507
1578
  state.headerIndexes = generateHeaderIndexes(getColumns(state));
1508
- // Updates state.wrapText and when isWrapableType, sets internal header actions
1579
+ // Updates state.wrapText and when isWrappableType, sets internal header actions
1509
1580
  updateHeaderActions(state);
1510
1581
  this.updateRowsAndCellIndexes(state);
1511
- updateSelectionState(state);
1582
+ updateBulkSelectionState(state);
1512
1583
  this._columnWidthManager.handleRowNumberOffsetChange(state, widthsData);
1513
1584
  updateColumnWidthsMetadata(getColumns(state), widthsData);
1514
1585
  // set the celltofocus next to null if the column still exists after indexes calculation
@@ -1,25 +1,36 @@
1
- export function getErrorsState() {
2
- return {
3
- errors: {
4
- rows: {},
5
- table: {},
6
- },
7
- };
8
- }
1
+ // Default empty error state
2
+ const DEFAULT_ERROR_STATE = {
3
+ rows: {},
4
+ table: {},
5
+ };
9
6
 
7
+ /**
8
+ * Retrieves the errors object from datatable's state object
9
+ * Returns the set of row-level errors and table-level errors
10
+ */
10
11
  export function getErrors(state) {
11
12
  return state.errors;
12
13
  }
13
14
 
15
+ /**
16
+ * Sets the row-level errors and table-level errors in datatable's state object
17
+ * Errors being set here overwrite the previous error object in the state
18
+ */
14
19
  export function setErrors(state, errors) {
15
- return (state.errors = Object.assign({}, getErrorsState(), errors));
20
+ return (state.errors = Object.assign({}, DEFAULT_ERROR_STATE, errors));
16
21
  }
17
22
 
23
+ /**
24
+ * Retrieves the row-level errors of a particular row from datatable's state object
25
+ */
18
26
  export function getRowError(state, rowKey) {
19
27
  const rows = getErrors(state).rows;
20
28
  return (rows && rows[rowKey]) || {};
21
29
  }
22
30
 
31
+ /**
32
+ * Retrieves the table-level errors from the datatable's state object
33
+ */
23
34
  export function getTableError(state) {
24
35
  return getErrors(state).table || {};
25
36
  }
@@ -3,13 +3,26 @@ import {
3
3
  getColumnWidthFromDef,
4
4
  } from './widthManagerShared';
5
5
 
6
+ /**
7
+ * Determines the expected table width
8
+ *
9
+ * @param {Number} availableWidth The available width for the entire table
10
+ * @param {Object} widthsMetadata The widths metadata object
11
+ * @returns {Number} The expected width of the table
12
+ */
6
13
  function getExpectedTableWidth(availableWidth, widthsMetadata) {
7
14
  const minExpectedTableWidth = getMinExpectedTableWidth(widthsMetadata);
8
- return hasNoFlexibleColumns(widthsMetadata)
15
+ return widthsMetadata.totalFlexibleColumns === 0
9
16
  ? minExpectedTableWidth
10
17
  : Math.max(minExpectedTableWidth, availableWidth);
11
18
  }
12
19
 
20
+ /**
21
+ * Determines the minimum expected table width
22
+ *
23
+ * @param {Object} widthsMetadata The widths metadata object
24
+ * @returns {Number} The minimum expected table width
25
+ */
13
26
  function getMinExpectedTableWidth(widthsMetadata) {
14
27
  const {
15
28
  totalFixedWidth,
@@ -21,21 +34,35 @@ function getMinExpectedTableWidth(widthsMetadata) {
21
34
  return minTotalFlexibleWidth + totalFixedWidth + totalResizedWidth;
22
35
  }
23
36
 
24
- function hasNoFlexibleColumns(widthsMetadata) {
25
- return widthsMetadata.totalFlexibleColumns === 0;
26
- }
27
-
37
+ /**
38
+ * Strategy for columns with defined fixed widths.
39
+ */
28
40
  export class FixedWidthStrategy {
41
+ // Private variables
29
42
  _columnWidthMetaData = {};
30
43
 
44
+ /************************** LIFECYCLE HOOKS **************************/
45
+
31
46
  constructor(minColumnWidth, maxColumnWidth) {
32
47
  this._columnWidthMetaData = { minColumnWidth, maxColumnWidth };
33
48
  }
34
49
 
50
+ /************************** PRIVATE SETTERS **************************/
51
+
52
+ /**
53
+ * Sets the minimum column width
54
+ *
55
+ * @param {Number} value The minimum width
56
+ */
35
57
  set minColumnWidth(value) {
36
58
  this._columnWidthMetaData.minColumnWidth = value;
37
59
  }
38
60
 
61
+ /**
62
+ * Sets the maximum column width
63
+ *
64
+ * @param {Number} value The maximum width
65
+ */
39
66
  set maxColumnWidth(value) {
40
67
  this._columnWidthMetaData.maxColumnWidth = value;
41
68
  }
@@ -43,9 +70,10 @@ export class FixedWidthStrategy {
43
70
  /**
44
71
  * Get adjusted column widths either from defined widths in columnDefs or by dividing total width
45
72
  * equally amongst the possible columns
46
- * @param datatableInterface - interface to datatable with callbacks giving width information
47
- * @param columnDefs - column definitions array with defined widths and other attributes
48
- * @returns {object} with columnWidths: [], expectedTableWidth: (number)
73
+ *
74
+ * @param {Object} datatableInterface Interface to datatable with callbacks giving width information
75
+ * @param {Array} columnDefs Ccolumn definitions array with defined widths and other attributes
76
+ * @returns {Object} columnWidths: [], expectedTableWidth: (number)
49
77
  */
50
78
  getAdjustedColumnWidths(datatableInterface, columnDefs) {
51
79
  const widthsMetadata = getTotalWidthsMetadata(
@@ -73,6 +101,13 @@ export class FixedWidthStrategy {
73
101
  return { columnWidths, expectedTableWidth };
74
102
  }
75
103
 
104
+ /**
105
+ * Determines the expected flexible column width
106
+ *
107
+ * @param {Object} widthsMetadata The widths metadata object
108
+ * @param {Number} totalTableWidth The total available width for the table
109
+ * @returns {Number} The column width
110
+ */
76
111
  _getFlexibleColumnWidth(widthsMetadata, totalTableWidth) {
77
112
  const {
78
113
  totalFixedWidth,
@@ -1,49 +1,31 @@
1
1
  import { unwrap } from 'lwc';
2
2
  import { getUserColumnIndex, getColumns } from './columns';
3
- import * as wraptext from './wrapText';
3
+ import { getActions, handleTriggeredAction } from './wrapText';
4
4
 
5
- function handleTriggeredInternalAction(dt, action, colKeyValue) {
6
- wraptext.handleTriggeredAction(dt.state, action, colKeyValue);
7
- dispatchHeaderActionEvent(dt, action, colKeyValue);
8
- }
9
-
10
- function handleTriggeredCustomerAction(dt, action, colKeyValue) {
11
- dispatchHeaderActionEvent(dt, action, colKeyValue);
12
- }
5
+ // Height of a clickable menu item
6
+ const ACTION_REM_HEIGHT = 2.125;
13
7
 
14
- function dispatchHeaderActionEvent(dt, action, colKeyValue) {
15
- const userColumnIndex = getUserColumnIndex(dt.state, colKeyValue);
16
- const customerColumnDefinition = dt.columns[userColumnIndex];
17
-
18
- dt.dispatchEvent(
19
- new CustomEvent('headeraction', {
20
- detail: {
21
- action: unwrap(action),
22
- columnDefinition: unwrap(customerColumnDefinition),
23
- },
24
- })
25
- );
26
- }
8
+ // Height of the menu divider, 1 rem + 1px (1/16px)
9
+ const DIVIDER_REM_HEIGHT = 1.0625;
27
10
 
28
- function getMenuAlignment(columns, index) {
29
- const isLastColumn = index === columns.length - 1;
30
-
31
- return isLastColumn || columns[index + 1].type === 'action'
32
- ? 'auto-right'
33
- : 'auto-left';
34
- }
11
+ /************************** PUBLIC METHODS ***************************/
35
12
 
13
+ /**
14
+ * Merges wrapText internal actions.
15
+ * If there are new internal actions in the future, they may be added here.
16
+ *
17
+ * @param {Object} state The state of the datatable
18
+ * @param {Object} columnDefinition The column definition to extract internal actions from
19
+ * @return {Array} All wrapText internal actions
20
+ */
36
21
  export function getInternalActions(state, columnDefinition) {
37
- // merge all internal actions here
38
- // currently, only wrapText internal actions
39
- // there may be new internal actions in the future
40
- return [...wraptext.getActions(state, columnDefinition)];
22
+ return [...getActions(state, columnDefinition)];
41
23
  }
42
24
 
43
25
  /**
44
26
  * Overrides the actions with the internal ones, plus the customer ones.
45
27
  *
46
- * @param {Object} state The state of the datatable.
28
+ * @param {Object} state The state of the datatable
47
29
  */
48
30
  export function updateHeaderActions(state) {
49
31
  const columns = getColumns(state);
@@ -59,31 +41,36 @@ export function updateHeaderActions(state) {
59
41
  });
60
42
  }
61
43
 
44
+ /**
45
+ * For internal actions, handles triggering the action.
46
+ * Then dispatches the header action event.
47
+ *
48
+ * @param {Event} event
49
+ */
62
50
  export function handleHeaderActionTriggered(event) {
51
+ event.stopPropagation();
52
+
63
53
  const { action, actionType, colKeyValue } = event.detail;
64
54
 
65
- event.stopPropagation();
66
- if (actionType === 'customer') {
67
- handleTriggeredCustomerAction(this, action, colKeyValue);
68
- } else {
69
- handleTriggeredInternalAction(this, action, colKeyValue);
55
+ if (actionType !== 'customer') {
56
+ handleTriggeredAction(this.state, action, colKeyValue);
70
57
  }
71
- }
72
58
 
73
- export function getColumnActionsDefaultState() {
74
- return Object.assign({}, wraptext.getDefaultState());
59
+ dispatchHeaderActionEvent(this, action, colKeyValue);
75
60
  }
76
61
 
77
- // in rem, the height of a clickable menu item
78
- const ACTION_HEIGHT = 2.125;
79
- // 1 rem + 1px (1/16px), height of the menu divider
80
- const DIVIDER_HEIGHT = 1.0625;
81
-
62
+ /**
63
+ * Calculates the size and positioning of the header action
64
+ * menu when it is opened.
65
+ *
66
+ * @param {Event} event
67
+ */
82
68
  export function handleHeaderActionMenuOpening(event) {
83
69
  event.stopPropagation();
84
70
  event.preventDefault();
85
- const actionsHeight = event.detail.actionsCount * ACTION_HEIGHT;
86
- const dividersHeight = event.detail.dividersCount * DIVIDER_HEIGHT;
71
+
72
+ const actionsHeight = event.detail.actionsCount * ACTION_REM_HEIGHT;
73
+ const dividersHeight = event.detail.dividersCount * DIVIDER_REM_HEIGHT;
87
74
  const wrapperHeight = 1;
88
75
  this._actionsMinHeightStyle = `min-height:${
89
76
  actionsHeight + dividersHeight + wrapperHeight
@@ -91,6 +78,47 @@ export function handleHeaderActionMenuOpening(event) {
91
78
  event.detail.saveContainerPosition(this.getViewableRect());
92
79
  }
93
80
 
81
+ /**
82
+ * Resets header action menu height when closed.
83
+ */
94
84
  export function handleHeaderActionMenuClosed() {
95
85
  this._actionsMinHeightStyle = '';
96
86
  }
87
+
88
+ /************************** PRIVATE METHODS ***************************/
89
+
90
+ /**
91
+ * Dispatches the `headeraction` event.
92
+ *
93
+ * @param {Object} dt The datatable
94
+ * @param {Object} action The action to dispatch
95
+ * @param {String} colKeyValue The column to dispatch the action on
96
+ */
97
+ function dispatchHeaderActionEvent(dt, action, colKeyValue) {
98
+ const userColumnIndex = getUserColumnIndex(dt.state, colKeyValue);
99
+ const customerColumnDefinition = dt.columns[userColumnIndex];
100
+
101
+ dt.dispatchEvent(
102
+ new CustomEvent('headeraction', {
103
+ detail: {
104
+ action: unwrap(action),
105
+ columnDefinition: unwrap(customerColumnDefinition),
106
+ },
107
+ })
108
+ );
109
+ }
110
+
111
+ /**
112
+ * Determines the menu alignment based on column placement.
113
+ *
114
+ * @param {Array} columns Array of all the columns
115
+ * @param {Integer} index The current column index to check
116
+ * @return {String} The computed alignment
117
+ */
118
+ function getMenuAlignment(columns, index) {
119
+ const isLastColumn = index === columns.length - 1;
120
+
121
+ return isLastColumn || columns[index + 1].type === 'action'
122
+ ? 'auto-right'
123
+ : 'auto-left';
124
+ }