lightning-base-components 1.21.3-alpha → 1.21.4-alpha

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (183) hide show
  1. package/metadata/raptor.json +49 -0
  2. package/package.json +88 -21
  3. package/scopedImports/@salesforce-label-LightningDatatable.showActions.js +1 -1
  4. package/scopedImports/@salesforce-label-LightningForm.controllerFieldsMessage.js +1 -0
  5. package/scopedImports/@salesforce-label-LightningForm.dependentFieldsHeader.js +1 -0
  6. package/scopedImports/@salesforce-label-LightningForm.dependentFieldsListHeading.js +1 -0
  7. package/scopedImports/@salesforce-label-LightningForm.generalDependentFieldsMessage.js +1 -0
  8. package/scopedImports/@salesforce-label-LightningForm.learnMore.js +1 -0
  9. package/scopedImports/@salesforce-label-LightningForm.okButton.js +1 -0
  10. package/scopedImports/@salesforce-label-LightningLookup.modalCancel.js +1 -0
  11. package/scopedImports/@salesforce-label-LightningLookup.modalSelect.js +1 -0
  12. package/scopedImports/@salesforce-label-LightningProgressIndicator.currentStage.js +1 -1
  13. package/scopedImports/@salesforce-label-LightningProgressIndicator.errorStage.js +1 -0
  14. package/scopedImports/@salesforce-label-LightningProgressIndicator.stageComplete.js +1 -1
  15. package/scopedImports/@salesforce-label-LightningProgressIndicator.stageNotStarted.js +1 -1
  16. package/src/lightning/avatar/avatar.html +1 -0
  17. package/src/lightning/badge/badge.html +3 -3
  18. package/src/lightning/baseCombobox/baseCombobox.html +4 -1
  19. package/src/lightning/baseCombobox/baseCombobox.js +3 -16
  20. package/src/lightning/button/__docs__/button.md +2 -1
  21. package/src/lightning/button/button.js +3 -4
  22. package/src/lightning/buttonIcon/__docs__/buttonIcon.md +1 -0
  23. package/src/lightning/buttonIcon/buttonIcon.html +1 -1
  24. package/src/lightning/buttonIcon/buttonIcon.js +18 -17
  25. package/src/lightning/buttonMenu/buttonMenu.css +5 -0
  26. package/src/lightning/buttonMenu/buttonMenu.js +2 -0
  27. package/src/lightning/colorPickerCustom/colorPickerCustom.js +12 -0
  28. package/src/lightning/colorPickerPanel/colorPickerPanel.js +11 -1
  29. package/src/lightning/combobox/combobox.html +1 -0
  30. package/src/lightning/datatable/__examples__disabled/customComponentWrapper/customComponentWrapper.html +11 -0
  31. package/src/lightning/datatable/__examples__disabled/customComponentWrapper/customComponentWrapper.js +25 -0
  32. package/src/lightning/datatable/__examples__disabled/customComponentWrapper/generateData.js +15 -0
  33. package/src/lightning/datatable/__examples__disabled/myCustomTypeDatatable/customInput.html +4 -0
  34. package/src/lightning/datatable/__examples__disabled/myCustomTypeDatatable/myCustomTypeDatatable.js +17 -0
  35. package/src/lightning/datatable/__examples__disabled/myCustomTypeDatatable/nestedSimpleComponentParent.html +7 -0
  36. package/src/lightning/datatable/__examples__disabled/simpleComponentNested/simpleComponentNested.html +9 -0
  37. package/src/lightning/datatable/__examples__disabled/simpleComponentNested/simpleComponentNested.js +6 -0
  38. package/src/lightning/datatable/autoWidthStrategy.js +8 -36
  39. package/src/lightning/datatable/columnResizer.js +51 -161
  40. package/src/lightning/datatable/columnWidthManager.js +25 -81
  41. package/src/lightning/datatable/columns.js +180 -302
  42. package/src/lightning/datatable/datatable.js +455 -441
  43. package/src/lightning/datatable/errors.js +17 -29
  44. package/src/lightning/datatable/fixedWidthStrategy.js +7 -22
  45. package/src/lightning/datatable/headerActions.js +8 -38
  46. package/src/lightning/datatable/indexes.js +42 -0
  47. package/src/lightning/datatable/infiniteLoading.js +16 -35
  48. package/src/lightning/datatable/inlineEdit.js +125 -156
  49. package/src/lightning/datatable/keyboard.js +226 -282
  50. package/src/lightning/datatable/renderManager.js +0 -4
  51. package/src/lightning/datatable/resizeObserver.js +4 -13
  52. package/src/lightning/datatable/rowLevelActions.js +2 -2
  53. package/src/lightning/datatable/rowNumber.js +21 -59
  54. package/src/lightning/datatable/rowSelection.js +95 -178
  55. package/src/lightning/datatable/rowSelectionShared.js +13 -27
  56. package/src/lightning/datatable/rows.js +171 -418
  57. package/src/lightning/datatable/sort.js +16 -75
  58. package/src/lightning/datatable/templates/div/div.html +12 -4
  59. package/src/lightning/datatable/templates/div/div.lbc.synthetic.css +10 -16
  60. package/src/lightning/datatable/templates/table/table.html +15 -5
  61. package/src/lightning/datatable/tree.js +17 -35
  62. package/src/lightning/datatable/types.js +10 -31
  63. package/src/lightning/datatable/utils.js +49 -24
  64. package/src/lightning/datatable/virtualization.js +2 -5
  65. package/src/lightning/datatable/widthManagerShared.js +0 -20
  66. package/src/lightning/datatable/wrapText.js +29 -60
  67. package/src/lightning/dualListbox/dualListbox.js +7 -8
  68. package/src/lightning/formattedName/formattedName.js +3 -2
  69. package/src/lightning/formattedName/formattedName.js-meta.xml +3 -0
  70. package/src/lightning/formattedNumber/formattedNumber.js +3 -2
  71. package/src/lightning/formattedNumber/formattedNumber.js-meta.xml +3 -0
  72. package/src/lightning/formattedRichText/richTextConfig.js +1 -0
  73. package/src/lightning/helptext/helptext.css +7 -0
  74. package/src/lightning/helptext/helptext.js +3 -4
  75. package/src/lightning/icon/icon.html +1 -1
  76. package/src/lightning/input/input.html +5 -0
  77. package/src/lightning/inputAddress/addressFormat.js +31 -4
  78. package/src/lightning/inputAddress/fieldsLayout.js +6 -0
  79. package/src/lightning/inputAddress/inputAddress.html +19 -1
  80. package/src/lightning/inputAddress/inputAddress.js +74 -3
  81. package/src/lightning/internationalizationLibrary/address/AddressFormat.js +553 -610
  82. package/src/lightning/lookupAddress/lookupAddress.html +6 -1
  83. package/src/lightning/lookupAddress/lookupAddress.js +25 -0
  84. package/src/lightning/modal/__docs__/modal.md +10 -1
  85. package/src/lightning/modal/__modalUtils__/modalContainerTestConstants.js +3 -7
  86. package/src/lightning/modal/__modalUtils__/modalContainerTestMethods.js +39 -133
  87. package/src/lightning/modal/__modalUtils__/modalContainerTestMockData.js +1 -1
  88. package/src/lightning/modal/modal.js +1 -1
  89. package/src/lightning/modalBase/modalBase.html +15 -10
  90. package/src/lightning/modalBase/modalBase.js +131 -146
  91. package/src/lightning/modalBody/modalBody.css +6 -0
  92. package/src/lightning/modalHeader/modalHeader.html +16 -4
  93. package/src/lightning/modalHeader/modalHeader.js +61 -14
  94. package/src/lightning/pill/link.html +1 -0
  95. package/src/lightning/pill/plain.html +1 -0
  96. package/src/lightning/pill/plainLink.html +1 -0
  97. package/src/lightning/primitiveBubble/primitiveBubble.js +42 -0
  98. package/src/lightning/primitiveDatatableCell/primitiveDatatableCell.js +1 -1
  99. package/src/lightning/primitiveHeaderActions/primitiveHeaderActions.html +1 -1
  100. package/src/lightning/primitiveHeaderActions/primitiveHeaderActions.js +13 -0
  101. package/src/lightning/primitiveHeaderFactory/nonsortableHeader.html +19 -6
  102. package/src/lightning/primitiveHeaderFactory/sortableHeader.html +3 -1
  103. package/src/lightning/primitiveResizeHandler/primitiveResizeHandler.css +11 -0
  104. package/src/lightning/primitiveResizeHandler/primitiveResizeHandler.html +2 -1
  105. package/src/lightning/primitiveResizeHandler/primitiveResizeHandler.js +1 -0
  106. package/src/lightning/progressStep/base.html +5 -6
  107. package/src/lightning/progressStep/progressStep.js +14 -9
  108. package/src/lightning/prompt/__docs__/prompt.md +1 -1
  109. package/src/lightning/shadowBaseClassPrivate/shadowBaseClassPrivate.js +0 -2
  110. package/src/lightning/sldsCommon/sldsCommon.css +134 -98
  111. package/src/lightning/sldsUtilsAlignment/sldsUtilsAlignment.css +1 -1
  112. package/src/lightning/sldsUtilsBox/sldsUtilsBox.css +14 -13
  113. package/src/lightning/sldsUtilsGrid/sldsUtilsGrid.css +95 -92
  114. package/src/lightning/sldsUtilsHyphenation/sldsUtilsHyphenation.css +1 -1
  115. package/src/lightning/sldsUtilsMargin/sldsUtilsMargin.css +77 -75
  116. package/src/lightning/sldsUtilsPadding/sldsUtilsPadding.css +73 -73
  117. package/src/lightning/sldsUtilsSizing/sldsUtilsSizing.css +552 -558
  118. package/src/lightning/sldsUtilsVisibility/sldsUtilsVisibility.css +2 -2
  119. package/src/lightning/staticMap/staticMap.js +3 -2
  120. package/src/lightning/tab/tab.js +6 -3
  121. package/src/lightning/tab/tab.js-meta.xml +3 -0
  122. package/src/lightning/tabBar/tabBar.js +10 -5
  123. package/src/lightning/tabset/tabset.html +2 -0
  124. package/src/lightning/tabset/tabset.js-meta.xml +3 -0
  125. package/src/lightning/textarea/textarea.js +6 -1
  126. package/src/lightning/toastContainer/__docs__/toastContainer.md +3 -2
  127. package/src/lightning/tooltipLibrary/tooltipLibrary.js +24 -15
  128. package/src/lightning/verticalNavigation/vertical-navigation.slds.css +14 -0
  129. package/src/lightning/verticalNavigation/verticalNavigation.css +1 -1
  130. package/src/lightning/verticalNavigation/verticalNavigation.html +1 -1
  131. package/src/lightning/verticalNavigation/verticalNavigation.js +66 -28
  132. package/src/lightning/verticalNavigation/verticalNavigation.js-meta.xml +3 -0
  133. package/src/lightning/verticalNavigationItem/vertical-navigation-item.slds.css +63 -0
  134. package/src/lightning/verticalNavigationItem/verticalNavigationItem.css +2 -3
  135. package/src/lightning/verticalNavigationItem/verticalNavigationItem.js +29 -15
  136. package/src/lightning/verticalNavigationItem/verticalNavigationItem.js-meta.xml +3 -0
  137. package/src/lightning/verticalNavigationItem/verticalNavigationItem.lbc.native.css +2 -0
  138. package/src/lightning/verticalNavigationItem/verticalNavigationItem.lbc.synthetic.css +3 -0
  139. package/src/lightning/verticalNavigationItemBadge/badge.slds.css +76 -0
  140. package/src/lightning/verticalNavigationItemBadge/vertical-navigation-item.slds.css +63 -0
  141. package/src/lightning/verticalNavigationItemBadge/verticalNavigationItemBadge.css +2 -3
  142. package/src/lightning/verticalNavigationItemBadge/verticalNavigationItemBadge.html +1 -1
  143. package/src/lightning/verticalNavigationItemBadge/verticalNavigationItemBadge.js +28 -15
  144. package/src/lightning/verticalNavigationItemBadge/verticalNavigationItemBadge.js-meta.xml +3 -0
  145. package/src/lightning/verticalNavigationItemBadge/verticalNavigationItemBadge.lbc.native.css +5 -0
  146. package/src/lightning/verticalNavigationItemBadge/verticalNavigationItemBadge.lbc.synthetic.css +3 -0
  147. package/src/lightning/verticalNavigationItemIcon/vertical-navigation-item.slds.css +63 -0
  148. package/src/lightning/verticalNavigationItemIcon/verticalNavigationItemIcon.css +2 -3
  149. package/src/lightning/verticalNavigationItemIcon/verticalNavigationItemIcon.js +29 -15
  150. package/src/lightning/verticalNavigationItemIcon/verticalNavigationItemIcon.js-meta.xml +3 -0
  151. package/src/lightning/verticalNavigationItemIcon/verticalNavigationItemIcon.lbc.native.css +3 -0
  152. package/src/lightning/verticalNavigationItemIcon/verticalNavigationItemIcon.lbc.synthetic.css +3 -0
  153. package/src/lightning/verticalNavigationOverflow/button.slds.css +503 -0
  154. package/src/lightning/verticalNavigationOverflow/vertical-navigation-item.slds.css +63 -0
  155. package/src/lightning/verticalNavigationOverflow/vertical-navigation-section.slds.css +17 -0
  156. package/src/lightning/verticalNavigationOverflow/verticalNavigationOverflow.css +2 -1
  157. package/src/lightning/verticalNavigationOverflow/verticalNavigationOverflow.html +2 -0
  158. package/src/lightning/verticalNavigationOverflow/verticalNavigationOverflow.js +18 -13
  159. package/src/lightning/verticalNavigationOverflow/verticalNavigationOverflow.js-meta.xml +3 -0
  160. package/src/lightning/verticalNavigationOverflow/verticalNavigationOverflow.lbc.native.css +5 -0
  161. package/src/lightning/verticalNavigationSection/vertical-navigation-section.slds.css +14 -14
  162. package/src/lightning/verticalNavigationSection/verticalNavigationSection.js-meta.xml +3 -0
  163. package/src/lightning/datatable/inlineEditShared.js +0 -26
  164. /package/src/lightning/datatable/{__examples__ → __examples__disabled}/customDatatableWrapper/customDatatableWrapper.html +0 -0
  165. /package/src/lightning/datatable/{__examples__ → __examples__disabled}/customDatatableWrapper/customDatatableWrapper.js +0 -0
  166. /package/src/lightning/datatable/{__examples__ → __examples__disabled}/customDatatypeDeleteRowBtn/customDatatypeDeleteRowBtn.html +0 -0
  167. /package/src/lightning/datatable/{__examples__ → __examples__disabled}/customDatatypeDeleteRowBtn/customDatatypeDeleteRowBtn.js +0 -0
  168. /package/src/lightning/datatable/{__examples__ → __examples__disabled}/customDatatypeLink/customDatatypeLink.html +0 -0
  169. /package/src/lightning/datatable/{__examples__ → __examples__disabled}/customDatatypeLink/customDatatypeLink.js +0 -0
  170. /package/src/lightning/datatable/{__examples__ → __examples__disabled}/customDatatypeNumber/customDatatypeNumber.html +0 -0
  171. /package/src/lightning/datatable/{__examples__ → __examples__disabled}/customDatatypeNumber/customDatatypeNumber.js +0 -0
  172. /package/src/lightning/datatable/{__examples__ → __examples__disabled}/customDatatypeRowOrderingBtn/customDatatypeRowOrderingBtn.html +0 -0
  173. /package/src/lightning/datatable/{__examples__ → __examples__disabled}/customDatatypeRowOrderingBtn/customDatatypeRowOrderingBtn.js +0 -0
  174. /package/src/lightning/datatable/{__examples__ → __examples__disabled}/customDatatypeTable/customDatatypeTable.js +0 -0
  175. /package/src/lightning/datatable/{__examples__ → __examples__disabled}/customDatatypeTable/customLink.html +0 -0
  176. /package/src/lightning/datatable/{__examples__ → __examples__disabled}/customDatatypeTable/customName.html +0 -0
  177. /package/src/lightning/datatable/{__examples__ → __examples__disabled}/customDatatypeTable/customNumber.html +0 -0
  178. /package/src/lightning/datatable/{__examples__ → __examples__disabled}/customDatatypeTable/customNumberEdit.html +0 -0
  179. /package/src/lightning/datatable/{__examples__ → __examples__disabled}/customDatatypeTable/deleteRow.html +0 -0
  180. /package/src/lightning/datatable/{__examples__ → __examples__disabled}/customDatatypeTable/iconPill.html +0 -0
  181. /package/src/lightning/datatable/{__examples__ → __examples__disabled}/customDatatypeTable/orderingButtons.html +0 -0
  182. /package/src/lightning/datatable/{__examples__ → __examples__disabled}/customNestedComponent/customNestedComponent.html +0 -0
  183. /package/src/lightning/datatable/{__examples__ → __examples__disabled}/customNestedComponent/customNestedComponent.js +0 -0
