lightning-base-components 1.21.3-alpha → 1.21.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 (183) hide show
  1. package/metadata/raptor.json +49 -0
  2. package/package.json +88 -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.modalCancel.js +1 -0
  11. package/scopedImports/@salesforce-label-LightningLookup.modalSelect.js +1 -0
  12. package/scopedImports/@salesforce-label-LightningProgressIndicator.currentStage.js +1 -1
  13. package/scopedImports/@salesforce-label-LightningProgressIndicator.errorStage.js +1 -0
  14. package/scopedImports/@salesforce-label-LightningProgressIndicator.stageComplete.js +1 -1
  15. package/scopedImports/@salesforce-label-LightningProgressIndicator.stageNotStarted.js +1 -1
  16. package/src/lightning/avatar/avatar.html +1 -0
  17. package/src/lightning/badge/badge.html +3 -3
  18. package/src/lightning/baseCombobox/baseCombobox.html +4 -1
  19. package/src/lightning/baseCombobox/baseCombobox.js +3 -16
  20. package/src/lightning/button/__docs__/button.md +2 -1
  21. package/src/lightning/button/button.js +3 -4
  22. package/src/lightning/buttonIcon/__docs__/buttonIcon.md +1 -0
  23. package/src/lightning/buttonIcon/buttonIcon.html +1 -1
  24. package/src/lightning/buttonIcon/buttonIcon.js +18 -17
  25. package/src/lightning/buttonMenu/buttonMenu.css +5 -0
  26. package/src/lightning/buttonMenu/buttonMenu.js +2 -0
  27. package/src/lightning/colorPickerCustom/colorPickerCustom.js +12 -0
  28. package/src/lightning/colorPickerPanel/colorPickerPanel.js +11 -1
  29. package/src/lightning/combobox/combobox.html +1 -0
  30. package/src/lightning/datatable/__examples__disabled/customComponentWrapper/customComponentWrapper.html +11 -0
  31. package/src/lightning/datatable/__examples__disabled/customComponentWrapper/customComponentWrapper.js +25 -0
  32. package/src/lightning/datatable/__examples__disabled/customComponentWrapper/generateData.js +15 -0
  33. package/src/lightning/datatable/__examples__disabled/myCustomTypeDatatable/customInput.html +4 -0
  34. package/src/lightning/datatable/__examples__disabled/myCustomTypeDatatable/myCustomTypeDatatable.js +17 -0
  35. package/src/lightning/datatable/__examples__disabled/myCustomTypeDatatable/nestedSimpleComponentParent.html +7 -0
  36. package/src/lightning/datatable/__examples__disabled/simpleComponentNested/simpleComponentNested.html +9 -0
  37. package/src/lightning/datatable/__examples__disabled/simpleComponentNested/simpleComponentNested.js +6 -0
  38. package/src/lightning/datatable/autoWidthStrategy.js +8 -36
  39. package/src/lightning/datatable/columnResizer.js +51 -161
  40. package/src/lightning/datatable/columnWidthManager.js +25 -81
  41. package/src/lightning/datatable/columns.js +180 -302
  42. package/src/lightning/datatable/datatable.js +455 -441
  43. package/src/lightning/datatable/errors.js +17 -29
  44. package/src/lightning/datatable/fixedWidthStrategy.js +7 -22
  45. package/src/lightning/datatable/headerActions.js +8 -38
  46. package/src/lightning/datatable/indexes.js +42 -0
  47. package/src/lightning/datatable/infiniteLoading.js +16 -35
  48. package/src/lightning/datatable/inlineEdit.js +125 -156
  49. package/src/lightning/datatable/keyboard.js +226 -282
  50. package/src/lightning/datatable/renderManager.js +0 -4
  51. package/src/lightning/datatable/resizeObserver.js +4 -13
  52. package/src/lightning/datatable/rowLevelActions.js +2 -2
  53. package/src/lightning/datatable/rowNumber.js +21 -59
  54. package/src/lightning/datatable/rowSelection.js +95 -178
  55. package/src/lightning/datatable/rowSelectionShared.js +13 -27
  56. package/src/lightning/datatable/rows.js +171 -418
  57. package/src/lightning/datatable/sort.js +16 -75
  58. package/src/lightning/datatable/templates/div/div.html +12 -4
  59. package/src/lightning/datatable/templates/div/div.lbc.synthetic.css +10 -16
  60. package/src/lightning/datatable/templates/table/table.html +15 -5
  61. package/src/lightning/datatable/tree.js +17 -35
  62. package/src/lightning/datatable/types.js +10 -31
  63. package/src/lightning/datatable/utils.js +49 -24
  64. package/src/lightning/datatable/virtualization.js +2 -5
  65. package/src/lightning/datatable/widthManagerShared.js +0 -20
  66. package/src/lightning/datatable/wrapText.js +29 -60
  67. package/src/lightning/dualListbox/dualListbox.js +7 -8
  68. package/src/lightning/formattedName/formattedName.js +3 -2
  69. package/src/lightning/formattedName/formattedName.js-meta.xml +3 -0
  70. package/src/lightning/formattedNumber/formattedNumber.js +3 -2
  71. package/src/lightning/formattedNumber/formattedNumber.js-meta.xml +3 -0
  72. package/src/lightning/formattedRichText/richTextConfig.js +1 -0
  73. package/src/lightning/helptext/helptext.css +7 -0
  74. package/src/lightning/helptext/helptext.js +3 -4
  75. package/src/lightning/icon/icon.html +1 -1
  76. package/src/lightning/input/input.html +5 -0
  77. package/src/lightning/inputAddress/addressFormat.js +31 -4
  78. package/src/lightning/inputAddress/fieldsLayout.js +6 -0
  79. package/src/lightning/inputAddress/inputAddress.html +19 -1
  80. package/src/lightning/inputAddress/inputAddress.js +74 -3
  81. package/src/lightning/internationalizationLibrary/address/AddressFormat.js +553 -610
  82. package/src/lightning/lookupAddress/lookupAddress.html +6 -1
  83. package/src/lightning/lookupAddress/lookupAddress.js +25 -0
  84. package/src/lightning/modal/__docs__/modal.md +10 -1
  85. package/src/lightning/modal/__modalUtils__/modalContainerTestConstants.js +3 -7
  86. package/src/lightning/modal/__modalUtils__/modalContainerTestMethods.js +39 -133
  87. package/src/lightning/modal/__modalUtils__/modalContainerTestMockData.js +1 -1
  88. package/src/lightning/modal/modal.js +1 -1
  89. package/src/lightning/modalBase/modalBase.html +15 -10
  90. package/src/lightning/modalBase/modalBase.js +131 -146
  91. package/src/lightning/modalBody/modalBody.css +6 -0
  92. package/src/lightning/modalHeader/modalHeader.html +16 -4
  93. package/src/lightning/modalHeader/modalHeader.js +61 -14
  94. package/src/lightning/pill/link.html +1 -0
  95. package/src/lightning/pill/plain.html +1 -0
  96. package/src/lightning/pill/plainLink.html +1 -0
  97. package/src/lightning/primitiveBubble/primitiveBubble.js +42 -0
  98. package/src/lightning/primitiveDatatableCell/primitiveDatatableCell.js +1 -1
  99. package/src/lightning/primitiveHeaderActions/primitiveHeaderActions.html +1 -1
  100. package/src/lightning/primitiveHeaderActions/primitiveHeaderActions.js +13 -0
  101. package/src/lightning/primitiveHeaderFactory/nonsortableHeader.html +19 -6
  102. package/src/lightning/primitiveHeaderFactory/sortableHeader.html +3 -1
  103. package/src/lightning/primitiveResizeHandler/primitiveResizeHandler.css +11 -0
  104. package/src/lightning/primitiveResizeHandler/primitiveResizeHandler.html +2 -1
  105. package/src/lightning/primitiveResizeHandler/primitiveResizeHandler.js +1 -0
  106. package/src/lightning/progressStep/base.html +5 -6
  107. package/src/lightning/progressStep/progressStep.js +14 -9
  108. package/src/lightning/prompt/__docs__/prompt.md +1 -1
  109. package/src/lightning/shadowBaseClassPrivate/shadowBaseClassPrivate.js +0 -2
  110. package/src/lightning/sldsCommon/sldsCommon.css +134 -98
  111. package/src/lightning/sldsUtilsAlignment/sldsUtilsAlignment.css +1 -1
  112. package/src/lightning/sldsUtilsBox/sldsUtilsBox.css +14 -13
  113. package/src/lightning/sldsUtilsGrid/sldsUtilsGrid.css +95 -92
  114. package/src/lightning/sldsUtilsHyphenation/sldsUtilsHyphenation.css +1 -1
  115. package/src/lightning/sldsUtilsMargin/sldsUtilsMargin.css +77 -75
  116. package/src/lightning/sldsUtilsPadding/sldsUtilsPadding.css +73 -73
  117. package/src/lightning/sldsUtilsSizing/sldsUtilsSizing.css +552 -558
  118. package/src/lightning/sldsUtilsVisibility/sldsUtilsVisibility.css +2 -2
  119. package/src/lightning/staticMap/staticMap.js +3 -2
  120. package/src/lightning/tab/tab.js +6 -3
  121. package/src/lightning/tab/tab.js-meta.xml +3 -0
  122. package/src/lightning/tabBar/tabBar.js +10 -5
  123. package/src/lightning/tabset/tabset.html +2 -0
  124. package/src/lightning/tabset/tabset.js-meta.xml +3 -0
  125. package/src/lightning/textarea/textarea.js +6 -1
  126. package/src/lightning/toastContainer/__docs__/toastContainer.md +3 -2
  127. package/src/lightning/tooltipLibrary/tooltipLibrary.js +24 -15
  128. package/src/lightning/verticalNavigation/vertical-navigation.slds.css +14 -0
  129. package/src/lightning/verticalNavigation/verticalNavigation.css +1 -1
  130. package/src/lightning/verticalNavigation/verticalNavigation.html +1 -1
  131. package/src/lightning/verticalNavigation/verticalNavigation.js +66 -28
  132. package/src/lightning/verticalNavigation/verticalNavigation.js-meta.xml +3 -0
  133. package/src/lightning/verticalNavigationItem/vertical-navigation-item.slds.css +63 -0
  134. package/src/lightning/verticalNavigationItem/verticalNavigationItem.css +2 -3
  135. package/src/lightning/verticalNavigationItem/verticalNavigationItem.js +29 -15
  136. package/src/lightning/verticalNavigationItem/verticalNavigationItem.js-meta.xml +3 -0
  137. package/src/lightning/verticalNavigationItem/verticalNavigationItem.lbc.native.css +2 -0
  138. package/src/lightning/verticalNavigationItem/verticalNavigationItem.lbc.synthetic.css +3 -0
  139. package/src/lightning/verticalNavigationItemBadge/badge.slds.css +76 -0
  140. package/src/lightning/verticalNavigationItemBadge/vertical-navigation-item.slds.css +63 -0
  141. package/src/lightning/verticalNavigationItemBadge/verticalNavigationItemBadge.css +2 -3
  142. package/src/lightning/verticalNavigationItemBadge/verticalNavigationItemBadge.html +1 -1
  143. package/src/lightning/verticalNavigationItemBadge/verticalNavigationItemBadge.js +28 -15
  144. package/src/lightning/verticalNavigationItemBadge/verticalNavigationItemBadge.js-meta.xml +3 -0
  145. package/src/lightning/verticalNavigationItemBadge/verticalNavigationItemBadge.lbc.native.css +5 -0
  146. package/src/lightning/verticalNavigationItemBadge/verticalNavigationItemBadge.lbc.synthetic.css +3 -0
  147. package/src/lightning/verticalNavigationItemIcon/vertical-navigation-item.slds.css +63 -0
  148. package/src/lightning/verticalNavigationItemIcon/verticalNavigationItemIcon.css +2 -3
  149. package/src/lightning/verticalNavigationItemIcon/verticalNavigationItemIcon.js +29 -15
  150. package/src/lightning/verticalNavigationItemIcon/verticalNavigationItemIcon.js-meta.xml +3 -0
  151. package/src/lightning/verticalNavigationItemIcon/verticalNavigationItemIcon.lbc.native.css +3 -0
  152. package/src/lightning/verticalNavigationItemIcon/verticalNavigationItemIcon.lbc.synthetic.css +3 -0
  153. package/src/lightning/verticalNavigationOverflow/button.slds.css +503 -0
  154. package/src/lightning/verticalNavigationOverflow/vertical-navigation-item.slds.css +63 -0
  155. package/src/lightning/verticalNavigationOverflow/vertical-navigation-section.slds.css +17 -0
  156. package/src/lightning/verticalNavigationOverflow/verticalNavigationOverflow.css +2 -1
  157. package/src/lightning/verticalNavigationOverflow/verticalNavigationOverflow.html +2 -0
  158. package/src/lightning/verticalNavigationOverflow/verticalNavigationOverflow.js +18 -13
  159. package/src/lightning/verticalNavigationOverflow/verticalNavigationOverflow.js-meta.xml +3 -0
  160. package/src/lightning/verticalNavigationOverflow/verticalNavigationOverflow.lbc.native.css +5 -0
  161. package/src/lightning/verticalNavigationSection/vertical-navigation-section.slds.css +14 -14
  162. package/src/lightning/verticalNavigationSection/verticalNavigationSection.js-meta.xml +3 -0
  163. package/src/lightning/datatable/inlineEditShared.js +0 -26
  164. /package/src/lightning/datatable/{__examples__ → __examples__disabled}/customDatatableWrapper/customDatatableWrapper.html +0 -0
  165. /package/src/lightning/datatable/{__examples__ → __examples__disabled}/customDatatableWrapper/customDatatableWrapper.js +0 -0
  166. /package/src/lightning/datatable/{__examples__ → __examples__disabled}/customDatatypeDeleteRowBtn/customDatatypeDeleteRowBtn.html +0 -0
  167. /package/src/lightning/datatable/{__examples__ → __examples__disabled}/customDatatypeDeleteRowBtn/customDatatypeDeleteRowBtn.js +0 -0
  168. /package/src/lightning/datatable/{__examples__ → __examples__disabled}/customDatatypeLink/customDatatypeLink.html +0 -0
  169. /package/src/lightning/datatable/{__examples__ → __examples__disabled}/customDatatypeLink/customDatatypeLink.js +0 -0
  170. /package/src/lightning/datatable/{__examples__ → __examples__disabled}/customDatatypeNumber/customDatatypeNumber.html +0 -0
  171. /package/src/lightning/datatable/{__examples__ → __examples__disabled}/customDatatypeNumber/customDatatypeNumber.js +0 -0
  172. /package/src/lightning/datatable/{__examples__ → __examples__disabled}/customDatatypeRowOrderingBtn/customDatatypeRowOrderingBtn.html +0 -0
  173. /package/src/lightning/datatable/{__examples__ → __examples__disabled}/customDatatypeRowOrderingBtn/customDatatypeRowOrderingBtn.js +0 -0
  174. /package/src/lightning/datatable/{__examples__ → __examples__disabled}/customDatatypeTable/customDatatypeTable.js +0 -0
  175. /package/src/lightning/datatable/{__examples__ → __examples__disabled}/customDatatypeTable/customLink.html +0 -0
  176. /package/src/lightning/datatable/{__examples__ → __examples__disabled}/customDatatypeTable/customName.html +0 -0
  177. /package/src/lightning/datatable/{__examples__ → __examples__disabled}/customDatatypeTable/customNumber.html +0 -0
  178. /package/src/lightning/datatable/{__examples__ → __examples__disabled}/customDatatypeTable/customNumberEdit.html +0 -0
  179. /package/src/lightning/datatable/{__examples__ → __examples__disabled}/customDatatypeTable/deleteRow.html +0 -0
  180. /package/src/lightning/datatable/{__examples__ → __examples__disabled}/customDatatypeTable/iconPill.html +0 -0
  181. /package/src/lightning/datatable/{__examples__ → __examples__disabled}/customDatatypeTable/orderingButtons.html +0 -0
  182. /package/src/lightning/datatable/{__examples__ → __examples__disabled}/customNestedComponent/customNestedComponent.html +0 -0
  183. /package/src/lightning/datatable/{__examples__ → __examples__disabled}/customNestedComponent/customNestedComponent.js +0 -0
