lightning-base-components 1.21.3-alpha → 1.21.5-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 (233) hide show
  1. package/metadata/raptor.json +49 -0
  2. package/package.json +96 -21
  3. package/scopedImports/@salesforce-label-LightningDatatable.showActions.js +1 -1
  4. package/scopedImports/@salesforce-label-LightningForm.controllerFieldsMessage.js +1 -0
  5. package/scopedImports/@salesforce-label-LightningForm.dependentFieldsHeader.js +1 -0
  6. package/scopedImports/@salesforce-label-LightningForm.dependentFieldsListHeading.js +1 -0
  7. package/scopedImports/@salesforce-label-LightningForm.generalDependentFieldsMessage.js +1 -0
  8. package/scopedImports/@salesforce-label-LightningForm.learnMore.js +1 -0
  9. package/scopedImports/@salesforce-label-LightningForm.okButton.js +1 -0
  10. package/scopedImports/@salesforce-label-LightningLookup.messageWhenSearchTermTooShort.js +1 -0
  11. package/scopedImports/@salesforce-label-LightningLookup.modalCancel.js +1 -0
  12. package/scopedImports/@salesforce-label-LightningLookup.modalSelect.js +1 -0
  13. package/scopedImports/@salesforce-label-LightningProgressIndicator.currentStage.js +1 -1
  14. package/scopedImports/@salesforce-label-LightningProgressIndicator.errorStage.js +1 -0
  15. package/scopedImports/@salesforce-label-LightningProgressIndicator.stageComplete.js +1 -1
  16. package/scopedImports/@salesforce-label-LightningProgressIndicator.stageNotStarted.js +1 -1
  17. package/src/lightning/accordion/__docs__/accordion.md +0 -4
  18. package/src/lightning/accordionSection/__docs__/accordionSection.md +0 -4
  19. package/src/lightning/avatar/__docs__/avatar.md +0 -4
  20. package/src/lightning/avatar/avatar.html +1 -0
  21. package/src/lightning/badge/__docs__/badge.md +0 -4
  22. package/src/lightning/badge/badge.html +3 -3
  23. package/src/lightning/barcodeScanner/__docs__/barcodeScanner.md +0 -4
  24. package/src/lightning/baseCombobox/baseCombobox.html +4 -1
  25. package/src/lightning/baseCombobox/baseCombobox.js +5 -18
  26. package/src/lightning/baseComboboxItem/baseComboboxItem.js +6 -10
  27. package/src/lightning/button/__docs__/button.md +5 -8
  28. package/src/lightning/button/button.js +3 -4
  29. package/src/lightning/buttonGroup/__docs__/buttonGroup.md +0 -4
  30. package/src/lightning/buttonIcon/__docs__/buttonIcon.md +1 -4
  31. package/src/lightning/buttonIcon/buttonIcon.html +1 -1
  32. package/src/lightning/buttonIcon/buttonIcon.js +18 -17
  33. package/src/lightning/buttonIconStateful/__docs__/buttonIconStateful.md +0 -4
  34. package/src/lightning/buttonMenu/__docs__/buttonMenu.md +0 -4
  35. package/src/lightning/buttonMenu/buttonMenu.css +5 -0
  36. package/src/lightning/buttonMenu/buttonMenu.js +2 -0
  37. package/src/lightning/buttonStateful/__docs__/buttonStateful.md +0 -4
  38. package/src/lightning/buttonStateful/buttonStateful.html +5 -3
  39. package/src/lightning/buttonStateful/buttonStateful.js +4 -0
  40. package/src/lightning/card/__docs__/card.md +0 -4
  41. package/src/lightning/card/card.js-meta.xml +3 -0
  42. package/src/lightning/carousel/__docs__/carousel.md +0 -4
  43. package/src/lightning/checkboxGroup/__docs__/checkboxGroup.md +0 -4
  44. package/src/lightning/colorPickerCustom/colorPickerCustom.js +12 -0
  45. package/src/lightning/colorPickerPanel/colorPickerPanel.js +11 -1
  46. package/src/lightning/combobox/__docs__/combobox.md +0 -4
  47. package/src/lightning/combobox/combobox.html +1 -0
  48. package/src/lightning/datatable/__examples__disabled/customComponentWrapper/customComponentWrapper.html +11 -0
  49. package/src/lightning/datatable/__examples__disabled/customComponentWrapper/customComponentWrapper.js +25 -0
  50. package/src/lightning/datatable/__examples__disabled/customComponentWrapper/generateData.js +15 -0
  51. package/src/lightning/datatable/__examples__disabled/myCustomTypeDatatable/customInput.html +4 -0
  52. package/src/lightning/datatable/__examples__disabled/myCustomTypeDatatable/myCustomTypeDatatable.js +17 -0
  53. package/src/lightning/datatable/__examples__disabled/myCustomTypeDatatable/nestedSimpleComponentParent.html +7 -0
  54. package/src/lightning/datatable/__examples__disabled/simpleComponentNested/simpleComponentNested.html +9 -0
  55. package/src/lightning/datatable/__examples__disabled/simpleComponentNested/simpleComponentNested.js +6 -0
  56. package/src/lightning/datatable/autoWidthStrategy.js +8 -36
  57. package/src/lightning/datatable/columnResizer.js +51 -161
  58. package/src/lightning/datatable/columnWidthManager.js +25 -81
  59. package/src/lightning/datatable/columns.js +180 -302
  60. package/src/lightning/datatable/datatable.js +454 -441
  61. package/src/lightning/datatable/errors.js +17 -29
  62. package/src/lightning/datatable/fixedWidthStrategy.js +7 -22
  63. package/src/lightning/datatable/headerActions.js +8 -38
  64. package/src/lightning/datatable/indexes.js +42 -0
  65. package/src/lightning/datatable/infiniteLoading.js +16 -35
  66. package/src/lightning/datatable/inlineEdit.js +126 -156
  67. package/src/lightning/datatable/keyboard.js +226 -282
  68. package/src/lightning/datatable/renderManager.js +0 -4
  69. package/src/lightning/datatable/resizeObserver.js +4 -13
  70. package/src/lightning/datatable/rowLevelActions.js +2 -2
  71. package/src/lightning/datatable/rowNumber.js +21 -59
  72. package/src/lightning/datatable/rowSelection.js +95 -178
  73. package/src/lightning/datatable/rowSelectionShared.js +13 -27
  74. package/src/lightning/datatable/rows.js +171 -418
  75. package/src/lightning/datatable/sort.js +16 -75
  76. package/src/lightning/datatable/templates/div/div.html +12 -4
  77. package/src/lightning/datatable/templates/div/div.lbc.synthetic.css +10 -16
  78. package/src/lightning/datatable/templates/table/table.html +15 -5
  79. package/src/lightning/datatable/tree.js +17 -35
  80. package/src/lightning/datatable/types.js +10 -31
  81. package/src/lightning/datatable/utils.js +48 -24
  82. package/src/lightning/datatable/virtualization.js +2 -5
  83. package/src/lightning/datatable/widthManagerShared.js +0 -20
  84. package/src/lightning/datatable/wrapText.js +29 -60
  85. package/src/lightning/dualListbox/__docs__/dualListbox.md +0 -4
  86. package/src/lightning/dualListbox/dualListbox.js +7 -8
  87. package/src/lightning/dynamicIcon/__docs__/dynamicIcon.md +0 -4
  88. package/src/lightning/formattedDateTime/__docs__/formattedDateTime.md +0 -4
  89. package/src/lightning/formattedLocation/__docs__/formattedLocation.md +0 -4
  90. package/src/lightning/formattedName/__docs__/formattedName.md +0 -4
  91. package/src/lightning/formattedName/formattedName.js +3 -2
  92. package/src/lightning/formattedName/formattedName.js-meta.xml +3 -0
  93. package/src/lightning/formattedNumber/__docs__/formattedNumber.md +0 -4
  94. package/src/lightning/formattedNumber/formattedNumber.js +3 -2
  95. package/src/lightning/formattedNumber/formattedNumber.js-meta.xml +3 -0
  96. package/src/lightning/formattedPhone/__docs__/formattedPhone.md +0 -4
  97. package/src/lightning/formattedRichText/richTextConfig.js +1 -0
  98. package/src/lightning/formattedText/__docs__/formattedText.md +0 -4
  99. package/src/lightning/formattedTime/__docs__/formattedTime.md +0 -4
  100. package/src/lightning/formattedUrl/__docs__/formattedUrl.md +0 -4
  101. package/src/lightning/helptext/helptext.css +7 -0
  102. package/src/lightning/helptext/helptext.js +3 -4
  103. package/src/lightning/icon/__docs__/icon.md +0 -4
  104. package/src/lightning/icon/icon.html +1 -1
  105. package/src/lightning/input/input.html +5 -0
  106. package/src/lightning/inputAddress/addressFormat.js +31 -4
  107. package/src/lightning/inputAddress/fieldsLayout.js +6 -0
  108. package/src/lightning/inputAddress/inputAddress.html +19 -1
  109. package/src/lightning/inputAddress/inputAddress.js +80 -3
  110. package/src/lightning/inputLocation/__docs__/inputLocation.md +0 -4
  111. package/src/lightning/internationalizationLibrary/address/AddressFormat.js +553 -610
  112. package/src/lightning/layout/__docs__/layout.md +0 -4
  113. package/src/lightning/layoutItem/__docs__/layoutItem.md +0 -4
  114. package/src/lightning/lookupAddress/lookupAddress.html +6 -1
  115. package/src/lightning/lookupAddress/lookupAddress.js +25 -0
  116. package/src/lightning/menuItem/__docs__/menuItem.md +0 -4
  117. package/src/lightning/menuSubheader/menu-subheader.slds.css +1 -1
  118. package/src/lightning/modal/__docs__/modal.md +10 -1
  119. package/src/lightning/modal/__modalUtils__/modalContainerTestConstants.js +3 -7
  120. package/src/lightning/modal/__modalUtils__/modalContainerTestMethods.js +39 -133
  121. package/src/lightning/modal/__modalUtils__/modalContainerTestMockData.js +1 -1
  122. package/src/lightning/modal/modal.js +1 -1
  123. package/src/lightning/modalBase/modalBase.html +15 -10
  124. package/src/lightning/modalBase/modalBase.js +132 -147
  125. package/src/lightning/modalBody/modalBody.css +6 -0
  126. package/src/lightning/modalHeader/modalHeader.html +16 -4
  127. package/src/lightning/modalHeader/modalHeader.js +61 -14
  128. package/src/lightning/pill/__docs__/pill.md +0 -4
  129. package/src/lightning/pill/link.html +1 -0
  130. package/src/lightning/pill/plain.html +1 -0
  131. package/src/lightning/pill/plainLink.html +1 -0
  132. package/src/lightning/pillContainer/__docs__/pillContainer.md +0 -4
  133. package/src/lightning/primitiveBubble/primitiveBubble.js +42 -0
  134. package/src/lightning/primitiveDatatableCell/primitiveDatatableCell.js +1 -1
  135. package/src/lightning/primitiveHeaderActions/primitiveHeaderActions.html +1 -1
  136. package/src/lightning/primitiveHeaderActions/primitiveHeaderActions.js +13 -0
  137. package/src/lightning/primitiveHeaderFactory/nonsortableHeader.html +19 -6
  138. package/src/lightning/primitiveHeaderFactory/sortableHeader.html +3 -1
  139. package/src/lightning/primitiveResizeHandler/primitiveResizeHandler.css +11 -0
  140. package/src/lightning/primitiveResizeHandler/primitiveResizeHandler.html +2 -1
  141. package/src/lightning/primitiveResizeHandler/primitiveResizeHandler.js +1 -0
  142. package/src/lightning/progressStep/base.html +5 -6
  143. package/src/lightning/progressStep/progressStep.js +14 -9
  144. package/src/lightning/prompt/__docs__/prompt.md +1 -1
  145. package/src/lightning/radioGroup/__docs__/radioGroup.md +0 -4
  146. package/src/lightning/relativeDateTime/__docs__/relativeDateTime.md +0 -4
  147. package/src/lightning/shadowBaseClassPrivate/shadowBaseClassPrivate.js +0 -2
  148. package/src/lightning/sldsCommon/sldsCommon.css +134 -98
  149. package/src/lightning/sldsUtilsAlignment/sldsUtilsAlignment.css +1 -1
  150. package/src/lightning/sldsUtilsBox/sldsUtilsBox.css +14 -13
  151. package/src/lightning/sldsUtilsGrid/sldsUtilsGrid.css +95 -92
  152. package/src/lightning/sldsUtilsHyphenation/sldsUtilsHyphenation.css +1 -1
  153. package/src/lightning/sldsUtilsMargin/sldsUtilsMargin.css +77 -75
  154. package/src/lightning/sldsUtilsPadding/sldsUtilsPadding.css +73 -73
  155. package/src/lightning/sldsUtilsSizing/sldsUtilsSizing.css +552 -558
  156. package/src/lightning/sldsUtilsVisibility/sldsUtilsVisibility.css +2 -2
  157. package/src/lightning/slider/__docs__/slider.md +0 -4
  158. package/src/lightning/spinner/__docs__/spinner.md +0 -4
  159. package/src/lightning/staticMap/staticMap.js +3 -2
  160. package/src/lightning/tab/__docs__/tab.md +0 -4
  161. package/src/lightning/tab/tab.js +6 -3
  162. package/src/lightning/tab/tab.js-meta.xml +3 -0
  163. package/src/lightning/tabBar/tabBar.js +10 -5
  164. package/src/lightning/tabset/__docs__/tabset.md +0 -4
  165. package/src/lightning/tabset/tabset.html +2 -0
  166. package/src/lightning/tabset/tabset.js-meta.xml +3 -0
  167. package/src/lightning/textarea/__docs__/textarea.md +0 -4
  168. package/src/lightning/textarea/textarea.js +6 -1
  169. package/src/lightning/tile/__docs__/tile.md +0 -4
  170. package/src/lightning/toastContainer/__docs__/toastContainer.md +3 -2
  171. package/src/lightning/tooltipLibrary/tooltipLibrary.js +24 -15
  172. package/src/lightning/tree/__docs__/tree.md +0 -4
  173. package/src/lightning/tree/tree.js +5 -1
  174. package/src/lightning/verticalNavigation/__docs__/verticalNavigation.md +0 -4
  175. package/src/lightning/verticalNavigation/vertical-navigation.slds.css +14 -0
  176. package/src/lightning/verticalNavigation/verticalNavigation.css +1 -1
  177. package/src/lightning/verticalNavigation/verticalNavigation.html +1 -1
  178. package/src/lightning/verticalNavigation/verticalNavigation.js +66 -28
  179. package/src/lightning/verticalNavigation/verticalNavigation.js-meta.xml +3 -0
  180. package/src/lightning/verticalNavigationItem/__docs__/verticalNavigationItem.md +0 -4
  181. package/src/lightning/verticalNavigationItem/vertical-navigation-item.slds.css +63 -0
  182. package/src/lightning/verticalNavigationItem/verticalNavigationItem.css +2 -3
  183. package/src/lightning/verticalNavigationItem/verticalNavigationItem.js +29 -15
  184. package/src/lightning/verticalNavigationItem/verticalNavigationItem.js-meta.xml +3 -0
  185. package/src/lightning/verticalNavigationItem/verticalNavigationItem.lbc.native.css +2 -0
  186. package/src/lightning/verticalNavigationItem/verticalNavigationItem.lbc.synthetic.css +3 -0
  187. package/src/lightning/verticalNavigationItemBadge/__docs__/verticalNavigationItemBadge.md +0 -4
  188. package/src/lightning/verticalNavigationItemBadge/badge.slds.css +76 -0
  189. package/src/lightning/verticalNavigationItemBadge/vertical-navigation-item.slds.css +63 -0
  190. package/src/lightning/verticalNavigationItemBadge/verticalNavigationItemBadge.css +2 -3
  191. package/src/lightning/verticalNavigationItemBadge/verticalNavigationItemBadge.html +1 -1
  192. package/src/lightning/verticalNavigationItemBadge/verticalNavigationItemBadge.js +28 -15
  193. package/src/lightning/verticalNavigationItemBadge/verticalNavigationItemBadge.js-meta.xml +3 -0
  194. package/src/lightning/verticalNavigationItemBadge/verticalNavigationItemBadge.lbc.native.css +5 -0
  195. package/src/lightning/verticalNavigationItemBadge/verticalNavigationItemBadge.lbc.synthetic.css +3 -0
  196. package/src/lightning/verticalNavigationItemIcon/__docs__/verticalNavigationItemIcon.md +0 -4
  197. package/src/lightning/verticalNavigationItemIcon/vertical-navigation-item.slds.css +63 -0
  198. package/src/lightning/verticalNavigationItemIcon/verticalNavigationItemIcon.css +2 -3
  199. package/src/lightning/verticalNavigationItemIcon/verticalNavigationItemIcon.js +29 -15
  200. package/src/lightning/verticalNavigationItemIcon/verticalNavigationItemIcon.js-meta.xml +3 -0
  201. package/src/lightning/verticalNavigationItemIcon/verticalNavigationItemIcon.lbc.native.css +3 -0
  202. package/src/lightning/verticalNavigationItemIcon/verticalNavigationItemIcon.lbc.synthetic.css +3 -0
  203. package/src/lightning/verticalNavigationOverflow/button.slds.css +503 -0
  204. package/src/lightning/verticalNavigationOverflow/vertical-navigation-item.slds.css +63 -0
  205. package/src/lightning/verticalNavigationOverflow/vertical-navigation-section.slds.css +17 -0
  206. package/src/lightning/verticalNavigationOverflow/verticalNavigationOverflow.css +2 -1
  207. package/src/lightning/verticalNavigationOverflow/verticalNavigationOverflow.html +2 -0
  208. package/src/lightning/verticalNavigationOverflow/verticalNavigationOverflow.js +18 -13
  209. package/src/lightning/verticalNavigationOverflow/verticalNavigationOverflow.js-meta.xml +3 -0
  210. package/src/lightning/verticalNavigationOverflow/verticalNavigationOverflow.lbc.native.css +5 -0
  211. package/src/lightning/verticalNavigationSection/vertical-navigation-section.slds.css +14 -14
  212. package/src/lightning/verticalNavigationSection/verticalNavigationSection.js-meta.xml +3 -0
  213. package/src/lightning/datatable/inlineEditShared.js +0 -26
  214. /package/src/lightning/datatable/{__examples__ → __examples__disabled}/customDatatableWrapper/customDatatableWrapper.html +0 -0
  215. /package/src/lightning/datatable/{__examples__ → __examples__disabled}/customDatatableWrapper/customDatatableWrapper.js +0 -0
  216. /package/src/lightning/datatable/{__examples__ → __examples__disabled}/customDatatypeDeleteRowBtn/customDatatypeDeleteRowBtn.html +0 -0
  217. /package/src/lightning/datatable/{__examples__ → __examples__disabled}/customDatatypeDeleteRowBtn/customDatatypeDeleteRowBtn.js +0 -0
  218. /package/src/lightning/datatable/{__examples__ → __examples__disabled}/customDatatypeLink/customDatatypeLink.html +0 -0
  219. /package/src/lightning/datatable/{__examples__ → __examples__disabled}/customDatatypeLink/customDatatypeLink.js +0 -0
  220. /package/src/lightning/datatable/{__examples__ → __examples__disabled}/customDatatypeNumber/customDatatypeNumber.html +0 -0
  221. /package/src/lightning/datatable/{__examples__ → __examples__disabled}/customDatatypeNumber/customDatatypeNumber.js +0 -0
  222. /package/src/lightning/datatable/{__examples__ → __examples__disabled}/customDatatypeRowOrderingBtn/customDatatypeRowOrderingBtn.html +0 -0
  223. /package/src/lightning/datatable/{__examples__ → __examples__disabled}/customDatatypeRowOrderingBtn/customDatatypeRowOrderingBtn.js +0 -0
  224. /package/src/lightning/datatable/{__examples__ → __examples__disabled}/customDatatypeTable/customDatatypeTable.js +0 -0
  225. /package/src/lightning/datatable/{__examples__ → __examples__disabled}/customDatatypeTable/customLink.html +0 -0
  226. /package/src/lightning/datatable/{__examples__ → __examples__disabled}/customDatatypeTable/customName.html +0 -0
  227. /package/src/lightning/datatable/{__examples__ → __examples__disabled}/customDatatypeTable/customNumber.html +0 -0
  228. /package/src/lightning/datatable/{__examples__ → __examples__disabled}/customDatatypeTable/customNumberEdit.html +0 -0
  229. /package/src/lightning/datatable/{__examples__ → __examples__disabled}/customDatatypeTable/deleteRow.html +0 -0
  230. /package/src/lightning/datatable/{__examples__ → __examples__disabled}/customDatatypeTable/iconPill.html +0 -0
  231. /package/src/lightning/datatable/{__examples__ → __examples__disabled}/customDatatypeTable/orderingButtons.html +0 -0
  232. /package/src/lightning/datatable/{__examples__ → __examples__disabled}/customNestedComponent/customNestedComponent.html +0 -0
  233. /package/src/lightning/datatable/{__examples__ → __examples__disabled}/customNestedComponent/customNestedComponent.js +0 -0