@@ -2,20 +2,19 @@ import { api } from 'lwc';
2
2
  import LightningShadowBaseClass from 'lightning/shadowBaseClassPrivate';
3
3
  import { classSet } from 'lightning/utils';
4
4
  import {
5
- makeEverythingExceptElementInert,
6
- normalizeString,
7
- synchronizeAttrs,
8
- restoreInertness,
9
- hasAnimation,
10
5
  ARIA,
6
+ hasAnimation,
11
7
  isAriaDescriptionSupported,
12
8
  isCSR,
9
+ makeEverythingExceptElementInert,
10
+ normalizeString,
11
+ restoreInertness,
12
+ synchronizeAttrs,
13
13
  } from 'lightning/utilsPrivate';
14
14
  import { instanceName, secure } from 'lightning/overlayUtils';
15
15
  import {
16
16
  getElementWithFocus,
17
17
  returnFocusToElement,
18
- findAllTabbableElements,
19
18
  } from 'lightning/focusUtils';
20
19
  import closeButtonAltText from '@salesforce/label/LightningModalBase.cancelandclose';
21
20
  import disableCloseBtnMessage from '@salesforce/label/LightningModalBase.waitstate';
@@ -27,7 +26,6 @@ const SIZE_SMALL = 'small';
27
26
  const SIZE_MEDIUM = 'medium';
