lightning-base-components 1.13.10-alpha → 1.14.4-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 (69) hide show
  1. package/metadata/raptor.json +24 -0
  2. package/package.json +20 -4
  3. package/scopedImports/@salesforce-internal-core.appVersion.js +1 -1
  4. package/scopedImports/@salesforce-label-LightningDualListbox.movedOptionsPlural.js +1 -0
  5. package/scopedImports/@salesforce-label-LightningDualListbox.movedOptionsSingular.js +1 -0
  6. package/scopedImports/@salesforce-label-LightningErrorMessage.validitySelectAtleastOne.js +1 -0
  7. package/scopedImports/@salesforce-label-LightningMap.titleWithAddress.js +1 -0
  8. package/scopedImports/@salesforce-label-LightningModalBase.cancelandclose.js +1 -0
  9. package/src/lightning/ariaObserver/__component__/ariaObserver.spec.js +112 -0
  10. package/src/lightning/ariaObserver/__docs__/ariaObserver.md +142 -0
  11. package/src/lightning/{utilsPrivate/contentMutation.js → ariaObserver/ariaObserver.js} +60 -98
  12. package/src/lightning/buttonMenu/keyboard.js +0 -10
  13. package/src/lightning/card/card.html +6 -0
  14. package/src/lightning/checkboxGroup/checkboxGroup.html +2 -2
  15. package/src/lightning/checkboxGroup/checkboxGroup.js +6 -1
  16. package/src/lightning/colorPickerCustom/colorPickerCustom.js +20 -1
  17. package/src/lightning/datatable/__docs__/datatable.md +55 -0
  18. package/src/lightning/datatable/__examples__/basic/basic.html +1 -1
  19. package/src/lightning/datatable/columns-shared.js +1 -1
  20. package/src/lightning/datatable/datatable.js +98 -30
  21. package/src/lightning/datatable/errors.js +20 -9
  22. package/src/lightning/datatable/headerActions.js +77 -49
  23. package/src/lightning/datatable/infiniteLoading.js +100 -28
  24. package/src/lightning/datatable/inlineEdit.js +505 -379
  25. package/src/lightning/datatable/inlineEditShared.js +24 -0
  26. package/src/lightning/datatable/keyboard.js +162 -127
  27. package/src/lightning/datatable/renderManager.js +201 -133
  28. package/src/lightning/datatable/rowLevelActions.js +17 -13
  29. package/src/lightning/datatable/rowNumber.js +54 -20
  30. package/src/lightning/datatable/rowSelection.js +760 -0
  31. package/src/lightning/datatable/rowSelectionShared.js +79 -0
  32. package/src/lightning/datatable/rows.js +17 -6
  33. package/src/lightning/datatable/state.js +16 -2
  34. package/src/lightning/datatable/templates/div/div.css +4 -0
  35. package/src/lightning/datatable/templates/div/div.html +6 -0
  36. package/src/lightning/datatable/templates/table/table.html +5 -0
  37. package/src/lightning/datatable/utils.js +14 -0
  38. package/src/lightning/datatable/wrapText.js +77 -47
  39. package/src/lightning/dualListbox/dualListbox.html +1 -1
  40. package/src/lightning/dualListbox/dualListbox.js +42 -0
  41. package/src/lightning/formattedDateTime/__docs__/formattedDateTime.md +36 -3
  42. package/src/lightning/formattedDateTime/__examples__/datetime/datetime.html +2 -2
  43. package/src/lightning/formattedDateTime/__examples__/datetime/datetime.js +3 -1
  44. package/src/lightning/formattedDateTime/__examples__/time/time.html +1 -1
  45. package/src/lightning/formattedDateTime/__examples__/time/time.js +3 -1
  46. package/src/lightning/formattedDateTime/formattedDateTime.js +1 -0
  47. package/src/lightning/input/input.html +1 -5
  48. package/src/lightning/input/input.js +69 -48
  49. package/src/lightning/inputUtils/validity.js +12 -1
  50. package/src/lightning/pillContainer/__docs__/pillContainer.md +45 -1
  51. package/src/lightning/primitiveCellActions/primitiveCellActions.js +69 -12
  52. package/src/lightning/primitiveCellFactory/cellWithStandardLayout.html +13 -11
  53. package/src/lightning/primitiveCellFactory/primitiveCellFactory.js +13 -8
  54. package/src/lightning/primitiveDatatableIeditPanel/primitiveDatatableIeditPanel.html +17 -14
  55. package/src/lightning/primitiveDatatableIeditPanel/primitiveDatatableIeditPanel.js +167 -98
  56. package/src/lightning/primitiveDatatableIeditTypeFactory/primitiveDatatableIeditTypeFactory.js +94 -69
  57. package/src/lightning/primitiveDatatableStatusBar/primitiveDatatableStatusBar.html +4 -4
  58. package/src/lightning/primitiveDatatableStatusBar/primitiveDatatableStatusBar.js +4 -4
  59. package/src/lightning/primitiveHeaderActions/primitiveHeaderActions.js +99 -37
  60. package/src/lightning/progressIndicator/progressIndicator.js +1 -1
  61. package/src/lightning/progressStep/progressStep.js +30 -22
  62. package/src/lightning/staticMap/staticMap.html +1 -0
  63. package/src/lightning/staticMap/staticMap.js +39 -2
  64. package/src/lightning/utils/classSet.js +4 -1
  65. package/src/lightning/utilsPrivate/utilsPrivate.js +12 -1
  66. package/scopedImports/@salesforce-label-LightningModalBase.close.js +0 -1
  67. package/src/lightning/datatable/inlineEdit-shared.js +0 -14
  68. package/src/lightning/datatable/selector-shared.js +0 -38
  69. package/src/lightning/datatable/selector.js +0 -527