@@ -1,164 +1,143 @@
1
1
  import { LightningElement, api, track, unwrap } from 'lwc';
2
- import tableTemplate from './templates/table/table.html';
3
2
  import divTemplate from './templates/div/div.html';
4
- import { classSet } from 'lightning/utils';
3
+ import tableTemplate from './templates/table/table.html';
4
+ import labelAriaLiveActionMode from '@salesforce/label/LightningDatatable.ariaLiveActionMode';
5
+ import labelAriaLiveNavigationMode from '@salesforce/label/LightningDatatable.ariaLiveNavigationMode';
6
+ import { EVENTS as FORMATTED_LOOKUP_EVENTS } from 'lightning/formattedLookup';
7
+ import { generateUniqueId } from 'lightning/inputUtils';
5
8
  import {
9
+ classSetToString,
10
+ isSafari,
6
11
  normalizeBoolean,
7
12
  normalizeString,
8
- isSafari,
9
13
  synchronizeAttrs,
10
- classSetToString,
11
14
  } from 'lightning/utilsPrivate';
12
15
  import { LightningDatatableResizeObserver } from './resizeObserver';
13
16
  import { ColumnWidthManager } from './columnWidthManager';
14
17
  import { getDefaultState } from './state';
15
- import { getColumns, normalizeColumns, generateHeaderIndexes } from './columns';
18
+ import { normalizeColumns, generateHeaderIndexes } from './columns';
19
+ import {
20
+ getCustomerColumnWidths,
21
+ getResizerDefaultState,
22
+ resizeColumnWithDelta,
23
+ setMaxColumnWidth,
24
+ setMinColumnWidth,
25
+ setResizeColumnDisabled,
26
+ setResizeStep,
27
+ updateColumnWidthsMetadata,
28
+ } from './columnResizer';
29
+ import { setErrors } from './errors';
16
30
  import {
17
- setData,
18
- getData,
19
- updateRowsAndCellIndexes,
20
31
  setKeyField,
21
- getKeyField,
22
- hasValidKeyField,
32
+ updateRowsAndCellIndexes,
23
33
  updateCellClassForRoleBasedMode,
24
34
  recomputeCellStyles,
25
35
  } from './rows';
