lightning-base-components 1.13.9-alpha → 1.14.3-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 (83) hide show
  1. package/metadata/raptor.json +1 -0
  2. package/package.json +21 -1
  3. package/scopedImports/@salesforce-internal-core.appVersion.js +1 -1
  4. package/scopedImports/@salesforce-label-LightningDualListbox.movedOptionsPlural.js +1 -0
  5. package/scopedImports/@salesforce-label-LightningDualListbox.movedOptionsSingular.js +1 -0
  6. package/scopedImports/@salesforce-label-LightningErrorMessage.validitySelectAtleastOne.js +1 -0
  7. package/scopedImports/@salesforce-label-LightningLookup.recentItems.js +1 -0
  8. package/scopedImports/@salesforce-label-LightningMap.titleWithAddress.js +1 -0
  9. package/src/lightning/ariaObserver/__component__/ariaObserver.spec.js +103 -0
  10. package/src/lightning/ariaObserver/__docs__/ariaObserver.md +142 -0
  11. package/src/lightning/{utilsPrivate/contentMutation.js → ariaObserver/ariaObserver.js} +51 -78
  12. package/src/lightning/baseCombobox/baseCombobox.html +1 -0
  13. package/src/lightning/baseCombobox/baseCombobox.js +14 -1
  14. package/src/lightning/buttonMenu/keyboard.js +0 -10
  15. package/src/lightning/card/card.html +6 -0
  16. package/src/lightning/checkboxGroup/checkboxGroup.html +2 -2
  17. package/src/lightning/checkboxGroup/checkboxGroup.js +6 -1
  18. package/src/lightning/colorPickerCustom/colorPickerCustom.js +20 -1
  19. package/src/lightning/combobox/combobox.css +12 -0
  20. package/src/lightning/combobox/combobox.html +1 -0
  21. package/src/lightning/datatable/__docs__/datatable.md +55 -0
  22. package/src/lightning/datatable/__examples__/basic/basic.html +1 -1
  23. package/src/lightning/datatable/columnWidthManager.js +7 -3
  24. package/src/lightning/datatable/columns-shared.js +1 -1
  25. package/src/lightning/datatable/datatable.js +122 -40
  26. package/src/lightning/datatable/errors.js +20 -9
  27. package/src/lightning/datatable/headerActions.js +77 -49
  28. package/src/lightning/datatable/inlineEdit.js +520 -373
  29. package/src/lightning/datatable/inlineEditShared.js +24 -0
  30. package/src/lightning/datatable/keyboard.js +1077 -933
  31. package/src/lightning/datatable/renderManager.js +241 -129
  32. package/src/lightning/datatable/resizer.js +91 -108
  33. package/src/lightning/datatable/rowLevelActions.js +17 -13
  34. package/src/lightning/datatable/rowNumber.js +54 -20
  35. package/src/lightning/datatable/rowSelection.js +760 -0
  36. package/src/lightning/datatable/rowSelectionShared.js +79 -0
  37. package/src/lightning/datatable/rows.js +16 -5
  38. package/src/lightning/datatable/state.js +10 -10
  39. package/src/lightning/datatable/templates/div/div.css +23 -0
  40. package/src/lightning/datatable/templates/div/div.html +6 -5
  41. package/src/lightning/datatable/templates/table/table.html +4 -4
  42. package/src/lightning/datatable/utils.js +14 -0
  43. package/src/lightning/datatable/widthManagerShared.js +1 -1
  44. package/src/lightning/dualListbox/dualListbox.html +1 -1
  45. package/src/lightning/dualListbox/dualListbox.js +42 -0
  46. package/src/lightning/iconSvgTemplates/buildTemplates/templates.js +2 -1
  47. package/src/lightning/iconSvgTemplates/buildTemplates/utility/contract_alt.html +1 -2
  48. package/src/lightning/iconSvgTemplates/buildTemplates/utility/contract_doc.html +8 -0
  49. package/src/lightning/iconSvgTemplatesRtl/buildTemplates/templates.js +2 -1
  50. package/src/lightning/iconSvgTemplatesRtl/buildTemplates/utility/contract_alt.html +1 -2
  51. package/src/lightning/iconSvgTemplatesRtl/buildTemplates/utility/contract_doc.html +8 -0
  52. package/src/lightning/iconSvgTemplatesUtility/buildTemplates/templates.js +2 -1
  53. package/src/lightning/iconSvgTemplatesUtility/buildTemplates/utility/contract_alt.html +1 -2
  54. package/src/lightning/iconSvgTemplatesUtility/buildTemplates/utility/contract_doc.html +8 -0
  55. package/src/lightning/iconSvgTemplatesUtilityRtl/buildTemplates/templates.js +2 -1
  56. package/src/lightning/iconSvgTemplatesUtilityRtl/buildTemplates/utility/contract_alt.html +1 -2
  57. package/src/lightning/iconSvgTemplatesUtilityRtl/buildTemplates/utility/contract_doc.html +8 -0
  58. package/src/lightning/input/input.html +0 -1
  59. package/src/lightning/input/input.js +69 -48
  60. package/src/lightning/inputUtils/validity.js +12 -1
  61. package/src/lightning/pillContainer/__docs__/pillContainer.md +45 -1
  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 +169 -80
  67. package/src/lightning/primitiveDatatableIeditTypeFactory/primitiveDatatableIeditTypeFactory.js +97 -62
  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/primitiveHeaderFactory/nonsortableHeader.html +5 -4
  72. package/src/lightning/primitiveHeaderFactory/primitiveHeaderFactory.js +46 -46
  73. package/src/lightning/primitiveHeaderFactory/selectableHeader.html +25 -23
  74. package/src/lightning/primitiveHeaderFactory/sortableHeader.html +13 -9
  75. package/src/lightning/progressIndicator/progressIndicator.js +4 -6
  76. package/src/lightning/progressStep/progressStep.js +31 -22
  77. package/src/lightning/staticMap/staticMap.html +1 -0
  78. package/src/lightning/staticMap/staticMap.js +39 -2
  79. package/src/lightning/utils/classSet.js +4 -1
  80. package/src/lightning/utilsPrivate/utilsPrivate.js +12 -1
  81. package/src/lightning/datatable/inlineEdit-shared.js +0 -14
  82. package/src/lightning/datatable/selector-shared.js +0 -38
  83. package/src/lightning/datatable/selector.js +0 -527