@@ -1,43 +1,23 @@
1
1
  import { assert } from 'lightning/utilsPrivate';
2
- import { classSet, isObjectLike, styleToString } from './utils';
3
- import { isTreeType, getAttributesNames } from './types';
2
+ import { classSet, isObjectLike } from './utils';
3
+ import { getAttributesNames } from './types';
4
4
  import {
5
- isSelectedRow,
6
- isDisabledRow,
7
- getRowSelectionInputType,
5
+ getCurrentSelectionLength,
6
+ SELECTABLE_HEADER_TYPE,
8
7
  } from './rowSelectionShared';
9
- import { getTreeStateIndicatorFieldNames, getStateTreeColumn } from './tree';
10
8
  import {
11
- getColumns,
12
9
  getTypeAttributesValues,
13
10
  getSubTypeAttributesValues,
14
11
  getCellAttributesValues,
15
- isCustomerColumn,
16
12
  generateColKeyValue,
17
13
  } from './columns';
18
- import { isRowNumberColumn, getRowNumberErrorColumnDef } from './rowNumber';
19
- import { getRowError } from './errors';
20
- import { getDirtyValueFromCell } from './inlineEditShared';
14
+ import { getRowNumberError } from './rowNumber';
21
15
 
22
- export function getData(state) {
23
- return state.data;
24
- }
25
-
26
- export function setData(state, data) {
27
- if (Array.isArray(data)) {
28
- state.data = data;
29
- } else {
30
- state.data = [];
31
- }
32
- }
33
-
34
- export function getRows(state) {
35
- return state.rows;
36
- }
37
-
38
- export function getKeyField(state) {
39
- return state.keyField;
40
- }
16
+ const CELL_EDIT_CLASS = 'slds-cell-edit';
17
+ const HAS_ERROR_CLASS = 'slds-has-error';
18
+ const IS_EDITED_CLASS = 'slds-is-edited';
19
+ const ROLE_BASED_CELL_CLASS = 'cell';
20
+ const TREE__ITEM_CLASS = 'slds-tree__item';
41
21
 
