lightning-base-components 1.14.2-alpha → 1.14.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.
Files changed (82) hide show
  1. package/metadata/raptor.json +33 -1
  2. package/package.json +20 -4
  3. package/scopedImports/@salesforce-label-LightningDualListbox.movedOptionsPlural.js +1 -0
  4. package/scopedImports/@salesforce-label-LightningDualListbox.movedOptionsSingular.js +1 -0
  5. package/scopedImports/@salesforce-label-LightningErrorMessage.validitySelectAtleastOne.js +1 -0
  6. package/scopedImports/@salesforce-label-LightningMap.titleWithAddress.js +1 -0
  7. package/scopedImports/@salesforce-label-LightningModalBase.cancelandclose.js +1 -0
  8. package/src/lightning/ariaObserver/__component__/ariaObserver.spec.js +9 -0
  9. package/src/lightning/ariaObserver/__docs__/ariaObserver.md +142 -0
  10. package/src/lightning/ariaObserver/ariaObserver.js +24 -35
  11. package/src/lightning/baseFormattedText/baseFormattedText.html +6 -1
  12. package/src/lightning/baseFormattedText/baseFormattedText.js +5 -0
  13. package/src/lightning/buttonMenu/keyboard.js +0 -10
  14. package/src/lightning/card/card.html +6 -0
  15. package/src/lightning/checkboxGroup/checkboxGroup.html +2 -2
  16. package/src/lightning/checkboxGroup/checkboxGroup.js +6 -1
  17. package/src/lightning/colorPickerCustom/colorPickerCustom.js +20 -1
  18. package/src/lightning/datatable/__docs__/datatable.md +55 -0
  19. package/src/lightning/datatable/__examples__/basic/basic.html +1 -1
  20. package/src/lightning/datatable/__examples__/withInfiniteLoading/fetchDataHelper.js +21 -0
  21. package/src/lightning/datatable/__examples__/withInfiniteLoading/withInfiniteLoading.html +13 -0
  22. package/src/lightning/datatable/__examples__/withInfiniteLoading/withInfiniteLoading.js +42 -0
  23. package/src/lightning/datatable/autoWidthStrategy.js +170 -61
  24. package/src/lightning/datatable/{resizer.js → columnResizer.js} +0 -0
  25. package/src/lightning/datatable/columnWidthManager.js +226 -44
  26. package/src/lightning/datatable/columns-shared.js +1 -1
  27. package/src/lightning/datatable/datatable.js +104 -33
  28. package/src/lightning/datatable/errors.js +20 -9
  29. package/src/lightning/datatable/fixedWidthStrategy.js +43 -8
  30. package/src/lightning/datatable/headerActions.js +77 -49
  31. package/src/lightning/datatable/infiniteLoading.js +100 -28
  32. package/src/lightning/datatable/inlineEdit.js +505 -379
  33. package/src/lightning/datatable/inlineEditShared.js +24 -0
  34. package/src/lightning/datatable/keyboard.js +162 -127
  35. package/src/lightning/datatable/renderManager.js +208 -133
  36. package/src/lightning/datatable/{datatableResizeObserver.js → resizeObserver.js} +46 -29
  37. package/src/lightning/datatable/resizeSensor.js +8 -0
  38. package/src/lightning/datatable/rowLevelActions.js +17 -13
  39. package/src/lightning/datatable/rowNumber.js +54 -20
  40. package/src/lightning/datatable/rowSelection.js +760 -0
  41. package/src/lightning/datatable/rowSelectionShared.js +79 -0
  42. package/src/lightning/datatable/rows.js +17 -6
  43. package/src/lightning/datatable/state.js +16 -2
  44. package/src/lightning/datatable/templates/div/div.css +4 -0
  45. package/src/lightning/datatable/templates/div/div.html +128 -117
  46. package/src/lightning/datatable/templates/table/table.html +5 -0
  47. package/src/lightning/datatable/utils.js +14 -0
  48. package/src/lightning/datatable/widthManagerShared.js +27 -3
  49. package/src/lightning/datatable/wrapText.js +77 -47
  50. package/src/lightning/dualListbox/dualListbox.html +1 -1
  51. package/src/lightning/dualListbox/dualListbox.js +42 -0
  52. package/src/lightning/formattedDateTime/__docs__/formattedDateTime.md +36 -3
  53. package/src/lightning/formattedDateTime/__examples__/datetime/datetime.html +2 -2
  54. package/src/lightning/formattedDateTime/__examples__/datetime/datetime.js +3 -1
  55. package/src/lightning/formattedDateTime/__examples__/time/time.html +1 -1
  56. package/src/lightning/formattedDateTime/__examples__/time/time.js +3 -1
  57. package/src/lightning/formattedDateTime/formattedDateTime.js +1 -0
  58. package/src/lightning/input/input.html +2 -5
  59. package/src/lightning/inputUtils/validity.js +12 -1
  60. package/src/lightning/pillContainer/__docs__/pillContainer.md +45 -1
  61. package/src/lightning/positionLibrary/positionLibrary.js +31 -43
  62. package/src/lightning/primitiveCellActions/primitiveCellActions.js +69 -12
  63. package/src/lightning/primitiveCellFactory/cellWithStandardLayout.html +13 -11
  64. package/src/lightning/primitiveCellFactory/primitiveCellFactory.js +13 -8
  65. package/src/lightning/primitiveDatatableIeditPanel/primitiveDatatableIeditPanel.html +17 -14
  66. package/src/lightning/primitiveDatatableIeditPanel/primitiveDatatableIeditPanel.js +167 -98
  67. package/src/lightning/primitiveDatatableIeditTypeFactory/primitiveDatatableIeditTypeFactory.js +94 -69
  68. package/src/lightning/primitiveDatatableStatusBar/primitiveDatatableStatusBar.html +4 -4
  69. package/src/lightning/primitiveDatatableStatusBar/primitiveDatatableStatusBar.js +4 -4
  70. package/src/lightning/primitiveHeaderActions/primitiveHeaderActions.js +99 -37
  71. package/src/lightning/progressIndicator/progressIndicator.js +1 -1
  72. package/src/lightning/progressStep/progressStep.js +1 -1
  73. package/src/lightning/spinner/spinner.html +1 -1
  74. package/src/lightning/spinner/spinner.js +12 -0
  75. package/src/lightning/staticMap/staticMap.html +1 -0
  76. package/src/lightning/staticMap/staticMap.js +39 -2
  77. package/src/lightning/utils/classSet.js +4 -1
  78. package/src/lightning/utilsPrivate/phonify.js +1 -1
  79. package/scopedImports/@salesforce-label-LightningModalBase.close.js +0 -1
  80. package/src/lightning/datatable/inlineEdit-shared.js +0 -14
  81. package/src/lightning/datatable/selector-shared.js +0 -38
  82. package/src/lightning/datatable/selector.js +0 -527