28
27
  const SIZE_LARGE = 'large';
29
28
  const SIZE_FULL = 'full';
30
- const OVERLAY_CONTAINER = 'lightning-overlay-container';
31
29
  const MODAL_BASE = 'lightning-modal-base';
32
30
 
33
31
  export default class LightningModalBase extends LightningShadowBaseClass {
@@ -47,6 +45,7 @@ export default class LightningModalBase extends LightningShadowBaseClass {
47
45
  isSmallScreenSize = null;
48
46
 
49
47
  // modalHeader, child
48
+ isHeadlessModalVariant = false;
50
49
  headerRegistered = false;
51
50
  headerHeight = 0;
52
51
  headerDefaultSlotIsPopulated = false;
@@ -163,48 +162,6 @@ export default class LightningModalBase extends LightningShadowBaseClass {
163
162
  return modal.disableClose;
164
163
  }
165
164
 
166
- /**
167
- * Toggle on and off disable close button feature
168
- * typically used very briefly when devs want to save form data to backend
169
- * and do not want the form to be closed before the save has
170
- * completed successfully
171
- * toggleDisableCloseButton sets local state to
172
- * (a) toggle display an aria-live message
173
- * (b) toggle set disabled on the <lightning-button-icon>
174
- * (c) toggle set aria-busy value on
175
- * elsewhere in modalBase and modal, ESC key is also disabled, and
176
- * calls to this.close() are prevented
177
- */
178
- toggleDisableCloseButton() {
179
- // this.disableCloseButton is local modalBase state
180
- // this.disableClose is modal.js @api state
181
- // we track both in order to handle transition correctly
182
- const isSwitchingToDisabled =
183
- !this.disableCloseButton && this.disableClose;
184
- /* Future enhancement possibility - trigger setInterval to remove and
185
- again add back 'Processing' text, as this will indicate to the screen
186
- reader user that the interface continues to be busy
187
- */
188
- const disableCloseButtonMessage = isSwitchingToDisabled
189
- ? this.disableCloseBtnMessage
190
- : '';
191
- if (isSwitchingToDisabled) {
192
- // Should disable close button
193
- this.ariaLiveMessage = disableCloseButtonMessage;
194
- this.showAriaLiveMessage = true;
195
- synchronizeAttrs(this.modalWrapper, { [`${ARIA.BUSY}`]: true });
196
- synchronizeAttrs(this.modalCloseButton, { disabled: 'disabled' });
197
- this.disableCloseButton = true;
198
- } else {
199
- // Should enable close button
200
- this.ariaLiveMessage = disableCloseBtnMessage;
201
- this.showAriaLiveMessage = false;
202
- synchronizeAttrs(this.modalWrapper, { [`${ARIA.BUSY}`]: null });
203
- synchronizeAttrs(this.modalCloseButton, { disabled: null });
204
- this.disableCloseButton = false;
205
- }
206
- }
207
-
208
165
  /**
209
166
  * Public method to get the modal slot element
210
167
  * @type {(HTMLElement|null)} The modal slot, currently a div elem
@@ -354,35 +311,99 @@ export default class LightningModalBase extends LightningShadowBaseClass {
354
311
  return classes.toString();
355
312
  }
356
313
 
314
+ get isDescriptionSet() {
315
+ const { description } = this;
316
+ // check for being set, as well as not just a description with spaces
317
+ // avoiding setting aria-describedby on section pointing to
318
+ // an empty SPAN element
319
+ return !!description?.trim().length;
320
+ }
321
+
357
322
  /**
358
- * Compute the correct lightning-button-icon CSS class to use
359
- * for the size="full" behaviors, based upon the screen size
360
- * threshold. Two classes are added for full screen behavior
361
- * to handle edge cases where customers change background of the
362
- * modal header so the close button maintains visibility for a11y
323
+ * Determines if aria-describedby should be set, and the span tag shown
324
+ * occurs only when aria-description is not supported.
325
+ * ex: when description api is set to '' or ' ',
326
+ * we don't want to show the span or set aria-describedby
363
327
  * @private
364
328
  */
365
- // slds-button slds-button_icon slds-modal__close slds-button_icon-inverse
366
- get computedCloseButtonCssClass() {
367
- let classes = classSet('slds-modal__close');
368
- const fullScreenActive =
369
- this.isSmallScreenSize && this.size === SIZE_FULL;
370
- classes.add({
371
- 'slds-modal_full-close-button': fullScreenActive,
372
- });
373
- return classes.toString();
329
+ get showAriaDescribedBy() {
330
+ return !isAriaDescriptionSupported() && this.isDescriptionSet;
374
331
  }
375
332
 
376
333
  /**
377
- * Compute the correct lightning-button-icon variant to use
378
- * for the size="full" behaviors, based upon the screen size
379
- * threshold. Important to maintain existing close button behavior
380
- * when size 'small', 'medium' and 'large' close button variant
381
- * when 'isSmallScreenSize = true' for a11y purposes
334
+ * When window is resizing, need to debounce callback
335
+ * Track internal variable _resizing
336
+ * @returns {Boolean}
382
337
  * @private
383
338
  */
384
- get computedCloseButtonVariant() {
385
- return this.shouldModalBeFullScreen() ? 'bare' : 'bare-inverse';
339
+ get modalResizing() {
340
+ if (!this._resizing) {
341
+ this._resizing = this.scheduleWindowResizeEvent.bind(this);
342
+ }
343
+ return this._resizing;
344
+ }
345
+
346
+ /**
347
+ * Toggle on and off disable close button feature
348
+ * typically used very briefly when devs want to save form data to backend
349
+ * and do not want the form to be closed before the save has
350
+ * completed successfully
351
+ * toggleDisableCloseButton sets local state to
352
+ * (a) toggle display an aria-live message
353
+ * (b) toggle set disabled on the <lightning-button-icon>
354
+ * (c) toggle set aria-busy value on
355
+ * elsewhere in modalBase and modal, ESC key is also disabled, and
356
+ * calls to this.close() are prevented
357
+ */
358
+ toggleDisableCloseButton() {
359
+ // this.disableCloseButton is local modalBase state
360
+ // this.disableClose is modal.js @api state
361
+ // we track both in order to handle transition correctly
362
+ const isSwitchingToDisabled =
363
+ !this.disableCloseButton && this.disableClose;
364
+ /* Future enhancement possibility - trigger setInterval to remove and
365
+ again add back 'Processing' text, as this will indicate to the screen
366
+ reader user that the interface continues to be busy
367
+ */
368
+ const disableCloseButtonMessage = isSwitchingToDisabled
369
+ ? this.disableCloseBtnMessage
370
+ : '';
371
+
372
+ const closeButtonDisable = isSwitchingToDisabled ? 'disabled' : null;
373
+
374
+ // Finally, set accessibility attributes for modal-base
375
+ if (isSwitchingToDisabled) {
376
+ // Should disable close button
377
+ this.ariaLiveMessage = disableCloseButtonMessage;
378
+ this.showAriaLiveMessage = true;
379
+ synchronizeAttrs(this.modalWrapper, { [`${ARIA.BUSY}`]: true });
380
+ this.disableCloseButton = true;
381
+ } else {
382
+ // Should enable close button
383
+ this.ariaLiveMessage = disableCloseButtonMessage;
384
+ this.showAriaLiveMessage = false;
385
+ synchronizeAttrs(this.modalWrapper, { [`${ARIA.BUSY}`]: null });
386
+ this.disableCloseButton = false;
387
+ }
388
+
389
+ // Modal with Header variant has close button icon on lightning-modal-header child component
390
+ // where-as Headless Modal variant has close button icon on modal-base,
391
+ if (!this.isHeadlessModalVariant) {
392
+ // dispatch secondary event to disable close button icon present on lightning-modal-header
393
+ this.headerTitleRef.dispatchEvent(
394
+ new CustomEvent('privatemodalheaderdisableclose', {
395
+ detail: {
396
+ disableClose: isSwitchingToDisabled,
397
+ [secure]: true,
398
+ },
399
+ bubbles: true,
400
+ })
401
+ );
402
+ } else {
403
+ synchronizeAttrs(this.modalCloseButton, {
404
+ disabled: closeButtonDisable,
405
+ });
406
+ }
386
407
  }
387
408
 
388
409
  /**
@@ -447,50 +468,10 @@ export default class LightningModalBase extends LightningShadowBaseClass {
447
468
  * </ul>
448
469
  * @param e - Event
449
470
  */
450
- handleFocusinEvents(e) {
471
+ handleFocusinEvents() {
451
472
  // eslint-disable-next-line @lwc/lwc/no-async-operation
452
473
  requestAnimationFrame(() => {
453
- e.preventDefault();
454
- e.stopPropagation();
455
-
456
- const focusinEvtTarget = e.target;
457
- const isFocusTargetAModal =
458
- focusinEvtTarget.matches(OVERLAY_CONTAINER);
459
- const wasANewModalStackedOnTopOfAnExistingModal =
460
- this.isStackedModal() &&
461
- this.savedInertElements.length >
462
- this.previousSavedInertElementsSize;
463
-
464
- if (wasANewModalStackedOnTopOfAnExistingModal) {
465
- // update private tracker in anticipation of more stacked modals
466
- this.previousSavedInertElementsSize =
467
- this.savedInertElements.length;
468
- }
469
-
470
- // 1. If focus is on a Modal, then track the last focussed element
471
- if (isFocusTargetAModal) {
472
- // Perf optimization: check if allTabbableElements needs updating
473
- if (
474
- !this.allTabbableElements ||
475
- wasANewModalStackedOnTopOfAnExistingModal
476
- ) {
477
- this.allTabbableElements =
478
- findAllTabbableElements(focusinEvtTarget);
479
- }
480
- const elementWithFocus = getElementWithFocus();
481
- const isModalTitleText =
482
- elementWithFocus.hasAttribute('data-label');
483
- if (
484
- isModalTitleText ||
485
- this.allTabbableElements.indexOf(elementWithFocus) !== -1
486
- ) {
487
- // element is part of the Modal with current focus on it, track it
488
- this.lastFocussedElementOnModal = elementWithFocus;
489
- }
490
- } // 2. If focus moved out of Modal, return focus to last element that was focussed.
491
- else {
492
- returnFocusToElement(this.lastFocussedElementOnModal);
493
- }
474
+ // W-14998924 note: code revert to unblock 250R downstream
494
475
  });
495
476
  }
496
477
 
@@ -541,25 +522,6 @@ export default class LightningModalBase extends LightningShadowBaseClass {
541
522
  }
542
523
  };
543
524
 
544
- get isDescriptionSet() {
545
- const { description } = this;
546
- // check for being set, as well as not just a description with spaces
547
- // avoiding setting aria-describedby on section pointing to
548
- // an empty SPAN element
549
- return description && description.trim().length > 0;
550
- }
551
-
552
- /**
553
- * Determines if aria-describedby should be set, and the span tag shown
554
- * occurs only when aria-description is not supported.
555
- * ex: when description api is set to '' or ' ',
556
- * we don't want to show the span or set aria-describedby
557
- * @private
558
- */
559
- get showAriaDescribedBy() {
560
- return !isAriaDescriptionSupported() && this.isDescriptionSet;
561
- }
562
-
563
525
  /**
564
526
  * Set either 'aria-describedby' or 'aria-description' value for accessibility
565
527
  * based on the presence of 'description' api value
@@ -648,6 +610,19 @@ export default class LightningModalBase extends LightningShadowBaseClass {
648
610
  console.error(errorMsg);
649
611
  }
650
612
 
613
+ /**
614
+ * Handle close button click triggered from lightning-modal-header
615
+ * @param e
616
+ */
617
+ handleModalHeaderCloseClick(e) {
618
+ if (!e?.detail?.[secure]) {
619
+ console.error('Invalid access to privatemodalheaderclose event');
620
+ return;
621
+ }
622
+ e.stopPropagation();
623
+ this.handleCloseClick();
624
+ }
625
+
651
626
  /**
652
627
  * Handle the close button click, or via ESC key
653
628
  * @private
@@ -659,8 +634,11 @@ export default class LightningModalBase extends LightningShadowBaseClass {
659
634
  }
660
635
  }
661
636
 
662
- // Handle privateclose event firing is prevented from occurring
663
- // when this.disableClose set true in modal.js
637
+ /**
638
+ * Handle privateclose event firing is prevented from occurring
639
+ * when this.disableClose set true in modal.js
640
+ * @param e
641
+ */
664
642
  handlePrivateClose(e) {
665
643
  if (!(e.detail && e.detail[secure])) {
666
644
  console.error('Invalid access to privateclose event');
@@ -701,6 +679,7 @@ export default class LightningModalBase extends LightningShadowBaseClass {
701
679
  console.error('Invalid access to privatedisableclose event');
702
680
  return;
703
681
  }
682
+
704
683
  this.toggleDisableCloseButton();
705
684
  }
706
685
 
@@ -871,6 +850,20 @@ export default class LightningModalBase extends LightningShadowBaseClass {
871
850
  if (!this.focusinEventBound) {
872
851
  this.addFocusinEventListener();
873
852
  }
853
+
854
+ this.updateHeadlessModalVariantState();
855
+ }
856
+
857
+ /**
858
+ * In case of a headless modal variant, the close button icon lives inside modalBase,
859
+ * while in other variants, the close icon lives inside lightning-modal-header
860
+ *
861
+ * This helper method is to accurately update the state of 'isHeadlessModalVariant' flag
862
+ * in order to selectively render the close <lightning-button-icon> in modalBase.html
863
+ */
864
+ updateHeadlessModalVariantState() {
865
+ this.isHeadlessModalVariant =
866
+ this.bodyRegistered && !this.headerRegistered;
874
867
  }
875
868
 
876
869
  /**
@@ -948,6 +941,8 @@ export default class LightningModalBase extends LightningShadowBaseClass {
948
941
  if (this.bodyRegistered) {
949
942
  this.updateModalBodyHeight();
950
943
  }
944
+
945
+ this.updateHeadlessModalVariantState();
951
946
  }
952
947
 
953
948
  /**
@@ -977,6 +972,7 @@ export default class LightningModalBase extends LightningShadowBaseClass {
977
972
  this.headerLabelId = null;
978
973
  this.headerLabelIsPopulated = null;
979
974
  this.headerTitleRef = null;
975
+ this.updateHeadlessModalVariantState();
980
976
  }
981
977
 
982
978
  /**
@@ -1019,6 +1015,8 @@ export default class LightningModalBase extends LightningShadowBaseClass {
1019
1015
  if (this.bodyRegistered) {
1020
1016
  this.updateModalBodyHeight();
1021
1017
  }
1018
+
1019
+ this.updateHeadlessModalVariantState();
1022
1020
  }
1023
1021
 
1024
1022
  /**
@@ -1045,19 +1043,6 @@ export default class LightningModalBase extends LightningShadowBaseClass {
1045
1043
  this.footerDefaultSlotIsPopulated = false;
1046
1044
  }
1047
1045
 
1048
- /**
1049
- * When window is resizing, need to debounce callback
1050
- * Track internal variable _resizing
1051
- * @returns {Boolean}
1052
- * @private
1053
- */
1054
- get modalResizing() {
1055
- if (!this._resizing) {
1056
- this._resizing = this.scheduleWindowResizeEvent.bind(this);
1057
- }
1058
- return this._resizing;
1059
- }
1060
-
1061
1046
  /**
1062
1047
  * Test to determine whether modal should display full screen behavior
1063
1048
  * @returns {Boolean}
@@ -1 +1,7 @@
1
1
  @import './modalBody.lbc.native.css';
2
+
3
+ /* Styles required for Multi-Column Sorting Modal in datatable */
4
+ :host(.modal_headerless) .slds-modal__content_headless {
5
+ border-top-right-radius: unset;
6
+ border-top-left-radius: unset;
7
+ }
@@ -1,13 +1,25 @@
1
- <template>
2
- <div class="slds-modal__header" part="modal-header">
1
+ <template>
2
+ <div class="slds-modal__header slds-text-align_left" part="modal-header"
3
+ onprivatemodalheaderdisableclose={handlePrivateModalHeaderDisableClose}
4
+ >
3
5
  <template if:true={label}>
4
6
  <h1
5
- id="modal-label"
6
7
  class="slds-modal__title slds-hyphenate"
7
- tabindex="-1"
8
8
  data-label
9
+ id="modal-label"
10
+ tabindex="-1"
9
11
  >{label}</h1>
10
12
  </template>
13
+ <lightning-button-icon
14
+ alternative-text={headerCloseButtonAltText}
15
+ class="slds-modal__close"
16
+ data-header-close-button
17
+ disabled={disableCloseButton}
18
+ icon-name="utility:close"
19
+ onclick={handleModalHeaderClose}
20
+ size="large"
21
+ variant="bare"
22
+ ></lightning-button-icon>
11
23
  <slot
12
24
  data-default-slot
13
25
  onslotchange={handleDefaultSlotChange}
@@ -1,12 +1,15 @@
1
1
  import { api } from 'lwc';
2
2
  import LightningShadowBaseClass from 'lightning/shadowBaseClassPrivate';
3
- import { getRealDOMId } from 'lightning/utilsPrivate';
3
+ import { getRealDOMId, synchronizeAttrs } from 'lightning/utilsPrivate';
4
+ import { secure } from 'lightning/overlayUtils';
5
+ import closeButtonAltText from '@salesforce/label/LightningModalBase.cancelandclose';
4
6
 
5
7
  // selectors
6
8
  const modalHeaderSelector = '.slds-modal__header';
7
9
  const labelSelector = '[data-label]';
8
10
  const slotWrapperSelector = '[data-slot-wrapper]';
9
11
  const defaultSlotSelector = '[data-default-slot]';
12
+ const headerCloseButtonSelector = '[data-header-close-button]';
10
13
 
11
14
  /**
12
15
  * Creates a header to display the heading and tagline at the top of a modal.
@@ -16,25 +19,13 @@ export default class LightningModalHeader extends LightningShadowBaseClass {
16
19
  initialRender = true;
17
20
  initialSlotRender = true;
18
21
  unregisterCallback = null;
22
+ headerCloseButtonAltText = closeButtonAltText;
19
23
 
20
24
  /**
21
25
  * Text to display as the heading at the top of the modal
22
26
  */
23
27
  @api label = '';
24
28
 
25
- /**
26
- * Handle the default slot change event
27
- * Always register with parent every slot change
28
- * @private
29
- */
30
- handleDefaultSlotChange() {
31
- // Set this once so that parent can know slot has rendered
32
- if (this.initialSlotRender) {
33
- this.initialSlotRender = false;
34
- }
35
- this.registerWithParent();
36
- }
37
-
38
29
  /**
39
30
  * Get the height of outer wrapper of modal header
40
31
  * @returns {number} represents a height value in pixels
@@ -125,6 +116,62 @@ export default class LightningModalHeader extends LightningShadowBaseClass {
125
116
  return (this.label && this.label.trim().length > 0) || false;
126
117
  }
127
118
 
119
+ /**
120
+ * Get the lightning-button-icon (close button element)
121
+ * @returns {(HTMLElement|null)}
122
+ * @private
123
+ */
124
+ get headerCloseButton() {
125
+ return this.template.querySelector(headerCloseButtonSelector);
126
+ }
127
+
128
+ /**
129
+ * Handle the default slot change event
130
+ * Always register with parent every slot change
131
+ * @private
132
+ */
133
+ handleDefaultSlotChange() {
134
+ // Set this once so that parent can know slot has rendered
135
+ if (this.initialSlotRender) {
136
+ this.initialSlotRender = false;
137
+ }
138
+ this.registerWithParent();
139
+ }
140
+
141
+ /**
142
+ * Toggle set disabled on the <lightning-button-icon> present inside lightning-modal-header
143
+ * @param e
144
+ */
145
+ handlePrivateModalHeaderDisableClose(e) {
146
+ if (!e?.detail?.[secure]) {
147
+ console.error(
148
+ 'Invalid access to privatemodalheaderdisableclose event'
149
+ );
150
+ return;
151
+ }
152
+ e.stopPropagation();
153
+
154
+ const closeButtonDisable = e.detail?.disableClose ? 'disabled' : null;
155
+
156
+ synchronizeAttrs(this.headerCloseButton, {
157
+ disabled: closeButtonDisable,
158
+ });
159
+ }
160
+
161
+ /**
162
+ * Handle close click on close <lightning-button-icon>
163
+ */
164
+ handleModalHeaderClose() {
165
+ const closeEvt = new CustomEvent('privatemodalheaderclose', {
166
+ bubbles: true,
167
+ composed: true,
168
+ detail: {
169
+ [secure]: true,
170
+ },
171
+ });
172
+ this.dispatchEvent(closeEvt);
173
+ }
174
+
128
175
  /**
129
176
  * Register modalHeader with modal parent, including callbacks to
130
177
  * unregister the modal header
@@ -33,6 +33,7 @@
33
33
  <lightning-button-icon
34
34
  icon-name="utility:close"
35
35
  class="slds-pill__remove"
36
+ exportparts="button-icon, icon"
36
37
  variant="bare"
37
38
  onclick={handleRemove}
38
39
  title={computedPillRemoveLabel}
@@ -9,6 +9,7 @@
9
9
  <lightning-button-icon
10
10
  icon-name="utility:close"
11
11
  class="slds-pill__remove"
12
+ exportparts="button-icon, icon"
12
13
  variant="bare"
13
14
  onclick={handleRemoveClick}
14
15
  title={computedPillRemoveLabel}
@@ -18,6 +18,7 @@
18
18
  <lightning-button-icon
19
19
  icon-name="utility:close"
20
20
  class="slds-pill__remove"
21
+ exportparts="button-icon, icon"
21
22
  variant="bare"
22
23
  onclick={handleRemoveClick}
23
24
  title={computedPillRemoveLabel}
@@ -9,6 +9,16 @@ const DEFAULT_ALIGN = {
9
9
  vertical: 'bottom',
10
10
  };
11
11
 
12
+ const DEFAULT_INVISIBLE_DIV_STYLES = {
13
+ height: '1.5rem',
14
+ position: 'absolute',
15
+ left: '0',
16
+ marginLeft: '0',
17
+ // add a little bit of offset to move the <div> closer to the target, that way the mouse
18
+ // doesn't move into the small white space between the target and <div>, which would close the tooltip
19
+ top: '-1.1rem',
20
+ };
21
+
12
22
  export default class LightningPrimitiveBubble extends LightningShadowBaseClass {
13
23
  @track
14
24
  state = {
@@ -54,6 +64,7 @@ export default class LightningPrimitiveBubble extends LightningShadowBaseClass {
54
64
  // - this is required to avoid the content update being in the wrong 'tick'
55
65
  this.setContentManually();
56
66
  this.setIdManually();
67
+ this.createInvisibleDivManually();
57
68
  }
58
69
 
59
70
  set content(value) {
@@ -109,6 +120,37 @@ export default class LightningPrimitiveBubble extends LightningShadowBaseClass {
109
120
  this.state.content;
110
121
  }
111
122
 
123
+ // manually create <div>, add positional styling, and append as child to bubble
124
+ createInvisibleDivManually() {
125
+ if (this.state.visible) {
126
+ const popoverBody = this.template.querySelector(
127
+ '.slds-popover__body'
128
+ );
129
+ const invisibleDiv = document.createElement('div');
130
+
131
+ let computedStyle = null;
132
+ if (window && popoverBody) {
133
+ computedStyle = window.getComputedStyle(popoverBody);
134
+ invisibleDiv.style.width =
135
+ computedStyle.getPropertyValue('width');
136
+ }
137
+
138
+ invisibleDiv.style.height = DEFAULT_INVISIBLE_DIV_STYLES.height;
139
+ invisibleDiv.style.position = DEFAULT_INVISIBLE_DIV_STYLES.position;
140
+ invisibleDiv.style.left = DEFAULT_INVISIBLE_DIV_STYLES.left;
141
+ invisibleDiv.style.marginLeft =
142
+ DEFAULT_INVISIBLE_DIV_STYLES.marginLeft;
143
+
144
+ const { vertical } = this.align;
145
+
146
+ // position <div> based on vertical alignment
147
+ invisibleDiv.style.top =
148
+ vertical === 'top' ? DEFAULT_INVISIBLE_DIV_STYLES.top : '';
149
+
150
+ popoverBody.appendChild(invisibleDiv);
151
+ }
152
+ }
153
+
112
154
  // compute class value for this bubble
113
155
  get computedPopoverClass() {
114
156
  const classes = classSet('slds-popover')
@@ -60,7 +60,7 @@ export default class PrimitiveDatatableCell extends LightningElement {
60
60
  if (editActionElement) {
61
61
  editActionElement.click();
62
62
  }
63
- } else if (actionableElements.length >= 1) {
63
+ } else if (actionableElements.length === 1) {
64
64
  const elem = actionableElements[0];
65
65
  let defaultActions = elem.getAttribute('data-action-triggers');
66
66
  defaultActions = defaultActions || '';
@@ -4,7 +4,7 @@
4
4
  id="primitive-header-action-button-menu-id"
5
5
  icon-size="x-small"
6
6
  menu-alignment={_actionMenuAlignment}
7
- alternative-text={i18n.showActions}
7
+ alternative-text={alternativeText}
8
8
  variant="bare"
9
9
  onopen={handleMenuOpen}
10
10
  onclose={handleMenuClose}
@@ -3,6 +3,7 @@ import labelShowActions from '@salesforce/label/LightningDatatable.showActions';
3
3
  import labelWrapText from '@salesforce/label/LightningDatatable.wrapText';
4
4
  import { LightningElement, api, track } from 'lwc';
5
5
  import { deepCopy } from 'lightning/utilsPrivate';
6
+ import { formatLabel } from 'lightning/utils';
6
7
 
7
8
  const i18n = {
8
9
  clipText: labelClipText,
@@ -42,6 +43,14 @@ export default class PrimitiveHeaderActions extends LightningElement {
42
43
  this.updateActions();
43
44
  }
44
45
 
46
+ /**
47
+ * Defines the label of the column header
48
+ *
49
+ * @type {String}
50
+ */
51
+
52
+ @api columnHeader;
53
+
45
54
  /************************** PUBLIC METHODS ***************************/
46
55
 
47
56
  /**
@@ -195,4 +204,8 @@ export default class PrimitiveHeaderActions extends LightningElement {
195
204
  getActionsByType(type) {
196
205
  return Array.isArray(this._actions[type]) ? this._actions[type] : [];
197
206
  }
207
+
208
+ get alternativeText() {
209
+ return formatLabel(i18n.showActions, this.columnHeader || '');
210
+ }
198
211
  }