42
22
  export function setKeyField(state, value) {
43
23
  if (typeof value === 'string') {
@@ -51,51 +31,6 @@ export function setKeyField(state, value) {
51
31
  }
52
32
  }
53
33
 
54
- export function hasValidKeyField(state) {
55
- const keyField = getKeyField(state);
56
- return typeof keyField === 'string';
57
- }
58
-
59
- /**
60
- * Resolves the CSS classes for a row based on the row.isSelected state
61
- *
62
- * @param {object} row - a row object in state.rows collection
63
- * @returns {string} the classSet string
64
- */
65
- export function resolveRowClassNames(row) {
66
- return `slds-hint-parent${row.isSelected ? ' slds-is-selected' : ''}`;
67
- }
68
-
69
- /**
70
- *
71
- * @param {object} state - data table state
72
- * @param {string} rowKeyValue - computed id for the row
73
- * @param {string} colKeyValue - computed id for the column
74
- * @returns {object} The user row that its related to the action.
75
- */
76
- export function getUserRowByCellKeys(state, rowKeyValue, colKeyValue) {
77
- const rowIndex = state.indexes[rowKeyValue][colKeyValue][0];
78
- return getData(state)[rowIndex];
79
- }
80
-
81
- /**
82
- * It creates a row key generator based on the keyField passed in by the consumer.
83
- * If the keyField passed in through the generator does not point to a value in the row object,
84
- * it falls back to a generated key using indexes. Ex. row-0/row-1
85
- *
86
- * @param {String} keyField - keyField provided by the consumer
87
- * @returns {Function} - function with the unique row key generator
88
- */
89
- export function uniqueRowKeyGenerator(keyField) {
90
- let index = 0;
91
- return function (row) {
92
- if (row[keyField]) {
93
- return row[keyField];
94
- }
95
- return `row-${index++}`;
96
- };
97
- }
98
-
99
34
  /**
100
35
  * It compute the state.rows collection based on the current normalized (data, columns)
101
36
  * and generate cells indexes map(state.indexes)
@@ -105,60 +40,83 @@ export function uniqueRowKeyGenerator(keyField) {
105
40
  * attaching the 'cell' class, calling this from connectedCallback of datatable would
106
41
  * eliminate the need for updateCellClassForRoleBasedMode.
107
42
  *
108
- * @param {object} state - the current datatable state
43
+ * @param {Object} state - The datatable state
44
+ * @param {Object} types - The type handling factory
109
45
  */
110
- export function updateRowsAndCellIndexes() {
111
- const { state, privateTypes: types } = this;
112
- const { keyField, renderModeRoleBased, virtualize, rowHeight } = state;
113
- const data = getData(state);
114
- const columns = getColumns(state);
115
- const computeUniqueRowKey = uniqueRowKeyGenerator(keyField);
46
+ export function updateRowsAndCellIndexes(state, types) {
47
+ const {
48
+ columns,
49
+ data,
50
+ keyField,
51
+ maxRowSelection,
52
+ renderModeRoleBased,
53
+ virtualize,
54
+ rowHeight,
55
+ } = state;
116
56
  const { length: rowCount } = data;
57
+ const { dirtyValues } = state.inlineEdit;
117
58
  const { length: colCount } = columns;
59
+ const currentSelectionLength =
60
+ maxRowSelection === 1 ? 1 : getCurrentSelectionLength(state);
61
+ const inputType = maxRowSelection === 1 ? 'radio' : 'checkbox';
118
62
 
119
63
  let scopeCol;
64
+ let treeColTypeAttrs;
120
65
  for (let colIndex = 0; colIndex < colCount; colIndex += 1) {
121
66
  const col = columns[colIndex];
122
- if (col.isScopeCol && types.isValidType(col.type)) {
67
+ const { type: columnType } = col;
68
+ if (!scopeCol && col.isScopeCol && types.isValidType(columnType)) {
123
69
  scopeCol = col;
124
- break;
70
+ }
71
+ if (columnType === 'tree' && treeColTypeAttrs === undefined) {
72
+ treeColTypeAttrs = getTypeAttributesValues(col);
125
73
  }
126
74
  }
127
75
 
128
76
  // initializing indexes
129
77
  state.indexes = {};
130
78
 
79
+ const { rows: errorsRows } = state.errors;
131
80
  const rows = Array(rowCount);
81
+ // Tracked state changes.
132
82
  state.rows = rows;
133
83
 
134
84
  for (let rowIndex = 0; rowIndex < rowCount; rowIndex += 1) {
135
85
  const rowData = data[rowIndex];
136
- const key = computeUniqueRowKey(rowData);
137
- const rowErrors = getRowError(state, key);
138
-
139
- state.indexes[key] = { rowIndex };
140
-
141
- const isRowSelected = isSelectedRow(state, key);
86
+ const rowDataKeyField = rowData[keyField];
87
+ const rowKeyValue = rowDataKeyField
88
+ ? `${rowDataKeyField}`
89
+ : `row-${rowIndex}`;
90
+ const dirtyRowData = dirtyValues[rowKeyValue];
91
+ const rowErrors = errorsRows && errorsRows[rowKeyValue];
92
+ const cellErrors = rowErrors && rowErrors.cells;
93
+ const errorFieldNames = rowErrors && rowErrors.fieldNames;
94
+
95
+ state.indexes[rowKeyValue] = { rowIndex };
96
+
97
+ const isRowSelected = !!state.selectedRowsKeys[rowKeyValue];
142
98
  const rowNumber = rowIndex + 1;
143
99
  const cells = Array(colCount);
144
100
 
145
101
  const row = {
146
- key,
102
+ key: rowKeyValue,
147
103
  cells,
148
104
  rowIndex,
149
105
  rowNumber, // for UTAM since methods are base-1
150
106
  ariaRowIndex: rowIndex + 2, // aria attrs are base-1 and also count header as a row
151
- inputType: getRowSelectionInputType(state),
107
+ inputType,
152
108
  isSelected: isRowSelected,
153
109
  ariaSelected: isRowSelected ? 'true' : false,
154
- isDisabled: isDisabledRow(state, key),
155
- classnames: resolveRowClassNames(rowData),
110
+ isDisabled:
111
+ !isRowSelected &&
112
+ maxRowSelection !== 1 &&
113
+ currentSelectionLength === maxRowSelection,
114
+ classnames: `slds-hint-parent${
115
+ isRowSelected ? ' slds-is-selected' : ''
116
+ }`,
156
117
  tabIndex: -1,
157
118
  style: virtualize
158
- ? styleToString({
159
- position: 'absolute',
160
- top: `${rowIndex * rowHeight}px`,
161
- })
119
+ ? `position:absolute;top:${rowIndex * rowHeight}px;`
162
120
  : '',
163
121
  level: undefined,
164
122
  posInSet: undefined,
@@ -168,7 +126,25 @@ export function updateRowsAndCellIndexes() {
168
126
  };
169
127
 
170
128
  // Add tree specific row properties.
171
- Object.assign(row, getRowStateForTree(rowData, state));
129
+ if (treeColTypeAttrs) {
130
+ const hasChildren = !!resolveAttributeValue(
131
+ treeColTypeAttrs.hasChildren,
132
+ rowData
133
+ );
134
+ row.hasChildren = hasChildren;
135
+ row.isExpanded = hasChildren
136
+ ? `${!!resolveAttributeValue(
137
+ treeColTypeAttrs.isExpanded,
138
+ rowData
139
+ )}`
140
+ : undefined;
141
+ row.level =
142
+ resolveAttributeValue(treeColTypeAttrs.level, rowData) || 1;
143
+ row.posInSet =
144
+ resolveAttributeValue(treeColTypeAttrs.posInSet, rowData) || 1;
145
+ row.setSize =
146
+ resolveAttributeValue(treeColTypeAttrs.setSize, rowData) || 1;
147
+ }
172
148
 
173
149
  rows[rowIndex] = row;
174
150
 
@@ -176,6 +152,7 @@ export function updateRowsAndCellIndexes() {
176
152
  for (let colIndex = 0; colIndex < colCount; colIndex += 1) {
177
153
  const col = columns[colIndex];
178
154
  const {
155
+ columnKey,
179
156
  fieldName,
180
157
  isScopeCol,
181
158
  label: dataLabel,
@@ -186,57 +163,111 @@ export function updateRowsAndCellIndexes() {
186
163
  const columnSubType = typeAttributes
187
164
  ? typeAttributes.subType
188
165
  : undefined;
189
- const dirtyValue = getDirtyValueFromCell(
190
- state,
191
- row.key,
192
- colKeyValue
193
- );
194
- const hasError = hasCellErrors(rowErrors, fieldName, col.columnKey);
166
+ const dirtyValue = dirtyRowData && dirtyRowData[colKeyValue];
167
+ const hasError = columnKey
168
+ ? !!(cellErrors && cellErrors[columnKey])
169
+ : !!(errorFieldNames && errorFieldNames.includes(fieldName));
170
+ const hasTreeData = columnType === 'tree';
195
171
  // value based on the fieldName
196
172
  const value =
197
173
  dirtyValue === undefined ? rowData[fieldName] : dirtyValue;
174
+ const displayReadOnlyIcon = !!col.displayReadOnlyIcon;
175
+ const editable = isCellEditable(rowData, col);
198
176
  const isValidType = types.isValidType(columnType);
199
- const isCheckbox = columnType === 'SELECTABLE_CHECKBOX';
177
+ const isCheckbox = columnType === SELECTABLE_HEADER_TYPE;
200
178
  const isDataType = isValidType && !isScopeCol;
201
179
  const isDataTypeScope = isValidType && isScopeCol;
202
180
 
203
181
  // cell object creation
204
182
  const cell = {
205
- columnType,
183
+ ariaReadOnly: !editable,
184
+ class: '',
185
+ colKeyValue, // unique column key value
206
186
  columnSubType,
187
+ columnType,
207
188
  dataLabel,
208
- value,
189
+ describedBy: dirtyValue ? 'unsaved-cell-notification' : null,
190
+ displayReadOnlyIcon,
209
191
  displayValue: rowData.displayValue || '',
210
- rowKeyValue: row.key, // unique row key value
211
- colKeyValue, // unique column key value
212
- tabIndex: -1,
213
- isCheckbox,
214
- class: computeCellClassNames(
215
- rowData,
216
- col,
217
- hasError,
218
- dirtyValue,
219
- renderModeRoleBased
220
- ),
192
+ editable,
221
193
  hasError,
194
+ isCheckbox,
222
195
  isDataType,
223
196
  isDataTypeScope,
197
+ rowKeyValue: row.key, // unique row key value
198
+ style: computeCellStyles(types, col, renderModeRoleBased),
199
+ tabIndex: -1,
200
+ value,
224
201
  wrapText: state.wrapText[colKeyValue], // wrapText state
225
202
  wrapTextMaxLines: state.wrapText[colKeyValue]
226
203
  ? state.wrapTextMaxLines
227
204
  : undefined,
228
- style: computeCellStyles(types, col, renderModeRoleBased),
229
205
  };
230
206
 
231
- if (isCustomerColumn(col)) {
232
- assignCustomerColumnAttributes(cell, row, rowData, col, types);
233
- } else if (isRowNumberColumn(col)) {
234
- assignRowNumberColumnAttributes(
235
- cell,
236
- rowData,
237
- types,
207
+ cell.class = computeCellClassNames(
208
+ cell,
209
+ hasTreeData,
210
+ dirtyValue,
211
+ renderModeRoleBased
212
+ );
213
+
214
+ if (!col.internal) {
215
+ // Assign cell type or cell subType attributes.
216
+ let attributeNames;
217
+ let attributeValues;
218
+ if (columnSubType) {
219
+ attributeNames = getAttributesNames(columnSubType);
220
+ attributeValues = getSubTypeAttributesValues(col);
221
+ } else {
222
+ attributeNames = types.getType(columnType).typeAttributes;
223
+ attributeValues = getTypeAttributesValues(col);
224
+ }
225
+ const attributeNamesLength = attributeNames
226
+ ? attributeNames.length
227
+ : 0;
228
+ for (let i = 0; i < attributeNamesLength; i += 1) {
229
+ const attrName = attributeNames[i];
230
+ const attrValue = attributeValues[attrName];
231
+ cell[`typeAttribute${i}`] = resolveAttributeValue(
232
+ attrValue,
233
+ rowData
234
+ );
235
+ }
236
+
237
+ // Extract the `cellAttributes` and their values that are specified in the
238
+ // column definition.
239
+ // If a cell attribute points to a fieldName in a row, that value is resolved here.
240
+ // This object that contains the resolved mapping is then set in the `cell`
241
+ // object in each row.
242
+ const cellAttributes = getCellAttributesValues(col);
243
+ const keys = Object.keys(cellAttributes);
244
+ for (let i = 0, { length } = keys; i < length; i += 1) {
245
+ const attrName = keys[i];
246
+ const attrValue = cellAttributes[attrName];
247
+ cell[attrName] = resolveAttributeValue(attrValue, rowData);
248
+ }
249
+
250
+ // If this is tree grid, this maps and sets into the cell object
251
+ // the tree specific attributes:
252
+ // 1) row.hasChildren to typeAttribute21 and
253
+ // 2) row.isExpanded to and typeAttribute22
254
+ if (hasTreeData) {
255
+ // Attaches if the row containing this cell hasChildren or
256
+ // not and isExpanded or not attributes to typeAttribute21
257
+ // and typeAttribute22 respectively typeAttribute0-typeAttribute20
258
+ // are reserved for types supported by tree
259
+ cell.typeAttribute21 = row.hasChildren;
260
+ cell.typeAttribute22 = row.isExpanded === 'true';
261
+ }
262
+ }
263
+ // Populate row number attributes.
264
+ else if (columnType === 'rowNumber') {
265
+ const scopeColValue = rowData[scopeCol.fieldName];
266
+ // computes and sets the resolved typeAttribute for the row
267
+ // number column error state
268
+ cell.typeAttribute0 = getRowNumberError(
238
269
  rowErrors,
239
- scopeCol
270
+ scopeColValue
240
271
  );
241
272
  }
242
273
 
@@ -249,176 +280,6 @@ export function updateRowsAndCellIndexes() {
249
280
  }
250
281
  }
251
282
 
252
- /**
253
- * Checks whether there are errors for the specified column
254
- * When a columnKey exists for a column, we will look for its errors inside the
255
- * cells property of rowErrors. Only when it doesn't exist will we look for a
256
- * reference to the column's fieldName.
257
- *
258
- * This maintains backwards compatibility with those continuing to use fieldName
259
- * as column identifiers.
260
- */
261
- function hasCellErrors(rowErrors, fieldName, columnKey) {
262
- const cellErrors = rowErrors.cells;
263
- const errorFieldNames = rowErrors.fieldNames;
264
- return columnKey
265
- ? !!(cellErrors && cellErrors[columnKey])
266
- : !!(errorFieldNames && errorFieldNames.includes(fieldName));
267
- }
268
-
269
- /**
270
- * Computes and sets the following resolved values in the cell object:
271
- * 1. `typeAttributes` specified in the column definition
272
- * 2. `cellAttributes` specified in the column definition
273
- * 3. Editability of the cell and subsequently the ariaReadOnly property
274
- * 4. Visibility of read only icon
275
- *
276
- * Computes and sets the following tree specific attributes
277
- * into typeAttributes21/22 in the cell object:
278
- * 1. row.hasChildren
279
- * 2. row.isExpanded
280
- *
281
- * @param {Object} cell - cell metadata
282
- * @param {Object} row - row metadata
283
- * @param {Object} rowData - data to be rendered in the cells of that row
284
- * @param {Object} colData - column definition
285
- * @param {Object} types - instance of DatatableTypes from `./types.js`
286
- */
287
- function assignCustomerColumnAttributes(cell, row, rowData, colData, types) {
288
- Object.assign(
289
- cell,
290
- computeCellTypeAttributes(rowData, colData, types),
291
- computeCellAttributes(rowData, colData),
292
- computeCellEditable(rowData, colData),
293
- computeCellDisplayReadOnlyIcon(colData)
294
- );
295
- if (!cell.editable) {
296
- cell.ariaReadOnly = true;
297
- }
298
-
299
- // If this is tree grid, this maps and sets into the cell object the tree specific attributes:
300
- // 1) row.hasChildren to typeAttribute21 and
301
- // 2) row.isExpanded to and typeAttribute22
302
- if (isTreeType(colData.type)) {
303
- Object.assign(cell, computeCellStateTypeAttributes(row));
304
- }
305
- }
306
-
307
- /**
308
- * Computes and sets the resolved typeAttribute for the row number column error state
309
- *
310
- * @param {Object} cell - cell metadata
311
- * @param {Object} rowData - data to be rendered in the cells of that row
312
- * @param {Object} types - instance of DatatableTypes from `./types.js`
313
- * @param {Object} rowErrors - contains the errors present in that row
314
- * @param {Object} scopeCol - column with scope=row
315
- */
316
- function assignRowNumberColumnAttributes(
317
- cell,
318
- rowData,
319
- types,
320
- rowErrors,
321
- scopeCol
322
- ) {
323
- const scopeColValue = rowData[scopeCol.fieldName];
324
- const errorColumnDef = getRowNumberErrorColumnDef(rowErrors, scopeColValue);
325
- Object.assign(
326
- cell,
327
- computeCellTypeAttributes(rowData, errorColumnDef, types)
328
- );
329
- }
330
-
331
- /**
332
- * This function extracts the `cellAttributes` and their values that are specified
333
- * in the column definition.
334
- * If a cell attribute points to a fieldName in a row, that value is resolved here.
335
- *
336
- * This object that contains the resolved mapping is then set in the `cell` object
337
- * in each row.
338
- *
339
- * @param {Object} rowData - current row data. Required for cases cellAttributes refers to a fieldName in a row
340
- * @param {Object} col - column definition
341
- * @returns {Object} - contains the resolved mapping of cellAttributes and their values
342
- */
343
- export function computeCellAttributes(rowData, col) {
344
- const cellAttrs = {};
345
- const cellAttributes = getCellAttributesValues(col);
346
- const keys = Object.keys(cellAttributes);
347
- for (let i = 0, { length } = keys; i < length; i += 1) {
348
- const attrName = keys[i];
349
- const attrValue = cellAttributes[attrName];
350
- cellAttrs[attrName] = resolveAttributeValue(attrValue, rowData);
351
- }
352
- return cellAttrs;
353
- }
354
-
355
- /**
356
- * This function retrieves the allowlisted type attributes for a particular type and
357
- * maps the value set in the column definition to `typeAttribute{index}`.
358
- *
359
- * The types and their corresponding allowlisted attributes can be seen in types.js
360
- *
361
- * Ex. For the type 'url', there are 3 type attributes allowlisted: label, target, tooltip
362
- * If you pass typeAttributes: {label: 'My Label', target: '_blank', myattr: false}
363
- * in the column definition, this function would map ->
364
- * typeAttribute0: 'My Label', typeAttribute1: '_blank' and typeAttribute2: undefined
365
- * `myattr` is not allowlisted so it is discarded
366
- *
367
- * This mapping is later set into the `cell` object for each row and
368
- * will be passed in to primitive-cell-factory as
369
- * type-attribute-0={cell.typeAttribute0}
370
- * type-attribute-1={cell.typeAttribute1}
371
- * ...
372
- *
373
- * @param {Object} rowData - current row data. Required for cases typeAttributes refers to a fieldName in a row
374
- * @param {Object} col - column definition
375
- * @param {Object} types - instance of DatatableTypes from `./types.js`
376
- * @returns {Object} - object containing all the typeAttributes{index} and their mapped values
377
- */
378
- export function computeCellTypeAttributes(rowData, column, types) {
379
- const { typeAttributes } = column;
380
- if (typeAttributes && typeAttributes.subType) {
381
- return computeCellSubTypeAttributes(rowData, column);
382
- }
383
- const attributeNames = types.getType(column.type).typeAttributes;
384
- const attributeValues = getTypeAttributesValues(column);
385
-
386
- const cellAttrs = {};
387
- const attributeNamesLength = attributeNames ? attributeNames.length : 0;
388
- for (let i = 0; i < attributeNamesLength; i += 1) {
389
- const attrName = attributeNames[i];
390
- const attrValue = attributeValues[attrName];
391
- cellAttrs[`typeAttribute${i}`] = resolveAttributeValue(
392
- attrValue,
393
- rowData
394
- );
395
- }
396
- return cellAttrs;
397
- }
398
-
399
- function computeCellSubTypeAttributes(rowData, column) {
400
- const attributeNames = getAttributesNames(column.typeAttributes.subType);
401
- const attributeValues = getSubTypeAttributesValues(column);
402
-
403
- const cellAttrs = {};
404
- const attributeNamesLength = attributeNames ? attributeNames.length : 0;
405
- for (let i = 0; i < attributeNamesLength; i += 1) {
406
- const attrName = attributeNames[i];
407
- const attrValue = attributeValues[attrName];
408
- cellAttrs[`typeAttribute${i}`] = resolveAttributeValue(
409
- attrValue,
410
- rowData
411
- );
412
- }
413
- return cellAttrs;
414
- }
415
-
416
- function computeCellEditable(row, column) {
417
- return {
418
- editable: isCellEditable(row, column),
419
- };
420
- }
421
-
422
283
  /**
423
284
  * Returns true in the following three cases:
424
285
  *
@@ -435,12 +296,6 @@ export function isCellEditable(rowData, col) {
435
296
  return !!resolveAttributeValue(col.editable, rowData);
436
297
  }
437
298
 
438
- function computeCellDisplayReadOnlyIcon(col) {
439
- return {
440
- displayReadOnlyIcon: !!col.displayReadOnlyIcon,
441
- };
442
- }
443
-
444
299
  /**
445
300
  * Computes styles to be set on the cell
446
301
  * 1. Remove padding from the cell if the cell is of a custom type
@@ -468,7 +323,7 @@ function computeCellStyles(types, col, renderModeRoleBased) {
468
323
 
469
324
  // Width needs to be managed when rendering as divs
470
325
  if (renderModeRoleBased) {
471
- const { columnWidth } = col.columnWidth;
326
+ const { columnWidth } = col;
472
327
  if (columnWidth > 0) {
473
328
  cellStyle += `width:${columnWidth}px;`;
474
329
  }
@@ -478,9 +333,8 @@ function computeCellStyles(types, col, renderModeRoleBased) {
478
333
  }
479
334
 
480
335
  function computeCellClassNames(
481
- row,
482
- column,
483
- hasError,
336
+ cell,
337
+ hasTreeData,
484
338
  dirtyValue,
485
339
  renderModeRoleBased
486
340
  ) {
@@ -488,60 +342,24 @@ function computeCellClassNames(
488
342
  // where the read only icon is to be displayed. This is an issue with their design that will need to
489
343
  // be addressed on their end, so once they do that we can modify this code accordingly.
490
344
  let cellClass = '';
491
- if (column.displayReadOnlyIcon || isCellEditable(row, column)) {
492
- cellClass += 'slds-cell-edit';
345
+ if (cell.displayReadOnlyIcon || cell.editable) {
346
+ cellClass += CELL_EDIT_CLASS;
493
347
  }
494
- if (isTreeType(column.type)) {
495
- cellClass += (cellClass.length ? ' ' : '') + 'slds-tree__item';
348
+ if (hasTreeData) {
349
+ cellClass += (cellClass.length ? ' ' : '') + TREE__ITEM_CLASS;
496
350
  }
497
- if (hasError) {
498
- cellClass += (cellClass.length ? ' ' : '') + 'slds-has-error';
351
+ if (cell.hasError) {
352
+ cellClass += (cellClass.length ? ' ' : '') + HAS_ERROR_CLASS;
499
353
  }
500
354
  if (dirtyValue !== undefined) {
501
- cellClass += (cellClass.length ? ' ' : '') + 'slds-is-edited';
355
+ cellClass += (cellClass.length ? ' ' : '') + IS_EDITED_CLASS;
502
356
  }
503
357
  if (renderModeRoleBased) {
504
- cellClass += (cellClass.length ? ' ' : '') + 'cell';
358
+ cellClass += (cellClass.length ? ' ' : '') + ROLE_BASED_CELL_CLASS;
505
359
  }
506
360
  return cellClass;
507
361
  }
508
362
 
509
- /**
510
- * Attaches if the row containing this cell hasChildren or not and isExpanded or not
511
- * attributes to typeAttribute21 and typeAttribute22 respectively
512
- * typeAttribute0-typeAttribute20 are reserved for types supported by tree
513
- * @param {object}row - current row which is stored in state.rows
514
- * @returns {{typeAttribute21, typeAttribute22: boolean}} typeAttributes
515
- * describing state of the row associated
516
- */
517
- function computeCellStateTypeAttributes(row) {
518
- return {
519
- typeAttribute21: row.hasChildren,
520
- typeAttribute22: row.isExpanded === 'true',
521
- };
522
- }
523
-
524
- export function getRowIndexByKey(state, key) {
525
- if (!state.indexes[key]) {
526
- return undefined;
527
- }
528
-
529
- return state.indexes[key].rowIndex;
530
- }
531
-
532
- export function getRowByKey(state, key) {
533
- const rows = getRows(state);
534
- return rows[getRowIndexByKey(state, key)];
535
- }
536
-
537
- export function rowKeyExists(state, key) {
538
- return !!state.indexes[key];
539
- }
540
-
541
- export function getRowsTotal(state) {
542
- return getRows(state).length;
543
- }
544
-
545
363
  function resolveAttributeValue(attrValue, rowData) {
546
364
  if (isObjectLike(attrValue)) {
547
365
  const { fieldName } = attrValue;
@@ -553,71 +371,6 @@ function resolveAttributeValue(attrValue, rowData) {
553
371
  return attrValue;
554
372
  }
555
373
 
556
- function getRowStateForTree(row, state) {
557
- const _row = {};
558
- const column = getStateTreeColumn(state);
559
- if (column) {
560
- _row.hasChildren = getRowHasChildren(column, row);
561
- _row.isExpanded = isRowExpanded(column, row);
562
- _row.level = getRowLevel(column, row);
563
- _row.posInSet = getRowPosInSet(column, row);
564
- _row.setSize = getRowSetSize(column, row);
565
- }
566
- return _row;
567
- }
568
-
569
- export function getRowLevel(column, rowData) {
570
- const treeColTypeAttrs = getTypeAttributesValues(column);
571
- return (
572
- resolveAttributeValue(
573
- treeColTypeAttrs[getTreeStateIndicatorFieldNames().level],
574
- rowData
575
- ) || 1
576
- );
577
- }
578
-
579
- function getRowPosInSet(column, row) {
580
- const treeColTypeAttrs = getTypeAttributesValues(column);
581
- return (
582
- resolveAttributeValue(
583
- treeColTypeAttrs[getTreeStateIndicatorFieldNames().position],
584
- row
585
- ) || 1
586
- );
587
- }
588
-
589
- function getRowSetSize(column, row) {
590
- const treeColTypeAttrs = getTypeAttributesValues(column);
591
- return (
592
- resolveAttributeValue(
593
- treeColTypeAttrs[getTreeStateIndicatorFieldNames().setsize],
594
- row
595
- ) || 1
596
- );
597
- }
598
-
599
- export function isRowExpanded(column, rowData) {
600
- const treeColTypeAttrs = getTypeAttributesValues(column);
601
- const hasChildren = resolveAttributeValue(
602
- treeColTypeAttrs[getTreeStateIndicatorFieldNames().children],
603
- rowData
604
- );
605
- return hasChildren
606
- ? `${!!resolveAttributeValue(
607
- treeColTypeAttrs[getTreeStateIndicatorFieldNames().expanded],
608
- rowData
609
- )}`
610
- : undefined;
611
- }
612
-
613
- function getRowHasChildren(column, rowData) {
614
- const treeColTypeAttrs = getTypeAttributesValues(column);
615
- return !!resolveAttributeValue(
616
- treeColTypeAttrs[getTreeStateIndicatorFieldNames().children],
617
- rowData
618
- );
619
- }
620
-
621
374
  /**
622
375
  * For the role-based table, we need to manage the width of each cell separately.
623
376
  * Re-compute the cell styles so that the width of the cell is set
@@ -626,7 +379,7 @@ function getRowHasChildren(column, rowData) {
626
379
  * @param {Object} state - Datatable's state object
627
380
  */
628
381
  export function recomputeCellStyles(types, state) {
629
- const columns = getColumns(state);
382
+ const { columns } = state;
630
383
  state.rows.forEach((row) => {
631
384
  row.cells.forEach((cell, colIndex) => {
632
385
  const colData = columns[colIndex];