@@ -21,28 +21,33 @@ const i18n = {
21
21
  showActions: labelShowActions,
22
22
  };
23
23
 
24
+ /**
25
+ * A cell-level action.
26
+ */
24
27
  export default class PrimitiveCellActions extends LightningElement {
25
- static delegatesFocus = true;
26
-
27
- @api rowKeyValue;
28
- @api colKeyValue;
29
- @api rowActions;
30
-
28
+ // Tracked objects
31
29
  @track containerRect;
32
30
  @track _actions = [];
33
31
 
32
+ // Private variables
33
+ static delegatesFocus = true;
34
34
  _isLoadingActions;
35
35
  _menuAlignment = DEFAULT_MENU_ALIGNMENT;
36
36
  _internalTabIndex = false;
37
37
 
38
- connectedCallback() {
39
- this._connected = true;
40
- }
38
+ /************************** PUBLIC ATTRIBUTES ***************************/
41
39
 
42
- disconnectedCallback() {
43
- this._connected = false;
44
- }
40
+ @api rowKeyValue;
41
+ @api colKeyValue;
42
+ @api rowActions;
45
43
 
44
+ /**
45
+ * Defines the current menu alignment
46
+ * See `VALID_MENU_ALIGNMENT` for valid menu alignment values
47
+ * See `DEFAULT_MENU_ALIGNMENT` for the default menu alignment
48
+ *
49
+ * @type {string}
50
+ */
46
51
  @api
47
52
  get menuAlignment() {
48
53
  return this._menuAlignment;
@@ -55,6 +60,11 @@ export default class PrimitiveCellActions extends LightningElement {
55
60
  });
56
61
  }