26
36
  import {
27
- isResizeColumnDisabled,
28
- setResizeColumnDisabled,
29
- getResizeStep,
30
- setResizeStep,
31
- getMinColumnWidth,
32
- setMinColumnWidth,
33
- getMaxColumnWidth,
34
- setMaxColumnWidth,
35
- getColumnsWidths,
36
- resizeColumnWithDelta,
37
- getCustomerColumnWidths,
38
- getCSSWidthStyleOfTable,
39
- updateColumnWidthsMetadata,
40
- getResizerDefaultState,
41
- } from './columnResizer';
37
+ handleCellButtonClick,
38
+ handleLoadDynamicActions,
39
+ handleRowActionTriggered,
40
+ } from './rowLevelActions';
41
+ import { setRowNumberOffset } from './rowNumber';
42
42
  import {
43
- syncSelectedRowsKeys,
43
+ handleDeselectAllRows,
44
+ handleDeselectRow,
44
45
  handleRowSelectionChange,
45
- updateBulkSelectionState,
46
- getMaxRowSelection,
47
- setMaxRowSelection,
48
- getSelectedRowsKeys,
49
- setSelectedRowsKeys,
50
46
  handleSelectAllRows,
51
- handleDeselectAllRows,
52
47
  handleSelectRow,
53
- handleDeselectRow,
54
- getHideSelectAllCheckbox,
55
- getCurrentSelectionLength,
48
+ setMaxRowSelection,
49
+ setSelectedRowsKeys,
50
+ syncSelectedRowsKeys,
51
+ updateBulkSelectionState,
56
52
  } from './rowSelection';
57
53
  import {
58
- syncActiveCell,
59
- handleKeydownOnCell,
60
- updateActiveCell,
61
- setBlurActiveCell,
62
- setFocusActiveCell,
63
- isActiveCell,
64
- updateCellTabIndex,
65
- getIndexesByKeys,
66
- updateTabIndexActiveCell,
67
- updateTabIndexActiveRow,
68
- unsetRowNavigationMode,
69
- updateRowNavigationMode,
70
- handleDatatableFocusOut,
71
- handleDatatableFocusIn,
72
- updateRowTabIndex,
73
- getIndexesActiveCell,
74
- reactToKeyboardOnRow,
75
- setCellToFocusFromPrev,
76
- updateCellToFocusFromPrev,
77
- resetCellToFocusFromPrev,
78
- datatableHasFocus,
79
- setCellClickedForFocus,
80
- handleKeydownOnTable,
81
- addFocusStylesToActiveCell,
82
- refocusCellElement,
83
- isCellElement,
84
- getActiveCellElement,
85
- getRowDataSelector,
86
- FOCUS_CLASS,
87
- updateActiveCellTabIndexAfterSync,
88
- } from './keyboard';
54
+ getCurrentSelectionLength,
55
+ getSelectedRowsKeys,
56
+ } from './rowSelectionShared';
89
57
  import {
90
- getRowNumberOffset,
91
- setRowNumberOffset,
92
- hasRowNumberColumn,
93
- setShowRowNumberColumn,
94
- } from './rowNumber';
58
+ handleHeaderActionMenuClosed,
59
+ handleHeaderActionTriggered,
60
+ handleHeaderActionMenuOpening,
61
+ updateHeaderInternalActions,
62
+ } from './headerActions';
95
63
  import {
96
64
  handleLoadMoreCheck,
97
- isInfiniteLoadingEnabled,
65
+ handlePrefetch,
98
66
  setEnableInfiniteLoading,
67
+ setLoading,
99
68
  getLoadMoreOffset,
100
69
  setLoadMoreOffset,
101
- isLoading,
102
- setLoading,
103
- handlePrefetch,
104
70
  } from './infiniteLoading';
105
-
106
- import {
107
- handleRowActionTriggered,
108
- handleLoadDynamicActions,
109
- handleCellButtonClick,
110
- } from './rowLevelActions';
111
71
  import {
112
- getSortedBy,
113
- setSortedBy,
114
- getSortedDirection,
115
- setSortedDirection,
116
- getDefaultSortDirection,
117
- setDefaultSortDirection,
118
- updateSorting,
119
- } from './sort';
120
- import {
121
- updateHeaderActions,
122
- handleHeaderActionTriggered,
123
- handleHeaderActionMenuOpening,
124
- handleHeaderActionMenuClosed,
125
- } from './headerActions';
126
- import { setWrapTextMaxLines } from './wrapText';
127
- import {
128
- isInlineEditTriggered,
129
72
  cancelInlineEdit,
73
+ closeInlineEdit,
74
+ getDirtyValues,
130
75
  handleEditCell,
131
76
  handleInlineEditFinish,
132
- handleMassCheckboxChange,
133
77
  handleInlineEditPanelScroll,
134
- getDirtyValues,
135
- setDirtyValues,
136
- closeInlineEdit,
78
+ handleMassCheckboxChange,
79
+ isInlineEditTriggered,
137
80
  openInlineEditOnActiveCell,
81
+ setDirtyValues,
138
82
  } from './inlineEdit';
83
+ import {
84
+ addFocusStylesToActiveCell,
85
+ datatableHasFocus,
86
+ FOCUS_CLASS,
87
+ getActiveCellElement,
88
+ getIndexesActiveCell,
89
+ getIndexesByKeys,
90
+ handleDatatableFocusIn,
91
+ handleDatatableFocusOut,
92
+ handleKeydownOnCell,
93
+ handleKeydownOnTable,
94
+ isActiveCell,
95
+ isCellElement,
96
+ KEYBOARD_ACTION_MODE,
97
+ KEYBOARD_NAVIGATION_MODE,
98
+ reactToKeyboardOnRow,
99
+ refocusCellElement,
100
+ setBlurActiveCell,
101
+ setCellClickedForFocus,
102
+ setCellToFocusFromPrev,
103
+ setFocusActiveCell,
104
+ syncActiveCell,
105
+ unsetRowNavigationMode,
106
+ updateActiveCellTabIndexAfterSync,
107
+ updateCellTabIndex,
108
+ updateCellToFocusFromPrev,
109
+ updateTabIndexActiveCell,
110
+ updateTabIndexActiveRow,
111
+ updateRowNavigationMode,
112
+ updateRowTabIndex,
113
+ } from './keyboard';
139
114
  import {
140
115
  isViewportRenderingEnabled,
141
116
  setViewportRendering,
142
- getDTWrapperHeight,
143
117
  setVirtualize,
144
118
  RenderManager,
145
119
  } from './renderManager';
120
+ import {
121
+ setDefaultSortDirection,
122
+ setSortedBy,
123
+ setSortedDirection,
124
+ updateSorting,
125
+ } from './sort';
126
+ import {
127
+ getGridContainerFromScrollerY,
128
+ getRowDataSelector,
129
+ getScrollerX,
130
+ getScrollerY,
131
+ } from './utils';
132
+ import { setWrapTextMaxLines } from './wrapText';
146
133
  import {
147
134
  handleVariableRowHeights,
148
135
  resetRowHeights,
149
136
  resetTableHeight,
150
137
  findFirstVisibleIndex,
151
138
  } from './virtualization';
152
- import { EVENTS as FORMATTED_LOOKUP_EVENTS } from 'lightning/formattedLookup';
153
-
154
139
  import { hasTreeDataType } from './tree';
155
- import { setErrors, getTableError, getErrors } from './errors';
156
-
157
- import { generateUniqueId } from 'lightning/inputUtils';
158
140
  import DatatableTypes from './types';
159
- import labelAriaLiveNavigationMode from '@salesforce/label/LightningDatatable.ariaLiveNavigationMode';
160
- import labelAriaLiveActionMode from '@salesforce/label/LightningDatatable.ariaLiveActionMode';
161
- import { styleToString } from './utils';
162
141
 
