lightning-base-components 1.21.2-alpha → 1.21.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 (222) hide show
  1. package/metadata/raptor.json +28 -1
  2. package/package.json +28 -2
  3. package/scopedImports/@salesforce-label-LightningRichTextEditor.colorPicker.js +1 -0
  4. package/src/lightning/accordion/accordion-section.slds.css +3 -3
  5. package/src/lightning/accordion/accordion.slds.css +1 -2
  6. package/src/lightning/accordionSection/accordion-section.slds.css +3 -3
  7. package/src/lightning/accordionSection/accordionSection.js +3 -1
  8. package/src/lightning/accordionSection/button.slds.css +1 -1
  9. package/src/lightning/badge/badge.js +1 -0
  10. package/src/lightning/badge/badge.js-meta.xml +3 -0
  11. package/src/lightning/baseCombobox/base-combobox.slds.css +11 -6
  12. package/src/lightning/baseCombobox/baseCombobox.html +1 -1
  13. package/src/lightning/baseCombobox/baseCombobox.js +2 -2
  14. package/src/lightning/baseCombobox/baseCombobox.js-meta.xml +6 -0
  15. package/src/lightning/baseCombobox/input-text.slds.css +41 -68
  16. package/src/lightning/baseCombobox/keyboard.js +12 -4
  17. package/src/lightning/baseCombobox/listbox.slds.css +51 -99
  18. package/src/lightning/baseCombobox/spinner.slds.css +62 -62
  19. package/src/lightning/baseComboboxFormattedText/baseComboboxFormattedText.js-meta.xml +6 -0
  20. package/src/lightning/baseComboboxItem/baseComboboxItem.js +10 -6
  21. package/src/lightning/baseComboboxItem/baseComboboxItem.js-meta.xml +6 -0
  22. package/src/lightning/baseComboboxItem/listbox.slds.css +51 -99
  23. package/src/lightning/baseFormattedText/baseFormattedText.js +2 -2
  24. package/src/lightning/button/button.js +2 -1
  25. package/src/lightning/button/button.slds.css +1 -1
  26. package/src/lightning/buttonIcon/button-icon.slds.css +1 -1
  27. package/src/lightning/buttonIconStateful/button-icon-stateful.slds.css +4 -2
  28. package/src/lightning/buttonIconStateful/button-icon.slds.css +1 -1
  29. package/src/lightning/buttonIconStateful/button.slds.css +1 -1
  30. package/src/lightning/buttonMenu/button-icon.slds.css +1 -1
  31. package/src/lightning/buttonMenu/button-menu.slds.css +8 -2
  32. package/src/lightning/buttonMenu/button.slds.css +1 -1
  33. package/src/lightning/buttonStateful/button-stateful.slds.css +6 -2
  34. package/src/lightning/buttonStateful/button.slds.css +1 -1
  35. package/src/lightning/buttonStateful/buttonStateful.js +4 -1
  36. package/src/lightning/calendar/calendar.js-meta.xml +6 -0
  37. package/src/lightning/calendar/calendar.slds.css +9 -2
  38. package/src/lightning/colorPickerCustom/color-picker-custom.slds.css +22 -23
  39. package/src/lightning/colorPickerCustom/input-text.slds.css +41 -68
  40. package/src/lightning/colorPickerPanel/color-picker-panel.slds.css +9 -10
  41. package/src/lightning/colorPickerPanel/popover.slds.css +0 -2
  42. package/src/lightning/combobox/combobox.slds.css +1 -2
  43. package/src/lightning/combobox/form-element.slds.css +54 -54
  44. package/src/lightning/datatable/__examples__/customDatatableWrapper/customDatatableWrapper.js +0 -69
  45. package/src/lightning/datatable/__examples__/customDatatypeDeleteRowBtn/customDatatypeDeleteRowBtn.html +1 -1
  46. package/src/lightning/datatable/__examples__/customDatatypeDeleteRowBtn/customDatatypeDeleteRowBtn.js +1 -16
  47. package/src/lightning/datatable/__examples__/customDatatypeLink/customDatatypeLink.html +3 -3
  48. package/src/lightning/datatable/__examples__/customDatatypeRowOrderingBtn/customDatatypeRowOrderingBtn.html +1 -8
  49. package/src/lightning/datatable/__examples__/customDatatypeRowOrderingBtn/customDatatypeRowOrderingBtn.js +2 -39
  50. package/src/lightning/datatable/__examples__/customDatatypeTable/customNumber.html +1 -1
  51. package/src/lightning/datatable/__examples__/customDatatypeTable/customNumberEdit.html +2 -0
  52. package/src/lightning/datatable/__examples__/customDatatypeTable/deleteRow.html +3 -2
  53. package/src/lightning/datatable/__examples__/customDatatypeTable/iconPill.html +1 -1
  54. package/src/lightning/datatable/__examples__/customNestedComponent/customNestedComponent.html +10 -0
  55. package/src/lightning/datatable/__examples__/customNestedComponent/customNestedComponent.js +12 -0
  56. package/src/lightning/datatable/autoWidthStrategy.js +147 -191
  57. package/src/lightning/datatable/columnResizer.js +35 -35
  58. package/src/lightning/datatable/columnWidthManager.js +118 -177
  59. package/src/lightning/datatable/columns.js +90 -59
  60. package/src/lightning/datatable/datagrid.slds.css +187 -0
  61. package/src/lightning/datatable/datatable.js +248 -229
  62. package/src/lightning/datatable/errors.js +3 -0
  63. package/src/lightning/datatable/fixedWidthStrategy.js +22 -29
  64. package/src/lightning/datatable/headerActions.js +7 -9
  65. package/src/lightning/datatable/infiniteLoading.js +15 -15
  66. package/src/lightning/datatable/inlineEdit.js +255 -235
  67. package/src/lightning/datatable/keyboard.js +318 -282
  68. package/src/lightning/datatable/renderManager.js +10 -7
  69. package/src/lightning/datatable/resizeObserver.js +11 -59
  70. package/src/lightning/datatable/rowLevelActions.js +6 -5
  71. package/src/lightning/datatable/rowNumber.js +23 -23
  72. package/src/lightning/datatable/rowSelection.js +173 -145
  73. package/src/lightning/datatable/rowSelectionShared.js +13 -6
  74. package/src/lightning/datatable/rows.js +231 -196
  75. package/src/lightning/datatable/sort.js +26 -22
  76. package/src/lightning/datatable/templates/div/div.css +2 -57
  77. package/src/lightning/datatable/templates/div/div.html +13 -6
  78. package/src/lightning/datatable/templates/div/div.lbc.native.css +3 -0
  79. package/src/lightning/datatable/templates/div/div.lbc.synthetic.css +86 -0
  80. package/src/lightning/datatable/templates/table/table.html +1 -0
  81. package/src/lightning/datatable/utils.js +5 -5
  82. package/src/lightning/datatable/widthManagerShared.js +24 -21
  83. package/src/lightning/datatable/wrapText.js +25 -26
  84. package/src/lightning/datepicker/datepicker.js +32 -9
  85. package/src/lightning/datepicker/datepicker.js-meta.xml +6 -0
  86. package/src/lightning/datepicker/form-element.slds.css +54 -54
  87. package/src/lightning/datepicker/input-text.slds.css +41 -68
  88. package/src/lightning/datetimepicker/datetimepicker.js-meta.xml +6 -0
  89. package/src/lightning/datetimepicker/form-element.slds.css +54 -54
  90. package/src/lightning/datetimepicker/input-text.slds.css +41 -68
  91. package/src/lightning/dualListbox/dual-listbox.slds.css +7 -2
  92. package/src/lightning/dualListbox/form-element.slds.css +54 -54
  93. package/src/lightning/dualListbox/listbox.slds.css +51 -99
  94. package/src/lightning/dynamicIcon/dynamic-icon-strength.slds.css +1 -2
  95. package/src/lightning/dynamicIcon/dynamic-icon-trend.slds.css +1 -2
  96. package/src/lightning/formattedDateTime/formattedDateTime.js +7 -62
  97. package/src/lightning/formattedDateTime/formattedDateTime.js-meta.xml +3 -0
  98. package/src/lightning/formattedLocation/formattedLocation.html +1 -3
  99. package/src/lightning/formattedLocation/formattedLocation.js +3 -25
  100. package/src/lightning/formattedLookup/events.js +2 -4
  101. package/src/lightning/formattedNumber/formattedNumber.js +2 -49
  102. package/src/lightning/formattedRichText/formattedRichText.js +5 -5
  103. package/src/lightning/formattedRichText/linkTextNodes.js +58 -0
  104. package/src/lightning/groupedCombobox/form-element.slds.css +54 -54
  105. package/src/lightning/groupedCombobox/grouped-combobox.slds.css +0 -2
  106. package/src/lightning/groupedCombobox/groupedCombobox.js-meta.xml +1 -1
  107. package/src/lightning/groupedCombobox/input-text.slds.css +41 -68
  108. package/src/lightning/helptext/button-icon.slds.css +1 -1
  109. package/src/lightning/helptext/form-element.slds.css +54 -54
  110. package/src/lightning/icon/icon.slds.css +12 -25
  111. package/src/lightning/input/form-element.slds.css +54 -54
  112. package/src/lightning/inputAddress/form-element.slds.css +54 -54
  113. package/src/lightning/inputAddress/input-address.slds.css +1 -2
  114. package/src/lightning/inputAddress/input-text.slds.css +41 -68
  115. package/src/lightning/inputAddress/inputAddress.js +1 -0
  116. package/src/lightning/inputAddress/inputAddress.js-meta.xml +3 -0
  117. package/src/lightning/inputLocation/form-element.slds.css +54 -54
  118. package/src/lightning/inputLocation/input-location.slds.css +1 -2
  119. package/src/lightning/inputLocation/input-text.slds.css +41 -68
  120. package/src/lightning/inputName/form-element.slds.css +54 -54
  121. package/src/lightning/inputName/input-text.slds.css +41 -68
  122. package/src/lightning/interactiveDialogBase/interactive-dialog-base.slds.css +0 -3
  123. package/src/lightning/interactiveDialogBase/interactiveDialogBase.js-meta.xml +6 -0
  124. package/src/lightning/lookupAddress/form-element.slds.css +54 -54
  125. package/src/lightning/lookupAddress/listbox.slds.css +51 -99
  126. package/src/lightning/lookupAddress/location.js +2 -0
  127. package/src/lightning/lookupAddress/lookup-address.slds.css +0 -2
  128. package/src/lightning/lookupAddress/lookupAddress.js +15 -10
  129. package/src/lightning/menuDivider/menu-divider.slds.css +0 -2
  130. package/src/lightning/menuItem/menu-item.slds.css +8 -2
  131. package/src/lightning/menuSubheader/menu-subheader.slds.css +1 -2
  132. package/src/lightning/modalBase/modal-base.slds.css +3 -3
  133. package/src/lightning/modalBase/modalBase.js +0 -8
  134. package/src/lightning/modalBase/modalBase.js-meta.xml +6 -0
  135. package/src/lightning/modalBody/modal-body.slds.css +1 -2
  136. package/src/lightning/modalFooter/modal-footer.slds.css +2 -2
  137. package/src/lightning/modalFooter/modalFooter.js +0 -21
  138. package/src/lightning/modalHeader/modal-header.slds.css +1 -2
  139. package/src/lightning/modalHeader/modalHeader.js +0 -22
  140. package/src/lightning/overlay/overlay.js-meta.xml +6 -0
  141. package/src/lightning/pill/pill.slds.css +32 -58
  142. package/src/lightning/pillContainer/button.slds.css +1 -1
  143. package/src/lightning/pillContainer/listbox.slds.css +51 -99
  144. package/src/lightning/pillContainer/pill-container.slds.css +6 -10
  145. package/src/lightning/pillContainer/pill.slds.css +32 -58
  146. package/src/lightning/popup/popover.slds.css +0 -2
  147. package/src/lightning/primitiveBubble/primitiveBubble.js-meta.xml +6 -0
  148. package/src/lightning/primitiveButton/primitiveButoon.js-meta.xml +6 -0
  149. package/src/lightning/primitiveCellCheckbox/checkbox.css +2 -0
  150. package/src/lightning/primitiveColorpickerButton/color-picker-button.slds.css +16 -38
  151. package/src/lightning/primitiveCustomCell/primitiveCustomCell.js +26 -1
  152. package/src/lightning/primitiveHeaderFactory/nonsortableHeader.css +1 -0
  153. package/src/lightning/primitiveHeaderFactory/selectableHeader.css +2 -0
  154. package/src/lightning/primitiveIcon/icon.slds.css +12 -25
  155. package/src/lightning/primitiveIcon/primitiveIcon.js-meta.xml +6 -0
  156. package/src/lightning/primitiveIframe/primitiveIframe.js +3 -1
  157. package/src/lightning/primitiveInputCheckbox/form-element.slds.css +54 -54
  158. package/src/lightning/primitiveInputCheckbox/primitiveInputCheckbox.js +5 -2
  159. package/src/lightning/primitiveInputCheckbox/primitiveInputCheckbox.js-meta.xml +6 -0
  160. package/src/lightning/primitiveInputCheckboxButton/form-element.slds.css +54 -54
  161. package/src/lightning/primitiveInputCheckboxButton/input-checkbox-button.slds.css +6 -4
  162. package/src/lightning/primitiveInputCheckboxButton/primitiveInputCheckboxButton.js +5 -2
  163. package/src/lightning/primitiveInputCheckboxButton/primitiveInputCheckboxButton.js-meta.xml +6 -0
  164. package/src/lightning/primitiveInputColor/form-element.slds.css +54 -54
  165. package/src/lightning/primitiveInputColor/input-color.slds.css +2 -3
  166. package/src/lightning/primitiveInputColor/input-text.slds.css +41 -68
  167. package/src/lightning/primitiveInputColor/primitiveInputColor.js +5 -2
  168. package/src/lightning/primitiveInputColor/primitiveInputColor.js-meta.xml +6 -0
  169. package/src/lightning/primitiveInputFile/button.slds.css +1 -1
  170. package/src/lightning/primitiveInputFile/form-element.slds.css +54 -54
  171. package/src/lightning/primitiveInputFile/input-file.slds.css +1 -4
  172. package/src/lightning/primitiveInputFile/primitiveInputFile.js +4 -2
  173. package/src/lightning/primitiveInputFile/primitiveInputFile.js-meta.xml +6 -0
  174. package/src/lightning/primitiveInputRadio/primitiveInputRadio.js +4 -2
  175. package/src/lightning/primitiveInputSimple/form-element.slds.css +54 -54
  176. package/src/lightning/primitiveInputSimple/input-text.slds.css +41 -68
  177. package/src/lightning/primitiveInputSimple/primitiveInputSimple.js-meta.xml +6 -0
  178. package/src/lightning/primitiveInputToggle/form-element.slds.css +54 -54
  179. package/src/lightning/primitiveInputToggle/input-toggle.slds.css +50 -27
  180. package/src/lightning/primitiveInputToggle/primitiveInputToggle.js +5 -2
  181. package/src/lightning/primitiveInputToggle/primitiveInputToggle.js-meta.xml +6 -0
  182. package/src/lightning/progressBar/progress-bar.slds.css +8 -10
  183. package/src/lightning/progressRing/progress-ring.slds.css +0 -23
  184. package/src/lightning/progressStep/progressStep.js +1 -14
  185. package/src/lightning/radioGroup/form-element.slds.css +54 -54
  186. package/src/lightning/radioGroup/radioGroup.html +1 -2
  187. package/src/lightning/radioGroup/radioGroup.js +1 -0
  188. package/src/lightning/routingService/routingService.js +31 -5
  189. package/src/lightning/select/form-element.slds.css +54 -54
  190. package/src/lightning/select/select.slds.css +4 -2
  191. package/src/lightning/sldsUtilsVisibility/sldsUtilsVisibility.css +4 -0
  192. package/src/lightning/spinner/spinner.slds.css +62 -62
  193. package/src/lightning/tab/tab.js +4 -2
  194. package/src/lightning/tab/tab.slds.css +14 -7
  195. package/src/lightning/tabBar/tab-bar.slds.css +16 -6
  196. package/src/lightning/tabset/__docs__/tabset.md +24 -1
  197. package/src/lightning/tabset/tabset.js +25 -38
  198. package/src/lightning/tabset/tabset.slds.css +0 -2
  199. package/src/lightning/textarea/form-element.slds.css +54 -54
  200. package/src/lightning/textarea/textarea.js +5 -1
  201. package/src/lightning/textarea/textarea.slds.css +22 -9
  202. package/src/lightning/timepicker/form-element.slds.css +54 -54
  203. package/src/lightning/timepicker/timepicker.js-meta.xml +6 -0
  204. package/src/lightning/timepicker/timepicker.slds.css +2 -2
  205. package/src/lightning/toast/__docs__/toast.md +20 -22
  206. package/src/lightning/toast/button-icon.slds.css +1 -1
  207. package/src/lightning/toast/icon.slds.css +12 -25
  208. package/src/lightning/toast/toast.js +15 -12
  209. package/src/lightning/toast/toast.slds.css +6 -18
  210. package/src/lightning/toastContainer/toast.slds.css +6 -18
  211. package/src/lightning/toastContainer/toastContainer.js +25 -17
  212. package/src/lightning/tooltipLibrary/tooltipLibrary.js +12 -9
  213. package/src/lightning/tree/tree.js +2 -0
  214. package/src/lightning/utils/classSet.js +9 -3
  215. package/src/lightning/utilsPrivate/formatUtils.js +158 -0
  216. package/src/lightning/utilsPrivate/textUtils.js +16 -0
  217. package/src/lightning/utilsPrivate/utilsPrivate.js +56 -15
  218. package/src/lightning/utilsPrivate/validationUtils.js +59 -0
  219. package/src/lightning/verticalNavigationSection/vertical-navigation-section.slds.css +0 -2
  220. package/src/lightning/datatable/resizeSensor.js +0 -244
  221. package/src/lightning/formattedRichText/linkify.js +0 -43
  222. package/src/lightning/utilsPrivate/smartSetAttribute.js +0 -19