@@ -1,10 +1,12 @@
1
- import { getScrollOffsetFromTableEnd } from './utils';
1
+ import { getScrollOffsetFromTableEnd, normalizeNumberAttribute } from './utils';
2
2
  import { LightningResizeObserver } from 'lightning/resizeObserver';
3
- import { normalizeBoolean } from 'lightning/utilsPrivate';
3
+ import { normalizeBoolean, normalizeString } from 'lightning/utilsPrivate';
4
4
 
5
- const BUFFER_ROW_COUNT = 5;
6
- const DEFAULT_ROW_HEIGHT = 30;
7
- const DEFAULT_SCROLL_THRESHOLD = 2 * BUFFER_ROW_COUNT * DEFAULT_ROW_HEIGHT;
5
+ export const DEFAULT_ROW_HEIGHT = 30.5;
6
+ const DEFAULT_BUFFER_SIZE = 5;
7
+ const ROW_THRESHOLD = 10;
8
+ const DEFAULT_SCROLL_THRESHOLD = ROW_THRESHOLD * DEFAULT_ROW_HEIGHT;
9
+ const VERTICAL_VIRTUALIZATION = 'vertical';
8
10
 
9
11
  export function setViewportRendering(state, value) {
10
12
  state.enableViewportRendering = normalizeBoolean(value);
@@ -14,39 +16,30 @@ export function isViewportRenderingEnabled(state) {
14
16
  return state.enableViewportRendering;
15
17
  }
16
18
 
17
- /**
18
- * @typedef RenderManagerConfig
19
- * @type {object}
20
- * @property {boolean} viewportRendering - specifies whether to use viewport rendering
21
- * @property {number} rowHeight - specifies the height of a row, in px
22
- */
23
-
24
- /**
25
- * Updates and normalizes the configuration for this RenderManager
26
- *
27
- * @param {LightningDatatable} dt
28
- * @param {RenderManager} renderManager
29
- * @param {RenderManagerConfig} config
30
- *
31
- * @returns {RenderManager}
32
- */
33
- function normalizeAndProcessConfig(dt, renderManager, config) {
34
- const { viewportRendering, rowHeight } = config;
35
-
36
- if (viewportRendering && typeof viewportRendering === 'boolean') {
37
- renderManager.initializeResizeObserver(dt);
38
- }
39
-
40
- if (typeof rowHeight === 'number') {
41
- renderManager.rowHeight = rowHeight;
42
- renderManager.threshold = calculateThreshold(rowHeight);
19
+ export function setVirtualize(state, value) {
20
+ if (state.renderModeRoleBased) {
21
+ state.virtualize = normalizeString(value, {
22
+ fallbackValue: '', //no virtualization enabled
23
+ validValues: [VERTICAL_VIRTUALIZATION],
24
+ });
25
+ } else {
26
+ state.virtualize = '';
43
27
  }
28
+ }
44
29
 
45
- return renderManager;
30
+ export function getDTWrapperHeight() {
31
+ return this.template.querySelector('.slds-scrollable_x').offsetHeight;
46
32
  }
47
33
 
48
- function calculateThreshold(rowHeight) {
49
- return 2 * BUFFER_ROW_COUNT * rowHeight;
34
+ /**
35
+ * Sets the first visible index in the datatable state based on
36
+ * a given scrollTop value and the current rowHeight
37
+ *
38
+ * @param {Object} state - datatable state
39
+ * @param {Number} scrollTop - scroll top to calculate first visible index for
40
+ */
41
+ export function setFirstVisibleIndex(state, scrollTop) {
42
+ state.firstVisibleIndex = Math.floor(scrollTop / state.rowHeight);
50
43
  }
51
44
 
52
45
  function getDefaultPreviousInfo() {
@@ -57,6 +50,15 @@ function getDefaultPreviousInfo() {
57
50
  };
58
51
  }
59
52
 
53
+ /**
54
+ * @typedef RenderManagerConfig
55
+ * @type {object}
56
+ * @property {boolean} viewportRendering - specifies whether to use viewport rendering
57
+ * @property {number} rowHeight - specifies the height of a row, in px
58
+ * @property {number|string} bufferSize - specifies the number of additional rows to render above/below what's visible on screen
59
+ * @property {string} virtualize - string representing what kind of virtualization to enable; currently only 'vertical' is available
60
+ */
61
+
60
62
  /**
61
63
  * Handles any custom rendering in datatable.
62
64
  *
@@ -66,38 +68,160 @@ function getDefaultPreviousInfo() {
66
68
  */
67
69
  export class RenderManager {
68
70
  constructor() {
69
- this.rowHeight = DEFAULT_ROW_HEIGHT;
70
71
  this.threshold = DEFAULT_SCROLL_THRESHOLD;
71
72
  this.wrapperHeight = 0;
72
73
  this.previousCache = getDefaultPreviousInfo();
73
74
  }
74
75
 
75
76
  /**
77
+ * Updates and normalizes configuration for RenderManager
78
+ * Used when setting renderConfig for datatable
79
+ * @param {Object} state - datatable state
80
+ * @param {Function} getWrapperHeight - function to get height of datatable wrapper
81
+ * @param {RenderManagerConfig} config - set of properties used for render management
82
+ */
83
+ configure(state, getWrapperHeight, config) {
84
+ const { viewportRendering, rowHeight, virtualize, bufferSize } = config;
85
+ setVirtualize(state, virtualize);
86
+
87
+ if (normalizeBoolean(viewportRendering) || state.virtualize) {
88
+ this.initializeResizeObserver(state, getWrapperHeight);
89
+ }
90
+ state.bufferSize = normalizeNumberAttribute(
91
+ 'bufferSize',
92
+ bufferSize || DEFAULT_BUFFER_SIZE,
93
+ 'non-negative',
94
+ DEFAULT_BUFFER_SIZE
95
+ );
96
+ if (typeof rowHeight === 'number') {
97
+ state.rowHeight = rowHeight;
98
+ this.threshold = ROW_THRESHOLD * state.rowHeight;
99
+ }
100
+ }
101
+
102
+ /**
103
+ * Render only rows that fit within the viewport
104
+ *
105
+ * If data has changed (verifying only row 1), reset everything
106
+ * Otherwise, if total row count has increased and we are within the scroll threshold,
107
+ * append a viewport's worth of rows to the currently rendered rows. This happens when
108
+ * the user has added more data to the datatable (e.g when a loadMore is triggered)
109
+ *
110
+ * @param {Object} state - datatable state
111
+ * @param {Node} gridContainer - node containing datatable header and rows
112
+ * @param {Boolean} forceUpdate - always recalculates row count if true
113
+ */
114
+ updateViewportRendering(state, gridContainer, forceUpdate) {
115
+ if (this.hasDataChanged(state.rows) || forceUpdate) {
116
+ this.updateRenderedRows(state, this.getRowCountWithBuffer(state));
117
+ } else if (
118
+ this.previousCache.totalRowCount < state.rows.length &&
119
+ this.isWithinThreshold(gridContainer)
120
+ ) {
121
+ this.updateRenderedRows(
122
+ state,
123
+ this.previousCache.renderedRowCount +
124
+ this.getRowCountWithBuffer(state)
125
+ );
126
+ } else {
127
+ this.updateRenderedRows(state, this.previousCache.renderedRowCount);
128
+ }
129
+ }
130
+
131
+ /**
132
+ * Handles scroll event on datatable if viewport rendering enabled
133
+ * If the scroll is within a specified threshold of the bottom,
134
+ * calculate and render the next batch of rows
76
135
  *
77
- * @param {LightningDatatable} dt
78
- * @param {RenderManagerConfig} config
136
+ * @param {Object} state - datatable state
137
+ * @param {Event} event - scroll event
79
138
  */
80
- configure(dt, config) {
81
- normalizeAndProcessConfig(dt, this, config);
139
+ handleScroll(state, event) {
140
+ const { rows, renderedRowCount } = state;
141
+ if (
142
+ this.isWithinThreshold(event.target.firstChild) &&
143
+ renderedRowCount < rows.length
144
+ ) {
145
+ this.updateRenderedRows(
146
+ state,
147
+ renderedRowCount + this.getRowCountWithBuffer(state)
148
+ );
149
+ }
150
+ }
151
+
152
+ /**
153
+ * calculates the range of rows that should be rendered based on the
154
+ * first visible index, buffer size and datatable height
155
+ *
156
+ * @param {Object} state - datatable state
157
+ * @returns {Object} object with firstIndex and lastIndex of rendered range of rows
158
+ */
159
+ getRenderedRange(state) {
160
+ const { firstVisibleIndex, bufferSize, renderedRowCount } = state;
161
+ const firstIndex = Math.max(firstVisibleIndex - bufferSize, 0);
162
+ const lastIndex = firstVisibleIndex - bufferSize + renderedRowCount;
163
+
164
+ return { firstIndex, lastIndex };
82
165
  }
83
166
 
167
+ /**
168
+ * Updates internal cache of row counts and first key
169
+ *
170
+ * @param {Object} state - datatable state
171
+ * @param {Number} rowCount - max number of rows to set renderedRowCount to
172
+ */
173
+ updateRenderedRows(state, rowCount) {
174
+ const rows = state.rows;
175
+ const totalRows = rows.length;
176
+ const normalizedRowCount = rowCount
177
+ ? Math.min(rowCount, totalRows)
178
+ : totalRows;
179
+ state.renderedRowCount = normalizedRowCount;
180
+
181
+ // Update our internal cache
182
+ this.previousCache.renderedRowCount = normalizedRowCount;
183
+ this.previousCache.totalRowCount = totalRows;
184
+
185
+ if (rows.length > 0) {
186
+ this.previousCache.firstRowKey = rows[0].key;
187
+ }
188
+ }
189
+
190
+ /**
191
+ * Caches the height of the wrapper in Datatable to avoid
192
+ * unnecessary reflows
193
+ *
194
+ * @param {Function} getWrapperHeight - function to get height of datatable wrapper
195
+ */
196
+ updateWrapperHeight(getWrapperHeight) {
197
+ this.wrapperHeight = getWrapperHeight();
198
+ }
199
+
200
+ /************************** OBSERVER MANAGEMENT **************************/
201
+
84
202
  /**
85
203
  * Initializes a resize observer to update the wrapper height
86
204
  * when the datatable component's height changes
87
205
  *
88
- * @param {LightningDatatable} dt
206
+ * @param {Object} state - datatable state
207
+ * @param {Function} getWrapperHeight - function to get height of datatable wrapper
89
208
  */
90
- initializeResizeObserver(dt) {
209
+ initializeResizeObserver(state, getWrapperHeight) {
91
210
  if (!this._heightResizeObserver) {
92
211
  this._heightResizeObserver = new LightningResizeObserver(() => {
93
212
  if (this._resizeObserverConnected) {
94
- this.updateWrapperHeight(dt);
213
+ this.updateWrapperHeight(getWrapperHeight);
214
+
215
+ // If the wrapper is now larger than the table or virtualization enabled,
216
+ // we need to update the rendered rows so users can continue scrolling
217
+ const rowCountWithBuffer =
218
+ this.getRowCountWithBuffer(state);
95
219
 
96
- // If the wrapper is now larger than the table, we need to update
97
- // the rendered rows so users can continue scrolling
98
- const rowCountWithBuffer = this.getRowCountWithBuffer();
99
- if (rowCountWithBuffer > dt._renderedRowCount) {
100
- this.updateRenderedRows(dt, rowCountWithBuffer);
220
+ if (
221
+ rowCountWithBuffer > state.renderedRowCount ||
222
+ state.virtualize
223
+ ) {
224
+ this.updateRenderedRows(state, rowCountWithBuffer);
101
225
  }
102
226
  }
103
227
  });
@@ -107,13 +231,10 @@ export class RenderManager {
107
231
  /**
108
232
  * Connect the resize observer to the correct element
109
233
  *
110
- * @param {LightningDatatable} dt
234
+ * @param {Node} resizeTarget
111
235
  */
112
- connectResizeObserver(dt) {
236
+ connectResizeObserver(resizeTarget) {
113
237
  if (this._heightResizeObserver) {
114
- const resizeTarget = dt.template.querySelector(
115
- 'div.dt-outer-container'
116
- );
117
238
  this._heightResizeObserver.observe(resizeTarget);
118
239
  this._resizeObserverConnected = true;
119
240
  }
@@ -129,104 +250,51 @@ export class RenderManager {
129
250
  }
130
251
  }
131
252
 
132
- hasWrapperHeight() {
133
- return !!this.wrapperHeight;
134
- }
135
-
136
- /**
137
- * Caches the height of the wrapper in Datatable to avoid
138
- * unnecessary reflows
139
- *
140
- * @param {LightningDatatable} dt
141
- */
142
- updateWrapperHeight(dt) {
143
- this.wrapperHeight =
144
- dt.template.querySelector('.slds-scrollable_x').offsetHeight;
145
- }
253
+ /************************* HELPER FUNCTIONS **************************/
146
254
 
147
255
  /**
148
256
  * Calculates how many rows fits within the current wrapper
149
257
  */
150
- getRowCountInViewport() {
151
- return Math.floor(this.wrapperHeight / this.rowHeight);
152
- }
153
-
154
- getRowCountWithBuffer() {
155
- return this.getRowCountInViewport() + BUFFER_ROW_COUNT;
258
+ getRowCountInViewport(state) {
259
+ return Math.ceil(this.wrapperHeight / state.rowHeight);
156
260
  }
157
261
 
158
262
  /**
159
- * Render only rows that fit within the viewport
160
- *
161
- * If data has changed (verifying only row 1), reset everything
162
- * Otherwise, if total row count has increased and we are within the scroll threshold,
163
- * append a viewport's worth of rows to the currently rendered rows. This happens when
164
- * the user has added more data to the datatable (e.g when a loadMore is triggered)
165
- *
166
- * @param {LightningDatatable} dt
263
+ * Calculates how many rows fit in current wrapper with an added buffer
264
+ * Used to determine how many additional rows to render
167
265
  */
168
- updateViewportRendering(dt, forceUpdate) {
169
- if (this.hasDataChanged(dt) || forceUpdate) {
170
- this.updateRenderedRows(dt, this.getRowCountWithBuffer());
171
- } else if (
172
- this.previousCache.totalRowCount < dt.state.rows.length &&
173
- this.isWithinThreshold(dt.template.querySelector('table'))
174
- ) {
175
- this.updateRenderedRows(
176
- dt,
177
- this.previousCache.renderedRowCount +
178
- this.getRowCountWithBuffer()
179
- );
180
- } else {
181
- this.updateRenderedRows(dt, this.previousCache.renderedRowCount);
182
- }
266
+ getRowCountWithBuffer(state) {
267
+ // buffer is before and after with virtualization
268
+ // but only after with viewport rendering
269
+ const multiplier = state.virtualize ? 2 : 1;
270
+ return (
271
+ this.getRowCountInViewport(state) + state.bufferSize * multiplier
272
+ );
183
273
  }
184
274
 
185
275
  /**
186
- * If the scroll is within a specified threshold of the bottom,
187
- * calculate and render the next batch of rows
188
- *
189
- * @param {LightningDatatable} dt
190
- * @param {Event} event - scroll event
276
+ * Checks if offset is within threshold of end of table
277
+ * Used when determining if additional rows should be rendered
278
+ * @returns {boolean} true if offset is within threshold
191
279
  */
192
- handleScroll(dt, event) {
193
- const currentLength = dt._renderedRowCount;
194
- if (
195
- this.isWithinThreshold(event.target.firstChild) &&
196
- currentLength < dt.state.rows.length
197
- ) {
198
- this.updateRenderedRows(
199
- dt,
200
- currentLength + this.getRowCountWithBuffer()
201
- );
202
- }
203
- }
204
-
205
- updateRenderedRows(dt, rowCount) {
206
- const totalRows = dt.state.rows.length;
207
- const normalizedRowCount = rowCount
208
- ? Math.min(rowCount, totalRows)
209
- : totalRows;
210
- dt._renderedRowCount = normalizedRowCount;
211
-
212
- // Update our internal cache
213
- this.previousCache.renderedRowCount = normalizedRowCount;
214
- this.previousCache.totalRowCount = totalRows;
215
-
216
- if (dt.state.rows.length > 0) {
217
- this.previousCache.firstRowKey = dt.state.rows[0].key;
218
- }
219
- }
220
-
221
280
  isWithinThreshold(target) {
222
281
  const offset = getScrollOffsetFromTableEnd(target);
223
- return offset < this.threshold;
282
+ return offset <= this.threshold;
224
283
  }
225
284
 
226
- hasDataChanged(dt) {
285
+ /**
286
+ * Checks key of first row to determine if data has changed
287
+ * Used to determine if viewport rendering should be reset
288
+ * @param {Array} rows
289
+ * @returns {Boolean} true if key of first row has changed
290
+ */
291
+ hasDataChanged(rows) {
227
292
  return (
228
- dt.state.rows.length > 0 &&
229
- this.previousCache.firstRowKey !== dt.state.rows[0].key
293
+ rows.length > 0 && this.previousCache.firstRowKey !== rows[0].key
230
294
  );
231
295
  }
296
+
297
+ hasWrapperHeight() {
298
+ return !!this.wrapperHeight;
299
+ }
232
300
  }
@@ -3,39 +3,43 @@ import { getUserRowByCellKeys } from './rows';
3
3
  import { getUserColumnIndex } from './columns';
4
4
 
5
5
  /**
6
+ * Handles the `privatecellactiontriggered` event on lightning-datatable
6
7
  *
7
- * @param {CustomEvent} event - row action
8
+ * @param {CustomEvent} event - `privatecellactiontriggered`
8
9
  */
9
10
  export function handleRowActionTriggered(event) {
10
- const { rowKeyValue, colKeyValue, action } = event.detail;
11
+ event.stopPropagation();
12
+
13
+ const { action, colKeyValue, rowKeyValue } = event.detail;
11
14
  const selectedRow = getUserRowByCellKeys(
12
15
  this.state,
13
16
  rowKeyValue,
14
17
  colKeyValue
15
18
  );
16
19
 
17
- event.stopPropagation();
18
-
19
20
  this.dispatchEvent(
20
21
  new CustomEvent('rowaction', {
21
22
  detail: {
22
- row: unwrap(selectedRow),
23
23
  action: unwrap(action),
24
+ row: unwrap(selectedRow),
24
25
  },
25
26
  })
26
27
  );
27
28
  }
28
29
 
29
30
  /**
31
+ * Handles the `privatecellactionmenuopening` event on lightning-datatable
30
32
  *
31
- * @param {CustomEvent} event - load dynamic actions
33
+ * @param {CustomEvent} event - `privatecellactionmenuopening`
32
34
  */
33
35
  export function handleLoadDynamicActions(event) {
36
+ event.stopPropagation();
37
+
34
38
  const {
35
- rowKeyValue,
36
- colKeyValue,
37
39
  actionsProviderFunction,
40
+ colKeyValue,
38
41
  doneCallback,
42
+ rowKeyValue,
39
43
  saveContainerPosition,
40
44
  } = event.detail;
41
45
  const selectedRow = getUserRowByCellKeys(
@@ -45,18 +49,18 @@ export function handleLoadDynamicActions(event) {
45
49
  );
46
50
 
47
51
  saveContainerPosition(this.getViewableRect());
48
-
49
- event.stopPropagation();
50
52
  actionsProviderFunction(unwrap(selectedRow), doneCallback);
51
53
  }
52
54
 
53
55
  /**
56
+ * Handles the `privatecellbuttonclicked` event on lightning-datatable
54
57
  *
55
- * @param {CustomEvent} event - fire `rowaction` on cell-button click
58
+ * @param {CustomEvent} event - `privatecellbuttonclicked`
56
59
  */
57
60
  export function handleCellButtonClick(event) {
58
61
  event.stopPropagation();
59
- const { rowKeyValue, colKeyValue } = event.detail;
62
+
63
+ const { colKeyValue, rowKeyValue } = event.detail;
60
64
  const row = getUserRowByCellKeys(this.state, rowKeyValue, colKeyValue);
61
65
  const userColumnIndex = getUserColumnIndex(this.state, colKeyValue);
62
66
  const userColumnDefinition = this._columns[userColumnIndex];
@@ -64,8 +68,8 @@ export function handleCellButtonClick(event) {
64
68
  this.dispatchEvent(
65
69
  new CustomEvent('rowaction', {
66
70
  detail: {
67
- row: unwrap(row),
68
71
  action: unwrap(userColumnDefinition.typeAttributes),
72
+ row: unwrap(row),
69
73
  },
70
74
  })
71
75
  );
@@ -4,22 +4,22 @@ import labelRowNumber from '@salesforce/label/LightningDatatable.rowNumber';
4
4
  import { formatLabel } from 'lightning/utils';
5
5
  import { normalizeBoolean } from 'lightning/utilsPrivate';
6
6
 
7
+ export const TOOLTIP_ALLOWANCE = 20;
7
8
  const CHAR_WIDTH = 10;
8
9
  const ROWNUMBER_PADDING = 12;
9
- const TOOLTIP_ALLOWANCE = 20;
10
- const COLUMN_TYPE = 'rowNumber';
10
+ const ROW_NUMBER_COLUMN_TYPE = 'rowNumber';
11
11
  const i18n = {
12
12
  rowLevelErrorAssistiveText: labelRowLevelErrorAssistiveText,
13
13
  rowNumber: labelRowNumber,
14
14
  };
15
15
 
16
- export function isRowNumberColumn(column) {
17
- return column.type === COLUMN_TYPE;
18
- }
19
-
16
+ /**
17
+ * Returns the initial default column definition
18
+ * for the row number column
19
+ */
20
20
  export function getRowNumberColumnDef() {
21
21
  return {
22
- type: COLUMN_TYPE,
22
+ type: ROW_NUMBER_COLUMN_TYPE,
23
23
  ariaLabel: i18n.rowNumber,
24
24
  sortable: false,
25
25
  initialWidth: 52,
@@ -31,39 +31,57 @@ export function getRowNumberColumnDef() {
31
31
  };
32
32
  }
33
33
 
34
- export function getRowNumberState() {
35
- return {
36
- showRowNumberColumn: false,
37
- rowNumberOffset: 0,
38
- };
39
- }
40
-
41
34
  /**
42
- * showRowNumberColumn
35
+ * Retrieves showRowNumberColumn from the state
36
+ * Can be used to determine if the datatable should
37
+ * show the row number column or not
43
38
  */
44
39
  export function hasRowNumberColumn(state) {
45
40
  return state.showRowNumberColumn;
46
41
  }
42
+
43
+ /**
44
+ * Normalizes the passed in `value` to a boolean and
45
+ * sets it to showRowNumberColumn in the state
46
+ */
47
47
  export function setShowRowNumberColumn(state, value) {
48
48
  state.showRowNumberColumn = normalizeBoolean(value);
49
49
  }
50
50
 
51
51
  /**
52
- * rowNumberOffset
52
+ * Retrieves rowNumberOffset from the state
53
53
  */
54
-
55
54
  export function getRowNumberOffset(state) {
56
55
  return state.rowNumberOffset;
57
56
  }
57
+
58
+ /**
59
+ * Normalizes the passed in value to a non-negative number
60
+ * and sets it to the rowNumberOffset in the state.
61
+ * If the value is invalid, it falls back to 0.
62
+ */
58
63
  export function setRowNumberOffset(state, value) {
59
64
  state.rowNumberOffset = normalizeNumberAttribute(
60
65
  'rowNumberOffset',
61
66
  value,
62
67
  'non-negative',
63
- getRowNumberState().rowNumberOffset
68
+ 0 // default rowNumberOffset value
64
69
  );
65
70
  }
66
71
 
72
+ export function isRowNumberColumn(column) {
73
+ return column.type === ROW_NUMBER_COLUMN_TYPE;
74
+ }
75
+
76
+ /**
77
+ * Calculates the width of the row number column
78
+ * This takes into account the number of digits in the row number
79
+ * (ex. 3 for 100 rows), padding in the cell and
80
+ * space allowance for the error tooltip which is rendered in this cell
81
+ *
82
+ * @param {Object} state - datatable's state object
83
+ * @returns
84
+ */
67
85
  export function getAdjustedRowNumberColumnWidth(state) {
68
86
  const numOfRows = state.rows.length;
69
87
  const offset = state.rowNumberOffset;
@@ -76,12 +94,19 @@ export function getAdjustedRowNumberColumnWidth(state) {
76
94
  );
77
95
  }
78
96
 
97
+ /**
98
+ * Retrieves the column index of the row number column
99
+ * Returns -1 if the row number column is not present
100
+ *
101
+ * @param {Object} state - datatable's state object
102
+ * @returns {Number} index of row number column. Returns -1 if not present
103
+ */
79
104
  export function getRowNumberColumnIndex(state) {
80
105
  if (hasRowNumberColumn(state) && state.columns.length > 0) {
81
106
  const columns = state.columns;
82
107
  for (let i = 0; i < columns.length; i++) {
83
108
  const column = columns[i];
84
- if (column.type === COLUMN_TYPE) {
109
+ if (column.type === ROW_NUMBER_COLUMN_TYPE) {
85
110
  return i;
86
111
  }
87
112
  }
@@ -89,6 +114,15 @@ export function getRowNumberColumnIndex(state) {
89
114
  return -1;
90
115
  }
91
116
 
117
+ /**
118
+ * Constructs and returns the column definition for the row number column
119
+ * Column definition contains the row number column's row type and
120
+ * the error object containing the title, error messages and alt text
121
+ *
122
+ * @param {Object} rowErrors - object containing metadata of errors in the row
123
+ * @param {String} rowTitle - value of the cell which has the scope of the row/rowheader
124
+ * @returns
125
+ */
92
126
  export function getRowNumberErrorColumnDef(rowErrors, rowTitle) {
93
127
  const { title, messages } = rowErrors;
94
128
 
@@ -105,7 +139,7 @@ export function getRowNumberErrorColumnDef(rowErrors, rowTitle) {
105
139
  );
106
140
 
107
141
  return {
108
- type: COLUMN_TYPE,
142
+ type: ROW_NUMBER_COLUMN_TYPE,
109
143
  typeAttributes: {
110
144
  error: { title, messages, alternativeText },
111
145
  },