@@ -1,3 +1,15 @@
1
1
  :host {
2
2
  display: block;
3
3
  }
4
+
5
+ /**
6
+ This is adding the red border around the combobox input when there's an error
7
+ Should be removed once SLDS has added support for this (@W-9240038)
8
+ */
9
+ :host.slds-has-error {
10
+ --slds-c-input-color-border:#ea001e;
11
+ --slds-c-input-shadow:#ea001e 0 0 0 1px inset;
12
+ --slds-c-input-color-background:var(--slds-c-input-color-background, var(--sds-c-input-color-background, white));
13
+ --slds-c-input-text-color:var(--slds-c-input-text-color, var(--sds-c-input-text-color), #74747);
14
+ }
15
+
@@ -15,6 +15,7 @@
15
15
  placeholder={placeholder}
16
16
  items={_items}
17
17
  input-text={_selectedLabel}
18
+ input-label={label}
18
19
  input-icon-size="xx-small"
19
20
  input-icon-name="utility:down"
20
21
  show-dropdown-activity-indicator={spinnerActive}
@@ -244,6 +244,28 @@ Valid data types and their supported attributes include:
244
244
  | text | Displays text using [lightning-formatted-text](bundle/lightning-formatted-text/). This is the default data type. | linkify |
245
245
  | url | Displays a URL using [lightning-formatted-url](bundle/lightning-formatted-url/) | label, target, tooltip |
246
246
 
247
+ In some situations, multiple columns reference the same `fieldName` but have different `fieldApiNames` and different ways of working with the field information. To give a column a unique ID when using the same field name for two columns, use the attribute `columnKey` instead of `fieldName` on one of the column definitions.
248
+
249
+ ```javascript
250
+ get columns() {
251
+ return [
252
+ // Column using 'fieldName' as identifier
253
+ {
254
+ label: 'Lead',
255
+ fieldName: 'leadId',
256
+ ...
257
+ },
258
+ // Column using 'columnKey' as identifier
259
+ {
260
+ label: 'Company',
261
+ columnKey: 'leadCompany',
262
+ fieldName: 'leadId',
263
+ ...
264
+ }
265
+ ]
266
+ }
267
+ ```
268
+
247
269
  #### Custom Formatting Examples
248
270
 
249
271
  To customize the formatting based on the data type, pass in the attributes for
@@ -494,6 +516,21 @@ const columns = [
494
516
 
495
517
  Custom classes are currently not supported. To apply custom styling on your datatable cells, create a custom data type and then apply your custom CSS classes. See [Custom Data Type Layout and Styles](docs/component-library/documentation/lwc/lwc.data_table_custom_types_styling).
496
518
 
519
+ #### Displaying Indicators for Read-Only Fields
520
+
521
+ You can display a lock icon on read-only fields to specify they're not editable. To specify that a column's field as read-only, set the column attribute `editable` to `false` and the column attribute `displayReadOnlyIcon` to `true` in the associated column definition. This example displays a lock icon on each field in a column called "Website."
522
+
523
+ ```javascript
524
+ const columns = [
525
+ {
526
+ label: 'Website',
527
+ fieldName: 'website',
528
+ type: 'url',
529
+ editable: false,
530
+ displayReadOnlyIcon: true,
531
+ }
532
+ ```
533
+
497
534
  #### Using Infinite Scrolling to Load More Rows
498
535
 
499
536
  Infinite scrolling enables you to load a subset of data and then display more
@@ -1031,6 +1068,24 @@ handleSave(event) {
1031
1068
  }
1032
1069
  ```
1033
1070
 
1071
+ You can also program an external element, such as a button, to open an inline edit panel on the currently active cell or next editable cell in the datatable. Invoke the `openInlineEdit()` method in the external element that should direct a user to the first editable cell in your datatable component.
1072
+
1073
+ This example opens a datatable cell for inline edit when the user clicks an "Edit" button.
1074
+
1075
+ ```javascript
1076
+ import { LightningElement } from 'lwc';
1077
+ export default class DatatableWithInlineEdit extends LightningElement {
1078
+ data = [];
1079
+ columns = columns;
1080
+ rowOffset = 0;
1081
+
1082
+ handleClick() {
1083
+ const dt = this.template.querySelector('lightning-datatable');
1084
+ dt.openInlineEdit();
1085
+ }
1086
+ }
1087
+ ```
1088
+
1034
1089
  For more information, see [Display Data in a Table with Inline Editing](docs/component-library/documentation/lwc/lwc.data_table_inline_edit).
1035
1090
 
1036
1091
  #### Displaying Errors
@@ -5,5 +5,5 @@
5
5
  data={data}
6
6
  columns={columns}>
7
7
  </lightning-datatable>
8
- </div>
8
+ </div>
9
9
  </template>
@@ -13,7 +13,7 @@ import {
13
13
  import {
14
14
  getColumnWidthFromDef,
15
15
  getDomWidth,
16
- getWidthStyle,
16
+ buildCSSWidthStyle,
17
17
  } from './widthManagerShared';
18
18
  import { isRTL } from 'lightning/utilsPrivate';
19
19
 
@@ -35,7 +35,7 @@ export function computeColumnWidths(adjustedWidths, columnDefs, widthsData) {
35
35
  const newWidth = columnWidths[index];
36
36
  widthsData.columnWidths[index] = newWidth;
37
37
  columnDef.columnWidth = newWidth;
38
- columnDef.style = getWidthStyle(newWidth);
38
+ columnDef.style = buildCSSWidthStyle(newWidth);
39
39
 
40
40
  // In RTL, we need to explicitly position the column headers.
41
41
  // We do this by providing the offset (in pixels) from the start of the table.
@@ -312,7 +312,11 @@ export class ColumnWidthManager {
312
312
  return [];
313
313
  },
314
314
  getTableElementWidth() {
315
- const tableElement = root.querySelector(TABLE_SEL);
315
+ // TODO: Figure out a clean way to retrieve and use the correct selectors
316
+ // Currently outside scope of this work. Should be addressed in W-8540110
317
+ const tableElement =
318
+ root.querySelector(TABLE_SEL) ||
319
+ root.querySelector('[role="grid"]');
316
320
  return getDomWidth(tableElement);
317
321
  },
318
322
  };
@@ -4,7 +4,7 @@
4
4
  * which also has a dependency on `columns.js` for `getColumnName()`.
5
5
  *
6
6
  * We split out some of the functions that could cause circular dependencies with
7
- * `column.js` into the `*-shared.js` files. `inlineEdit-shared.js` is another.
7
+ * `column.js` into the `*-shared.js` files. `inlineEditShared.js` is another.
8
8
  */
9
9
 
10
10
  export function getColumnName(column) {
@@ -35,14 +35,14 @@ import {
35
35
  getColumnsWidths,
36
36
  resizeColumnWithDelta,
37
37
  getCustomerColumnWidths,
38
- getTableWidthStyle,
38
+ getCSSWidthStyleOfTable,
39
39
  updateColumnWidthsMetadata,
40
40
  getResizerDefaultState,
41
41
  } from './resizer';
42
42
  import {
43
43
  syncSelectedRowsKeys,
44
44
  handleRowSelectionChange,
45
- updateSelectionState,
45
+ updateBulkSelectionState,
46
46
  getMaxRowSelection,
47
47
  setMaxRowSelection,
48
48
  getSelectedRowsKeys,
@@ -53,10 +53,10 @@ import {
53
53
  handleDeselectRow,
54
54
  getHideSelectAllCheckbox,
55
55
  getCurrentSelectionLength,
56
- } from './selector';
56
+ } from './rowSelection';
57
57
  import {
58
58
  syncActiveCell,
59
- handleCellKeydown,
59
+ handleKeydownOnCell,
60
60
  updateActiveCell,
61
61
  setBlurActiveCell,
62
62
  setFocusActiveCell,
@@ -67,7 +67,7 @@ import {
67
67
  updateTabIndexActiveRow,
68
68
  unsetRowNavigationMode,
69
69
  updateRowNavigationMode,
70
- handleDatatableLosedFocus,
70
+ handleDatatableFocusOut,
71
71
  handleDatatableFocusIn,
72
72
  updateTabIndexRow,
73
73
  getIndexesActiveCell,
@@ -77,9 +77,10 @@ import {
77
77
  resetCellToFocusFromPrev,
78
78
  datatableHasFocus,
79
79
  setCellClickedForFocus,
80
- handleKeyDown,
80
+ handleKeydownOnTable,
81
81
  addFocusStylesToActiveCell,
82
82
  refocusCellElement,
83
+ isCellElement,
83
84
  } from './keyboard';
84
85
  import {
85
86
  getRowNumberOffset,
@@ -134,7 +135,13 @@ import {
134
135
  import {
135
136
  isViewportRenderingEnabled,
136
137
  setViewportRendering,
138
+ getDTRows,
139
+ getDTRenderedRowCount,
140
+ setDTRenderedRowCount,
141
+ getDTWrapperHeight,
142
+ normalizeVirtualization,
137
143
  RenderManager,
144
+ DEFAULT_ROW_HEIGHT,
138
145
  } from './renderManager';
139
146
 
140
147
  import { hasTreeDataType } from './tree';
@@ -144,6 +151,7 @@ import { generateUniqueId } from 'lightning/inputUtils';
144
151
  import DatatableTypes from './types';
145
152
  import labelAriaLiveNavigationMode from '@salesforce/label/LightningDatatable.ariaLiveNavigationMode';
146
153
  import labelAriaLiveActionMode from '@salesforce/label/LightningDatatable.ariaLiveActionMode';
154
+ import { styleToString } from './utils';
147
155
 
148
156
  const i18n = {
149
157
  ariaLiveNavigationMode: labelAriaLiveNavigationMode,
@@ -192,12 +200,14 @@ export default class LightningDatatable extends LightningElement {
192
200
  _customerSelectedRows = null;
193
201
  _datatableId = generateUniqueId('lgt-datatable');
194
202
  _draftValues = [];
203
+ _firstVisibleIndex = 0; // first row that should be visible in viewport, used for virtualization
195
204
  _isResizing = false; // Whether resizing is in progress
196
205
  _privateTypes = {};
197
206
  _privateWidthObserver = null; // Instance of LightningDatatableResizeObserver
198
207
  _renderMode = 'table';
199
208
  _renderedRowCount = 0;
200
209
  _suppressBottomBar = false;
210
+ _virtualize = '';
201
211
 
202
212
  /************************* PUBLIC PROPERTIES *************************/
203
213
 
@@ -448,7 +458,7 @@ export default class LightningDatatable extends LightningElement {
448
458
 
449
459
  set maxColumnWidth(value) {
450
460
  const { state, widthsData } = this;
451
- setMaxColumnWidth(state, widthsData, value);
461
+ setMaxColumnWidth(getColumns(state), widthsData, value);
452
462
  this._columnWidthManager.maxColumnWidth = this.maxColumnWidth;
453
463
  }
454
464
 
@@ -484,7 +494,7 @@ export default class LightningDatatable extends LightningElement {
484
494
 
485
495
  set minColumnWidth(value) {
486
496
  const { state, widthsData } = this;
487
- setMinColumnWidth(state, widthsData, value);
497
+ setMinColumnWidth(getColumns(state), widthsData, value);
488
498
  this._columnWidthManager.minColumnWidth = this.minColumnWidth;
489
499
  }
490
500
 
@@ -493,6 +503,7 @@ export default class LightningDatatable extends LightningElement {
493
503
  * @type {object}
494
504
  * @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
505
  * @property {number} rowHeight - Specifies the height of a row, in px
506
+ * @property {string} virtualize - specifies whether to enable virtualization. This requires the "role-based" render mode and a fixed-height container for lightning-datatable
496
507
  */
497
508
 
498
509
  /**
@@ -508,10 +519,28 @@ export default class LightningDatatable extends LightningElement {
508
519
 
509
520
  set renderConfig(value) {
510
521
  if (typeof value === 'object' && !isIE11) {
511
- const enableViewportRendering = value.viewportRendering;
512
- setViewportRendering(this.state, enableViewportRendering);
522
+ const { viewportRendering, virtualize } = value;
523
+ setViewportRendering(this.state, viewportRendering);
524
+ if (this.state.renderModeRoleBased) {
525
+ this._virtualize = normalizeVirtualization(virtualize);
526
+ }
513
527
 
514
- this._renderManager.configure(this, value);
528
+ this._renderManager.configure(
529
+ this.getRows,
530
+ this.getWrapperHeight,
531
+ this.getRenderedRowCount,
532
+ this.setRenderedRowCount,
533
+ value
534
+ );
535
+ // if renderConfig already exists, update rendering
536
+ if (this._renderConfig) {
537
+ this._renderManager.updateViewportRendering(
538
+ this.state.rows,
539
+ this.setRenderedRowCount,
540
+ this.gridContainer,
541
+ true
542
+ );
543
+ }
515
544
  this._renderConfig = value;
516
545
  }
517
546
  }
@@ -759,23 +788,38 @@ export default class LightningDatatable extends LightningElement {
759
788
 
760
789
  get computedTableStyle() {
761
790
  if (this._columnWidthManager.isAutoResizingUpdateQueued()) {
762
- return ['table-layout:auto'].join(';');
791
+ return styleToString(['table-layout:auto']);
763
792
  }
764
- return ['table-layout:fixed', getTableWidthStyle(this.widthsData)].join(
765
- ';'
766
- );
793
+ return styleToString([
794
+ 'table-layout:fixed',
795
+ getCSSWidthStyleOfTable(this.widthsData),
796
+ ]);
767
797
  }
768
798
 
799
+ /**
800
+ * Resets row-number counter to offset to show
801
+ * correct value when row number column is present
802
+ * and adds necessary position and height styles when
803
+ * virtualization is enabled
804
+ */
769
805
  get computedTbodyStyle() {
806
+ const style = [];
770
807
  if (
771
808
  hasRowNumberColumn(this.state) &&
772
809
  getRowNumberOffset(this.state) >= 0
773
810
  ) {
774
- return (
811
+ style.push(
775
812
  'counter-reset: row-number ' + getRowNumberOffset(this.state)
776
813
  );
777
814
  }
778
- return '';
815
+ if (this._virtualize) {
816
+ const length = this.state.rows.length;
817
+ style.push(
818
+ 'position: relative',
819
+ `height:${length * DEFAULT_ROW_HEIGHT}px`
820
+ );
821
+ }
822
+ return styleToString(style);
779
823
  }
780
824
 
781
825
  /**
@@ -795,7 +839,7 @@ export default class LightningDatatable extends LightningElement {
795
839
  if (this._columnWidthManager.isAutoResizingUpdateQueued()) {
796
840
  return `${minHeight}overflow-x:auto`;
797
841
  }
798
- return `${minHeight}${getTableWidthStyle(this.widthsData)}`;
842
+ return `${minHeight}${getCSSWidthStyleOfTable(this.widthsData)}`;
799
843
  }
800
844
 
801
845
  get scrollerXStyles() {
@@ -811,9 +855,7 @@ export default class LightningDatatable extends LightningElement {
811
855
  styles['overflow-x'] = 'auto';
812
856
  }
813
857
 
814
- return Object.entries(styles)
815
- .map(([key, value]) => key + ':' + value)
816
- .join(';');
858
+ return styleToString(styles);
817
859
  }
818
860
 
819
861
  /**
@@ -896,6 +938,14 @@ export default class LightningDatatable extends LightningElement {
896
938
  }
897
939
 
898
940
  get renderedRows() {
941
+ if (this._virtualize) {
942
+ const { firstIndex, lastIndex } =
943
+ this._renderManager.getRenderedRange(
944
+ this._firstVisibleIndex,
945
+ this._renderedRowCount
946
+ );
947
+ return this.state.rows.slice(firstIndex, lastIndex);
948
+ }
899
949
  if (this.viewportRendering && !isIE11) {
900
950
  return this.state.rows.slice(0, this._renderedRowCount);
901
951
  }
@@ -935,6 +985,10 @@ export default class LightningDatatable extends LightningElement {
935
985
  this.updateRowsAndCellIndexes = updateRowsAndCellIndexes.bind(this);
936
986
 
937
987
  this._renderManager = new RenderManager();
988
+ this.getRenderedRowCount = getDTRenderedRowCount.bind(this);
989
+ this.setRenderedRowCount = setDTRenderedRowCount.bind(this);
990
+ this.getRows = getDTRows.bind(this);
991
+ this.getWrapperHeight = getDTWrapperHeight.bind(this);
938
992
  }
939
993
 
940
994
  /**
@@ -987,7 +1041,7 @@ export default class LightningDatatable extends LightningElement {
987
1041
  // Cell Interaction
988
1042
  this.template.addEventListener(
989
1043
  'privatecellkeydown',
990
- handleCellKeydown.bind(this)
1044
+ handleKeydownOnCell.bind(this)
991
1045
  );
992
1046
 
993
1047
  this.template.addEventListener(
@@ -1094,16 +1148,24 @@ export default class LightningDatatable extends LightningElement {
1094
1148
  // set the previous focused cell to null after render is done
1095
1149
  resetCellToFocusFromPrev(state);
1096
1150
 
1097
- if (this.viewportRendering) {
1098
- this._renderManager.connectResizeObserver(this);
1151
+ if (this.viewportRendering || this._virtualize) {
1152
+ const resizeTarget = this.template.querySelector(
1153
+ 'div.dt-outer-container'
1154
+ );
1155
+ this._renderManager.connectResizeObserver(resizeTarget);
1099
1156
  if (!this._renderManager.hasWrapperHeight()) {
1100
- this._renderManager.updateWrapperHeight(this);
1157
+ this._renderManager.updateWrapperHeight(this.getWrapperHeight);
1101
1158
 
1102
1159
  // Reset the row count if we already had one before updating the wrapper height.
1103
1160
  // This can happen if the number of rows was calculated before the datatable
1104
1161
  // was rendered.
1105
1162
  if (this._renderedRowCount) {
1106
- this._renderManager.updateViewportRendering(this, true);
1163
+ this._renderManager.updateViewportRendering(
1164
+ this.state.rows,
1165
+ this.setRenderedRowCount,
1166
+ this.gridContainer,
1167
+ true
1168
+ );
1107
1169
  }
1108
1170
  }
1109
1171
  }
@@ -1126,15 +1188,15 @@ export default class LightningDatatable extends LightningElement {
1126
1188
  * @param {KeyboardEvent} event - `keydown`
1127
1189
  */
1128
1190
  handleTableKeydown(event) {
1129
- handleKeyDown.call(this, event);
1191
+ handleKeydownOnTable.call(this, event);
1130
1192
  }
1131
1193
 
1132
1194
  /**
1133
- * Handles the `keydown` event on <tr> (table-based) and div[role="row"] (role-based)
1195
+ * Handles the `keydown` event on data row <tr> (table-based) and div[role="row"] (role-based)
1134
1196
  *
1135
1197
  * @param {KeyboardEvent} event - `keydown`
1136
1198
  */
1137
- handleTrRowKeyDown(event) {
1199
+ handleKeydownOnDataRow(event) {
1138
1200
  // we probably should not be doing this unless we actually are interested in it
1139
1201
  if (
1140
1202
  this.state.keyboardMode === 'NAVIGATION' &&
@@ -1186,9 +1248,16 @@ export default class LightningDatatable extends LightningElement {
1186
1248
  }
1187
1249
 
1188
1250
  handleInlineEditPanelScroll.call(this, event);
1189
-
1190
- if (this.viewportRendering) {
1191
- this._renderManager.handleScroll(this, event);
1251
+ if (this._virtualize) {
1252
+ this._firstVisibleIndex =
1253
+ this._renderManager.getFirstVisibleIndex(event);
1254
+ } else if (this.viewportRendering) {
1255
+ this._renderManager.handleScroll(
1256
+ this.state.rows,
1257
+ this._renderedRowCount,
1258
+ this.setRenderedRowCount,
1259
+ event
1260
+ );
1192
1261
  }
1193
1262
  }
1194
1263
 
@@ -1201,8 +1270,9 @@ export default class LightningDatatable extends LightningElement {
1201
1270
  handleCellClick(event) {
1202
1271
  // handles the case when clicking on the margin/pading of the td/th
1203
1272
  const targetTagName = event.target.tagName.toLowerCase();
1273
+ const targetRole = event.target.getAttribute('role');
1204
1274
 
1205
- if (targetTagName === 'td' || targetTagName === 'th') {
1275
+ if (isCellElement(targetTagName, targetRole)) {
1206
1276
  // get the row/col key value from the primitive cell.
1207
1277
  const { rowKeyValue, colKeyValue } =
1208
1278
  event.target.querySelector(':first-child');
@@ -1248,7 +1318,12 @@ export default class LightningDatatable extends LightningElement {
1248
1318
  const { state, widthsData } = this;
1249
1319
  const { colIndex, widthDelta } = event.detail;
1250
1320
  if (widthDelta !== 0) {
1251
- resizeColumnWithDelta(state, widthsData, colIndex, widthDelta);
1321
+ resizeColumnWithDelta(
1322
+ getColumns(state),
1323
+ widthsData,
1324
+ colIndex,
1325
+ widthDelta
1326
+ );
1252
1327
  this.fireOnResize(true);
1253
1328
  this.safariHeaderFix();
1254
1329
  }
@@ -1349,7 +1424,7 @@ export default class LightningDatatable extends LightningElement {
1349
1424
  * @param {FocusEvent} event - `focusout`
1350
1425
  */
1351
1426
  handleTableFocusOut(event) {
1352
- handleDatatableLosedFocus.call(this, event);
1427
+ handleDatatableFocusOut.call(this, event);
1353
1428
  }
1354
1429
 
1355
1430
  /**
@@ -1439,7 +1514,10 @@ export default class LightningDatatable extends LightningElement {
1439
1514
  const { state, widthsData } = this;
1440
1515
  const event = new CustomEvent('resize', {
1441
1516
  detail: {
1442
- columnWidths: getCustomerColumnWidths(state, widthsData),
1517
+ columnWidths: getCustomerColumnWidths(
1518
+ getColumns(state),
1519
+ widthsData
1520
+ ),
1443
1521
  isUserTriggered: !!isUserTriggered,
1444
1522
  },
1445
1523
  });
@@ -1455,8 +1533,12 @@ export default class LightningDatatable extends LightningElement {
1455
1533
 
1456
1534
  this.updateRowsAndCellIndexes(state);
1457
1535
 
1458
- if (this.viewportRendering) {
1459
- this._renderManager.updateViewportRendering(this);
1536
+ if (this.viewportRendering || this._virtualize) {
1537
+ this._renderManager.updateViewportRendering(
1538
+ this.state.rows,
1539
+ this.setRenderedRowCount,
1540
+ this.gridContainer
1541
+ );
1460
1542
  }
1461
1543
 
1462
1544
  this._columnWidthManager.handleRowNumberOffsetChange(state, widthsData);
@@ -1499,9 +1581,9 @@ export default class LightningDatatable extends LightningElement {
1499
1581
  // Updates state.wrapText and when isWrapableType, sets internal header actions
1500
1582
  updateHeaderActions(state);
1501
1583
  this.updateRowsAndCellIndexes(state);
1502
- updateSelectionState(state);
1584
+ updateBulkSelectionState(state);
1503
1585
  this._columnWidthManager.handleRowNumberOffsetChange(state, widthsData);
1504
- updateColumnWidthsMetadata(state, widthsData);
1586
+ updateColumnWidthsMetadata(getColumns(state), widthsData);
1505
1587
  // set the celltofocus next to null if the column still exists after indexes calculation
1506
1588
  updateCellToFocusFromPrev(state);
1507
1589
 
@@ -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
  }