@@ -79,15 +79,13 @@ export function handleDeselectAllRows(event) {
79
79
  */
80
80
  export function handleSelectRow(event) {
81
81
  event.stopPropagation();
82
+ const { state } = this;
82
83
  const { rowKeyValue, isMultiple } = event.detail;
83
- let fromRowKey = rowKeyValue;
84
-
85
- if (isMultiple) {
86
- fromRowKey = getLastRowSelection(this.state) || rowKeyValue;
87
- }
88
-
89
- markSelectedRowsInterval(this.state, fromRowKey, rowKeyValue);
90
- setLastRowSelection(this.state, rowKeyValue);
84
+ const fromRowKey = isMultiple
85
+ ? getLastRowSelection(state) || rowKeyValue
86
+ : rowKeyValue;
87
+ markSelectedRowsInterval(state, fromRowKey, rowKeyValue);
88
+ setLastRowSelection(state, rowKeyValue);
91
89
  this.fireSelectedRowsChange(this.getSelectedRows(), {
92
90
  action: ROWS_ACTION.ROW_SELECT,
93
91
  value: rowKeyValue,
@@ -105,15 +103,13 @@ export function handleSelectRow(event) {
105
103
  */
106
104
  export function handleDeselectRow(event) {
107
105
  event.stopPropagation();
106
+ const { state } = this;
108
107
  const { rowKeyValue, isMultiple } = event.detail;
109
- let fromRowKey = rowKeyValue;
110
-
111
- if (isMultiple) {
112
- fromRowKey = getLastRowSelection(this.state) || rowKeyValue;
113
- }
114
-
115
- markDeselectedRowsInterval(this.state, fromRowKey, rowKeyValue);
116
- setLastRowSelection(this.state, rowKeyValue);
108
+ const fromRowKey = isMultiple
109
+ ? getLastRowSelection(state) || rowKeyValue
110
+ : rowKeyValue;
111
+ markDeselectedRowsInterval(state, fromRowKey, rowKeyValue);
112
+ setLastRowSelection(state, rowKeyValue);
117
113
  this.fireSelectedRowsChange(this.getSelectedRows(), {
118
114
  action: ROWS_ACTION.ROW_DESELECT,
119
115
  value: rowKeyValue,
@@ -139,22 +135,23 @@ export function handleRowSelectionChange() {
139
135
  * 2. If max-row-selection has been reached, mark the remaining rows
140
136
  * to reflect that they are not selected and disable them.
141
137
  *
142
- * @param {Object} state - datatable's state object
138
+ * @param {Object} state - The datatable state
143
139
  */
144
140
  export function markAllRowsSelected(state) {
145
141
  const rows = getRows(state);
146
142
  const maxRowSelection = getMaxRowSelection(state);
147
143
 
148
144
  resetSelectedRowsKeys(state);
149
- rows.forEach((row, index) => {
150
- if (index < maxRowSelection || maxRowSelection === undefined) {
145
+ for (let i = 0, { length: rowCount } = rows; i < rowCount; i += 1) {
146
+ const row = rows[i];
147
+ if (maxRowSelection === undefined || i < maxRowSelection) {
151
148
  setRowSelectedAttributes(true, row);
152
149
  addKeyToSelectedRowKeys(state, row.key);
153
150
  } else {
154
151
  row.isDisabled = true;
155
152
  setRowSelectedAttributes(false, row);
156
153
  }
157
- });
154
+ }
158
155
  }
159
156
 
160
157
  /**
@@ -163,17 +160,17 @@ export function markAllRowsSelected(state) {
163
160
  * set `isSelected` and `ariaSelected` to false and enable the row. Also resolve
164
161
  * the `classnames` for the row to reflect that it is not selected.
165
162
  *
166
- * @param {Object} state - datatable's state object
163
+ * @param {Object} state - The datatable state
167
164
  * @returns
168
165
  */
169
166
  export function markAllRowsDeselected(state) {
170
167
  const rows = getRows(state);
171
-
172
168
  resetSelectedRowsKeys(state);
173
- rows.forEach((row) => {
169
+ for (let i = 0, { length: rowCount } = rows; i < rowCount; i += 1) {
170
+ const row = rows[i];
174
171
  row.isDisabled = false;
175
172
  setRowSelectedAttributes(false, row);
176
- });
173
+ }
177
174
  }
178
175
 
179
176
  /**
@@ -190,22 +187,20 @@ export function markAllRowsDeselected(state) {
190
187
  * This does not handle the case when the header checkbox that selects
191
188
  * all rows of the table is clicked. That is handled by - `handleSelectAllRows`
192
189
  *
193
- * @param {Object} state - datatable's state object
190
+ * @param {Object} state - The datatable state
194
191
  * @param {String} startRowKey - row key value of the first row that was selected (start of the interval)
195
192
  * @param {String} endRowKey - row key value of the last row that was selected (end of the interval)
196
193
  */
197
194
  function markSelectedRowsInterval(state, startRowKey, endRowKey) {
198
195
  const rows = getRows(state);
199
196
  const { start, end } = getRowIntervalIndexes(state, startRowKey, endRowKey);
200
- const maxRowSelection = getMaxRowSelection(state) || getRowsTotal(state);
201
- let i = start,
202
- maxSelectionReached;
203
-
204
- while (i <= end && !maxSelectionReached) {
205
- markRowSelected(state, rows[i].key);
206
- maxSelectionReached =
207
- getCurrentSelectionLength(state) >= maxRowSelection;
208
- i++;
197
+ const total = getMaxRowSelection(state) || getRowsTotal(state);
198
+ let rowIndex = start;
199
+ let maxSelectionReached;
200
+ while (rowIndex <= end && !maxSelectionReached) {
201
+ markRowSelected(state, rows[rowIndex].key);
202
+ maxSelectionReached = getCurrentSelectionLength(state) >= total;
203
+ rowIndex += 1;
209
204
  }
210
205
  }
211
206
 
@@ -222,7 +217,7 @@ function markSelectedRowsInterval(state, startRowKey, endRowKey) {
222
217
  * This does not handle the case when the header checkbox is clicked to de-select all rows
223
218
  * That is handledd by - `handleDeselectAllRows`
224
219
  *
225
- * @param {Object} state - datatable's state object
220
+ * @param {Object} state - The datatable state
226
221
  * @param {String} startRowKey - row key value of the first row that was selected (start of the interval)
227
222
  * @param {String} endRowKey - row key value of the last row that was selected (end of the interval)
228
223
  */
@@ -230,8 +225,8 @@ function markDeselectedRowsInterval(state, startRowKey, endRowKey) {
230
225
  const rows = getRows(state);
231
226
  const { start, end } = getRowIntervalIndexes(state, startRowKey, endRowKey);
232
227
 
233
- for (let i = start; i <= end; i++) {
234
- markRowDeselected(state, rows[i].key);
228
+ for (let rowIndex = start; rowIndex <= end; rowIndex += 1) {
229
+ markRowDeselected(state, rows[rowIndex].key);
235
230
  }
236
231
  }
237
232
 
@@ -248,28 +243,28 @@ function markDeselectedRowsInterval(state, startRowKey, endRowKey) {
248
243
  * a. If another row was previously selected before, de-select that row
249
244
  * b. Add the row key value of that row to the state
250
245
  *
251
- * @param {Object} state - datatable's state object
246
+ * @param {Object} state - The datatable state
252
247
  * @param {String} rowKeyValue - row key value of row to mark selected
253
248
  */
254
249
  export function markRowSelected(state, rowKeyValue) {
255
250
  const row = getRowByKey(state, rowKeyValue);
256
- const maxRowSelection = getMaxRowSelection(state) || getRowsTotal(state);
257
- const previousSelectionLength = getCurrentSelectionLength(state);
251
+ const prevSelectionLength = getCurrentSelectionLength(state);
252
+ const total = getMaxRowSelection(state) || getRowsTotal(state);
258
253
 
259
254
  setRowSelectedAttributes(true, row);
260
255
 
261
- if (maxRowSelection > 1) {
256
+ if (total > 1) {
262
257
  addKeyToSelectedRowKeys(state, row.key);
263
- if (previousSelectionLength + 1 === maxRowSelection) {
258
+ if (prevSelectionLength + 1 === total) {
264
259
  markDeselectedRowDisabled(state);
265
260
  }
266
261
  } else {
267
- if (previousSelectionLength === 1) {
268
- const previousSelectedRow = getRowByKey(
262
+ if (prevSelectionLength === 1) {
263
+ const prevSelectedRow = getRowByKey(
269
264
  state,
270
265
  Object.keys(state.selectedRowsKeys)[0]
271
266
  );
272
- setRowSelectedAttributes(false, previousSelectedRow);
267
+ setRowSelectedAttributes(false, prevSelectedRow);
273
268
  resetSelectedRowsKeys(state);
274
269
  }
275
270
  addKeyToSelectedRowKeys(state, row.key);
@@ -307,14 +302,14 @@ export function markRowDeselected(state, rowKeyValue) {
307
302
  * Sets `isSelected`, `ariaSelected` and `classnames` on the row object
308
303
  * which are used by the template to render the appropriate values.
309
304
  *
310
- * @param {Object} state - datatable's state object
305
+ * @param {Object} state - The datatable state
311
306
  * @param {Array} keys - a list of row key values to be marked selected
312
307
  */
313
308
  function markRowsSelectedByKeys(state, keys) {
314
- keys.forEach((rowKeyValue) => {
315
- const row = getRowByKey(state, rowKeyValue);
309
+ for (let i = 0, { length } = keys; i < length; i += 1) {
310
+ const row = getRowByKey(state, keys[i]);
316
311
  setRowSelectedAttributes(true, row);
317
- });
312
+ }
318
313
  }
319
314
 
320
315
  /**
@@ -324,14 +319,14 @@ function markRowsSelectedByKeys(state, keys) {
324
319
  * to one which reflects that the row is not selected on the row object.
325
320
  * These are used by the template to render the appropriate values.
326
321
  *
327
- * @param {Object} state - datatable's state object
322
+ * @param {Object} state - The datatable state
328
323
  * @param {Array} keys - a list of row key values to be marked selected
329
324
  */
330
325
  function markRowsDeselectedByKeys(state, keys) {
331
- keys.forEach((rowKeyValue) => {
332
- const row = getRowByKey(state, rowKeyValue);
326
+ for (let i = 0, { length } = keys; i < length; i += 1) {
327
+ const row = getRowByKey(state, keys[i]);
333
328
  setRowSelectedAttributes(false, row);
334
- });
329
+ }
335
330
  }
336
331
 
337
332
  /**
@@ -344,11 +339,12 @@ function markRowsDeselectedByKeys(state, keys) {
344
339
  */
345
340
  export function markDeselectedRowDisabled(state) {
346
341
  const rows = getRows(state);
347
- rows.forEach((row) => {
342
+ for (let i = 0, { length: rowCount } = rows; i < rowCount; i += 1) {
343
+ const row = rows[i];
348
344
  if (!isSelectedRow(state, row.key)) {
349
345
  row.isDisabled = true;
350
346
  }
351
- });
347
+ }
352
348
  }
353
349
 
354
350
  /**
@@ -358,15 +354,16 @@ export function markDeselectedRowDisabled(state) {
358
354
  * previously selected but a row was deselected, now allowing
359
355
  * any other row to be selected - for this, all rows should be enabled
360
356
  *
361
- * @param {Object} state - datatable's state object
357
+ * @param {Object} state - The datatable state
362
358
  */
363
359
  export function markDeselectedRowEnabled(state) {
364
360
  const rows = getRows(state);
365
- rows.forEach((row) => {
361
+ for (let i = 0, { length: rowCount } = rows; i < rowCount; i += 1) {
362
+ const row = rows[i];
366
363
  if (!isSelectedRow(state, row.key)) {
367
364
  row.isDisabled = false;
368
365
  }
369
- });
366
+ }
370
367
  }
371
368
 
372
369
  /************************** SELECTED ROW KEYS **************************/
@@ -409,8 +406,7 @@ export function setSelectedRowsKeys(state, value) {
409
406
 
410
407
  // Convert the selectedRows Array to an Object that state.selectedRowKeys expects
411
408
  // ['a', 'b'] -> { a : true, b : true}
412
- const normalizedSelectedRowsKeys =
413
- normalizeSelectedRowsKey(selectedRows);
409
+ const selectedRowsKeys = normalizeSelectedRowsKey(selectedRows);
414
410
 
415
411
  // Compute differences between currently selected rows and
416
412
  // newly selected row keys. The diff will tell which new rows
@@ -419,18 +415,19 @@ export function setSelectedRowsKeys(state, value) {
419
415
  const selectionOperations = getSelectedDiff(state, selectedRows);
420
416
  const deselectionOperations = getDeselectedDiff(
421
417
  state,
422
- normalizedSelectedRowsKeys
418
+ selectedRowsKeys
423
419
  );
424
420
  markRowsSelectedByKeys(state, selectionOperations);
425
421
  markRowsDeselectedByKeys(state, deselectionOperations);
426
- state.selectedRowsKeys = normalizedSelectedRowsKeys;
422
+ state.selectedRowsKeys = selectedRowsKeys;
427
423
 
424
+ const { length: selectedRowsCount } = selectedRows;
428
425
  // If we select the max number of rows allowed and if max-row-selection > 1 (multi-select),
429
426
  // disable all the other rows to prevent further selection
430
- if (selectedRows.length === maxRowSelection && maxRowSelection > 1) {
427
+ if (selectedRowsCount === maxRowSelection && maxRowSelection > 1) {
431
428
  markDeselectedRowDisabled(state);
432
429
  } else if (
433
- selectedRows.length < maxRowSelection &&
430
+ selectedRowsCount < maxRowSelection &&
434
431
  previousSelectionLength === maxRowSelection
435
432
  ) {
436
433
  // If the previous selection had reached the max limit and the new selection
@@ -448,34 +445,45 @@ export function setSelectedRowsKeys(state, value) {
448
445
 
449
446
  export function syncSelectedRowsKeys(state, selectedRows) {
450
447
  let changed = false;
451
- const { selectedRowsKeys, keyField } = state;
452
- const maxRowSelection = getMaxRowSelection(state) || getRowsTotal(state);
448
+ const { keyField, selectedRowsKeys } = state;
449
+ const { length: selectedRowCount } = selectedRows;
453
450
  if (Object.keys(selectedRowsKeys).length !== selectedRows.length) {
454
451
  changed = true;
452
+ // Untracked state change.
455
453
  state.selectedRowsKeys = updateSelectedRowsKeysFromSelectedRows(
456
454
  selectedRows,
457
455
  keyField
458
456
  );
459
457
  } else {
460
- changed = selectedRows.some((row) => !selectedRowsKeys[row[keyField]]);
461
- if (changed) {
462
- state.selectedRowsKeys = updateSelectedRowsKeysFromSelectedRows(
463
- selectedRows,
464
- keyField
465
- );
458
+ for (let i = 0; i < selectedRowCount; i += 1) {
459
+ const row = selectedRows[i];
460
+ if (!selectedRowsKeys[row[keyField]]) {
461
+ changed = true;
462
+ // Untracked state change.
463
+ state.selectedRowsKeys = updateSelectedRowsKeysFromSelectedRows(
464
+ selectedRows,
465
+ keyField
466
+ );
467
+ break;
468
+ }
466
469
  }
467
470
  }
468
- if (maxRowSelection > 1 && changed) {
469
- if (selectedRows.length < maxRowSelection) {
470
- markDeselectedRowEnabled(state);
471
- } else {
472
- markDeselectedRowDisabled(state);
471
+ if (changed) {
472
+ const total = getMaxRowSelection(state) || getRowsTotal(state);
473
+ if (total > 1) {
474
+ // Tracked state changes.
475
+ if (selectedRowCount < total) {
476
+ markDeselectedRowEnabled(state);
477
+ } else {
478
+ markDeselectedRowDisabled(state);
479
+ }
473
480
  }
474
481
  }
482
+ // Tracked state change.
475
483
  updateBulkSelectionState(state);
476
484
 
477
485
  return {
478
- ifChanged: (callback) => {
486
+ ifChanged(callback) {
479
487
  if (changed && typeof callback === 'function') {
480
488
  callback(selectedRows);
481
489
  }
@@ -484,10 +492,12 @@ export function syncSelectedRowsKeys(state, selectedRows) {
484
492
  }
485
493
 
486
494
  function updateSelectedRowsKeysFromSelectedRows(selectedRows, keyField) {
487
- return selectedRows.reduce((selectedRowsKeys, row) => {
495
+ const selectedRowsKeys = {};
496
+ for (let i = 0, { length } = selectedRows; i < length; i += 1) {
497
+ const row = selectedRows[i];
488
498
  selectedRowsKeys[row[keyField]] = true;
489
- return selectedRowsKeys;
490
- }, {});
499
+ }
500
+ return selectedRowsKeys;
491
501
  }
492
502
 
493
503
  function addKeyToSelectedRowKeys(state, key) {
@@ -500,15 +510,23 @@ function removeKeyFromSelectedRowKeys(state, key) {
500
510
  state.selectedRowsKeys[key] = false;
501
511
  }
502
512
 
503
- function normalizeSelectedRowsKey(value) {
504
- return value.reduce((map, key) => {
505
- map[key] = true;
506
- return map;
507
- }, {});
513
+ function normalizeSelectedRowsKey(keys) {
514
+ const selectedRowsKeys = {};
515
+ for (let i = 0, { length } = keys; i < length; i += 1) {
516
+ selectedRowsKeys[keys[i]] = true;
517
+ }
518
+ return selectedRowsKeys;
508
519
  }
509
520
 
510
521
  function filterValidKeys(state, keys) {
511
- return keys.filter((key) => rowKeyExists(state, key));
522
+ const filtered = [];
523
+ for (let i = 0, { length } = keys; i < length; i += 1) {
524
+ const key = keys[i];
525
+ if (rowKeyExists(state, key)) {
526
+ filtered.push(key);
527
+ }
528
+ }
529
+ return filtered;
512
530
  }
513
531
 
514
532
  export function resetSelectedRowsKeys(state) {
@@ -521,11 +539,11 @@ export function resetSelectedRowsKeys(state) {
521
539
  * Returns the row key value of the row that was last selected
522
540
  * Returns undefined if the row key value is invalid
523
541
  *
524
- * @param {Object} state - the datatable state.
542
+ * @param {Object} state - The datatable state.
525
543
  * @returns {String | undefined } the row key or undefined.
526
544
  */
527
545
  function getLastRowSelection(state) {
528
- const lastSelectedRowKey = state.lastSelectedRowKey;
546
+ const { lastSelectedRowKey } = state;
529
547
  const keyIsValid =
530
548
  lastSelectedRowKey !== undefined &&
531
549
  getRowIndexByKey(state, lastSelectedRowKey) !== undefined;
@@ -551,19 +569,18 @@ function setLastRowSelection(state, rowKeyValue) {
551
569
  *
552
570
  * @param {Number} previousMaxRowSelection
553
571
  * @param {Number} newMaxRowSelection
554
- * @returns
572
+ * @returns {Boolean}
555
573
  */
556
574
  export function inputTypeNeedsToChange(
557
575
  previousMaxRowSelection,
558
576
  newMaxRowSelection
559
577
  ) {
560
578
  return (
579
+ previousMaxRowSelection === 0 ||
580
+ newMaxRowSelection === 0 ||
561
581
  (previousMaxRowSelection === 1 &&
562
582
  isMultiSelection(newMaxRowSelection)) ||
563
- (isMultiSelection(previousMaxRowSelection) &&
564
- newMaxRowSelection === 1) ||
565
- previousMaxRowSelection === 0 ||
566
- newMaxRowSelection === 0
583
+ (newMaxRowSelection === 1 && isMultiSelection(previousMaxRowSelection))
567
584
  );
568
585
  }
569
586
 
@@ -571,10 +588,12 @@ export function updateRowSelectionInputType(state) {
571
588
  const type = getRowSelectionInputType(state);
572
589
  const rows = getRows(state);
573
590
 
574
- rows.forEach((row) => {
591
+ for (let i = 0, { length: rowCount } = rows; i < rowCount; i += 1) {
592
+ // Tracked state changes.
593
+ const row = rows[i];
575
594
  row.inputType = type;
576
595
  row.isDisabled = isDisabledRow(state, row.key);
577
- });
596
+ }
578
597
  }
579
598
 
580
599
  /************************** MAX ROW SELECTION **************************/
@@ -587,22 +606,25 @@ export function updateRowSelectionInputType(state) {
587
606
  * and input type is radio if maxRowSelection = 1.
588
607
  * Invalid values are set to default and an error is logged
589
608
  *
590
- * @param {Object} state - the datatable state.
609
+ * @param {Object} state - The datatable state
591
610
  * @param {Number | String} - value to set for maxRowSelection
592
611
  */
593
612
  export function setMaxRowSelection(state, value) {
594
613
  const previousSelectedRowsKeys = getSelectedRowsKeys(state);
614
+ // Tracked state changes.
595
615
  markAllRowsDeselected(state);
596
616
  if (isNonNegativeInteger(value)) {
597
617
  const previousMaxRowSelection = getMaxRowSelection(state);
618
+ // Untracked state change.
598
619
  state.maxRowSelection = Number(value);
599
620
  const newMaxRowSelection = getMaxRowSelection(state);
600
- // reselect up to maxRowSelection rows
621
+ // Reselect up to maxRowSelection rows.
601
622
  const numberOfRows = Math.min(
602
623
  previousSelectedRowsKeys.length,
603
624
  newMaxRowSelection
604
625
  );
605
- for (let i = 0; i < numberOfRows; i++) {
626
+ for (let i = 0; i < numberOfRows; i += 1) {
627
+ // Tracked state changes.
606
628
  markRowSelected(state, previousSelectedRowsKeys[i]);
607
629
  }
608
630
  if (
@@ -611,10 +633,12 @@ export function setMaxRowSelection(state, value) {
611
633
  getMaxRowSelection(state)
612
634
  )
613
635
  ) {
636
+ // Tracked state changes.
614
637
  updateRowSelectionInputType(state);
615
638
  updateBulkSelectionState(state);
616
639
  }
617
640
  } else {
641
+ // Untracked state change.
618
642
  state.maxRowSelection = MAX_ROW_SELECTION_DEFAULT;
619
643
  // suppress console error if no value is passed in
620
644
  if (value !== null && value !== undefined) {
@@ -629,28 +653,24 @@ export function setMaxRowSelection(state, value) {
629
653
  /************************** BULK SELECTION STATE **************************/
630
654
 
631
655
  export function updateBulkSelectionState(state) {
632
- const selectBoxesColumnIndex = getSelectBoxesColumnIndex(state);
633
- if (selectBoxesColumnIndex >= 0) {
634
- state.columns[selectBoxesColumnIndex] = Object.assign(
635
- {},
636
- state.columns[selectBoxesColumnIndex],
637
- {
638
- bulkSelection: getBulkSelectionState(state),
639
- isBulkSelectionDisabled: isBulkSelectionDisabled(state),
640
- }
641
- );
656
+ const { columns } = state;
657
+ const colIndex = getSelectBoxesColumnIndex(state);
658
+ if (colIndex >= 0) {
659
+ const col = columns[colIndex];
660
+ const updatedCol = Object.assign({}, col);
661
+ updatedCol.bulkSelection = getBulkSelectionState(state);
662
+ updatedCol.isBulkSelectionDisabled = isBulkSelectionDisabled(state);
663
+ columns[colIndex] = updatedCol;
642
664
  }
643
665
  }
644
666
 
645
667
  function getBulkSelectionState(state) {
646
- const selected = getCurrentSelectionLength(state);
647
668
  const total = getMaxRowSelection(state) || getRowsTotal(state);
648
- if (selected === 0) {
649
- return 'none';
650
- } else if (selected === total) {
651
- return 'all';
669
+ const selected = getCurrentSelectionLength(state);
670
+ if (selected) {
671
+ return selected === total ? 'all' : 'some';
652
672
  }
653
- return 'some';
673
+ return 'none';
654
674
  }
655
675
 
656
676
  function isBulkSelectionDisabled(state) {
@@ -665,10 +685,10 @@ function isBulkSelectionDisabled(state) {
665
685
  * Returns an object that contains the start index which is the lower index value of the two
666
686
  * and the end index which is the higher value of the two.
667
687
  *
668
- * @param {Object} state - datatable's state object
669
- * @param {String} startRowKey - row key value of the first row that was selected (start of the interval)
670
- * @param {String} endRowKey - row key value of the last row that was selected (end of the interval)
671
- * @returns {Object} - object with start index and end index
688
+ * @param {Object} state - The datatable state
689
+ * @param {String} startRowKey - The row key value of the first row that was selected (start of the interval)
690
+ * @param {String} endRowKey - The row key value of the last row that was selected (end of the interval)
691
+ * @returns {Object} - An object with start index and end index
672
692
  */
673
693
  function getRowIntervalIndexes(state, startRowKey, endRowKey) {
674
694
  const start =
@@ -687,9 +707,9 @@ function getRowIntervalIndexes(state, startRowKey, endRowKey) {
687
707
  *
688
708
  * Note: This change is volatile, and will be reset (lost) in the next index regeneration.
689
709
  *
690
- * @param {Object} state - the state of the datatable
691
- * @param {String} rowKeyValue - the row key of the cell to mark selected
692
- * @param {String} colKeyValue - the col key of the cell to mark selected
710
+ * @param {Object} state - The datatable state
711
+ * @param {String} rowKeyValue - The row key of the cell to mark selected
712
+ * @param {String} colKeyValue - The column key of the cell to mark selected
693
713
  */
694
714
  export function setAriaSelectedOnCell(state, rowKeyValue, colKeyValue) {
695
715
  const row = getRowByKey(state, rowKeyValue);
@@ -707,9 +727,9 @@ export function setAriaSelectedOnCell(state, rowKeyValue, colKeyValue) {
707
727
  *
708
728
  * Note: This change is volatile, and will be reset (lost) in the next index regeneration.
709
729
  *
710
- * @param {Object} state - the state of the datatable
711
- * @param {String} rowKeyValue - the row key of the cell to select
712
- * @param {String} colKeyValue - the col key of the cell to select
730
+ * @param {Object} state - The datatable state
731
+ * @param {String} rowKeyValue - The row key of the cell to select
732
+ * @param {String} colKeyValue - The column key of the cell to select
713
733
  */
714
734
  export function unsetAriaSelectedOnCell(state, rowKeyValue, colKeyValue) {
715
735
  const row = getRowByKey(state, rowKeyValue);
@@ -725,8 +745,8 @@ export function unsetAriaSelectedOnCell(state, rowKeyValue, colKeyValue) {
725
745
  * to one which reflects the selected value of the row on the row object.
726
746
  * These are used by the template to render the appropriate values.
727
747
  *
728
- * @param {Boolean} selectedValue - is the row selected or not
729
- * @param {Object} row - the row on which to set the selected attributes
748
+ * @param {Boolean} selectedValue - Whether the row is selected
749
+ * @param {Object} row - The row
730
750
  */
731
751
  function setRowSelectedAttributes(selectedValue, row) {
732
752
  row.isSelected = selectedValue;
@@ -734,32 +754,40 @@ function setRowSelectedAttributes(selectedValue, row) {
734
754
  row.classnames = resolveRowClassNames(row);
735
755
  }
736
756
 
737
- function getSelectedDiff(state, value) {
738
- const selectedRowsKeys = state.selectedRowsKeys;
739
- return value.filter((key) => !selectedRowsKeys[key]);
757
+ function getSelectedDiff(state, selectedRows) {
758
+ const filtered = [];
759
+ const { selectedRowsKeys } = state;
760
+ for (let i = 0, { length } = selectedRows; i < length; i += 1) {
761
+ const rowKeyValue = selectedRows[i];
762
+ if (!selectedRowsKeys[rowKeyValue]) {
763
+ filtered.push(rowKeyValue);
764
+ }
765
+ }
766
+ return filtered;
740
767
  }
741
768
 
742
769
  function getDeselectedDiff(state, value) {
743
- const currentSelectedRowsKeys = state.selectedRowsKeys;
744
- return Object.keys(currentSelectedRowsKeys).filter(
745
- (key) => currentSelectedRowsKeys[key] && !value[key]
746
- );
770
+ const filtered = [];
771
+ const { selectedRowsKeys } = state;
772
+ const keys = Object.keys(selectedRowsKeys);
773
+ for (let i = 0, { length } = keys; i < length; i += 1) {
774
+ const rowKeyValue = keys[i];
775
+ if (selectedRowsKeys[rowKeyValue] && !value[rowKeyValue]) {
776
+ filtered.push(rowKeyValue);
777
+ }
778
+ }
779
+ return filtered;
747
780
  }
748
781
 
749
782
  function getSelectBoxesColumnIndex(state) {
750
783
  const columns = getColumns(state) || [];
751
- let selectBoxColumnIndex = -1;
752
-
753
- columns.some((column, index) => {
754
- if (column.type === SELECTABLE_ROW_CHECKBOX) {
755
- selectBoxColumnIndex = index;
756
- return true;
784
+ for (let colIndex = 0; colIndex < columns.length; colIndex += 1) {
785
+ const col = columns[colIndex];
786
+ if (col.type === SELECTABLE_ROW_CHECKBOX) {
787
+ return colIndex;
757
788
  }
758
-
759
- return false;
760
- });
761
-
762
- return selectBoxColumnIndex;
789
+ }
790
+ return -1;
763
791
  }
764
792
 
765
793
  /**
@@ -27,7 +27,7 @@ export function isSelectedRow(state, rowKeyValue) {
27
27
  *
28
28
  * NOTE: Do not disable selection when `max-row-selection` is 1 and a row has been selected.
29
29
  *
30
- * @param {Object} state Datatable state object
30
+ * @param {Object} state The datatable state
31
31
  * @param {String} rowKeyValue The row key value to lookup
32
32
  * @returns {Boolean} Whether the row should be disabled or not
33
33
  */
@@ -72,7 +72,7 @@ export function getMaxRowSelection(state) {
72
72
  /**
73
73
  * Determines the number of rows currently selected.
74
74
  *
75
- * @param {Object} state Datatable state object
75
+ * @param {Object} state The datatable state
76
76
  * @returns {Integer} The number of currently selected rows
77
77
  */
78
78
  export function getCurrentSelectionLength(state) {
@@ -82,11 +82,18 @@ export function getCurrentSelectionLength(state) {
82
82
  /**
83
83
  * Retrieves the row keys that are currently selected.
84
84
  *
85
- * @param {Object} state Datatable state object
85
+ * @param {Object} state The datatable state
86
86
  * @returns {Array} An array of the row keys that are currently selected
87
87
  */
88
88
  export function getSelectedRowsKeys(state) {
89
- return Object.keys(state.selectedRowsKeys).filter(
90
- (key) => state.selectedRowsKeys[key]
91
- );
89
+ const filtered = [];
90
+ const { selectedRowsKeys } = state;
91
+ const keys = Object.keys(selectedRowsKeys);
92
+ for (let i = 0, { length } = keys; i < length; i += 1) {
93
+ const rowKeyValue = keys[i];
94
+ if (selectedRowsKeys[rowKeyValue]) {
95
+ filtered.push(rowKeyValue);
96
+ }
97
+ }
98
+ return filtered;
92
99
  }