57
62
 
63
+ /************************** PUBLIC METHODS ***************************/
64
+
65
+ /**
66
+ * Sets focus on a lightning-button-menu
67
+ */
58
68
  @api
59
69
  focus() {
60
70
  if (this._connected) {
@@ -62,6 +72,9 @@ export default class PrimitiveCellActions extends LightningElement {
62
72
  }
63
73
  }
64
74
 
75
+ /**
76
+ * Clicks a lightning-button-menu
77
+ */
65
78
  @api
66
79
  click() {
67
80
  if (this._connected) {
@@ -73,18 +86,42 @@ export default class PrimitiveCellActions extends LightningElement {
73
86
  }
74
87
  }
75
88
 
89
+ /************************** PRIVATE GETTERS **************************/
90
+
91
+ /**
92
+ * Returns the computed menu alignment value
93
+ *
94
+ * @return {string} Current computed menu alignment
95
+ */
76
96
  get computedMenuAlignment() {
77
97
  return this.menuAlignment;
78
98
  }
79
99
 
100
+ /**
101
+ * Returns the button alternative text in the appropriate language
102
+ *
103
+ * @return {string} Language-specific button alternative text
104
+ */
80
105
  get buttonAlternateText() {
81
106
  return `${i18n.showActions}`;
82
107
  }
83
108
 
109
+ /**
110
+ * Returns the spinner alternative text in the appropriate language
111
+ *
112
+ * @return {string} Language-specific spinner alternative text
113
+ */
84
114
  get spinnerAlternateText() {
85
115
  return `${i18n.loadingActions}`;
86
116
  }
87
117
 
118
+ /************************ EVENT DISPATCHERS **************************/
119
+
120
+ /**
121
+ * Handles selecting an action
122
+ *
123
+ * @param {Event} event
124
+ */
88
125
  handleActionSelect(event) {
89
126
  this.dispatchEvent(
90
127
  new CustomEvent('privatecellactiontriggered', {
@@ -100,6 +137,9 @@ export default class PrimitiveCellActions extends LightningElement {
100
137
  );
101
138
  }
102
139
 
140
+ /**
141
+ * Handles the opening of an action menu
142
+ */
103
143
  handleMenuOpen() {
104
144
  this.elementRect = this.template
105
145
  .querySelector('lightning-button-menu')
@@ -135,6 +175,23 @@ export default class PrimitiveCellActions extends LightningElement {
135
175
  }
136
176
  }
137
177
 
178
+ /************************** LIFECYCLE HOOKS **************************/
179
+
180
+ connectedCallback() {
181
+ this._connected = true;
182
+ }
183
+
184
+ disconnectedCallback() {
185
+ this._connected = false;
186
+ }
187
+
188
+ /************************* HELPER FUNCTIONS **************************/
189
+
190
+ /**
191
+ * Resets loading state when all actions have been loaded
192
+ *
193
+ * @param {object} actions - Actions displayed in the menu
194
+ */
138
195
  finishLoadingActions(actions) {
139
196
  this._isLoadingActions = false;
140
197
  this._actions = actions;
@@ -215,18 +215,20 @@
215
215
 
216
216
  <!-- row number -->
217
217
  <template if:true={isRowNumber}>
218
- <lightning-primitive-datatable-tooltip data-navigation="enable"
219
- data-action-triggers="enter,space"
220
- class={rowNumberErrorClass}
221
- size="xx-small"
222
- header={typeAttribute0.title}
223
- content={typeAttribute0.messages}
224
- variant='error'
225
- internal-tab-index={internalTabIndex}
226
- alternative-text={typeAttribute0.alternativeText}>
218
+ <template if:true={_rowHasError}>
219
+ <lightning-primitive-datatable-tooltip data-navigation="enable"
220
+ data-action-triggers="enter,space"
221
+ class="slds-m-horizontal_xxx-small"
222
+ size="xx-small"
223
+ header={typeAttribute0.title}
224
+ content={typeAttribute0.messages}
225
+ variant='error'
226
+ internal-tab-index={internalTabIndex}
227
+ alternative-text={typeAttribute0.alternativeText}>
227
228
 
228
- </lightning-primitive-datatable-tooltip>
229
- <span class="slds-row-number slds-text-body_small slds-text-color_weak"></span>
229
+ </lightning-primitive-datatable-tooltip>
230
+ </template>
231
+ <span class="slds-row-number slds-text-body_small slds-text-color_weak" style={computedRowNumberStyle}></span>
230
232
  </template>
231
233
 
232
234
  <!-- text -->
@@ -8,6 +8,9 @@ import labelEditHasError from '@salesforce/label/LightningDatatable.editHasError
8
8
  import labelTrue from '@salesforce/label/LightningDatatable.true';
9
9
  import labelFalse from '@salesforce/label/LightningDatatable.false';
10
10
 
11
+ // Same constant (TOOLTIP_ALLOWANCE) as used in lightning/datatable/rowNumber.js
12
+ // If making change to this, make sure to modify in rowNumber.js as well
13
+ const TOOLTIP_ALLOWANCE = 20;
11
14
  const i18n = {
12
15
  edit: labelEdit,
13
16
  editHasError: labelEditHasError,
@@ -58,6 +61,7 @@ export default class PrivateCellFactory extends PrimitiveDatatableCell {
58
61
  @api wrapTextMaxLines;
59
62
 
60
63
  _wrapText = false;
64
+ _rowHasError = false;
61
65
 
62
66
  @api
63
67
  get wrapText() {
@@ -153,7 +157,13 @@ export default class PrivateCellFactory extends PrimitiveDatatableCell {
153
157
  }
154
158
 
155
159
  get isRowNumber() {
156
- return this.isType('rowNumber');
160
+ if (this.isType('rowNumber')) {
161
+ const error = this.typeAttribute0;
162
+ this._rowHasError = error && error.title && error.messages;
163
+ return true;
164
+ }
165
+
166
+ return false;
157
167
  }
158
168
 
159
169
  get isAction() {
@@ -285,13 +295,8 @@ export default class PrivateCellFactory extends PrimitiveDatatableCell {
285
295
  .toString();
286
296
  }
287
297
 
288
- get rowNumberErrorClass() {
289
- const classes = classSet('slds-m-horizontal_xxx-small');
290
- const error = this.typeAttribute0;
291
- if (error) {
292
- classes.add({ 'slds-hidden': !error.title && !error.messages });
293
- }
294
- return classes.toString();
298
+ get computedRowNumberStyle() {
299
+ return this._rowHasError ? '' : `padding-left: ${TOOLTIP_ALLOWANCE}px;`;
295
300
  }
296
301
 
297
302
  get editIconAssistiveText() {
@@ -3,19 +3,21 @@
3
3
  if:true={visible}
4
4
  class="slds-popover slds-popover_edit"
5
5
  role="dialog"
6
+ aria-label={dialogAriaLabel}
6
7
  tabindex="-1"
7
8
  onblur={handleTypeElemBlur}
8
9
  onfocus={handleTypeElemFocus}
9
10
  onkeydown={handleCellKeydown}
10
- style={computedStyle}
11
- >
11
+ style={computedStyle}>
12
+
12
13
  <span class="inline-edit-form-start" tabindex="0" onfocus={handleFormStartFocus}></span>
13
14
  <div class="slds-popover__body">
14
15
  <form onsubmit={handleEditFormSubmit} novalidate>
16
+ <!-- Renders the required indicator -->
15
17
  <lightning-primitive-datatable-iedit-input-wrapper
16
18
  required={required}
17
- class="slds-grid slds-p-left_xx-small"
18
- >
19
+ class="slds-grid slds-p-left_xx-small">
20
+ <!-- Renders the appropriate input type in the inline edit panel -->
19
21
  <lightning-primitive-datatable-iedit-type-factory
20
22
  required={required}
21
23
  class="dt-type-edit-factory slds-col"
@@ -24,10 +26,11 @@
24
26
  edited-value={editedValue}
25
27
  onblur={handleTypeElemBlur}
26
28
  onfocus={handleTypeElemFocus}
27
- key={inputKey}
28
- ></lightning-primitive-datatable-iedit-type-factory>
29
+ key={inputKey}>
30
+ </lightning-primitive-datatable-iedit-type-factory>
29
31
  </lightning-primitive-datatable-iedit-input-wrapper>
30
32
  <template if:true={isMassEditEnabled}>
33
+ <!-- Checkbox to select in order to mass edit multiple rows -->
31
34
  <lightning-input
32
35
  data-mass-selection="true"
33
36
  type="checkbox"
@@ -35,32 +38,32 @@
35
38
  label={massEditCheckboxLabel}
36
39
  onchange={handleMassCheckboxChange}
37
40
  onblur={handleTypeElemBlur}
38
- onfocus={handleTypeElemFocus}
39
- ></lightning-input>
41
+ onfocus={handleTypeElemFocus}>
42
+ </lightning-input>
40
43
  </template>
41
44
  <template if:false={isMassEditEnabled}>
42
45
  <button type="submit" aria-hidden="true" tabindex="-1" class="slds-hide" value="save"></button>
43
46
  </template>
44
47
  </form>
45
48
  </div>
49
+ <!-- If in mass edit mode, render 'Cancel' and 'Apply' buttons -->
46
50
  <template if:true={isMassEditEnabled}>
47
51
  <div class="slds-popover__footer">
48
52
  <div class="slds-grid slds-grid_align-end">
49
53
  <lightning-button
50
- label={cancelLabel}
54
+ label={i18n.cancel}
51
55
  onblur={handleTypeElemBlur}
52
56
  onfocus={handleTypeElemFocus}
53
- onclick={cancelEdition}
54
- ></lightning-button>
57
+ onclick={cancelEditing}>
58
+ </lightning-button>
55
59
  <lightning-button
56
- label={applyLabel}
60
+ label={i18n.apply}
57
61
  style="margin-left: .25rem"
58
62
  variant="brand"
59
63
  onblur={handleTypeElemBlur}
60
64
  onfocus={handleTypeElemFocus}
61
65
  data-form-last-element="true"
62
- onclick={processSubmission}
63
- >
66
+ onclick={processSubmission}>
64
67
  </lightning-button>
65
68
  </div>
66
69
  </div>
@@ -1,4 +1,5 @@
1
1
  import { LightningElement, api } from 'lwc';
2
+ import labelEdit from '@salesforce/label/LightningDatatable.edit';
2
3
  import labelUpdateSelectedItems from '@salesforce/label/LightningDatatable.updateSelectedItems';
3
4
  import labelCancel from '@salesforce/label/LightningDatatable.cancel';
4
5
  import labelApply from '@salesforce/label/LightningDatatable.apply';
@@ -6,12 +7,15 @@ import { InteractingState } from 'lightning/inputUtils';
6
7
  import { formatLabel } from 'lightning/utils';
7
8
 
8
9
  const i18n = {
10
+ edit: labelEdit,
9
11
  updateSelectedItems: labelUpdateSelectedItems,
10
12
  cancel: labelCancel,
11
13
  apply: labelApply,
12
14
  };
13
15
 
14
16
  export default class PrimitiveDatatableIeditPanel extends LightningElement {
17
+ /************************* PUBLIC PROPERTIES *************************/
18
+
15
19
  @api visible;
16
20
  @api rowKeyValue;
17
21
  @api colKeyValue;
@@ -21,14 +25,80 @@ export default class PrimitiveDatatableIeditPanel extends LightningElement {
21
25
  @api numberOfSelectedRows;
22
26
  @api resolvedTypeAttributes;
23
27
 
24
- connectedCallback() {
25
- this.interactingState = new InteractingState({
26
- duration: 10,
27
- debounceInteraction: true,
28
- });
29
- this.interactingState.onleave(() => this.handlePanelLoosedFocus());
28
+ /**
29
+ * Checked when opening an edit panel to see if it's valid
30
+ * Logs an error if type is custom but does not have the
31
+ * required editTemplate with [data-inputable="true"] element
32
+ */
33
+ @api
34
+ get isEditableValid() {
35
+ if (
36
+ !this.columnDef.editableCustomType ||
37
+ this.inputableElement.isEditableCustomValid
38
+ ) {
39
+ return true;
40
+ } else if (this.columnDef.editableCustomType) {
41
+ console.error(
42
+ 'Editable custom types must define an editTemplate that includes an element with attribute data-inputable set to "true"'
43
+ );
44
+ }
45
+ return false;
46
+ }
47
+
48
+ /**
49
+ * Returns whether or not the mass edit update checkbox is selected
50
+ */
51
+ @api
52
+ get isMassEditChecked() {
53
+ return (
54
+ this.isMassEditEnabled &&
55
+ this.template.querySelector('[data-mass-selection="true"]').checked
56
+ );
57
+ }
58
+
59
+ /**
60
+ * Returns the value of the input in the inline edit panel
61
+ * This is retrieved typically when processing inline edit completion
62
+ */
63
+ @api
64
+ get value() {
65
+ return this.inputableElement ? this.inputableElement.value : null;
66
+ }
67
+
68
+ /**
69
+ * Returns the validity state object of the input in the inline edit panel
70
+ */
71
+ @api
72
+ get validity() {
73
+ return this.inputableElement.validity;
74
+ }
75
+
76
+ /************************* PUBLIC METHODS *************************/
77
+
78
+ /**
79
+ * Focuses on the input element in the inline edit panel
80
+ */
81
+ @api
82
+ focus() {
83
+ const elem = this.inputableElement;
84
+ this.interactingState.enter();
85
+
86
+ if (elem) {
87
+ elem.focus();
88
+ }
89
+ }
90
+
91
+ /**
92
+ * Returns the <section> element which is the container of the
93
+ * positioned inline edit panel
94
+ */
95
+ @api
96
+ getPositionedElement() {
97
+ return this.template.querySelector('section');
30
98
  }
31
99
 
100
+ /************************* PRIVATE GETTERS *************************/
101
+
32
102
  get computedStyle() {
33
103
  const styleHash = {
34
104
  'z-index': 1000,
@@ -43,29 +113,41 @@ export default class PrimitiveDatatableIeditPanel extends LightningElement {
43
113
  .join(';');
44
114
  }
45
115
 
116
+ get inputableElement() {
117
+ return this.template.querySelector('.dt-type-edit-factory');
118
+ }
119
+
46
120
  get inputKey() {
47
121
  return this.rowKeyValue + this.colKeyValue;
48
122
  }
49
123
 
124
+ get required() {
125
+ return (
126
+ this.columnDef.typeAttributes &&
127
+ this.columnDef.typeAttributes.required
128
+ );
129
+ }
130
+
50
131
  get massEditCheckboxLabel() {
51
132
  return formatLabel(i18n.updateSelectedItems, this.numberOfSelectedRows);
52
133
  }
53
134
 
54
- get applyLabel() {
55
- return i18n.apply;
135
+ get dialogAriaLabel() {
136
+ const columnName = this.columnDef.label;
137
+ return `${i18n.edit} ${columnName}`;
56
138
  }
57
139
 
58
- get cancelLabel() {
59
- return i18n.cancel;
140
+ get i18n() {
141
+ return i18n;
60
142
  }
61
143
 
62
- get required() {
63
- return (
64
- this.columnDef.typeAttributes &&
65
- this.columnDef.typeAttributes.required
66
- );
67
- }
144
+ /************************* EVENT HANDLERS *************************/
68
145
 
146
+ /**
147
+ * Handles tabbing backwards out of the inline edit panel from the first form element.
148
+ * If mass edit is enabled, this will set the focus on the last element in the panel - traps focus.
149
+ * If mass edit is not enabled, it will process completion of inline edit
150
+ */
69
151
  handleFormStartFocus() {
70
152
  this.interactingState.enter();
71
153
 
@@ -79,6 +161,11 @@ export default class PrimitiveDatatableIeditPanel extends LightningElement {
79
161
  }
80
162
  }
81
163
 
164
+ /**
165
+ * Handles tabbing forwards out of the inline edit panel from the last form element.
166
+ * If mass edit is enabled, this will set focus on the first element in the panel - traps focus.
167
+ * If mass edit is not enabled, it will process the completion of inline edit
168
+ */
82
169
  handleFormEndsFocus() {
83
170
  this.interactingState.enter();
84
171
 
@@ -92,71 +179,20 @@ export default class PrimitiveDatatableIeditPanel extends LightningElement {
92
179
  }
93
180
  }
94
181
 
95
- triggerEditFinished(detail) {
96
- detail.rowKeyValue = detail.rowKeyValue || this.rowKeyValue;
97
- detail.colKeyValue = detail.colKeyValue || this.colKeyValue;
98
-
99
- const event = new CustomEvent('ieditfinished', {
100
- detail,
101
- });
102
- this.dispatchEvent(event);
103
- }
104
-
105
- @api
106
- focus() {
107
- const elem = this.inputableElement;
108
- this.interactingState.enter();
109
-
110
- if (elem) {
111
- elem.focus();
112
- }
113
- }
114
-
115
- get inputableElement() {
116
- return this.template.querySelector('.dt-type-edit-factory');
117
- }
118
-
119
182
  /**
120
- * Checked when opening an edit panel to see if it's valid
121
- * Logs an error if type is custom but does not have the
122
- * required editTemplate with [data-inputable="true"] element
183
+ * This is executed when interactingState.leave is triggered
184
+ * which happens when the inline edit panel loses focus
123
185
  */
124
- @api
125
- get isEditableValid() {
126
- if (
127
- !this.columnDef.editableCustomType ||
128
- this.inputableElement.isEditableCustomValid
129
- ) {
130
- return true;
131
- } else if (this.columnDef.editableCustomType) {
132
- console.error(
133
- 'Editable custom types must define an editTemplate that includes an element with attribute data-inputable set to "true"'
134
- );
186
+ handlePanelLostFocus() {
187
+ if (this.visible) {
188
+ this.triggerEditFinished({
189
+ reason: 'lost-focus',
190
+ });
135
191
  }
136
- return false;
137
- }
138
-
139
- @api
140
- get value() {
141
- return this.inputableElement ? this.inputableElement.value : null;
142
- }
143
-
144
- @api
145
- get validity() {
146
- return this.inputableElement.validity;
147
- }
148
-
149
- @api
150
- get isMassEditChecked() {
151
- return (
152
- this.isMassEditEnabled &&
153
- this.template.querySelector('[data-mass-selection="true"]').checked
154
- );
155
192
  }
156
193
 
157
- @api
158
- getPositionedElement() {
159
- return this.template.querySelector('section');
194
+ handleTypeElemFocus() {
195
+ this.interactingState.enter();
160
196
  }
161
197
 
162
198
  handleTypeElemBlur() {
@@ -165,10 +201,6 @@ export default class PrimitiveDatatableIeditPanel extends LightningElement {
165
201
  }
166
202
  }
167
203
 
168
- handleTypeElemFocus() {
169
- this.interactingState.enter();
170
- }
171
-
172
204
  handleEditFormSubmit(event) {
173
205
  event.preventDefault();
174
206
  event.stopPropagation();
@@ -180,24 +212,71 @@ export default class PrimitiveDatatableIeditPanel extends LightningElement {
180
212
  return false;
181
213
  }
182
214
 
215
+ /**
216
+ * If the Escape key is pressed on the inline edit panel,
217
+ * we prevent default action, stop propagation of the event
218
+ * and close the inline edit panel
219
+ *
220
+ * @param {KeyboardEvent} event - keydown
221
+ */
183
222
  handleCellKeydown(event) {
184
223
  const { keyCode } = event;
185
224
 
186
225
  if (keyCode === 27) {
187
226
  // Esc key
227
+ event.preventDefault();
188
228
  event.stopPropagation();
189
- this.cancelEdition();
229
+ this.cancelEditing();
190
230
  }
191
231
  }
192
232
 
193
- handlePanelLoosedFocus() {
194
- if (this.visible) {
195
- this.triggerEditFinished({
196
- reason: 'loosed-focus',
197
- });
198
- }
233
+ /************************* EVENT DISPATCHERS *************************/
234
+
235
+ /**
236
+ * Change handler for the mass edit checkbox.
237
+ * Dispatches the `masscheckboxchange` event along with the new checked value
238
+ *
239
+ * @param {CustomEvent} event - `change` event from lightning-input
240
+ */
241
+ handleMassCheckboxChange(event) {
242
+ const customEvent = new CustomEvent('masscheckboxchange', {
243
+ detail: {
244
+ checked: event.detail.checked,
245
+ },
246
+ });
247
+
248
+ this.dispatchEvent(customEvent);
199
249
  }
200
250
 
251
+ /**
252
+ * Dispatches the `ieditfinished` event with the detail object containing
253
+ * the reason for inline edit finishing and the rowKeyValue and colKeyValue
254
+ * with which the particular cell which was edited can be identified.
255
+ *
256
+ * @param {Object} detail - typically contains the reason for inline edit finishing
257
+ */
258
+ triggerEditFinished(detail) {
259
+ detail.rowKeyValue = detail.rowKeyValue || this.rowKeyValue;
260
+ detail.colKeyValue = detail.colKeyValue || this.colKeyValue;
261
+
262
+ const event = new CustomEvent('ieditfinished', {
263
+ detail,
264
+ });
265
+ this.dispatchEvent(event);
266
+ }
267
+
268
+ /************************* LIFECYCLE HOOKS *************************/
269
+
270
+ connectedCallback() {
271
+ this.interactingState = new InteractingState({
272
+ duration: 10,
273
+ debounceInteraction: true,
274
+ });
275
+ this.interactingState.onleave(() => this.handlePanelLostFocus());
276
+ }
277
+
278
+ /************************* HELPER FUNCTIONS *************************/
279
+
201
280
  focusLastElement() {
202
281
  this.template.querySelector('[data-form-last-element="true"]').focus();
203
282
  }
@@ -210,19 +289,9 @@ export default class PrimitiveDatatableIeditPanel extends LightningElement {
210
289
  }
211
290
  }
212
291
 
213
- cancelEdition() {
292
+ cancelEditing() {
214
293
  this.triggerEditFinished({
215
294
  reason: 'edit-canceled',
216
295
  });
217
296
  }
218
-
219
- handleMassCheckboxChange(event) {
220
- const customEvent = new CustomEvent('masscheckboxchange', {
221
- detail: {
222
- checked: event.detail.checked,
223
- },
224
- });
225
-
226
- this.dispatchEvent(customEvent);
227
- }
228
297
  }