lightning-base-components 1.21.4-alpha → 1.21.6-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.
- package/metadata/raptor.json +2 -1
- package/package.json +9 -1
- package/scopedImports/@salesforce-label-LightningLookup.messageWhenSearchTermTooShort.js +1 -0
- package/src/lightning/accordion/__docs__/accordion.md +0 -4
- package/src/lightning/accordionSection/__docs__/accordionSection.md +0 -4
- package/src/lightning/avatar/__docs__/avatar.md +0 -4
- package/src/lightning/badge/__docs__/badge.md +0 -4
- package/src/lightning/badge/badge.slds.css +1 -1
- package/src/lightning/barcodeScanner/__docs__/barcodeScanner.md +0 -4
- package/src/lightning/baseCombobox/baseCombobox.js +2 -2
- package/src/lightning/baseComboboxItem/baseComboboxItem.js +6 -10
- package/src/lightning/button/__docs__/button.md +3 -7
- package/src/lightning/buttonGroup/__docs__/buttonGroup.md +0 -4
- package/src/lightning/buttonIcon/__docs__/buttonIcon.md +0 -4
- package/src/lightning/buttonIconStateful/__docs__/buttonIconStateful.md +0 -4
- package/src/lightning/buttonMenu/__docs__/buttonMenu.md +0 -4
- package/src/lightning/buttonStateful/__docs__/buttonStateful.md +0 -4
- package/src/lightning/buttonStateful/buttonStateful.html +5 -3
- package/src/lightning/buttonStateful/buttonStateful.js +4 -0
- package/src/lightning/card/__docs__/card.md +0 -4
- package/src/lightning/card/card.js-meta.xml +3 -0
- package/src/lightning/carousel/__docs__/carousel.md +0 -4
- package/src/lightning/checkboxGroup/__docs__/checkboxGroup.md +0 -4
- package/src/lightning/combobox/__docs__/combobox.md +0 -4
- package/src/lightning/combobox/form-element.slds.css +4 -1
- package/src/lightning/datatable/columnWidthManager.js +3 -3
- package/src/lightning/datatable/columns.js +17 -18
- package/src/lightning/datatable/datatable.js +146 -84
- package/src/lightning/datatable/indexes.js +1 -3
- package/src/lightning/datatable/infiniteLoading.js +1 -1
- package/src/lightning/datatable/inlineEdit.js +10 -7
- package/src/lightning/datatable/keyboard.js +21 -44
- package/src/lightning/datatable/renderManager.js +9 -18
- package/src/lightning/datatable/rows.js +112 -128
- package/src/lightning/datatable/sort.js +35 -14
- package/src/lightning/datatable/state.js +5 -0
- package/src/lightning/datatable/tree.js +0 -33
- package/src/lightning/datatable/utils.js +15 -5
- package/src/lightning/datepicker/datepicker.js +12 -3
- package/src/lightning/datepicker/form-element.slds.css +4 -1
- package/src/lightning/datetimepicker/form-element.slds.css +4 -1
- package/src/lightning/dualListbox/__docs__/dualListbox.md +0 -4
- package/src/lightning/dualListbox/form-element.slds.css +4 -1
- package/src/lightning/dynamicIcon/__docs__/dynamicIcon.md +0 -4
- package/src/lightning/formattedDateTime/__docs__/formattedDateTime.md +0 -4
- package/src/lightning/formattedLocation/__docs__/formattedLocation.md +0 -4
- package/src/lightning/formattedName/__docs__/formattedName.md +0 -4
- package/src/lightning/formattedNumber/__docs__/formattedNumber.md +0 -4
- package/src/lightning/formattedPhone/__docs__/formattedPhone.md +0 -4
- package/src/lightning/formattedText/__docs__/formattedText.md +0 -4
- package/src/lightning/formattedTime/__docs__/formattedTime.md +0 -4
- package/src/lightning/formattedUrl/__docs__/formattedUrl.md +0 -4
- package/src/lightning/groupedCombobox/form-element.slds.css +4 -1
- package/src/lightning/helptext/form-element.slds.css +4 -1
- package/src/lightning/icon/__docs__/icon.md +0 -4
- package/src/lightning/input/form-element.slds.css +4 -1
- package/src/lightning/inputAddress/form-element.slds.css +4 -1
- package/src/lightning/inputAddress/inputAddress.js +13 -7
- package/src/lightning/inputLocation/__docs__/inputLocation.md +0 -4
- package/src/lightning/inputLocation/form-element.slds.css +4 -1
- package/src/lightning/inputName/form-element.slds.css +4 -1
- package/src/lightning/layout/__docs__/layout.md +0 -4
- package/src/lightning/layoutItem/__docs__/layoutItem.md +0 -4
- package/src/lightning/lookupAddress/form-element.slds.css +4 -1
- package/src/lightning/menuItem/__docs__/menuItem.md +0 -4
- package/src/lightning/menuSubheader/menu-subheader.slds.css +1 -1
- package/src/lightning/modalBase/modalBase.js +14 -31
- package/src/lightning/pill/__docs__/pill.md +0 -4
- package/src/lightning/pillContainer/__docs__/pillContainer.md +0 -4
- package/src/lightning/primitiveBubble/primitiveBubble.js +26 -11
- package/src/lightning/primitiveHeaderFactory/primitiveHeaderFactory.js +1 -1
- package/src/lightning/primitiveInputCheckbox/form-element.slds.css +4 -1
- package/src/lightning/primitiveInputCheckboxButton/form-element.slds.css +4 -1
- package/src/lightning/primitiveInputColor/form-element.slds.css +4 -1
- package/src/lightning/primitiveInputFile/form-element.slds.css +4 -1
- package/src/lightning/primitiveInputSimple/form-element.slds.css +4 -1
- package/src/lightning/primitiveInputToggle/form-element.slds.css +4 -1
- package/src/lightning/progressBar/progress-bar.slds.css +1 -1
- package/src/lightning/radioGroup/__docs__/radioGroup.md +0 -4
- package/src/lightning/radioGroup/form-element.slds.css +4 -1
- package/src/lightning/relativeDateTime/__docs__/relativeDateTime.md +0 -4
- package/src/lightning/select/form-element.slds.css +4 -1
- package/src/lightning/slider/__docs__/slider.md +0 -4
- package/src/lightning/spinner/__docs__/spinner.md +0 -4
- package/src/lightning/tab/__docs__/tab.md +0 -4
- package/src/lightning/tabset/__docs__/tabset.md +0 -4
- package/src/lightning/textarea/__docs__/textarea.md +0 -4
- package/src/lightning/textarea/__examples__/various/various.html +18 -1
- package/src/lightning/textarea/form-element.slds.css +4 -1
- package/src/lightning/textarea/textarea.js +25 -0
- package/src/lightning/tile/__docs__/tile.md +0 -4
- package/src/lightning/timepicker/form-element.slds.css +4 -1
- package/src/lightning/tree/__docs__/tree.md +0 -4
- package/src/lightning/tree/tree.js +5 -1
- package/src/lightning/verticalNavigation/__docs__/verticalNavigation.md +0 -4
- package/src/lightning/verticalNavigationItem/__docs__/verticalNavigationItem.md +0 -4
- package/src/lightning/verticalNavigationItem/vertical-navigation-item.slds.css +1 -1
- package/src/lightning/verticalNavigationItemBadge/__docs__/verticalNavigationItemBadge.md +0 -4
- package/src/lightning/verticalNavigationItemBadge/badge.slds.css +1 -1
- package/src/lightning/verticalNavigationItemBadge/vertical-navigation-item.slds.css +1 -1
- package/src/lightning/verticalNavigationItemIcon/__docs__/verticalNavigationItemIcon.md +0 -4
- package/src/lightning/verticalNavigationItemIcon/vertical-navigation-item.slds.css +1 -1
- package/src/lightning/verticalNavigationOverflow/vertical-navigation-item.slds.css +1 -1
- package/src/lightning/datatable/columns-shared.js +0 -12
|
@@ -1,12 +1,7 @@
|
|
|
1
1
|
import { getShadowActiveElements, isRTL } from 'lightning/utilsPrivate';
|
|
2
2
|
import { getCellFromIndexes, HEADER_ROW_KEY, getRowByKey } from './indexes';
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
getStateTreeColumn,
|
|
6
|
-
fireRowToggleEvent,
|
|
7
|
-
} from './tree';
|
|
8
|
-
import { generateColKeyValue, getStateColumnIndex } from './columns';
|
|
9
|
-
import { isCellEditable } from './rows';
|
|
3
|
+
import { fireRowToggleEvent } from './tree';
|
|
4
|
+
import { getStateColumnIndex } from './columns';
|
|
10
5
|
import { findFirstVisibleIndex } from './virtualization';
|
|
11
6
|
import { getColDataSelector, getRowDataSelector, getScrollerY } from './utils';
|
|
12
7
|
|
|
@@ -211,10 +206,7 @@ function reactToArrowLeft(state, template, event) {
|
|
|
211
206
|
// Update activeCell.
|
|
212
207
|
state.activeCell = {
|
|
213
208
|
rowKeyValue,
|
|
214
|
-
colKeyValue:
|
|
215
|
-
state.columns[nextColIndex],
|
|
216
|
-
nextColIndex
|
|
217
|
-
),
|
|
209
|
+
colKeyValue: state.columns[nextColIndex].colKeyValue,
|
|
218
210
|
};
|
|
219
211
|
// Tracked state change.
|
|
220
212
|
setFocusActiveCell(state, template, NAVIGATION_DIR.LEFT);
|
|
@@ -233,10 +225,7 @@ function reactToArrowRight(state, template, event) {
|
|
|
233
225
|
// Update activeCell.
|
|
234
226
|
state.activeCell = {
|
|
235
227
|
rowKeyValue,
|
|
236
|
-
colKeyValue:
|
|
237
|
-
state.columns[nextColIndex],
|
|
238
|
-
nextColIndex
|
|
239
|
-
),
|
|
228
|
+
colKeyValue: state.columns[nextColIndex].colKeyValue,
|
|
240
229
|
};
|
|
241
230
|
setFocusActiveCell(state, template, NAVIGATION_DIR.RIGHT);
|
|
242
231
|
}
|
|
@@ -375,10 +364,7 @@ export function reactToTabForward(state, template) {
|
|
|
375
364
|
state.activeCell = {
|
|
376
365
|
rowKeyValue:
|
|
377
366
|
nextRowIndex === -1 ? HEADER_ROW_KEY : state.rows[nextRowIndex].key,
|
|
378
|
-
colKeyValue:
|
|
379
|
-
state.columns[nextColIndex],
|
|
380
|
-
nextColIndex
|
|
381
|
-
),
|
|
367
|
+
colKeyValue: state.columns[nextColIndex].colKeyValue,
|
|
382
368
|
};
|
|
383
369
|
// Tracked state change.
|
|
384
370
|
setFocusActiveCell(state, template, NAVIGATION_DIR.TAB_FORWARD, {
|
|
@@ -395,10 +381,7 @@ export function reactToTabBackward(state, template) {
|
|
|
395
381
|
state.activeCell = {
|
|
396
382
|
rowKeyValue:
|
|
397
383
|
nextRowIndex === -1 ? HEADER_ROW_KEY : state.rows[nextRowIndex].key,
|
|
398
|
-
colKeyValue:
|
|
399
|
-
state.columns[nextColIndex],
|
|
400
|
-
nextColIndex
|
|
401
|
-
),
|
|
384
|
+
colKeyValue: state.columns[nextColIndex].colKeyValue,
|
|
402
385
|
};
|
|
403
386
|
// Tracked state change.
|
|
404
387
|
setFocusActiveCell(state, template, NAVIGATION_DIR.TAB_BACKWARD, {
|
|
@@ -505,7 +488,7 @@ function reactToArrowLeftOnRow(dt, state, template, event) {
|
|
|
505
488
|
if (rowHasChildren && rowExpanded) {
|
|
506
489
|
fireRowToggleEvent(dt, rowKeyValue, rowExpanded);
|
|
507
490
|
} else if (rowLevel > 1) {
|
|
508
|
-
const treeColumn =
|
|
491
|
+
const { treeColumn } = state;
|
|
509
492
|
if (treeColumn) {
|
|
510
493
|
const { colKeyValue } = treeColumn;
|
|
511
494
|
const { rowIndex } = getIndexesByKeys(
|
|
@@ -552,7 +535,7 @@ function reactToArrowRightOnRow(dt, state, template, event) {
|
|
|
552
535
|
function reactToArrowUpOnRow(state, template, event) {
|
|
553
536
|
// Move tabIndex 0 one row down.
|
|
554
537
|
const { rowKeyValue, keyEvent } = event.detail;
|
|
555
|
-
const treeColumn =
|
|
538
|
+
const { treeColumn } = state;
|
|
556
539
|
|
|
557
540
|
keyEvent.stopPropagation();
|
|
558
541
|
keyEvent.preventDefault();
|
|
@@ -579,7 +562,7 @@ function reactToArrowUpOnRow(state, template, event) {
|
|
|
579
562
|
function reactToArrowDownOnRow(state, template, event) {
|
|
580
563
|
// Move tabIndex 0 one row down.
|
|
581
564
|
const { rowKeyValue, keyEvent } = event.detail;
|
|
582
|
-
const treeColumn =
|
|
565
|
+
const { treeColumn } = state;
|
|
583
566
|
|
|
584
567
|
keyEvent.stopPropagation();
|
|
585
568
|
keyEvent.preventDefault();
|
|
@@ -624,7 +607,7 @@ function getDefaultActiveCell(state) {
|
|
|
624
607
|
const { rows } = state;
|
|
625
608
|
return {
|
|
626
609
|
rowKeyValue: rows.length > 0 ? rows[0].key : HEADER_ROW_KEY,
|
|
627
|
-
colKeyValue:
|
|
610
|
+
colKeyValue: columns[colIndex].colKeyValue,
|
|
628
611
|
};
|
|
629
612
|
}
|
|
630
613
|
|
|
@@ -822,7 +805,7 @@ export function setFocusActiveCell(
|
|
|
822
805
|
const { rowIndex, colIndex } = getIndexesActiveCell(state);
|
|
823
806
|
let cellElement = getActiveCellElement(template, state);
|
|
824
807
|
|
|
825
|
-
state.activeCell.
|
|
808
|
+
state.activeCell.hasFocus = !(info && isActiveCellValid(state));
|
|
826
809
|
|
|
827
810
|
updateCellTabIndex(state, rowIndex, colIndex);
|
|
828
811
|
|
|
@@ -874,7 +857,7 @@ export function setFocusActiveCell(
|
|
|
874
857
|
export function setBlurActiveCell(state, template) {
|
|
875
858
|
if (state.activeCell) {
|
|
876
859
|
const { rowIndex, colIndex } = getIndexesActiveCell(state);
|
|
877
|
-
state.activeCell.
|
|
860
|
+
state.activeCell.hasFocus = false;
|
|
878
861
|
let cellElement = getActiveCellElement(template, state);
|
|
879
862
|
// eslint-disable-next-line @lwc/lwc/no-async-operation
|
|
880
863
|
setTimeout(() => {
|
|
@@ -957,7 +940,7 @@ export function updateCellToFocusFromPrev(state) {
|
|
|
957
940
|
* @param {Node} template - The custom element template `this.template`
|
|
958
941
|
*/
|
|
959
942
|
export function addFocusStylesToActiveCell(state, template) {
|
|
960
|
-
state.activeCell.
|
|
943
|
+
state.activeCell.hasFocus = true;
|
|
961
944
|
const cellElement = getActiveCellElement(template, state);
|
|
962
945
|
if (cellElement) {
|
|
963
946
|
cellElement.parentElement.classList.add(FOCUS_CLASS);
|
|
@@ -1053,7 +1036,7 @@ export function handleDatatableFocusIn(event) {
|
|
|
1053
1036
|
// workaround for delegatesFocus issue that focusin is called when not supposed to W-6220418
|
|
1054
1037
|
if (isFocusInside(event.currentTarget)) {
|
|
1055
1038
|
if (state.activeCell && !state.rowMode) {
|
|
1056
|
-
state.activeCell.
|
|
1039
|
+
state.activeCell.hasFocus = true;
|
|
1057
1040
|
const cellElement = getActiveCellElement(this.template, state);
|
|
1058
1041
|
// we need to check because of the tree,
|
|
1059
1042
|
// at this point it may remove/change the rows/keys because opening or closing a row.
|
|
@@ -1243,10 +1226,7 @@ function getNextIndexDownWrapped(state, rowIndex) {
|
|
|
1243
1226
|
/***************************** ROW NAVIGATION MODE *****************************/
|
|
1244
1227
|
|
|
1245
1228
|
function canBeRowNavigationMode(state) {
|
|
1246
|
-
return
|
|
1247
|
-
state.keyboardMode === KEYBOARD_NAVIGATION_MODE &&
|
|
1248
|
-
hasTreeDataType(state)
|
|
1249
|
-
);
|
|
1229
|
+
return state.keyboardMode === KEYBOARD_NAVIGATION_MODE && state.treeColumn;
|
|
1250
1230
|
}
|
|
1251
1231
|
|
|
1252
1232
|
function isRowNavigationMode(state) {
|
|
@@ -1257,10 +1237,7 @@ function isRowNavigationMode(state) {
|
|
|
1257
1237
|
}
|
|
1258
1238
|
|
|
1259
1239
|
function setRowNavigationMode(state) {
|
|
1260
|
-
if (
|
|
1261
|
-
hasTreeDataType(state) &&
|
|
1262
|
-
state.keyboardMode === KEYBOARD_NAVIGATION_MODE
|
|
1263
|
-
) {
|
|
1240
|
+
if (state.treeColumn && state.keyboardMode === KEYBOARD_NAVIGATION_MODE) {
|
|
1264
1241
|
state.rowMode = true;
|
|
1265
1242
|
}
|
|
1266
1243
|
}
|
|
@@ -1276,13 +1253,12 @@ export function unsetRowNavigationMode(state) {
|
|
|
1276
1253
|
* Earlier it didn't have tree data, set rowMode to true to start
|
|
1277
1254
|
* if rowMode is false and earlier it has tree data, keep it false
|
|
1278
1255
|
* if rowMode is true and it has tree data, keep it true
|
|
1279
|
-
* @param {Boolean} hadTreeDataTypePreviously - state object
|
|
1280
1256
|
* @param {Object} state - The state object
|
|
1281
1257
|
*/
|
|
1282
|
-
export function updateRowNavigationMode(
|
|
1283
|
-
if (!
|
|
1258
|
+
export function updateRowNavigationMode(state) {
|
|
1259
|
+
if (!state.treeColumn) {
|
|
1284
1260
|
state.rowMode = false;
|
|
1285
|
-
} else if (state.rowMode === false && !hadTreeDataTypePreviously) {
|
|
1261
|
+
} else if (state.rowMode === false && !state.hadTreeDataTypePreviously) {
|
|
1286
1262
|
state.rowMode = true;
|
|
1287
1263
|
}
|
|
1288
1264
|
}
|
|
@@ -1360,7 +1336,8 @@ function scrollToCell(state, template, rowIndex) {
|
|
|
1360
1336
|
export function isActiveCellEditable(state) {
|
|
1361
1337
|
if (state.activeCell) {
|
|
1362
1338
|
const { rowIndex, colIndex } = getIndexesActiveCell(state);
|
|
1363
|
-
|
|
1339
|
+
const activeCell = state.rows[rowIndex].cells[colIndex];
|
|
1340
|
+
return activeCell ? activeCell.editable : false;
|
|
1364
1341
|
}
|
|
1365
1342
|
return false;
|
|
1366
1343
|
}
|
|
@@ -13,10 +13,6 @@ export function setViewportRendering(state, value) {
|
|
|
13
13
|
state.enableViewportRendering = normalizeBoolean(value);
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
export function isViewportRenderingEnabled(state) {
|
|
17
|
-
return state.enableViewportRendering;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
16
|
export function setVirtualize(state, value) {
|
|
21
17
|
if (state.renderModeRoleBased) {
|
|
22
18
|
state.virtualize = normalizeString(value, {
|
|
@@ -68,16 +64,11 @@ export class RenderManager {
|
|
|
68
64
|
* @param {RenderManagerConfig} config - The render management config
|
|
69
65
|
*/
|
|
70
66
|
configure(state, getWrapperHeight, config) {
|
|
71
|
-
const {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
fixedHeight,
|
|
77
|
-
} = config;
|
|
78
|
-
setVirtualize(state, virtualize);
|
|
79
|
-
|
|
80
|
-
if (normalizeBoolean(viewportRendering) || state.virtualize) {
|
|
67
|
+
const { rowHeight, bufferSize } = config;
|
|
68
|
+
// Untracked state changes.
|
|
69
|
+
setVirtualize(state, config.virtualize);
|
|
70
|
+
setViewportRendering(state, config.viewportRendering);
|
|
71
|
+
if (state.virtualize || state.enableViewportRendering) {
|
|
81
72
|
this.initializeResizeObserver(state, getWrapperHeight);
|
|
82
73
|
}
|
|
83
74
|
let computedBufferSize =
|
|
@@ -88,10 +79,10 @@ export class RenderManager {
|
|
|
88
79
|
'non-negative',
|
|
89
80
|
DEFAULT_BUFFER_SIZE
|
|
90
81
|
);
|
|
91
|
-
state.fixedHeight = normalizeBoolean(fixedHeight);
|
|
82
|
+
state.fixedHeight = normalizeBoolean(config.fixedHeight);
|
|
92
83
|
if (typeof rowHeight === 'number') {
|
|
93
84
|
state.rowHeight = rowHeight;
|
|
94
|
-
this.threshold = ROW_THRESHOLD *
|
|
85
|
+
this.threshold = ROW_THRESHOLD * rowHeight;
|
|
95
86
|
}
|
|
96
87
|
}
|
|
97
88
|
|
|
@@ -212,7 +203,7 @@ export class RenderManager {
|
|
|
212
203
|
const normalizedRowCount = rowCount
|
|
213
204
|
? Math.min(rowCount, totalRows)
|
|
214
205
|
: totalRows;
|
|
215
|
-
if (
|
|
206
|
+
if (state.enableViewportRendering) {
|
|
216
207
|
if (state.renderedRowCount < normalizedRowCount) {
|
|
217
208
|
state.renderedRowCount = normalizedRowCount;
|
|
218
209
|
// Update our internal cache
|
|
@@ -247,7 +238,7 @@ export class RenderManager {
|
|
|
247
238
|
* when the datatable component's height changes
|
|
248
239
|
*
|
|
249
240
|
* @param {Object} state - datatable state
|
|
250
|
-
* @param {Function} getWrapperHeight - function to get height of datatable wrapper
|
|
241
|
+
* @param {Function} getWrapperHeight - A function to get the height of datatable wrapper
|
|
251
242
|
*/
|
|
252
243
|
initializeResizeObserver(state, getWrapperHeight) {
|
|
253
244
|
if (!this._heightResizeObserver) {
|
|
@@ -9,7 +9,6 @@ import {
|
|
|
9
9
|
getTypeAttributesValues,
|
|
10
10
|
getSubTypeAttributesValues,
|
|
11
11
|
getCellAttributesValues,
|
|
12
|
-
generateColKeyValue,
|
|
13
12
|
} from './columns';
|
|
14
13
|
import { getRowNumberError } from './rowNumber';
|
|
15
14
|
|
|
@@ -19,6 +18,16 @@ const IS_EDITED_CLASS = 'slds-is-edited';
|
|
|
19
18
|
const ROLE_BASED_CELL_CLASS = 'cell';
|
|
20
19
|
const TREE__ITEM_CLASS = 'slds-tree__item';
|
|
21
20
|
|
|
21
|
+
function resolveAttributeValue(attrValue, rowData) {
|
|
22
|
+
if (isObjectLike(attrValue)) {
|
|
23
|
+
const { fieldName } = attrValue;
|
|
24
|
+
if (fieldName) {
|
|
25
|
+
return rowData[fieldName];
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return attrValue;
|
|
29
|
+
}
|
|
30
|
+
|
|
22
31
|
export function setKeyField(state, value) {
|
|
23
32
|
if (typeof value === 'string') {
|
|
24
33
|
state.keyField = value;
|
|
@@ -32,8 +41,7 @@ export function setKeyField(state, value) {
|
|
|
32
41
|
}
|
|
33
42
|
|
|
34
43
|
/**
|
|
35
|
-
*
|
|
36
|
-
* and generate cells indexes map(state.indexes)
|
|
44
|
+
* Compute state.rows and state.indexes based on the current normalized (data, columns).
|
|
37
45
|
*
|
|
38
46
|
* TODO: Reduce redundant calls to this function. This is indirectly called by the
|
|
39
47
|
* setters of 'data' and 'columns'. Additionally, for the role-based table, if we are
|
|
@@ -43,18 +51,11 @@ export function setKeyField(state, value) {
|
|
|
43
51
|
* @param {Object} state - The datatable state
|
|
44
52
|
* @param {Object} types - The type handling factory
|
|
45
53
|
*/
|
|
46
|
-
export function
|
|
47
|
-
const {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
keyField,
|
|
51
|
-
maxRowSelection,
|
|
52
|
-
renderModeRoleBased,
|
|
53
|
-
virtualize,
|
|
54
|
-
rowHeight,
|
|
55
|
-
} = state;
|
|
54
|
+
export function updateRowsAndCells(state, types) {
|
|
55
|
+
const { columns, data, keyField, maxRowSelection, virtualize, rowHeight } =
|
|
56
|
+
state;
|
|
57
|
+
const { privateCustomTypes } = types;
|
|
56
58
|
const { length: rowCount } = data;
|
|
57
|
-
const { dirtyValues } = state.inlineEdit;
|
|
58
59
|
const { length: colCount } = columns;
|
|
59
60
|
const currentSelectionLength =
|
|
60
61
|
maxRowSelection === 1 ? 1 : getCurrentSelectionLength(state);
|
|
@@ -76,7 +77,6 @@ export function updateRowsAndCellIndexes(state, types) {
|
|
|
76
77
|
// initializing indexes
|
|
77
78
|
state.indexes = {};
|
|
78
79
|
|
|
79
|
-
const { rows: errorsRows } = state.errors;
|
|
80
80
|
const rows = Array(rowCount);
|
|
81
81
|
// Tracked state changes.
|
|
82
82
|
state.rows = rows;
|
|
@@ -87,37 +87,36 @@ export function updateRowsAndCellIndexes(state, types) {
|
|
|
87
87
|
const rowKeyValue = rowDataKeyField
|
|
88
88
|
? `${rowDataKeyField}`
|
|
89
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
90
|
|
|
95
91
|
state.indexes[rowKeyValue] = { rowIndex };
|
|
96
92
|
|
|
97
93
|
const isRowSelected = !!state.selectedRowsKeys[rowKeyValue];
|
|
98
94
|
const rowNumber = rowIndex + 1;
|
|
95
|
+
const scopeColValue = scopeCol
|
|
96
|
+
? rowData[scopeCol.fieldName]
|
|
97
|
+
: undefined;
|
|
99
98
|
const cells = Array(colCount);
|
|
100
99
|
|
|
101
100
|
const row = {
|
|
102
|
-
key: rowKeyValue,
|
|
103
|
-
cells,
|
|
104
|
-
rowIndex,
|
|
105
|
-
rowNumber, // for UTAM since methods are base-1
|
|
106
101
|
ariaRowIndex: rowIndex + 2, // aria attrs are base-1 and also count header as a row
|
|
102
|
+
ariaSelected: isRowSelected ? 'true' : false,
|
|
103
|
+
cells,
|
|
104
|
+
classnames: `slds-hint-parent${
|
|
105
|
+
isRowSelected ? ' slds-is-selected' : ''
|
|
106
|
+
}`,
|
|
107
107
|
inputType,
|
|
108
108
|
isSelected: isRowSelected,
|
|
109
|
-
ariaSelected: isRowSelected ? 'true' : false,
|
|
110
109
|
isDisabled:
|
|
111
110
|
!isRowSelected &&
|
|
112
111
|
maxRowSelection !== 1 &&
|
|
113
112
|
currentSelectionLength === maxRowSelection,
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
tabIndex: -1,
|
|
113
|
+
key: rowKeyValue,
|
|
114
|
+
rowIndex,
|
|
115
|
+
rowNumber, // for UTAM since methods are base-1
|
|
118
116
|
style: virtualize
|
|
119
117
|
? `position:absolute;top:${rowIndex * rowHeight}px;`
|
|
120
118
|
: '',
|
|
119
|
+
tabIndex: -1,
|
|
121
120
|
level: undefined,
|
|
122
121
|
posInSet: undefined,
|
|
123
122
|
setSize: undefined,
|
|
@@ -152,29 +151,27 @@ export function updateRowsAndCellIndexes(state, types) {
|
|
|
152
151
|
for (let colIndex = 0; colIndex < colCount; colIndex += 1) {
|
|
153
152
|
const col = columns[colIndex];
|
|
154
153
|
const {
|
|
155
|
-
|
|
156
|
-
fieldName,
|
|
154
|
+
colKeyValue,
|
|
157
155
|
isScopeCol,
|
|
158
156
|
label: dataLabel,
|
|
159
157
|
type: columnType,
|
|
160
158
|
typeAttributes,
|
|
161
159
|
} = col;
|
|
162
|
-
const colKeyValue = generateColKeyValue(col, colIndex);
|
|
163
160
|
const columnSubType = typeAttributes
|
|
164
161
|
? typeAttributes.subType
|
|
165
162
|
: undefined;
|
|
166
|
-
const dirtyValue = dirtyRowData && dirtyRowData[colKeyValue];
|
|
167
|
-
const hasError = columnKey
|
|
168
|
-
? !!(cellErrors && cellErrors[columnKey])
|
|
169
|
-
: !!(errorFieldNames && errorFieldNames.includes(fieldName));
|
|
170
163
|
const hasTreeData = columnType === 'tree';
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
164
|
+
const privateType =
|
|
165
|
+
privateCustomTypes && privateCustomTypes.get(columnType);
|
|
166
|
+
const standardCellLayout = privateType
|
|
167
|
+
? privateType.standardCellLayout
|
|
168
|
+
: false;
|
|
174
169
|
const displayReadOnlyIcon = !!col.displayReadOnlyIcon;
|
|
175
|
-
const editable =
|
|
170
|
+
const editable = !!resolveAttributeValue(col.editable, rowData);
|
|
176
171
|
const isValidType = types.isValidType(columnType);
|
|
177
172
|
const isCheckbox = columnType === SELECTABLE_HEADER_TYPE;
|
|
173
|
+
const isCustom = privateType !== undefined;
|
|
174
|
+
const isCustomBareLayout = isCustom && !standardCellLayout;
|
|
178
175
|
const isDataType = isValidType && !isScopeCol;
|
|
179
176
|
const isDataTypeScope = isValidType && isScopeCol;
|
|
180
177
|
|
|
@@ -186,31 +183,23 @@ export function updateRowsAndCellIndexes(state, types) {
|
|
|
186
183
|
columnSubType,
|
|
187
184
|
columnType,
|
|
188
185
|
dataLabel,
|
|
189
|
-
describedBy: dirtyValue ? 'unsaved-cell-notification' : null,
|
|
190
186
|
displayReadOnlyIcon,
|
|
191
187
|
displayValue: rowData.displayValue || '',
|
|
192
188
|
editable,
|
|
193
|
-
hasError,
|
|
189
|
+
hasError: undefined,
|
|
194
190
|
isCheckbox,
|
|
191
|
+
isCustomBareLayout,
|
|
195
192
|
isDataType,
|
|
196
193
|
isDataTypeScope,
|
|
197
|
-
rowKeyValue
|
|
198
|
-
|
|
194
|
+
rowKeyValue, // unique row key value
|
|
195
|
+
scopeColValue,
|
|
196
|
+
style: '',
|
|
199
197
|
tabIndex: -1,
|
|
200
|
-
value,
|
|
201
|
-
wrapText:
|
|
202
|
-
wrapTextMaxLines:
|
|
203
|
-
? state.wrapTextMaxLines
|
|
204
|
-
: undefined,
|
|
198
|
+
value: undefined,
|
|
199
|
+
wrapText: undefined, // wrapText state
|
|
200
|
+
wrapTextMaxLines: 0,
|
|
205
201
|
};
|
|
206
202
|
|
|
207
|
-
cell.class = computeCellClassNames(
|
|
208
|
-
cell,
|
|
209
|
-
hasTreeData,
|
|
210
|
-
dirtyValue,
|
|
211
|
-
renderModeRoleBased
|
|
212
|
-
);
|
|
213
|
-
|
|
214
203
|
if (!col.internal) {
|
|
215
204
|
// Assign cell type or cell subType attributes.
|
|
216
205
|
let attributeNames;
|
|
@@ -260,40 +249,79 @@ export function updateRowsAndCellIndexes(state, types) {
|
|
|
260
249
|
cell.typeAttribute22 = row.isExpanded === 'true';
|
|
261
250
|
}
|
|
262
251
|
}
|
|
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(
|
|
269
|
-
rowErrors,
|
|
270
|
-
scopeColValue
|
|
271
|
-
);
|
|
272
|
-
}
|
|
273
252
|
|
|
274
253
|
// adding cell indexes to state.indexes
|
|
275
254
|
// Keeping the hash for backward compatibility, but we need to have 2 indexes, 1 for columns and one for rows,
|
|
276
255
|
// because of memory usage and also at certain point we might have the data but not the columns
|
|
277
256
|
state.indexes[row.key][colKeyValue] = [rowIndex, colIndex];
|
|
278
257
|
cells[colIndex] = cell;
|
|
258
|
+
|
|
259
|
+
// Update cell properties including class, style, and value properties.
|
|
260
|
+
updateCell(state, rowIndex, colIndex);
|
|
279
261
|
}
|
|
280
262
|
}
|
|
281
263
|
}
|
|
282
264
|
|
|
283
265
|
/**
|
|
284
|
-
*
|
|
266
|
+
* Performs a smaller update on the cell at the given rowIndex and colIndex.
|
|
267
|
+
* Used by updateCells() and updateCellsByColIndex().
|
|
285
268
|
*
|
|
286
|
-
*
|
|
287
|
-
*
|
|
288
|
-
*
|
|
289
|
-
*
|
|
290
|
-
* Returns false in all other cases.
|
|
291
|
-
*
|
|
292
|
-
* @param {object} rowData - a row data object stored in datatable state. Must be truthy.
|
|
293
|
-
* @param {object} col - a column data object stored in datatable state. Must be truthy.
|
|
269
|
+
* @param {Object} state - The tracked datatable state
|
|
270
|
+
* @param {Object} rowIndex - The cell row index
|
|
271
|
+
* @param {Object} colIndex - The cell column index
|
|
272
|
+
* @param {Object} [_state = state] - The untracked datatable state
|
|
294
273
|
*/
|
|
295
|
-
export function
|
|
296
|
-
|
|
274
|
+
export function updateCell(state, rowIndex, colIndex) {
|
|
275
|
+
const { renderModeRoleBased } = state;
|
|
276
|
+
const { rows: errorsRows } = state.errors;
|
|
277
|
+
const row = state.rows[rowIndex];
|
|
278
|
+
const rowData = state.data[rowIndex];
|
|
279
|
+
const { key: rowKeyValue } = row;
|
|
280
|
+
const dirtyRowData = state.inlineEdit.dirtyValues[rowKeyValue];
|
|
281
|
+
const rowErrors = errorsRows && errorsRows[rowKeyValue];
|
|
282
|
+
const cellErrors = rowErrors && rowErrors.cells;
|
|
283
|
+
const errorFieldNames = rowErrors && rowErrors.fieldNames;
|
|
284
|
+
const col = state.columns[colIndex];
|
|
285
|
+
const cell = row.cells[colIndex];
|
|
286
|
+
const { colKeyValue, columnKey, fieldName, type: columnType } = col;
|
|
287
|
+
const dirtyValue = dirtyRowData && dirtyRowData[colKeyValue];
|
|
288
|
+
const hasError = columnKey
|
|
289
|
+
? !!(cellErrors && cellErrors[columnKey])
|
|
290
|
+
: !!(errorFieldNames && errorFieldNames.includes(fieldName));
|
|
291
|
+
const hasTreeData = columnType === 'tree';
|
|
292
|
+
// value based on the fieldName
|
|
293
|
+
const value = dirtyValue === undefined ? rowData[fieldName] : dirtyValue;
|
|
294
|
+
const wrapText = state.wrapText[colKeyValue];
|
|
295
|
+
const wrapTextMaxLines = wrapText ? state.wrapTextMaxLines : undefined;
|
|
296
|
+
|
|
297
|
+
cell.hasError = hasError;
|
|
298
|
+
cell.wrapText = wrapText;
|
|
299
|
+
cell.wrapTextMaxLines = wrapTextMaxLines;
|
|
300
|
+
cell.value = value;
|
|
301
|
+
|
|
302
|
+
if (col.internal && col.type === 'rowNumber') {
|
|
303
|
+
cell.typeAttribute0 = getRowNumberError(rowErrors, cell.scopeColValue);
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
let cellClass = '';
|
|
307
|
+
if (cell.displayReadOnlyIcon || cell.editable) {
|
|
308
|
+
cellClass += CELL_EDIT_CLASS;
|
|
309
|
+
}
|
|
310
|
+
if (hasTreeData) {
|
|
311
|
+
cellClass += (cellClass.length ? ' ' : '') + TREE__ITEM_CLASS;
|
|
312
|
+
}
|
|
313
|
+
if (hasError) {
|
|
314
|
+
cellClass += (cellClass.length ? ' ' : '') + HAS_ERROR_CLASS;
|
|
315
|
+
}
|
|
316
|
+
if (dirtyValue !== undefined) {
|
|
317
|
+
cellClass += (cellClass.length ? ' ' : '') + IS_EDITED_CLASS;
|
|
318
|
+
}
|
|
319
|
+
if (renderModeRoleBased) {
|
|
320
|
+
cellClass += (cellClass.length ? ' ' : '') + ROLE_BASED_CELL_CLASS;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
cell.class = cellClass;
|
|
324
|
+
cell.style = computeCellStyles(cell, col, renderModeRoleBased);
|
|
297
325
|
}
|
|
298
326
|
|
|
299
327
|
/**
|
|
@@ -308,14 +336,9 @@ export function isCellEditable(rowData, col) {
|
|
|
308
336
|
* @param {Boolean} renderModeRoleBased - render mode of datatable (div || table)
|
|
309
337
|
* @returns {String} - styles to be set on the cell
|
|
310
338
|
*/
|
|
311
|
-
function computeCellStyles(
|
|
312
|
-
const columnType = col.type;
|
|
313
|
-
|
|
339
|
+
function computeCellStyles(cell, col, renderModeRoleBased) {
|
|
314
340
|
let cellStyle = '';
|
|
315
|
-
if (
|
|
316
|
-
types.isCustomType(columnType) &&
|
|
317
|
-
!types.isStandardCellLayoutForCustomType(columnType)
|
|
318
|
-
) {
|
|
341
|
+
if (cell.isCustomBareLayout) {
|
|
319
342
|
// When a custom type is not using the standard layout,
|
|
320
343
|
// remove the padding that comes with the standard layout
|
|
321
344
|
cellStyle = 'padding: 0;';
|
|
@@ -332,45 +355,6 @@ function computeCellStyles(types, col, renderModeRoleBased) {
|
|
|
332
355
|
return cellStyle;
|
|
333
356
|
}
|
|
334
357
|
|
|
335
|
-
function computeCellClassNames(
|
|
336
|
-
cell,
|
|
337
|
-
hasTreeData,
|
|
338
|
-
dirtyValue,
|
|
339
|
-
renderModeRoleBased
|
|
340
|
-
) {
|
|
341
|
-
// TODO: With the current SLDS design, the 'slds-cell-edit' class is required on a cell in cases
|
|
342
|
-
// where the read only icon is to be displayed. This is an issue with their design that will need to
|
|
343
|
-
// be addressed on their end, so once they do that we can modify this code accordingly.
|
|
344
|
-
let cellClass = '';
|
|
345
|
-
if (cell.displayReadOnlyIcon || cell.editable) {
|
|
346
|
-
cellClass += CELL_EDIT_CLASS;
|
|
347
|
-
}
|
|
348
|
-
if (hasTreeData) {
|
|
349
|
-
cellClass += (cellClass.length ? ' ' : '') + TREE__ITEM_CLASS;
|
|
350
|
-
}
|
|
351
|
-
if (cell.hasError) {
|
|
352
|
-
cellClass += (cellClass.length ? ' ' : '') + HAS_ERROR_CLASS;
|
|
353
|
-
}
|
|
354
|
-
if (dirtyValue !== undefined) {
|
|
355
|
-
cellClass += (cellClass.length ? ' ' : '') + IS_EDITED_CLASS;
|
|
356
|
-
}
|
|
357
|
-
if (renderModeRoleBased) {
|
|
358
|
-
cellClass += (cellClass.length ? ' ' : '') + ROLE_BASED_CELL_CLASS;
|
|
359
|
-
}
|
|
360
|
-
return cellClass;
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
function resolveAttributeValue(attrValue, rowData) {
|
|
364
|
-
if (isObjectLike(attrValue)) {
|
|
365
|
-
const { fieldName } = attrValue;
|
|
366
|
-
if (fieldName) {
|
|
367
|
-
return rowData[fieldName];
|
|
368
|
-
}
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
return attrValue;
|
|
372
|
-
}
|
|
373
|
-
|
|
374
358
|
/**
|
|
375
359
|
* For the role-based table, we need to manage the width of each cell separately.
|
|
376
360
|
* Re-compute the cell styles so that the width of the cell is set
|
|
@@ -378,27 +362,27 @@ function resolveAttributeValue(attrValue, rowData) {
|
|
|
378
362
|
*
|
|
379
363
|
* @param {Object} state - Datatable's state object
|
|
380
364
|
*/
|
|
381
|
-
export function recomputeCellStyles(
|
|
365
|
+
export function recomputeCellStyles(state) {
|
|
382
366
|
const { columns } = state;
|
|
383
367
|
state.rows.forEach((row) => {
|
|
384
368
|
row.cells.forEach((cell, colIndex) => {
|
|
385
369
|
const colData = columns[colIndex];
|
|
386
|
-
cell.style = computeCellStyles(
|
|
370
|
+
cell.style = computeCellStyles(cell, colData, true);
|
|
387
371
|
});
|
|
388
372
|
});
|
|
389
373
|
}
|
|
390
374
|
|
|
391
375
|
/**
|
|
392
|
-
* The cells' classes are normally updated via `
|
|
393
|
-
* happens after renderMode is set since `
|
|
376
|
+
* The cells' classes are normally updated via `updateRowsAndCells()`. This ideally
|
|
377
|
+
* happens after renderMode is set since `updateRowsAndCells` requires the final
|
|
394
378
|
* renderMode value in order to set the 'cell' class on each cell.
|
|
395
379
|
*
|
|
396
|
-
* However, in some cases, it's possible that
|
|
380
|
+
* However, in some cases, it's possible that updateRowsAndCells is called
|
|
397
381
|
* before the renderMode is set (to 'role-based'). This will cause the 'cell' class to NOT be set
|
|
398
382
|
* in the individual cells because state.renderModeRoleBased will be `false` at that point.
|
|
399
383
|
* As a result, positioning of the cell content will be off.
|
|
400
384
|
*
|
|
401
|
-
* In such a case where the renderMode is 'role-based' and when the
|
|
385
|
+
* In such a case where the renderMode is 'role-based' and when the updateRowsAndCells
|
|
402
386
|
* has already been called (indicated by the presence of 'state.rows'), retroactively
|
|
403
387
|
* add the 'cell' class to each cell.
|
|
404
388
|
*
|