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.
- package/metadata/raptor.json +24 -0
- package/package.json +20 -4
- package/scopedImports/@salesforce-internal-core.appVersion.js +1 -1
- package/scopedImports/@salesforce-label-LightningDualListbox.movedOptionsPlural.js +1 -0
- package/scopedImports/@salesforce-label-LightningDualListbox.movedOptionsSingular.js +1 -0
- package/scopedImports/@salesforce-label-LightningErrorMessage.validitySelectAtleastOne.js +1 -0
- package/scopedImports/@salesforce-label-LightningMap.titleWithAddress.js +1 -0
- package/scopedImports/@salesforce-label-LightningModalBase.cancelandclose.js +1 -0
- package/src/lightning/ariaObserver/__component__/ariaObserver.spec.js +112 -0
- package/src/lightning/ariaObserver/__docs__/ariaObserver.md +142 -0
- package/src/lightning/{utilsPrivate/contentMutation.js → ariaObserver/ariaObserver.js} +60 -98
- package/src/lightning/buttonMenu/keyboard.js +0 -10
- package/src/lightning/card/card.html +6 -0
- package/src/lightning/checkboxGroup/checkboxGroup.html +2 -2
- package/src/lightning/checkboxGroup/checkboxGroup.js +6 -1
- package/src/lightning/colorPickerCustom/colorPickerCustom.js +20 -1
- package/src/lightning/datatable/__docs__/datatable.md +55 -0
- package/src/lightning/datatable/__examples__/basic/basic.html +1 -1
- package/src/lightning/datatable/columns-shared.js +1 -1
- package/src/lightning/datatable/datatable.js +98 -30
- package/src/lightning/datatable/errors.js +20 -9
- package/src/lightning/datatable/headerActions.js +77 -49
- package/src/lightning/datatable/infiniteLoading.js +100 -28
- package/src/lightning/datatable/inlineEdit.js +505 -379
- package/src/lightning/datatable/inlineEditShared.js +24 -0
- package/src/lightning/datatable/keyboard.js +162 -127
- package/src/lightning/datatable/renderManager.js +201 -133
- package/src/lightning/datatable/rowLevelActions.js +17 -13
- package/src/lightning/datatable/rowNumber.js +54 -20
- package/src/lightning/datatable/rowSelection.js +760 -0
- package/src/lightning/datatable/rowSelectionShared.js +79 -0
- package/src/lightning/datatable/rows.js +17 -6
- package/src/lightning/datatable/state.js +16 -2
- package/src/lightning/datatable/templates/div/div.css +4 -0
- package/src/lightning/datatable/templates/div/div.html +6 -0
- package/src/lightning/datatable/templates/table/table.html +5 -0
- package/src/lightning/datatable/utils.js +14 -0
- package/src/lightning/datatable/wrapText.js +77 -47
- package/src/lightning/dualListbox/dualListbox.html +1 -1
- package/src/lightning/dualListbox/dualListbox.js +42 -0
- package/src/lightning/formattedDateTime/__docs__/formattedDateTime.md +36 -3
- package/src/lightning/formattedDateTime/__examples__/datetime/datetime.html +2 -2
- package/src/lightning/formattedDateTime/__examples__/datetime/datetime.js +3 -1
- package/src/lightning/formattedDateTime/__examples__/time/time.html +1 -1
- package/src/lightning/formattedDateTime/__examples__/time/time.js +3 -1
- package/src/lightning/formattedDateTime/formattedDateTime.js +1 -0
- package/src/lightning/input/input.html +1 -5
- package/src/lightning/input/input.js +69 -48
- package/src/lightning/inputUtils/validity.js +12 -1
- package/src/lightning/pillContainer/__docs__/pillContainer.md +45 -1
- package/src/lightning/primitiveCellActions/primitiveCellActions.js +69 -12
- package/src/lightning/primitiveCellFactory/cellWithStandardLayout.html +13 -11
- package/src/lightning/primitiveCellFactory/primitiveCellFactory.js +13 -8
- package/src/lightning/primitiveDatatableIeditPanel/primitiveDatatableIeditPanel.html +17 -14
- package/src/lightning/primitiveDatatableIeditPanel/primitiveDatatableIeditPanel.js +167 -98
- package/src/lightning/primitiveDatatableIeditTypeFactory/primitiveDatatableIeditTypeFactory.js +94 -69
- package/src/lightning/primitiveDatatableStatusBar/primitiveDatatableStatusBar.html +4 -4
- package/src/lightning/primitiveDatatableStatusBar/primitiveDatatableStatusBar.js +4 -4
- package/src/lightning/primitiveHeaderActions/primitiveHeaderActions.js +99 -37
- package/src/lightning/progressIndicator/progressIndicator.js +1 -1
- package/src/lightning/progressStep/progressStep.js +30 -22
- package/src/lightning/staticMap/staticMap.html +1 -0
- package/src/lightning/staticMap/staticMap.js +39 -2
- package/src/lightning/utils/classSet.js +4 -1
- package/src/lightning/utilsPrivate/utilsPrivate.js +12 -1
- package/scopedImports/@salesforce-label-LightningModalBase.close.js +0 -1
- package/src/lightning/datatable/inlineEdit-shared.js +0 -14
- package/src/lightning/datatable/selector-shared.js +0 -38
- package/src/lightning/datatable/selector.js +0 -527
|
@@ -8,6 +8,7 @@ import labelHexLabel from '@salesforce/label/LightningColorPicker.hexLabel';
|
|
|
8
8
|
import labelHueInput from '@salesforce/label/LightningColorPicker.hueInput';
|
|
9
9
|
import labelRInput from '@salesforce/label/LightningColorPicker.rInput';
|
|
10
10
|
import labelRedAbbr from '@salesforce/label/LightningColorPicker.redAbbr';
|
|
11
|
+
import formFactorPropertyName from '@salesforce/client/formFactor';
|
|
11
12
|
import { LightningElement, api, track } from 'lwc';
|
|
12
13
|
import { keyCodes } from 'lightning/utilsPrivate';
|
|
13
14
|
import { generateUniqueId, getErrorMessage } from 'lightning/inputUtils';
|
|
@@ -58,7 +59,25 @@ export default class LightningColorPickerCustom extends LightningElement {
|
|
|
58
59
|
if (!this._initialized) {
|
|
59
60
|
// eslint-disable-next-line @lwc/lwc/no-async-operation
|
|
60
61
|
requestAnimationFrame(() => {
|
|
61
|
-
|
|
62
|
+
// (*1*)
|
|
63
|
+
if (formFactorPropertyName !== 'Large') {
|
|
64
|
+
/**
|
|
65
|
+
* We need to wait for one more animation frame and invoke .focus()
|
|
66
|
+
* in iOS. This is because the positionLibray.js initially sets the position
|
|
67
|
+
* of this color-picker element to "top: 0px" and then later repositions it asynchronously
|
|
68
|
+
* it the next animation frames. The first (*1*) rAF callback is fired between
|
|
69
|
+
* setting "top: 0px" and then later repositioning it. Calling .focus() in this callback
|
|
70
|
+
* triggers a re-paint step and the page is scrolled to the top due to "top: 0px" being
|
|
71
|
+
* present in the styles. To avoid this, we can delay the next re-paint after color-picker
|
|
72
|
+
* is repositioned correctly by positionLibrary.js. Hence we wait for next animation frame
|
|
73
|
+
* and then call .focus() to trigger the next re-paint after the color-picker is repositioned correctly
|
|
74
|
+
* which was initially positioned with "top: 0px" by positionLibrary.js
|
|
75
|
+
*/
|
|
76
|
+
// eslint-disable-next-line @lwc/lwc/no-async-operation
|
|
77
|
+
requestAnimationFrame(() => this.focus());
|
|
78
|
+
} else {
|
|
79
|
+
this.focus();
|
|
80
|
+
}
|
|
62
81
|
});
|
|
63
82
|
this.gradient();
|
|
64
83
|
this.handleUpdateAnchor();
|
|
@@ -244,6 +244,28 @@ Valid data types and their supported attributes include:
|
|
|
244
244
|
| text | Displays text using [lightning-formatted-text](bundle/lightning-formatted-text/). This is the default data type. | linkify |
|
|
245
245
|
| url | Displays a URL using [lightning-formatted-url](bundle/lightning-formatted-url/) | label, target, tooltip |
|
|
246
246
|
|
|
247
|
+
In some situations, multiple columns reference the same `fieldName` but have different `fieldApiNames` and different ways of working with the field information. To give a column a unique ID when using the same field name for two columns, use the attribute `columnKey` instead of `fieldName` on one of the column definitions.
|
|
248
|
+
|
|
249
|
+
```javascript
|
|
250
|
+
get columns() {
|
|
251
|
+
return [
|
|
252
|
+
// Column using 'fieldName' as identifier
|
|
253
|
+
{
|
|
254
|
+
label: 'Lead',
|
|
255
|
+
fieldName: 'leadId',
|
|
256
|
+
...
|
|
257
|
+
},
|
|
258
|
+
// Column using 'columnKey' as identifier
|
|
259
|
+
{
|
|
260
|
+
label: 'Company',
|
|
261
|
+
columnKey: 'leadCompany',
|
|
262
|
+
fieldName: 'leadId',
|
|
263
|
+
...
|
|
264
|
+
}
|
|
265
|
+
]
|
|
266
|
+
}
|
|
267
|
+
```
|
|
268
|
+
|
|
247
269
|
#### Custom Formatting Examples
|
|
248
270
|
|
|
249
271
|
To customize the formatting based on the data type, pass in the attributes for
|
|
@@ -494,6 +516,21 @@ const columns = [
|
|
|
494
516
|
|
|
495
517
|
Custom classes are currently not supported. To apply custom styling on your datatable cells, create a custom data type and then apply your custom CSS classes. See [Custom Data Type Layout and Styles](docs/component-library/documentation/lwc/lwc.data_table_custom_types_styling).
|
|
496
518
|
|
|
519
|
+
#### Displaying Indicators for Read-Only Fields
|
|
520
|
+
|
|
521
|
+
You can display a lock icon on read-only fields to specify they're not editable. To specify that a column's field as read-only, set the column attribute `editable` to `false` and the column attribute `displayReadOnlyIcon` to `true` in the associated column definition. This example displays a lock icon on each field in a column called "Website."
|
|
522
|
+
|
|
523
|
+
```javascript
|
|
524
|
+
const columns = [
|
|
525
|
+
{
|
|
526
|
+
label: 'Website',
|
|
527
|
+
fieldName: 'website',
|
|
528
|
+
type: 'url',
|
|
529
|
+
editable: false,
|
|
530
|
+
displayReadOnlyIcon: true,
|
|
531
|
+
}
|
|
532
|
+
```
|
|
533
|
+
|
|
497
534
|
#### Using Infinite Scrolling to Load More Rows
|
|
498
535
|
|
|
499
536
|
Infinite scrolling enables you to load a subset of data and then display more
|
|
@@ -1031,6 +1068,24 @@ handleSave(event) {
|
|
|
1031
1068
|
}
|
|
1032
1069
|
```
|
|
1033
1070
|
|
|
1071
|
+
You can also program an external element, such as a button, to open an inline edit panel on the currently active cell or next editable cell in the datatable. Invoke the `openInlineEdit()` method in the external element that should direct a user to the first editable cell in your datatable component.
|
|
1072
|
+
|
|
1073
|
+
This example opens a datatable cell for inline edit when the user clicks an "Edit" button.
|
|
1074
|
+
|
|
1075
|
+
```javascript
|
|
1076
|
+
import { LightningElement } from 'lwc';
|
|
1077
|
+
export default class DatatableWithInlineEdit extends LightningElement {
|
|
1078
|
+
data = [];
|
|
1079
|
+
columns = columns;
|
|
1080
|
+
rowOffset = 0;
|
|
1081
|
+
|
|
1082
|
+
handleClick() {
|
|
1083
|
+
const dt = this.template.querySelector('lightning-datatable');
|
|
1084
|
+
dt.openInlineEdit();
|
|
1085
|
+
}
|
|
1086
|
+
}
|
|
1087
|
+
```
|
|
1088
|
+
|
|
1034
1089
|
For more information, see [Display Data in a Table with Inline Editing](docs/component-library/documentation/lwc/lwc.data_table_inline_edit).
|
|
1035
1090
|
|
|
1036
1091
|
#### Displaying Errors
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* which also has a dependency on `columns.js` for `getColumnName()`.
|
|
5
5
|
*
|
|
6
6
|
* We split out some of the functions that could cause circular dependencies with
|
|
7
|
-
* `column.js` into the `*-shared.js` files. `
|
|
7
|
+
* `column.js` into the `*-shared.js` files. `inlineEditShared.js` is another.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
export function getColumnName(column) {
|
|
@@ -42,7 +42,7 @@ import {
|
|
|
42
42
|
import {
|
|
43
43
|
syncSelectedRowsKeys,
|
|
44
44
|
handleRowSelectionChange,
|
|
45
|
-
|
|
45
|
+
updateBulkSelectionState,
|
|
46
46
|
getMaxRowSelection,
|
|
47
47
|
setMaxRowSelection,
|
|
48
48
|
getSelectedRowsKeys,
|
|
@@ -53,7 +53,7 @@ import {
|
|
|
53
53
|
handleDeselectRow,
|
|
54
54
|
getHideSelectAllCheckbox,
|
|
55
55
|
getCurrentSelectionLength,
|
|
56
|
-
} from './
|
|
56
|
+
} from './rowSelection';
|
|
57
57
|
import {
|
|
58
58
|
syncActiveCell,
|
|
59
59
|
handleKeydownOnCell,
|
|
@@ -80,6 +80,9 @@ import {
|
|
|
80
80
|
handleKeydownOnTable,
|
|
81
81
|
addFocusStylesToActiveCell,
|
|
82
82
|
refocusCellElement,
|
|
83
|
+
isCellElement,
|
|
84
|
+
getActiveCellElement,
|
|
85
|
+
FOCUS_CLASS,
|
|
83
86
|
} from './keyboard';
|
|
84
87
|
import {
|
|
85
88
|
getRowNumberOffset,
|
|
@@ -134,7 +137,11 @@ import {
|
|
|
134
137
|
import {
|
|
135
138
|
isViewportRenderingEnabled,
|
|
136
139
|
setViewportRendering,
|
|
140
|
+
getDTWrapperHeight,
|
|
141
|
+
setFirstVisibleIndex,
|
|
142
|
+
setVirtualize,
|
|
137
143
|
RenderManager,
|
|
144
|
+
DEFAULT_ROW_HEIGHT,
|
|
138
145
|
} from './renderManager';
|
|
139
146
|
|
|
140
147
|
import { hasTreeDataType } from './tree';
|
|
@@ -144,6 +151,7 @@ import { generateUniqueId } from 'lightning/inputUtils';
|
|
|
144
151
|
import DatatableTypes from './types';
|
|
145
152
|
import labelAriaLiveNavigationMode from '@salesforce/label/LightningDatatable.ariaLiveNavigationMode';
|
|
146
153
|
import labelAriaLiveActionMode from '@salesforce/label/LightningDatatable.ariaLiveActionMode';
|
|
154
|
+
import { styleToString } from './utils';
|
|
147
155
|
|
|
148
156
|
const i18n = {
|
|
149
157
|
ariaLiveNavigationMode: labelAriaLiveNavigationMode,
|
|
@@ -196,7 +204,6 @@ export default class LightningDatatable extends LightningElement {
|
|
|
196
204
|
_privateTypes = {};
|
|
197
205
|
_privateWidthObserver = null; // Instance of LightningDatatableResizeObserver
|
|
198
206
|
_renderMode = 'table';
|
|
199
|
-
_renderedRowCount = 0;
|
|
200
207
|
_suppressBottomBar = false;
|
|
201
208
|
|
|
202
209
|
/************************* PUBLIC PROPERTIES *************************/
|
|
@@ -493,6 +500,7 @@ export default class LightningDatatable extends LightningElement {
|
|
|
493
500
|
* @type {object}
|
|
494
501
|
* @property {boolean} viewportRendering - Specifies whether to defer rendering of rows outside the viewport until the user begins scrolling. To use this feature, create a fixed-height container element for lightning-datatable.
|
|
495
502
|
* @property {number} rowHeight - Specifies the height of a row, in px
|
|
503
|
+
* @property {string} virtualize - specifies whether to enable virtualization. This requires the "role-based" render mode and a fixed-height container for lightning-datatable
|
|
496
504
|
*/
|
|
497
505
|
|
|
498
506
|
/**
|
|
@@ -508,10 +516,21 @@ export default class LightningDatatable extends LightningElement {
|
|
|
508
516
|
|
|
509
517
|
set renderConfig(value) {
|
|
510
518
|
if (typeof value === 'object' && !isIE11) {
|
|
511
|
-
|
|
512
|
-
setViewportRendering(this.state, enableViewportRendering);
|
|
519
|
+
setViewportRendering(this.state, value.viewportRendering);
|
|
513
520
|
|
|
514
|
-
this._renderManager.configure(
|
|
521
|
+
this._renderManager.configure(
|
|
522
|
+
this.state,
|
|
523
|
+
this.getWrapperHeight,
|
|
524
|
+
value
|
|
525
|
+
);
|
|
526
|
+
// if renderConfig already exists, update rendering
|
|
527
|
+
if (this._renderConfig) {
|
|
528
|
+
this._renderManager.updateViewportRendering(
|
|
529
|
+
this.state,
|
|
530
|
+
this.gridContainer,
|
|
531
|
+
true
|
|
532
|
+
);
|
|
533
|
+
}
|
|
515
534
|
this._renderConfig = value;
|
|
516
535
|
}
|
|
517
536
|
}
|
|
@@ -536,6 +555,9 @@ export default class LightningDatatable extends LightningElement {
|
|
|
536
555
|
validValues: ['default', 'role-based'],
|
|
537
556
|
});
|
|
538
557
|
this.state.renderModeRoleBased = this._renderMode === 'role-based';
|
|
558
|
+
if (this._renderConfig) {
|
|
559
|
+
setVirtualize(this.state, this._renderConfig.virtualize);
|
|
560
|
+
}
|
|
539
561
|
updateCellClassForRoleBasedMode(this.state);
|
|
540
562
|
}
|
|
541
563
|
|
|
@@ -759,24 +781,42 @@ export default class LightningDatatable extends LightningElement {
|
|
|
759
781
|
|
|
760
782
|
get computedTableStyle() {
|
|
761
783
|
if (this._columnWidthManager.isAutoResizingUpdateQueued()) {
|
|
762
|
-
return ['table-layout:auto']
|
|
784
|
+
return styleToString(['table-layout:auto']);
|
|
763
785
|
}
|
|
764
|
-
return [
|
|
786
|
+
return styleToString([
|
|
765
787
|
'table-layout:fixed',
|
|
766
788
|
getCSSWidthStyleOfTable(this.widthsData),
|
|
767
|
-
]
|
|
789
|
+
]);
|
|
768
790
|
}
|
|
769
791
|
|
|
792
|
+
/**
|
|
793
|
+
* Resets row-number counter to offset to show
|
|
794
|
+
* correct value when row number column is present
|
|
795
|
+
* and adds necessary position and height styles when
|
|
796
|
+
* virtualization is enabled
|
|
797
|
+
*/
|
|
770
798
|
get computedTbodyStyle() {
|
|
799
|
+
const style = [];
|
|
800
|
+
const { firstVisibleIndex, bufferSize, virtualize, rows } = this.state;
|
|
771
801
|
if (
|
|
772
802
|
hasRowNumberColumn(this.state) &&
|
|
773
803
|
getRowNumberOffset(this.state) >= 0
|
|
774
804
|
) {
|
|
775
|
-
|
|
776
|
-
|
|
805
|
+
const firstRenderedRow = Math.max(
|
|
806
|
+
firstVisibleIndex - bufferSize,
|
|
807
|
+
0
|
|
808
|
+
);
|
|
809
|
+
const rowNumber = firstRenderedRow + getRowNumberOffset(this.state);
|
|
810
|
+
style.push(`counter-reset: row-number ${rowNumber}`);
|
|
811
|
+
}
|
|
812
|
+
if (virtualize) {
|
|
813
|
+
const length = rows.length;
|
|
814
|
+
style.push(
|
|
815
|
+
'position: relative',
|
|
816
|
+
`height:${length * DEFAULT_ROW_HEIGHT}px`
|
|
777
817
|
);
|
|
778
818
|
}
|
|
779
|
-
return
|
|
819
|
+
return styleToString(style);
|
|
780
820
|
}
|
|
781
821
|
|
|
782
822
|
/**
|
|
@@ -812,9 +852,7 @@ export default class LightningDatatable extends LightningElement {
|
|
|
812
852
|
styles['overflow-x'] = 'auto';
|
|
813
853
|
}
|
|
814
854
|
|
|
815
|
-
return
|
|
816
|
-
.map(([key, value]) => key + ':' + value)
|
|
817
|
-
.join(';');
|
|
855
|
+
return styleToString(styles);
|
|
818
856
|
}
|
|
819
857
|
|
|
820
858
|
/**
|
|
@@ -897,10 +935,16 @@ export default class LightningDatatable extends LightningElement {
|
|
|
897
935
|
}
|
|
898
936
|
|
|
899
937
|
get renderedRows() {
|
|
938
|
+
const { virtualize, rows, renderedRowCount } = this.state;
|
|
939
|
+
if (virtualize) {
|
|
940
|
+
const { firstIndex, lastIndex } =
|
|
941
|
+
this._renderManager.getRenderedRange(this.state);
|
|
942
|
+
return rows.slice(firstIndex, lastIndex);
|
|
943
|
+
}
|
|
900
944
|
if (this.viewportRendering && !isIE11) {
|
|
901
|
-
return
|
|
945
|
+
return rows.slice(0, renderedRowCount);
|
|
902
946
|
}
|
|
903
|
-
return
|
|
947
|
+
return rows;
|
|
904
948
|
}
|
|
905
949
|
|
|
906
950
|
get showSelectAllCheckbox() {
|
|
@@ -936,6 +980,7 @@ export default class LightningDatatable extends LightningElement {
|
|
|
936
980
|
this.updateRowsAndCellIndexes = updateRowsAndCellIndexes.bind(this);
|
|
937
981
|
|
|
938
982
|
this._renderManager = new RenderManager();
|
|
983
|
+
this.getWrapperHeight = getDTWrapperHeight.bind(this);
|
|
939
984
|
}
|
|
940
985
|
|
|
941
986
|
/**
|
|
@@ -1094,17 +1139,35 @@ export default class LightningDatatable extends LightningElement {
|
|
|
1094
1139
|
this._customerSelectedRows = null;
|
|
1095
1140
|
// set the previous focused cell to null after render is done
|
|
1096
1141
|
resetCellToFocusFromPrev(state);
|
|
1142
|
+
// reset focus styles on re-render
|
|
1143
|
+
if (state.activeCell && state.activeCell.focused) {
|
|
1144
|
+
const cellElement = getActiveCellElement(template, state);
|
|
1145
|
+
if (
|
|
1146
|
+
cellElement &&
|
|
1147
|
+
cellElement.parentElement &&
|
|
1148
|
+
!cellElement.parentElement.classList.contains(FOCUS_CLASS)
|
|
1149
|
+
) {
|
|
1150
|
+
setFocusActiveCell(template, state, null, null, false);
|
|
1151
|
+
}
|
|
1152
|
+
}
|
|
1097
1153
|
|
|
1098
|
-
if (this.viewportRendering) {
|
|
1099
|
-
this.
|
|
1154
|
+
if (this.viewportRendering || state.virtualize) {
|
|
1155
|
+
const resizeTarget = this.template.querySelector(
|
|
1156
|
+
'div.dt-outer-container'
|
|
1157
|
+
);
|
|
1158
|
+
this._renderManager.connectResizeObserver(resizeTarget);
|
|
1100
1159
|
if (!this._renderManager.hasWrapperHeight()) {
|
|
1101
|
-
this._renderManager.updateWrapperHeight(this);
|
|
1160
|
+
this._renderManager.updateWrapperHeight(this.getWrapperHeight);
|
|
1102
1161
|
|
|
1103
1162
|
// Reset the row count if we already had one before updating the wrapper height.
|
|
1104
1163
|
// This can happen if the number of rows was calculated before the datatable
|
|
1105
1164
|
// was rendered.
|
|
1106
|
-
if (this.
|
|
1107
|
-
this._renderManager.updateViewportRendering(
|
|
1165
|
+
if (this.state.renderedRowCount) {
|
|
1166
|
+
this._renderManager.updateViewportRendering(
|
|
1167
|
+
this.state,
|
|
1168
|
+
this.gridContainer,
|
|
1169
|
+
true
|
|
1170
|
+
);
|
|
1108
1171
|
}
|
|
1109
1172
|
}
|
|
1110
1173
|
}
|
|
@@ -1187,9 +1250,10 @@ export default class LightningDatatable extends LightningElement {
|
|
|
1187
1250
|
}
|
|
1188
1251
|
|
|
1189
1252
|
handleInlineEditPanelScroll.call(this, event);
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1253
|
+
if (this.state.virtualize) {
|
|
1254
|
+
setFirstVisibleIndex(this.state, event.target.scrollTop);
|
|
1255
|
+
} else if (this.viewportRendering) {
|
|
1256
|
+
this._renderManager.handleScroll(this.state, event);
|
|
1193
1257
|
}
|
|
1194
1258
|
}
|
|
1195
1259
|
|
|
@@ -1202,8 +1266,9 @@ export default class LightningDatatable extends LightningElement {
|
|
|
1202
1266
|
handleCellClick(event) {
|
|
1203
1267
|
// handles the case when clicking on the margin/pading of the td/th
|
|
1204
1268
|
const targetTagName = event.target.tagName.toLowerCase();
|
|
1269
|
+
const targetRole = event.target.getAttribute('role');
|
|
1205
1270
|
|
|
1206
|
-
if (targetTagName
|
|
1271
|
+
if (isCellElement(targetTagName, targetRole)) {
|
|
1207
1272
|
// get the row/col key value from the primitive cell.
|
|
1208
1273
|
const { rowKeyValue, colKeyValue } =
|
|
1209
1274
|
event.target.querySelector(':first-child');
|
|
@@ -1464,8 +1529,11 @@ export default class LightningDatatable extends LightningElement {
|
|
|
1464
1529
|
|
|
1465
1530
|
this.updateRowsAndCellIndexes(state);
|
|
1466
1531
|
|
|
1467
|
-
if (this.viewportRendering) {
|
|
1468
|
-
this._renderManager.updateViewportRendering(
|
|
1532
|
+
if (this.viewportRendering || state.virtualize) {
|
|
1533
|
+
this._renderManager.updateViewportRendering(
|
|
1534
|
+
this.state,
|
|
1535
|
+
this.gridContainer
|
|
1536
|
+
);
|
|
1469
1537
|
}
|
|
1470
1538
|
|
|
1471
1539
|
this._columnWidthManager.handleRowNumberOffsetChange(state, widthsData);
|
|
@@ -1505,10 +1573,10 @@ export default class LightningDatatable extends LightningElement {
|
|
|
1505
1573
|
setDirtyValues(state, this._draftValues);
|
|
1506
1574
|
updateRowNavigationMode(hadTreeDataTypePreviously, state);
|
|
1507
1575
|
state.headerIndexes = generateHeaderIndexes(getColumns(state));
|
|
1508
|
-
// Updates state.wrapText and when
|
|
1576
|
+
// Updates state.wrapText and when isWrappableType, sets internal header actions
|
|
1509
1577
|
updateHeaderActions(state);
|
|
1510
1578
|
this.updateRowsAndCellIndexes(state);
|
|
1511
|
-
|
|
1579
|
+
updateBulkSelectionState(state);
|
|
1512
1580
|
this._columnWidthManager.handleRowNumberOffsetChange(state, widthsData);
|
|
1513
1581
|
updateColumnWidthsMetadata(getColumns(state), widthsData);
|
|
1514
1582
|
// set the celltofocus next to null if the column still exists after indexes calculation
|
|
@@ -1,25 +1,36 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
},
|
|
7
|
-
};
|
|
8
|
-
}
|
|
1
|
+
// Default empty error state
|
|
2
|
+
const DEFAULT_ERROR_STATE = {
|
|
3
|
+
rows: {},
|
|
4
|
+
table: {},
|
|
5
|
+
};
|
|
9
6
|
|
|
7
|
+
/**
|
|
8
|
+
* Retrieves the errors object from datatable's state object
|
|
9
|
+
* Returns the set of row-level errors and table-level errors
|
|
10
|
+
*/
|
|
10
11
|
export function getErrors(state) {
|
|
11
12
|
return state.errors;
|
|
12
13
|
}
|
|
13
14
|
|
|
15
|
+
/**
|
|
16
|
+
* Sets the row-level errors and table-level errors in datatable's state object
|
|
17
|
+
* Errors being set here overwrite the previous error object in the state
|
|
18
|
+
*/
|
|
14
19
|
export function setErrors(state, errors) {
|
|
15
|
-
return (state.errors = Object.assign({},
|
|
20
|
+
return (state.errors = Object.assign({}, DEFAULT_ERROR_STATE, errors));
|
|
16
21
|
}
|
|
17
22
|
|
|
23
|
+
/**
|
|
24
|
+
* Retrieves the row-level errors of a particular row from datatable's state object
|
|
25
|
+
*/
|
|
18
26
|
export function getRowError(state, rowKey) {
|
|
19
27
|
const rows = getErrors(state).rows;
|
|
20
28
|
return (rows && rows[rowKey]) || {};
|
|
21
29
|
}
|
|
22
30
|
|
|
31
|
+
/**
|
|
32
|
+
* Retrieves the table-level errors from the datatable's state object
|
|
33
|
+
*/
|
|
23
34
|
export function getTableError(state) {
|
|
24
35
|
return getErrors(state).table || {};
|
|
25
36
|
}
|
|
@@ -1,49 +1,31 @@
|
|
|
1
1
|
import { unwrap } from 'lwc';
|
|
2
2
|
import { getUserColumnIndex, getColumns } from './columns';
|
|
3
|
-
import
|
|
3
|
+
import { getActions, handleTriggeredAction } from './wrapText';
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
dispatchHeaderActionEvent(dt, action, colKeyValue);
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
function handleTriggeredCustomerAction(dt, action, colKeyValue) {
|
|
11
|
-
dispatchHeaderActionEvent(dt, action, colKeyValue);
|
|
12
|
-
}
|
|
5
|
+
// Height of a clickable menu item
|
|
6
|
+
const ACTION_REM_HEIGHT = 2.125;
|
|
13
7
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
const customerColumnDefinition = dt.columns[userColumnIndex];
|
|
17
|
-
|
|
18
|
-
dt.dispatchEvent(
|
|
19
|
-
new CustomEvent('headeraction', {
|
|
20
|
-
detail: {
|
|
21
|
-
action: unwrap(action),
|
|
22
|
-
columnDefinition: unwrap(customerColumnDefinition),
|
|
23
|
-
},
|
|
24
|
-
})
|
|
25
|
-
);
|
|
26
|
-
}
|
|
8
|
+
// Height of the menu divider, 1 rem + 1px (1/16px)
|
|
9
|
+
const DIVIDER_REM_HEIGHT = 1.0625;
|
|
27
10
|
|
|
28
|
-
|
|
29
|
-
const isLastColumn = index === columns.length - 1;
|
|
30
|
-
|
|
31
|
-
return isLastColumn || columns[index + 1].type === 'action'
|
|
32
|
-
? 'auto-right'
|
|
33
|
-
: 'auto-left';
|
|
34
|
-
}
|
|
11
|
+
/************************** PUBLIC METHODS ***************************/
|
|
35
12
|
|
|
13
|
+
/**
|
|
14
|
+
* Merges wrapText internal actions.
|
|
15
|
+
* If there are new internal actions in the future, they may be added here.
|
|
16
|
+
*
|
|
17
|
+
* @param {Object} state The state of the datatable
|
|
18
|
+
* @param {Object} columnDefinition The column definition to extract internal actions from
|
|
19
|
+
* @return {Array} All wrapText internal actions
|
|
20
|
+
*/
|
|
36
21
|
export function getInternalActions(state, columnDefinition) {
|
|
37
|
-
|
|
38
|
-
// currently, only wrapText internal actions
|
|
39
|
-
// there may be new internal actions in the future
|
|
40
|
-
return [...wraptext.getActions(state, columnDefinition)];
|
|
22
|
+
return [...getActions(state, columnDefinition)];
|
|
41
23
|
}
|
|
42
24
|
|
|
43
25
|
/**
|
|
44
26
|
* Overrides the actions with the internal ones, plus the customer ones.
|
|
45
27
|
*
|
|
46
|
-
* @param {Object} state The state of the datatable
|
|
28
|
+
* @param {Object} state The state of the datatable
|
|
47
29
|
*/
|
|
48
30
|
export function updateHeaderActions(state) {
|
|
49
31
|
const columns = getColumns(state);
|
|
@@ -59,31 +41,36 @@ export function updateHeaderActions(state) {
|
|
|
59
41
|
});
|
|
60
42
|
}
|
|
61
43
|
|
|
44
|
+
/**
|
|
45
|
+
* For internal actions, handles triggering the action.
|
|
46
|
+
* Then dispatches the header action event.
|
|
47
|
+
*
|
|
48
|
+
* @param {Event} event
|
|
49
|
+
*/
|
|
62
50
|
export function handleHeaderActionTriggered(event) {
|
|
51
|
+
event.stopPropagation();
|
|
52
|
+
|
|
63
53
|
const { action, actionType, colKeyValue } = event.detail;
|
|
64
54
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
handleTriggeredCustomerAction(this, action, colKeyValue);
|
|
68
|
-
} else {
|
|
69
|
-
handleTriggeredInternalAction(this, action, colKeyValue);
|
|
55
|
+
if (actionType !== 'customer') {
|
|
56
|
+
handleTriggeredAction(this.state, action, colKeyValue);
|
|
70
57
|
}
|
|
71
|
-
}
|
|
72
58
|
|
|
73
|
-
|
|
74
|
-
return Object.assign({}, wraptext.getDefaultState());
|
|
59
|
+
dispatchHeaderActionEvent(this, action, colKeyValue);
|
|
75
60
|
}
|
|
76
61
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
62
|
+
/**
|
|
63
|
+
* Calculates the size and positioning of the header action
|
|
64
|
+
* menu when it is opened.
|
|
65
|
+
*
|
|
66
|
+
* @param {Event} event
|
|
67
|
+
*/
|
|
82
68
|
export function handleHeaderActionMenuOpening(event) {
|
|
83
69
|
event.stopPropagation();
|
|
84
70
|
event.preventDefault();
|
|
85
|
-
|
|
86
|
-
const
|
|
71
|
+
|
|
72
|
+
const actionsHeight = event.detail.actionsCount * ACTION_REM_HEIGHT;
|
|
73
|
+
const dividersHeight = event.detail.dividersCount * DIVIDER_REM_HEIGHT;
|
|
87
74
|
const wrapperHeight = 1;
|
|
88
75
|
this._actionsMinHeightStyle = `min-height:${
|
|
89
76
|
actionsHeight + dividersHeight + wrapperHeight
|
|
@@ -91,6 +78,47 @@ export function handleHeaderActionMenuOpening(event) {
|
|
|
91
78
|
event.detail.saveContainerPosition(this.getViewableRect());
|
|
92
79
|
}
|
|
93
80
|
|
|
81
|
+
/**
|
|
82
|
+
* Resets header action menu height when closed.
|
|
83
|
+
*/
|
|
94
84
|
export function handleHeaderActionMenuClosed() {
|
|
95
85
|
this._actionsMinHeightStyle = '';
|
|
96
86
|
}
|
|
87
|
+
|
|
88
|
+
/************************** PRIVATE METHODS ***************************/
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Dispatches the `headeraction` event.
|
|
92
|
+
*
|
|
93
|
+
* @param {Object} dt The datatable
|
|
94
|
+
* @param {Object} action The action to dispatch
|
|
95
|
+
* @param {String} colKeyValue The column to dispatch the action on
|
|
96
|
+
*/
|
|
97
|
+
function dispatchHeaderActionEvent(dt, action, colKeyValue) {
|
|
98
|
+
const userColumnIndex = getUserColumnIndex(dt.state, colKeyValue);
|
|
99
|
+
const customerColumnDefinition = dt.columns[userColumnIndex];
|
|
100
|
+
|
|
101
|
+
dt.dispatchEvent(
|
|
102
|
+
new CustomEvent('headeraction', {
|
|
103
|
+
detail: {
|
|
104
|
+
action: unwrap(action),
|
|
105
|
+
columnDefinition: unwrap(customerColumnDefinition),
|
|
106
|
+
},
|
|
107
|
+
})
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Determines the menu alignment based on column placement.
|
|
113
|
+
*
|
|
114
|
+
* @param {Array} columns Array of all the columns
|
|
115
|
+
* @param {Integer} index The current column index to check
|
|
116
|
+
* @return {String} The computed alignment
|
|
117
|
+
*/
|
|
118
|
+
function getMenuAlignment(columns, index) {
|
|
119
|
+
const isLastColumn = index === columns.length - 1;
|
|
120
|
+
|
|
121
|
+
return isLastColumn || columns[index + 1].type === 'action'
|
|
122
|
+
? 'auto-right'
|
|
123
|
+
: 'auto-left';
|
|
124
|
+
}
|