163
142
  const i18n = {
164
143
  ariaLiveNavigationMode: labelAriaLiveNavigationMode,
@@ -202,31 +181,33 @@ export default class LightningDatatable extends LightningElement {
202
181
 
203
182
  // Private Variables
204
183
  _actionsMinHeightStyle = ''; // Min height required while actions menu is opened
205
- _columns = [];
206
- _columnWidthsMode = 'fixed';
184
+ _checkboxColumnHeaderId = null;
185
+ _columnWidthManager;
207
186
  _customerSelectedRows = null;
208
187
  _datatableId = generateUniqueId('lgt-datatable');
209
188
  _draftValues = [];
210
189
  _isResizing = false; // Whether resizing is in progress
211
190
  _lastRenderedRow = null; // last rendered row, used for UTAM
212
191
  _privateTypes = {};
213
- _privateWidthObserver = null; // Instance of LightningDatatableResizeObserver
214
- _renderMode = 'table';
192
+ _rawColumns = [];
193
+ _renderConfig;
194
+ _renderManager;
195
+ _renderMode = 'default';
215
196
  _shouldResetFocus = false; // used to ensure focus isn't lost from changes in renderedRows
216
197
  _suppressBottomBar = false;
217
- _checkboxColumnHeaderId;
198
+ _widthObserver = null; // Instance of LightningDatatableResizeObserver
218
199
 
219
200
  /************************* PUBLIC PROPERTIES *************************/
220
201
 
221
202
  /**
222
203
  * Public property for passing `aria-label` down to the child table element.
223
204
  */
224
- ariaLabel = null;
205
+ @api ariaLabel = null;
225
206
 
226
207
  /**
227
208
  * Public property for passing `aria-labelledby` down to the child table element.
228
209
  */
229
- ariaLabelledBy = null;
210
+ @api ariaLabelledBy = null;
230
211
 
231
212
  /**
232
213
  * Public property for passing `aria-describedby` down to the child table element.
@@ -254,9 +235,7 @@ export default class LightningDatatable extends LightningElement {
254
235
  this._columnWidthManager.columnWidthMode = normalizedValue;
255
236
  if (widthsData.columnWidthsMode !== normalizedValue) {
256
237
  // Tracked state changes.
257
- this._columnWidthManager.handleWidthModeChange(
258
- getColumns(this.state)
259
- );
238
+ this._columnWidthManager.handleWidthModeChange(this.state.columns);
260
239
  }
261
240
  // Untracked state change.
262
241
  widthsData.columnWidthsMode = normalizedValue;
@@ -270,13 +249,14 @@ export default class LightningDatatable extends LightningElement {
270
249
  */
271
250
  @api
272
251
  get columns() {
273
- return this._columns;
252
+ return this._rawColumns;
274
253
  }
275
254
 
276
255
  set columns(value) {
277
- this._columns = Array.isArray(value) ? value : [];
278
- this.updateColumns(this._columns);
279
- this._columnWidthManager.handleColumnsChange(getColumns(this.state));
256
+ const _rawColumns = Array.isArray(value) ? value : [];
257
+ this._rawColumns = _rawColumns;
258
+ this.updateColumns(this._rawColumns);
259
+ this._columnWidthManager.handleColumnsChange(this.state.columns);
280
260
  }
281
261
 
282
262
  /**
@@ -286,22 +266,24 @@ export default class LightningDatatable extends LightningElement {
286
266
  @api
287
267
  // eslint-disable-next-line @lwc/lwc/valid-api
288
268
  get data() {
289
- return getData(this.state);
269
+ return this.state.data;
290
270
  }
291
271
 
292
272
  set data(value) {
293
273
  const { state } = this;
294
- const previousData = getData(state);
274
+ const { data: previousData } = state;
295
275
  const data = Array.isArray(value) ? value : [];
296
276
 
297
- const columns = getColumns(state);
298
- this._columnWidthManager.handleDataChange(previousData, data, columns);
299
-
300
- // set data in state
301
- setData(state, value);
277
+ // Untracked state change.
278
+ state.data = data;
279
+ this._columnWidthManager.handleDataChange(
280
+ previousData,
281
+ data,
282
+ state.columns
283
+ );
302
284
 
303
285
  // do necessary updates since rows have changed
304
- if (hasValidKeyField(state)) {
286
+ if (this.hasValidKeyField) {
305
287
  this.updateRowsState();
306
288
  resetTableHeight(state);
307
289
  }
@@ -319,7 +301,7 @@ export default class LightningDatatable extends LightningElement {
319
301
  */
320
302
  @api
321
303
  get defaultSortDirection() {
322
- return getDefaultSortDirection(this.state);
304
+ return this.state.defaultSortDirection;
323
305
  }
324
306
 
325
307
  set defaultSortDirection(value) {
@@ -342,8 +324,8 @@ export default class LightningDatatable extends LightningElement {
342
324
  this._draftValues = value;
343
325
  setDirtyValues(state, value);
344
326
 
345
- if (hasValidKeyField(state)) {
346
- this.updateRowsAndCellIndexes(state);
327
+ if (this.hasValidKeyField) {
328
+ this.updateRowsAndCells();
347
329
  }
348
330
 
349
331
  updateActiveCellTabIndexAfterSync(state);
@@ -358,14 +340,14 @@ export default class LightningDatatable extends LightningElement {
358
340
  */
359
341
  @api
360
342
  get enableInfiniteLoading() {
361
- return isInfiniteLoadingEnabled(this.state);
343
+ return this.state.enableInfiniteLoading;
362
344
  }
363
345
 
364
346
  set enableInfiniteLoading(value) {
365
347
  const { state } = this;
366
348
  // Untracked state change.
367
349
  setEnableInfiniteLoading(state, value);
368
- handlePrefetch.call(this, this.template, state);
350
+ handlePrefetch.call(this);
369
351
  }
370
352
 
371
353
  /**
@@ -375,7 +357,7 @@ export default class LightningDatatable extends LightningElement {
375
357
  */
376
358
  @api
377
359
  get errors() {
378
- return getErrors(this.state);
360
+ return this.state.errors;
379
361
  }
380
362
 
381
363
  set errors(value) {
@@ -400,12 +382,12 @@ export default class LightningDatatable extends LightningElement {
400
382
  this._columnWidthManager.handleCheckboxColumnChange(
401
383
  state.hideCheckboxColumn,
402
384
  normalizedValue,
403
- getColumns(state)
385
+ state.columns
404
386
  );
405
387
  // Untracked state changes.
406
388
  state.hideCheckboxColumn = normalizedValue;
407
389
  // update the columns metadata again to update the status.
408
- this.updateColumns(this._columns);
390
+ this.updateColumns(this._rawColumns);
409
391
  }
410
392
 
411
393
  /**
@@ -445,7 +427,7 @@ export default class LightningDatatable extends LightningElement {
445
427
  */
446
428
  @api
447
429
  get isLoading() {
448
- return isLoading(this.state);
430
+ return this.state.isLoading;
449
431
  }
450
432
 
451
433
  set isLoading(value) {
@@ -461,7 +443,7 @@ export default class LightningDatatable extends LightningElement {
461
443
  */
462
444
  @api
463
445
  get keyField() {
464
- return getKeyField(this.state);
446
+ return this.state.keyField;
465
447
  }
466
448
 
467
449
  set keyField(value) {
@@ -497,15 +479,15 @@ export default class LightningDatatable extends LightningElement {
497
479
  */
498
480
  @api
499
481
  get maxColumnWidth() {
500
- return getMaxColumnWidth(this.widthsData);
482
+ return this.widthsData.maxColumnWidth;
501
483
  }
502
484
 
503
485
  set maxColumnWidth(value) {
504
- const { state, widthsData } = this;
505
- // Tracked state change.
506
- setMaxColumnWidth(getColumns(state), widthsData, value);
486
+ const { widthsData } = this;
487
+ // Tracked state changes.
488
+ setMaxColumnWidth(this.state.columns, widthsData, value);
507
489
  // Untracked state change.
508
- this._columnWidthManager.maxColumnWidth = this.maxColumnWidth;
490
+ this._columnWidthManager.maxColumnWidth = widthsData.maxColumnWidth;
509
491
  }
510
492
 
511
493
  /**
@@ -516,7 +498,7 @@ export default class LightningDatatable extends LightningElement {
516
498
  */
517
499
  @api
518
500
  get maxRowSelection() {
519
- return getMaxRowSelection(this.state);
501
+ return this.state.maxRowSelection;
520
502
  }
521
503
 
522
504
  set maxRowSelection(value) {
@@ -537,15 +519,15 @@ export default class LightningDatatable extends LightningElement {
537
519
  */
538
520
  @api
539
521
  get minColumnWidth() {
540
- return getMinColumnWidth(this.widthsData);
522
+ return this.widthsData.minColumnWidth;
541
523
  }
542
524
 
543
525
  set minColumnWidth(value) {
544
- const { state, widthsData } = this;
526
+ const { widthsData } = this;
545
527
  // Tracked state change.
546
- setMinColumnWidth(getColumns(state), widthsData, value);
528
+ setMinColumnWidth(this.state.columns, widthsData, value);
547
529
  // Untracked state change.
548
- this._columnWidthManager.minColumnWidth = this.minColumnWidth;
530
+ this._columnWidthManager.minColumnWidth = widthsData.minColumnWidth;
549
531
  }
550
532
 
551
533
  /**
@@ -609,7 +591,6 @@ export default class LightningDatatable extends LightningElement {
609
591
  validValues: ['default', 'role-based'],
610
592
  });
611
593
  state.renderModeRoleBased = this._renderMode === 'role-based';
612
- this._columnWidthManager.setRenderMode(this.renderMode);
613
594
  if (_renderConfig) {
614
595
  setVirtualize(state, _renderConfig.virtualize);
615
596
  }
@@ -623,7 +604,7 @@ export default class LightningDatatable extends LightningElement {
623
604
  */
624
605
  @api
625
606
  get resizeColumnDisabled() {
626
- return isResizeColumnDisabled(this.widthsData);
607
+ return this.widthsData.resizeColumnDisabled;
627
608
  }
628
609
 
629
610
  set resizeColumnDisabled(value) {
@@ -639,7 +620,7 @@ export default class LightningDatatable extends LightningElement {
639
620
  */
640
621
  @api
641
622
  get resizeStep() {
642
- return getResizeStep(this.widthsData);
623
+ return this.widthsData.resizeStep;
643
624
  }
644
625
 
645
626
  set resizeStep(value) {
@@ -655,15 +636,18 @@ export default class LightningDatatable extends LightningElement {
655
636
  */
656
637
  @api
657
638
  get rowNumberOffset() {
658
- return getRowNumberOffset(this.state);
639
+ return this.state.rowNumberOffset;
659
640
  }
660
641
 
661
642
  set rowNumberOffset(value) {
662
- const { state, widthsData } = this;
643
+ const { state } = this;
663
644
  // Untracked state change.
664
645
  setRowNumberOffset(state, value);
665
646
  // Tracked state changes.
666
- this._columnWidthManager.handleRowNumberOffsetChange(state, widthsData);
647
+ this._columnWidthManager.handleRowNumberOffsetChange(
648
+ state,
649
+ this.widthsData
650
+ );
667
651
  }
668
652
 
669
653
  /**
@@ -687,20 +671,20 @@ export default class LightningDatatable extends LightningElement {
687
671
  */
688
672
  @api
689
673
  get showRowNumberColumn() {
690
- return hasRowNumberColumn(this.state);
674
+ return this.state.showRowNumberColumn;
691
675
  }
692
676
 
693
677
  set showRowNumberColumn(value) {
694
- const { state, _columns } = this;
678
+ const { state, _rawColumns } = this;
695
679
  // A mix of tracked and untracked state changes.
696
680
  this._columnWidthManager.handleRowNumberColumnChange(
697
- getRowNumberOffset(state),
681
+ state.rowNumberOffset,
698
682
  value,
699
- getColumns(state)
683
+ state.columns
700
684
  );
701
685
  // Untracked state change.
702
- setShowRowNumberColumn(state, value);
703
- this.updateColumns(_columns);
686
+ state.showRowNumberColumn = normalizeBoolean(value);
687
+ this.updateColumns(_rawColumns);
704
688
  }
705
689
 
706
690
  /**
@@ -710,7 +694,7 @@ export default class LightningDatatable extends LightningElement {
710
694
  */
711
695
  @api
712
696
  get sortedBy() {
713
- return getSortedBy(this.state);
697
+ return this.state.sortedBy;
714
698
  }
715
699
 
716
700
  set sortedBy(value) {
@@ -727,7 +711,7 @@ export default class LightningDatatable extends LightningElement {
727
711
  */
728
712
  @api
729
713
  get sortedDirection() {
730
- return getSortedDirection(this.state);
714
+ return this.state.sortedDirection;
731
715
  }
732
716
 
733
717
  set sortedDirection(value) {
@@ -766,19 +750,19 @@ export default class LightningDatatable extends LightningElement {
766
750
  // Untracked state changes.
767
751
  setWrapTextMaxLines(state, value);
768
752
  this._columnWidthManager.wrapTextMaxLines = state.wrapTextMaxLines;
769
- this.updateRowsAndCellIndexes(state);
753
+ this.updateRowsAndCells();
770
754
  }
771
755
 
772
756
  /************************** PUBLIC METHODS ***************************/
773
757
 
774
758
  /**
775
759
  * Returns data in each selected row.
776
- * @returns {array} An array of data in each selected row.
760
+ * @returns {Array} An array of data in each selected row.
777
761
  */
778
762
  @api
779
763
  getSelectedRows() {
780
764
  const { state } = this;
781
- const data = unwrap(getData(state));
765
+ const data = unwrap(state.data);
782
766
  const { rows } = state;
783
767
  const selectedRows = [];
784
768
  for (let i = 0, { length: rowCount } = rows; i < rowCount; i += 1) {
@@ -824,20 +808,21 @@ export default class LightningDatatable extends LightningElement {
824
808
 
825
809
  get computedTableContainerClass() {
826
810
  return classSetToString({
827
- 'slds-table_header-fixed_container': !this.hideTableHeader,
811
+ 'slds-table_header-fixed_container': !this.state.hideTableHeader,
828
812
  'slds-scrollable_x': !this._isResizing,
829
813
  });
830
814
  }
831
815
 
832
816
  get computedTableClass() {
833
- const headerType = this.hideTableHeader ? 'hidden' : 'fixed';
817
+ const { state } = this;
818
+ const headerType = state.hideTableHeader ? 'hidden' : 'fixed';
834
819
  return classSetToString({
835
820
  'slds-table': true,
836
821
  [`slds-table_header-${headerType}`]: true,
837
822
  'slds-table_bordered': true,
838
823
  'slds-table_edit': true,
839
- 'slds-table_resizable-cols': this.hasResizebleColumns,
840
- 'slds-tree slds-table_tree': hasTreeDataType(this.state),
824
+ 'slds-table_resizable-cols': !this.widthsData.resizeColumnDisabled,
825
+ 'slds-tree slds-table_tree': hasTreeDataType(state),
841
826
  });
842
827
  }
843
828
 
@@ -849,8 +834,11 @@ export default class LightningDatatable extends LightningElement {
849
834
  const tableLayout = this._columnWidthManager.isAutoResizingUpdateQueued
850
835
  ? 'auto'
851
836
  : 'fixed';
852
- let style = `table-layout:${tableLayout}`;
853
- style += getCSSWidthStyleOfTable(this.widthsData);
837
+ let style = `table-layout: ${tableLayout};`;
838
+ const { tableWidth } = this.widthsData;
839
+ if (tableWidth) {
840
+ style += `width: ${tableWidth}px;`;
841
+ }
854
842
  return style;
855
843
  }
856
844
 
@@ -862,9 +850,9 @@ export default class LightningDatatable extends LightningElement {
862
850
  */
863
851
  get computedTbodyStyle() {
864
852
  const { state } = this;
865
- const rowNumberOffset = getRowNumberOffset(state);
853
+ const { rowNumberOffset } = state;
866
854
  let style = '';
867
- if (hasRowNumberColumn(state) && rowNumberOffset >= 0) {
855
+ if (state.showRowNumberColumn && rowNumberOffset >= 0) {
868
856
  const { firstVisibleIndex, bufferSize } = state;
869
857
  const firstRenderedRow = Math.max(
870
858
  firstVisibleIndex - bufferSize,
@@ -890,35 +878,30 @@ export default class LightningDatatable extends LightningElement {
890
878
  * is overflowing horizontally, we need to set the width in order
891
879
  * to be able to view the remaining columns on scroll.
892
880
  */
893
- get computedScrollerStyle() {
881
+ get computedScrollerYStyle() {
894
882
  const minHeight = this._actionsMinHeightStyle
895
883
  ? `${this._actionsMinHeightStyle};`
896
884
  : '';
897
885
  if (this._columnWidthManager.isAutoResizingUpdateQueued) {
898
886
  return `${minHeight}overflow-x:auto`;
899
887
  }
900
- return `${minHeight}${getCSSWidthStyleOfTable(this.widthsData)}`;
888
+ const { tableWidth } = this.widthsData;
889
+ return tableWidth ? `width: ${tableWidth}px;` : '';
901
890
  }
902
891
 
903
- get scrollerXStyles() {
904
- const styles = {
905
- height: '100%',
906
- };
907
-
892
+ get computedScrollerXStyle() {
893
+ let style = 'height: 100%;';
908
894
  if (this.showStatusBar) {
909
- styles['padding-bottom'] = '3rem';
895
+ style += 'padding-bottom: 3rem;';
910
896
  }
911
-
912
897
  if (this._columnWidthManager.isAutoResizingUpdateQueued) {
913
- styles['overflow-x'] = 'auto';
898
+ style += 'overflow-x: auto;';
914
899
  }
915
-
916
- if (this.wrapTableHeader) {
900
+ if (this.state.wrapTableHeader) {
917
901
  // increase padding from 2rem to 3rem on the top when header wraps
918
- styles['padding-top'] = '3rem';
902
+ style += 'padding-top: 3rem;';
919
903
  }
920
-
921
- return styleToString(styles);
904
+ return style;
922
905
  }
923
906
 
924
907
  /**
@@ -931,17 +914,15 @@ export default class LightningDatatable extends LightningElement {
931
914
  }
932
915
 
933
916
  get computedAriaLiveClassForNavMode() {
934
- const keyboardMode = this.state.keyboardMode;
935
- return classSet()
936
- .add({
937
- 'slds-hide': keyboardMode !== 'NAVIGATION',
938
- 'slds-assistive-text': keyboardMode === 'NAVIGATION',
939
- })
940
- .toString();
917
+ const isNavMode = this.state.keyboardMode === KEYBOARD_NAVIGATION_MODE;
918
+ return classSetToString({
919
+ 'slds-hide': !isNavMode,
920
+ 'slds-assistive-text': isNavMode,
921
+ });
941
922
  }
942
923
 
943
924
  get computedAriaLiveClassForActionMode() {
944
- const isActionMode = this.state.keyboardMode === 'ACTION';
925
+ const isActionMode = this.state.keyboardMode === KEYBOARD_ACTION_MODE;
945
926
  return classSetToString({
946
927
  'slds-hide': !isActionMode,
947
928
  'slds-assistive-text': isActionMode,
@@ -958,7 +939,7 @@ export default class LightningDatatable extends LightningElement {
958
939
  }
959
940
 
960
941
  get hasValidKeyField() {
961
- if (hasValidKeyField(this.state)) {
942
+ if (typeof this.state.keyField === 'string') {
962
943
  return true;
963
944
  }
964
945
  // eslint-disable-next-line no-console
@@ -968,12 +949,8 @@ export default class LightningDatatable extends LightningElement {
968
949
  return false;
969
950
  }
970
951
 
971
- get numberOfColumns() {
972
- return getColumns(this.state).length;
973
- }
974
-
975
952
  get hasResizebleColumns() {
976
- return !isResizeColumnDisabled(this.widthsData);
953
+ return !this.widthsData.resizeColumnDisabled;
977
954
  }
978
955
 
979
956
  get privateTypes() {
@@ -1004,15 +981,15 @@ export default class LightningDatatable extends LightningElement {
1004
981
  }
1005
982
 
1006
983
  get showSelectAllCheckbox() {
1007
- return !getHideSelectAllCheckbox(this.state);
984
+ return this.state.maxRowSelection !== 1;
1008
985
  }
1009
986
 
1010
987
  get showStatusBar() {
1011
- return isInlineEditTriggered(this.state) && !this.suppressBottomBar;
988
+ return !this._suppressBottomBar && isInlineEditTriggered(this.state);
1012
989
  }
1013
990
 
1014
991
  get tableError() {
1015
- return getTableError(this.state);
992
+ return this.state.errors.table;
1016
993
  }
1017
994
 
1018
995
  get i18n() {
@@ -1030,12 +1007,11 @@ export default class LightningDatatable extends LightningElement {
1030
1007
  constructor() {
1031
1008
  super();
1032
1009
 
1033
- this._privateTypes = new DatatableTypes(this.constructor.customTypes);
1034
1010
  this._columnWidthManager = new ColumnWidthManager(this.widthsData);
1035
- this.updateRowsAndCellIndexes = updateRowsAndCellIndexes.bind(this);
1011
+ this._privateTypes = new DatatableTypes(this.constructor.customTypes);
1036
1012
 
1037
1013
  this._renderManager = new RenderManager();
1038
- this.getWrapperHeight = getDTWrapperHeight.bind(this);
1014
+ this.getWrapperHeight = () => getScrollerX(this.template).offsetHeight;
1039
1015
  }
1040
1016
 
1041
1017
  /**
@@ -1043,84 +1019,75 @@ export default class LightningDatatable extends LightningElement {
1043
1019
  */
1044
1020
  connectedCallback() {
1045
1021
  const { template } = this;
1046
- const {
1047
- handleResizeColumn,
1048
- handleUpdateColumnSort,
1049
- handleCellFocusByClick,
1050
- handleFalseCellBlur,
1051
- handleSelectionCellClick,
1052
- } = this;
1053
1022
 
1054
1023
  // Row selection and de-selection
1055
- this.addEventListener(
1056
- 'rowselection',
1057
- handleRowSelectionChange.bind(this)
1058
- );
1059
- template.addEventListener(
1060
- 'selectallrows',
1061
- handleSelectionCellClick.bind(this)
1062
- );
1063
- template.addEventListener(
1064
- 'deselectallrows',
1065
- handleSelectionCellClick.bind(this)
1066
- );
1067
- template.addEventListener(
1068
- 'selectrow',
1069
- handleSelectionCellClick.bind(this)
1070
- );
1071
- template.addEventListener(
1072
- 'deselectrow',
1073
- handleSelectionCellClick.bind(this)
1074
- );
1024
+ this.addEventListener('rowselection', (event) => {
1025
+ this.handleRowSelectionChange(event);
1026
+ });
1027
+ template.addEventListener('selectallrows', (event) => {
1028
+ this.handleSelectionCellClick(event);
1029
+ });
1030
+ template.addEventListener('deselectallrows', (event) => {
1031
+ this.handleSelectionCellClick(event);
1032
+ });
1033
+ template.addEventListener('selectrow', (event) => {
1034
+ this.handleSelectionCellClick(event);
1035
+ });
1036
+ template.addEventListener('deselectrow', (event) => {
1037
+ this.handleSelectionCellClick(event);
1038
+ });
1075
1039
  // Column resizing
1076
- template.addEventListener('resizecol', handleResizeColumn.bind(this));
1040
+ template.addEventListener('resizecol', (event) => {
1041
+ this.handleResizeColumn(event);
1042
+ });
1077
1043
  // Column sorting
1078
- template.addEventListener(
1079
- 'privateupdatecolsort',
1080
- handleUpdateColumnSort.bind(this)
1081
- );
1044
+ template.addEventListener('privateupdatecolsort', (event) => {
1045
+ this.handleUpdateColumnSort(event);
1046
+ });
1082
1047
  // Cell interaction
1083
- template.addEventListener(
1084
- 'privatecellkeydown',
1085
- handleKeydownOnCell.bind(this)
1086
- );
1087
- template.addEventListener(
1088
- 'privatecellfocusedbyclick',
1089
- handleCellFocusByClick.bind(this)
1090
- );
1091
- template.addEventListener(
1092
- 'privatecellfalseblurred',
1093
- handleFalseCellBlur.bind(this)
1094
- );
1048
+ template.addEventListener('privatecellkeydown', (event) => {
1049
+ this.handleKeydownOnCell(event);
1050
+ });
1051
+ template.addEventListener('privatecellfocusedbyclick', (event) => {
1052
+ this.handleCellFocusByClick(event);
1053
+ });
1054
+ template.addEventListener('privatecellfalseblurred', (event) => {
1055
+ this.handleFalseCellBlur(event);
1056
+ });
1095
1057
  // Row level actions
1096
- template.addEventListener(
1097
- 'privatecellactiontriggered',
1098
- handleRowActionTriggered.bind(this)
1099
- );
1100
- template.addEventListener(
1101
- 'privatecellactionmenuopening',
1102
- handleLoadDynamicActions.bind(this)
1103
- );
1104
- template.addEventListener(
1105
- 'privatecellbuttonclicked',
1106
- handleCellButtonClick.bind(this)
1107
- );
1058
+ template.addEventListener('privatecellactiontriggered', (event) => {
1059
+ this.handleRowActionTriggered(event);
1060
+ });
1061
+ template.addEventListener('privatecellactionmenuopening', (event) => {
1062
+ this.handleLoadDynamicActions(event);
1063
+ });
1064
+ template.addEventListener('privatecellbuttonclicked', (event) => {
1065
+ this.handleCellButtonClick(event);
1066
+ });
1108
1067
 
1109
- // Header Actions
1068
+ // Header actions
1110
1069
  template.addEventListener(
1111
1070
  'privatecellheaderactionmenuopening',
1112
- handleHeaderActionMenuOpening.bind(this)
1071
+ (event) => {
1072
+ this.handleHeaderActionMenuOpening(event);
1073
+ }
1113
1074
  );
1114
1075
  template.addEventListener(
1115
1076
  'privatecellheaderactionmenuclosed',
1116
- handleHeaderActionMenuClosed.bind(this)
1077
+ (event) => {
1078
+ this.handleHeaderActionMenuClosed(event);
1079
+ }
1117
1080
  );
1118
1081
  template.addEventListener(
1119
1082
  'privatecellheaderactiontriggered',
1120
- handleHeaderActionTriggered.bind(this)
1083
+ (event) => {
1084
+ this.handleHeaderActionTriggered(event);
1085
+ }
1121
1086
  );
1122
1087
  // Inline edit
1123
- template.addEventListener('privateeditcell', handleEditCell.bind(this));
1088
+ template.addEventListener('privateeditcell', (event) => {
1089
+ this.handleEditCell(event);
1090
+ });
1124
1091
  }
1125
1092
 
1126
1093
  /**
@@ -1143,21 +1110,8 @@ export default class LightningDatatable extends LightningElement {
1143
1110
  'aria-describedby': this.ariaDescribedBy,
1144
1111
  });
1145
1112
 
1146
- let { _privateWidthObserver } = this;
1147
- if (!_privateWidthObserver) {
1148
- _privateWidthObserver = new LightningDatatableResizeObserver(
1149
- template,
1150
- state,
1151
- widthsData,
1152
- _columnWidthManager
1153
- );
1154
- this._privateWidthObserver = _privateWidthObserver;
1155
- } else if (!_privateWidthObserver.isConnected()) {
1156
- _privateWidthObserver.observe(template);
1157
- }
1158
-
1159
1113
  if (_columnWidthManager.isResizingUpdateQueued) {
1160
- const columns = getColumns(state);
1114
+ const { columns } = state;
1161
1115
  const fireResizeEvent = _columnWidthManager.shouldFireResizeEvent(
1162
1116
  widthsData,
1163
1117
  columns
@@ -1168,26 +1122,44 @@ export default class LightningDatatable extends LightningElement {
1168
1122
  columns,
1169
1123
  widthsData
1170
1124
  );
1171
-
1172
1125
  if (fireResizeEvent) {
1173
1126
  this.fireOnResize(false);
1174
1127
  }
1175
1128
  this.updateTableAndScrollerStyleOnRender();
1176
1129
  }
1177
1130
 
1131
+ let { _widthObserver } = this;
1132
+ if (!_widthObserver) {
1133
+ // Tracked state changes.
1134
+ _widthObserver = new LightningDatatableResizeObserver(
1135
+ template,
1136
+ () => {
1137
+ // Tracked state change.
1138
+ _columnWidthManager.adjustColumnsSizeAfterResize(
1139
+ template,
1140
+ state.columns,
1141
+ widthsData
1142
+ );
1143
+ }
1144
+ );
1145
+ this._widthObserver = _widthObserver;
1146
+ } else if (!_widthObserver.isConnected()) {
1147
+ _widthObserver.observe(template);
1148
+ }
1149
+
1178
1150
  // Managing the cell widths is only required for the role-based table
1179
1151
  if (state.renderModeRoleBased) {
1180
1152
  // TODO: Look to further optimize - Do this only when required
1181
1153
  recomputeCellStyles(this.privateTypes, state);
1182
1154
  }
1183
1155
 
1184
- handlePrefetch.call(this, template, state);
1156
+ handlePrefetch.call(this);
1185
1157
 
1186
1158
  // customerSelectedRows is only valid till render, after it, the one
1187
1159
  // used should be the one from the state.
1188
1160
  this._customerSelectedRows = null;
1189
1161
  // Set the previous focused cell to null after render is done.
1190
- resetCellToFocusFromPrev(state);
1162
+ state.cellToFocusNext = undefined;
1191
1163
 
1192
1164
  // Reset focus styles on re-render.
1193
1165
  if (this._shouldResetFocus) {
@@ -1207,7 +1179,7 @@ export default class LightningDatatable extends LightningElement {
1207
1179
  !cellElement.parentElement.classList.contains(FOCUS_CLASS)
1208
1180
  ) {
1209
1181
  // Tracked state change.
1210
- setFocusActiveCell(template, state, null, null, false);
1182
+ setFocusActiveCell(state, template, null, null, false);
1211
1183
  }
1212
1184
  }
1213
1185
  }
@@ -1237,21 +1209,20 @@ export default class LightningDatatable extends LightningElement {
1237
1209
  }
1238
1210
 
1239
1211
  updateTableAndScrollerStyleOnRender() {
1240
- const role = '[role="' + this.computedTableRole + '"]';
1241
- const tableElement = this.template.querySelector(role);
1242
- const scrollYEle = this.template.querySelector('.slds-scrollable_y');
1212
+ const scrollYEle = getScrollerY(this.template);
1213
+ const tableElement = getGridContainerFromScrollerY(scrollYEle);
1243
1214
  if (tableElement) {
1244
1215
  tableElement.style = this.computedTableStyle;
1245
1216
  }
1246
1217
  if (scrollYEle) {
1247
- scrollYEle.style = this.computedScrollerStyle;
1218
+ scrollYEle.style = this.computedScrollerYStyle;
1248
1219
  }
1249
1220
  }
1250
1221
 
1251
1222
  disconnectedCallback() {
1252
- const { _privateWidthObserver } = this;
1253
- if (_privateWidthObserver) {
1254
- _privateWidthObserver.disconnect();
1223
+ const { _widthObserver } = this;
1224
+ if (_widthObserver) {
1225
+ _widthObserver.disconnect();
1255
1226
  }
1256
1227
 
1257
1228
  this._renderManager.disconnectResizeObserver();
@@ -1259,6 +1230,24 @@ export default class LightningDatatable extends LightningElement {
1259
1230
 
1260
1231
  /************************** EVENT HANDLERS ***************************/
1261
1232
 
1233
+ handleCellButtonClick = handleCellButtonClick;
1234
+
1235
+ handleEditCell = handleEditCell;
1236
+
1237
+ handleHeaderActionMenuClosed = handleHeaderActionMenuClosed;
1238
+
1239
+ handleHeaderActionMenuOpening = handleHeaderActionMenuOpening;
1240
+
1241
+ handleHeaderActionTriggered = handleHeaderActionTriggered;
1242
+
1243
+ handleKeydownOnCell = handleKeydownOnCell;
1244
+
1245
+ handleLoadDynamicActions = handleLoadDynamicActions;
1246
+
1247
+ handleRowSelectionChange = handleRowSelectionChange;
1248
+
1249
+ handleRowActionTriggered = handleRowActionTriggered;
1250
+
1262
1251
  handleCustomTypesChange() {
1263
1252
  const assignedNodes = this.template
1264
1253
  .querySelector('slot[name="customdatatypes"]')
@@ -1269,33 +1258,31 @@ export default class LightningDatatable extends LightningElement {
1269
1258
  this._privateTypes = new DatatableTypes(
1270
1259
  provider.getDataTypes()
1271
1260
  );
1272
- this.updateColumns(this._columns);
1261
+ this.updateColumns(this._rawColumns);
1273
1262
  }
1274
1263
  }
1275
1264
  }
1276
1265
 
1277
1266
  /**
1278
- * Handles the `keydown` event on <table> and the
1267
+ * Handles the 'keydown' event on <table> and the
1279
1268
  * corresponding <div> on the role-based table
1280
1269
  *
1281
- * @param {KeyboardEvent} event - `keydown`
1270
+ * @param {KeyboardEvent} event - 'keydown'
1282
1271
  */
1283
- handleTableKeydown(event) {
1284
- handleKeydownOnTable.call(this, event);
1285
- }
1272
+ handleTableKeydown = handleKeydownOnTable;
1286
1273
 
1287
1274
  /**
1288
- * Handles the `keydown` event on data row <tr> (table-based) and div[role="row"] (role-based)
1275
+ * Handles the 'keydown' event on data row <tr> (table-based) and div[role="row"] (role-based)
1289
1276
  *
1290
- * @param {KeyboardEvent} event - `keydown`
1277
+ * @param {KeyboardEvent} event - 'keydown'
1291
1278
  */
1292
1279
  handleKeydownOnDataRow(event) {
1293
1280
  const { state } = this;
1294
1281
  // we probably should not be doing this unless we actually are interested in it
1295
- if (state.keyboardMode === 'NAVIGATION' && state.rowMode === true) {
1282
+ if (state.keyboardMode === KEYBOARD_NAVIGATION_MODE && state.rowMode) {
1296
1283
  event.stopPropagation();
1297
1284
  const { currentTarget: tr } = event;
1298
- reactToKeyboardOnRow(this, state, {
1285
+ reactToKeyboardOnRow(this, {
1299
1286
  target: tr,
1300
1287
  detail: {
1301
1288
  keyCode: event.keyCode,
@@ -1310,23 +1297,23 @@ export default class LightningDatatable extends LightningElement {
1310
1297
  }
1311
1298
 
1312
1299
  /**
1313
- * Handles the `scroll` event on the table container
1300
+ * Handles the 'scroll' event on the table container
1314
1301
  *
1315
- * @param {Event} event - `scroll`
1302
+ * @param {Event} event - 'scroll'
1316
1303
  */
1317
1304
  handleHorizontalScroll(event) {
1318
1305
  handleInlineEditPanelScroll.call(this, event);
1319
1306
  }
1320
1307
 
1321
1308
  /**
1322
- * Handles the `scroll` event on the child of the
1323
- * table container at div.slds-scrollable_y
1309
+ * Handles the 'scroll' event on the child of the
1310
+ * table container at div.slds-scrollable_y.
1324
1311
  *
1325
- * @param {Event} event - `scroll`
1312
+ * @param {Event} event - 'scroll'
1326
1313
  */
1327
1314
  handleVerticalScroll(event) {
1328
1315
  const { state } = this;
1329
- if (this.enableInfiniteLoading) {
1316
+ if (state.enableInfiniteLoading) {
1330
1317
  handleLoadMoreCheck.call(this, event);
1331
1318
  }
1332
1319
 
@@ -1348,15 +1335,13 @@ export default class LightningDatatable extends LightningElement {
1348
1335
  *
1349
1336
  * @param {MouseEvent} event - `click`
1350
1337
  */
1351
- handleCellClick(event) {
1338
+ handleTableCellClick(event) {
1352
1339
  // handles the case when clicking on the margin/pading of the td/th
1353
- const targetTagName = event.target.tagName.toLowerCase();
1354
- const targetRole = event.target.getAttribute('role');
1355
-
1356
- if (isCellElement(targetTagName, targetRole)) {
1340
+ const { target } = event;
1341
+ if (isCellElement(target)) {
1357
1342
  // get the row/col key value from the primitive cell.
1358
1343
  const { rowKeyValue, colKeyValue } =
1359
- event.target.querySelector(':first-child');
1344
+ target.querySelector(':first-child');
1360
1345
 
1361
1346
  const { state, template } = this;
1362
1347
  if (
@@ -1378,9 +1363,9 @@ export default class LightningDatatable extends LightningElement {
1378
1363
  }
1379
1364
 
1380
1365
  /**
1381
- * Handles the `privateupdatecolsort` event on lightning-datatable
1366
+ * Handles the 'privateupdatecolsort' event on lightning-datatable
1382
1367
  *
1383
- * @param {CustomEvent} event - `privateupdatecolsort`
1368
+ * @param {CustomEvent} event - 'privateupdatecolsort'
1384
1369
  */
1385
1370
  handleUpdateColumnSort(event) {
1386
1371
  event.stopPropagation();
@@ -1393,9 +1378,9 @@ export default class LightningDatatable extends LightningElement {
1393
1378
  }
1394
1379
 
1395
1380
  /**
1396
- * Handles the `resizecol` event on lightning-datatable
1381
+ * Handles the 'resizecol' event on lightning-datatable
1397
1382
  *
1398
- * @param {CustomEvent} event - `resizecol`
1383
+ * @param {CustomEvent} event - 'resizecol'
1399
1384
  */
1400
1385
  handleResizeColumn(event) {
1401
1386
  event.stopPropagation();
@@ -1403,21 +1388,21 @@ export default class LightningDatatable extends LightningElement {
1403
1388
  const { colIndex, widthDelta: delta } = event.detail;
1404
1389
  if (delta !== 0) {
1405
1390
  resizeColumnWithDelta(
1406
- getColumns(state),
1391
+ state.columns,
1407
1392
  this.widthsData,
1408
1393
  colIndex,
1409
1394
  delta
1410
1395
  );
1411
1396
  this.fireOnResize(true);
1412
- this.safariHeaderFix();
1397
+ this.fixHeaderForSafari();
1413
1398
  }
1414
1399
  }
1415
1400
 
1416
1401
  /**
1417
- * Handles the `privateresizestart` event on the <tr> and the corresponding
1402
+ * Handles the 'privateresizestart' event on the <tr> and the corresponding
1418
1403
  * <div> in the role-based table on the column header row
1419
1404
  *
1420
- * @param {CustomEvent} event - `privateresizestart`
1405
+ * @param {CustomEvent} event - 'privateresizestart'
1421
1406
  */
1422
1407
  handleResizeStart(event) {
1423
1408
  event.stopPropagation();
@@ -1425,10 +1410,10 @@ export default class LightningDatatable extends LightningElement {
1425
1410
  }
1426
1411
 
1427
1412
  /**
1428
- * Handles the `privateresizeend` event on the <tr> and the corresponding
1413
+ * Handles the 'privateresizeend' event on the <tr> and the corresponding
1429
1414
  * <div> in the role-based table on the column header row
1430
1415
  *
1431
- * @param {CustomEvent} event - `privateresizeend`
1416
+ * @param {CustomEvent} event - 'privateresizeend'
1432
1417
  */
1433
1418
  handleResizeEnd(event) {
1434
1419
  event.stopPropagation();
@@ -1457,9 +1442,9 @@ export default class LightningDatatable extends LightningElement {
1457
1442
  }
1458
1443
 
1459
1444
  /**
1460
- * Handles the `privatecellfocusedbyclick` event on lightning-datatable
1445
+ * Handles the 'privatecellfocusedbyclick' event on lightning-datatable
1461
1446
  *
1462
- * @param {CustomEvent} event - `privatecellfocusedbyclick`
1447
+ * @param {CustomEvent} event - 'privatecellfocusedbyclick'
1463
1448
  */
1464
1449
  handleCellFocusByClick(event) {
1465
1450
  event.stopPropagation();
@@ -1473,14 +1458,14 @@ export default class LightningDatatable extends LightningElement {
1473
1458
  updateRowTabIndex(state, rowIndex, -1);
1474
1459
  }
1475
1460
  this.setActiveCell(rowKeyValue, colKeyValue);
1476
- refocusCellElement(this.template, state, needsRefocusOnCellElement);
1461
+ refocusCellElement(state, this.template, needsRefocusOnCellElement);
1477
1462
  }
1478
1463
  }
1479
1464
 
1480
1465
  /**
1481
- * Handles the `privatecellfalseblurred` event on lightning-datatable
1466
+ * Handles the 'privatecellfalseblurred' event on lightning-datatable
1482
1467
  *
1483
- * @param {CustomEvent} event - `privatecellfalseblurred`
1468
+ * @param {CustomEvent} event - 'privatecellfalseblurred'
1484
1469
  */
1485
1470
  handleFalseCellBlur(event) {
1486
1471
  event.stopPropagation();
@@ -1490,21 +1475,19 @@ export default class LightningDatatable extends LightningElement {
1490
1475
  this.setActiveCell(rowKeyValue, colKeyValue);
1491
1476
  }
1492
1477
  // Tracked state change.
1493
- setFocusActiveCell(this.template, state);
1478
+ setFocusActiveCell(state, this.template);
1494
1479
  }
1495
1480
 
1496
1481
  /**
1497
- * Handles the `focusin` event on <table> and the corresponding
1482
+ * Handles the 'focusin' event on <table> and the corresponding
1498
1483
  * <div> on the role-based table
1499
1484
  *
1500
- * @param {FocusEvent} event - `focusin`
1485
+ * @param {FocusEvent} event - 'focusin'
1501
1486
  */
1502
- handleTableFocusIn(event) {
1503
- handleDatatableFocusIn.call(this, event);
1504
- }
1487
+ handleTableFocusIn = handleDatatableFocusIn;
1505
1488
 
1506
1489
  /**
1507
- * Handles the `focusout` event on <table> and the corresponding
1490
+ * Handles the 'focusout' event on <table> and the corresponding
1508
1491
  * <div> on the role-based table
1509
1492
  *
1510
1493
  * This gets called both when we expect the table to lose focus
@@ -1515,7 +1498,7 @@ export default class LightningDatatable extends LightningElement {
1515
1498
  * _shouldResetFocus, which will be true if and only if focus was
1516
1499
  * lost due to a renderedRows change for a virtualized table.
1517
1500
  *
1518
- * @param {FocusEvent} event - `focusout`
1501
+ * @param {FocusEvent} event - 'focusout'
1519
1502
  */
1520
1503
  handleTableFocusOut(event) {
1521
1504
  handleDatatableFocusOut.call(this, event);
@@ -1526,31 +1509,27 @@ export default class LightningDatatable extends LightningElement {
1526
1509
  }
1527
1510
 
1528
1511
  /**
1529
- * Handles the `ieditfinished` event on the inline edit panel -
1512
+ * Handles the 'ieditfinished' event on the inline edit panel -
1530
1513
  * `lightning-primitive-datatable-iedit-panel`
1531
1514
  *
1532
- * @param {CustomEvent} event - `ieditfinished`
1515
+ * @param {CustomEvent} event - 'ieditfinished'
1533
1516
  */
1534
- handleInlineEditFinish(event) {
1535
- handleInlineEditFinish.call(this, event);
1536
- }
1517
+ handleInlineEditFinish = handleInlineEditFinish;
1537
1518
 
1538
1519
  /**
1539
- * Handles the `masscheckboxchange` event on the inline edit panel -
1520
+ * Handles the 'masscheckboxchange' event on the inline edit panel -
1540
1521
  * `lightning-primitive-datatable-iedit-panel`
1541
1522
  *
1542
- * @param {CustomEvent} event - `masscheckboxchange`
1523
+ * @param {CustomEvent} event - 'masscheckboxchange'
1543
1524
  */
1544
- handleMassCheckboxChange(event) {
1545
- handleMassCheckboxChange.call(this, event);
1546
- }
1525
+ handleMassCheckboxChange = handleMassCheckboxChange;
1547
1526
 
1548
1527
  /**
1549
- * Handles the `privatesave` event on the status bar -
1528
+ * Handles the 'privatesave' event on the status bar -
1550
1529
  * `lightning-primitive-datatable-status-bar` and
1551
1530
  * fires the `save` custom event
1552
1531
  *
1553
- * @param {CustomEvent} event - `privatesave`
1532
+ * @param {CustomEvent} event - 'privatesave'
1554
1533
  */
1555
1534
  handleInlineEditSave(event) {
1556
1535
  event.stopPropagation();
@@ -1567,11 +1546,11 @@ export default class LightningDatatable extends LightningElement {
1567
1546
  }
1568
1547
 
1569
1548
  /**
1570
- * Handles the `privatecancel` event on the status bar -
1549
+ * Handles the 'privatecancel' event on the status bar -
1571
1550
  * `lightning-primitive-datatable-status-bar` and
1572
1551
  * fires the `cancel` custom event
1573
1552
  *
1574
- * @param {CustomEvent} event - `privatecancel`
1553
+ * @param {CustomEvent} event - 'privatecancel'
1575
1554
  */
1576
1555
  handleInlineEditCancel(event) {
1577
1556
  event.stopPropagation();
@@ -1593,17 +1572,16 @@ export default class LightningDatatable extends LightningElement {
1593
1572
 
1594
1573
  /**
1595
1574
  * @event LightningDatatable#onprivatelookupitempicked We need to augment the original event LightningFormattedLookup#onprivatelookupitempicked
1596
- * @type {object}
1597
- * @property {string} recordId
1598
- * @property {number} rowIndex
1599
- * @property {string} rowKeyValue
1575
+ * @type {Object}
1576
+ * @property {String} recordId
1577
+ * @property {Number} rowIndex
1578
+ * @property {String} rowKeyValue
1600
1579
  */
1601
-
1602
1580
  /**
1603
- * Handles the `privatelookupitempicked` event from the lightning-formatted-lookup or force-lookup
1604
- * `lightning-primitive-datatable-status-bar` and fires the augmented `privatelookupitempicked` custom event
1581
+ * Handles the 'privatelookupitempicked' event from the lightning-formatted-lookup or force-lookup
1582
+ * `lightning-primitive-datatable-status-bar` and fires the augmented 'privatelookupitempicked' custom event
1605
1583
  *
1606
- * @param {CustomEvent} event - `privatelookupitempicked`
1584
+ * @param {CustomEvent} event - 'privatelookupitempicked'
1607
1585
  * @fires LightningDatatable#onprivatelookupitempicked
1608
1586
  */
1609
1587
  handlePrivateLookupItemPicked(event) {
@@ -1635,55 +1613,65 @@ export default class LightningDatatable extends LightningElement {
1635
1613
 
1636
1614
  /************************ EVENT DISPATCHERS **************************/
1637
1615
 
1638
- fireSelectedRowsChange(selectedRows, config) {
1639
- const event = new CustomEvent('rowselection', {
1640
- detail: { selectedRows, config: config || {} },
1641
- });
1642
-
1643
- this.dispatchEvent(event);
1616
+ fireSelectedRowsChange(selectedRows, config = {}) {
1617
+ this.dispatchEvent(
1618
+ new CustomEvent('rowselection', {
1619
+ detail: { selectedRows, config },
1620
+ })
1621
+ );
1644
1622
  }
1645
1623
 
1646
1624
  fireSortedColumnChange(fieldName, columnKey, sortDirection) {
1647
- const event = new CustomEvent('sort', {
1648
- detail: { fieldName, columnKey, sortDirection },
1649
- });
1650
- this.dispatchEvent(event);
1625
+ this.dispatchEvent(
1626
+ new CustomEvent('sort', {
1627
+ detail: { fieldName, columnKey, sortDirection },
1628
+ })
1629
+ );
1651
1630
  }
1652
1631
 
1653
1632
  fireOnResize(isUserTriggered) {
1654
- const { state, widthsData } = this;
1655
- const event = new CustomEvent('resize', {
1656
- detail: {
1657
- columnWidths: getCustomerColumnWidths(
1658
- getColumns(state),
1659
- widthsData
1660
- ),
1661
- isUserTriggered: !!isUserTriggered,
1662
- },
1663
- });
1664
- this.dispatchEvent(event);
1633
+ this.dispatchEvent(
1634
+ new CustomEvent('resize', {
1635
+ detail: {
1636
+ columnWidths: getCustomerColumnWidths(
1637
+ this.state.columns,
1638
+ this.widthsData
1639
+ ),
1640
+ isUserTriggered: !!isUserTriggered,
1641
+ },
1642
+ })
1643
+ );
1665
1644
  }
1666
1645
 
1667
1646
  /************************* HELPER FUNCTIONS **************************/
1668
1647
 
1669
1648
  updateRowsState() {
1670
- const { state, widthsData, template } = this;
1671
- // calculate cell to focus next before indexes are updated
1672
- setCellToFocusFromPrev(state, template);
1649
+ this.updateRowsBeforeIndexes();
1650
+ this.updateRowsAndCells();
1651
+ this.updateRowsAfterIndexes();
1652
+ }
1673
1653
 
1674
- this.updateRowsAndCellIndexes(state);
1654
+ updateRowsBeforeIndexes() {
1655
+ // Untracked state change.
1656
+ setCellToFocusFromPrev(this.state, this.template);
1657
+ }
1675
1658
 
1659
+ updateRowsAfterIndexes() {
1660
+ const { state, widthsData } = this;
1676
1661
  if (this.viewportRendering || state.virtualize) {
1677
1662
  this._renderManager.updateViewportRendering(
1678
- this.state,
1663
+ state,
1679
1664
  this.gridContainer,
1680
1665
  !!state.virtualize
1681
1666
  );
1682
1667
  }
1683
1668
 
1669
+ // Tracked state changes.
1684
1670
  this._columnWidthManager.handleRowNumberOffsetChange(state, widthsData);
1685
- // update celltofocus next to null if the row still exists after indexes calculation
1671
+ // Untracked state change.
1672
+ // Unset the cellToFocusNext if the row still exists after indexes calculation.
1686
1673
  updateCellToFocusFromPrev(state);
1674
+ // A mix of tracked and untracked state changes.
1687
1675
  syncSelectedRowsKeys(state, this.getSelectedRows()).ifChanged(() => {
1688
1676
  // Only trigger row selection event once after all the setters have executed
1689
1677
  // Otherwise, event can be fired with stale data if not all setters have been triggered
@@ -1697,52 +1685,77 @@ export default class LightningDatatable extends LightningElement {
1697
1685
  });
1698
1686
  }
1699
1687
  });
1688
+ // Untracked state change.
1700
1689
  syncActiveCell(state);
1701
1690
 
1702
- if (state.keyboardMode === 'NAVIGATION') {
1691
+ if (state.keyboardMode === KEYBOARD_NAVIGATION_MODE) {
1692
+ // Tracked state changes.
1703
1693
  updateTabIndexActiveCell(state);
1704
1694
  updateTabIndexActiveRow(state);
1705
1695
  }
1706
- // if there is previously focused cell which was deleted set focus from celltofocus next
1707
- if (state.cellToFocusNext && state.activeCell) {
1708
- setFocusActiveCell(this.template, this.state);
1696
+ // if there is previously focused cell which was deleted set focus from cellToFocusNext
1697
+ if (state.activeCell && state.cellToFocusNext) {
1698
+ // Tracked state change.
1699
+ setFocusActiveCell(state, this.template);
1709
1700
  }
1710
1701
  }
1711
1702
 
1712
1703
  updateColumns(columns) {
1713
- const { state, widthsData, template } = this;
1704
+ const { state } = this;
1705
+ this.updateColumnsBeforeIndexes(columns);
1706
+ state.headerIndexes = generateHeaderIndexes(state.columns);
1707
+ this.updateRowsAndCells();
1708
+ this.updateColumnsAfterIndexes();
1709
+ }
1710
+
1711
+ updateColumnsBeforeIndexes(columns) {
1712
+ const { state } = this;
1714
1713
  const hadTreeDataTypePreviously = hasTreeDataType(state);
1715
- // calculate cell to focus next before indexes are updated
1716
- setCellToFocusFromPrev(state, template);
1714
+ // Untracked state changes.
1715
+ // Calculate cell to focus next before indexes are updated.
1716
+ setCellToFocusFromPrev(state, this.template);
1717
1717
  normalizeColumns(state, columns, this.privateTypes);
1718
- setDirtyValues(state, this._draftValues);
1719
1718
  updateRowNavigationMode(hadTreeDataTypePreviously, state);
1720
- state.headerIndexes = generateHeaderIndexes(getColumns(state));
1719
+ // Tracked state changes.
1720
+ setDirtyValues(state, this._draftValues);
1721
1721
  // Updates state.wrapText and when isWrappableType, sets internal header actions
1722
- updateHeaderActions(state);
1723
- this.updateRowsAndCellIndexes(state);
1722
+ updateHeaderInternalActions(state);
1723
+ }
1724
+
1725
+ updateColumnsAfterIndexes() {
1726
+ const { state, widthsData } = this;
1727
+
1728
+ // Tracked state changes.
1724
1729
  updateBulkSelectionState(state);
1725
1730
  this._columnWidthManager.handleRowNumberOffsetChange(state, widthsData);
1726
- updateColumnWidthsMetadata(getColumns(state), widthsData);
1727
- // set the celltofocus next to null if the column still exists after indexes calculation
1731
+ updateColumnWidthsMetadata(state.columns, widthsData);
1732
+ // Unset the cellToFocusNext if the column still exists after indexes calculation.
1728
1733
  updateCellToFocusFromPrev(state);
1729
1734
 
1730
- if (getColumns(state).length !== getColumnsWidths(widthsData).length) {
1731
- if (getData(state).length > 0) {
1732
- // when there are column changes, update the active cell
1733
- syncActiveCell(state);
1734
- }
1735
+ if (
1736
+ state.data.length > 0 &&
1737
+ state.columns.length !== widthsData.columnWidths.length
1738
+ ) {
1739
+ // Untracked state change.
1740
+ // When there are column changes, update the active cell.
1741
+ syncActiveCell(state);
1735
1742
  }
1736
- if (state.keyboardMode === 'NAVIGATION') {
1743
+ if (state.keyboardMode === KEYBOARD_NAVIGATION_MODE) {
1744
+ // Tracked state changes.
1737
1745
  updateTabIndexActiveCell(state);
1738
1746
  updateTabIndexActiveRow(state);
1739
1747
  }
1740
- // if there is previously focused cell which was deleted set focus from celltofocus next
1741
- if (state.cellToFocusNext && state.activeCell) {
1742
- setFocusActiveCell(this.template, this.state);
1748
+ // If there is previously focused cell which was deleted set focus from cellToFocusNext.
1749
+ if (state.activeCell && state.cellToFocusNext) {
1750
+ // Tracked state change.
1751
+ setFocusActiveCell(state, this.template);
1743
1752
  }
1744
1753
  }
1745
1754
 
1755
+ updateRowsAndCells() {
1756
+ updateRowsAndCellIndexes(this.state, this._privateTypes);
1757
+ }
1758
+
1746
1759
  updateVirtualizedRowHeights() {
1747
1760
  const state = this.state;
1748
1761
  const virtualizedRows = state.virtualize && this.renderedRows.length;
@@ -1768,10 +1781,9 @@ export default class LightningDatatable extends LightningElement {
1768
1781
  state.rowHeight = height;
1769
1782
  resetTableHeight(state);
1770
1783
  state.rows.forEach((row) => {
1771
- row.style = styleToString({
1772
- position: 'absolute',
1773
- top: `${row.rowIndex * height}px`,
1774
- });
1784
+ row.style = `position:absolute;top:${
1785
+ row.rowIndex * height
1786
+ }px;`;
1775
1787
  });
1776
1788
  }
1777
1789
  }
@@ -1780,19 +1792,22 @@ export default class LightningDatatable extends LightningElement {
1780
1792
 
1781
1793
  setSelectedRows(value) {
1782
1794
  setSelectedRowsKeys(this.state, value);
1783
- handleRowSelectionChange.call(this);
1795
+ this.handleRowSelectionChange();
1784
1796
  }
1785
1797
 
1786
1798
  setActiveCell(rowKeyValue, colKeyValue) {
1787
- const { template, state } = this;
1799
+ const { state, template } = this;
1788
1800
  const { rowIndex, colIndex } = getIndexesByKeys(
1789
1801
  state,
1790
1802
  rowKeyValue,
1791
1803
  colKeyValue
1792
1804
  );
1793
- setBlurActiveCell(template, state);
1794
- updateActiveCell(state, rowKeyValue, colKeyValue);
1795
- addFocusStylesToActiveCell(template, state);
1805
+ // Tracked state change.
1806
+ setBlurActiveCell(state, template);
1807
+ // Untracked state change.
1808
+ state.activeCell = { rowKeyValue, colKeyValue };
1809
+ // Tracked state changes.
1810
+ addFocusStylesToActiveCell(state, template);
1796
1811
  updateCellTabIndex(state, rowIndex, colIndex, 0);
1797
1812
  }
1798
1813
 
@@ -1800,30 +1815,27 @@ export default class LightningDatatable extends LightningElement {
1800
1815
  * @returns {Object} containing the visible dimensions of the table { left, right, top, bottom, }
1801
1816
  */
1802
1817
  getViewableRect() {
1803
- const scrollerX = this.template
1804
- .querySelector('.slds-scrollable_x')
1805
- .getBoundingClientRect();
1806
- const scrollerY = this.template
1807
- .querySelector('.slds-scrollable_y')
1808
- .getBoundingClientRect();
1818
+ const { template } = this;
1819
+ const scrollerY = getScrollerY(template);
1820
+ const scrollerYRect = scrollerY.getBoundingClientRect();
1821
+ const scrollerX = getScrollerX(template);
1822
+ const scrollerXRect = scrollerX.getBoundingClientRect();
1809
1823
 
1810
1824
  return {
1811
- left: scrollerX.left,
1812
- right: scrollerX.right,
1813
- top: scrollerY.top,
1814
- bottom: scrollerY.bottom,
1825
+ left: scrollerXRect.left,
1826
+ right: scrollerXRect.right,
1827
+ top: scrollerYRect.top,
1828
+ bottom: scrollerYRect.bottom,
1815
1829
  };
1816
1830
  }
1817
1831
 
1818
1832
  // W-6363867, W-7143375 Safari Refresh Bug
1819
- safariHeaderFix() {
1833
+ fixHeaderForSafari() {
1820
1834
  if (isSafari) {
1821
1835
  const thead = this.template.querySelector('thead');
1822
-
1823
1836
  if (thead) {
1824
1837
  /* Safari hack: hide and show the table head to force a browser repaint */
1825
1838
  thead.style.display = 'none';
1826
-
1827
1839
  // eslint-disable-next-line @lwc/lwc/no-async-operation
1828
1840
  requestAnimationFrame(() => {
1829
1841
  thead.style.display = '';
@@ -1836,10 +1848,11 @@ export default class LightningDatatable extends LightningElement {
1836
1848
  * @returns { rowIndex: number, rowKeyValue: string } Compute the information to use to generate the lookupItemPicked event based on the row where the event comes from
1837
1849
  */
1838
1850
  computeRowLookupItemPickedInformation(currentTarget) {
1839
- const rowIndex =
1840
- Number.parseInt(currentTarget.dataset.rowNumber, 10) - 1; // Row number always start to 1, so we convert it to be able to use it for an array
1841
- const rowKeyValue = currentTarget.dataset.rowKeyValue;
1842
-
1851
+ const { dataset } = currentTarget;
1852
+ // Row number always start to 1, so we convert it to be able to use
1853
+ // it for an array
1854
+ const rowIndex = Number.parseInt(dataset.rowNumber, 10) - 1;
1855
+ const { rowKeyValue } = dataset;
1843
1856
  return { rowIndex, rowKeyValue };
1844
1857
  }
1845
1858
  }