lightning-base-components 1.14.3-alpha → 1.14.7-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 (144) hide show
  1. package/metadata/raptor.json +37 -4
  2. package/package.json +11 -4
  3. package/scopedImports/@salesforce-label-LightningModalBase.cancelandclose.js +1 -0
  4. package/scopedImports/@salesforce-label-LightningProgressBar.progressBar.js +1 -0
  5. package/src/lightning/alert/__docs__/alert.md +101 -0
  6. package/src/lightning/alert/__examples__disabled/basic/basic.css +7 -0
  7. package/src/lightning/alert/__examples__disabled/basic/basic.html +8 -0
  8. package/src/lightning/alert/__examples__disabled/basic/basic.js +14 -0
  9. package/src/lightning/alert/alert.html +3 -0
  10. package/src/lightning/alert/alert.js +78 -0
  11. package/src/lightning/alert/alert.js-meta.xml +6 -0
  12. package/src/lightning/ariaObserver/__component__/ariaObserver.spec.js +9 -0
  13. package/src/lightning/ariaObserver/ariaObserver.js +24 -35
  14. package/src/lightning/baseFormattedText/baseFormattedText.html +6 -1
  15. package/src/lightning/baseFormattedText/baseFormattedText.js +5 -0
  16. package/src/lightning/buttonMenu/buttonMenu.js +12 -0
  17. package/src/lightning/confirm/__docs__/confirm.md +100 -0
  18. package/src/lightning/confirm/__examples__disabled/basic/basic.css +7 -0
  19. package/src/lightning/confirm/__examples__disabled/basic/basic.html +8 -0
  20. package/src/lightning/confirm/__examples__disabled/basic/basic.js +14 -0
  21. package/src/lightning/confirm/confirm.html +3 -0
  22. package/src/lightning/confirm/confirm.js +80 -0
  23. package/src/lightning/confirm/confirm.js-meta.xml +6 -0
  24. package/src/lightning/datatable/__examples__/withInfiniteLoading/fetchDataHelper.js +21 -0
  25. package/src/lightning/datatable/__examples__/withInfiniteLoading/withInfiniteLoading.html +13 -0
  26. package/src/lightning/datatable/__examples__/withInfiniteLoading/withInfiniteLoading.js +42 -0
  27. package/src/lightning/datatable/autoWidthStrategy.js +170 -61
  28. package/src/lightning/datatable/{resizer.js → columnResizer.js} +0 -0
  29. package/src/lightning/datatable/columnWidthManager.js +226 -44
  30. package/src/lightning/datatable/columns.js +166 -71
  31. package/src/lightning/datatable/datatable.js +132 -60
  32. package/src/lightning/datatable/fixedWidthStrategy.js +43 -8
  33. package/src/lightning/datatable/headerActions.js +2 -2
  34. package/src/lightning/datatable/infiniteLoading.js +100 -28
  35. package/src/lightning/datatable/inlineEdit.js +21 -30
  36. package/src/lightning/datatable/keyboard.js +166 -131
  37. package/src/lightning/datatable/renderManager.js +117 -122
  38. package/src/lightning/datatable/{datatableResizeObserver.js → resizeObserver.js} +46 -29
  39. package/src/lightning/datatable/resizeSensor.js +19 -3
  40. package/src/lightning/datatable/rowSelection.js +1 -1
  41. package/src/lightning/datatable/rowSelectionShared.js +33 -20
  42. package/src/lightning/datatable/rows.js +7 -8
  43. package/src/lightning/datatable/sort.js +8 -8
  44. package/src/lightning/datatable/state.js +14 -2
  45. package/src/lightning/datatable/templates/div/div.html +127 -117
  46. package/src/lightning/datatable/templates/table/table.html +5 -0
  47. package/src/lightning/datatable/tree.js +25 -0
  48. package/src/lightning/datatable/types.js +77 -9
  49. package/src/lightning/datatable/utils.js +51 -24
  50. package/src/lightning/datatable/virtualization.js +319 -0
  51. package/src/lightning/datatable/widthManagerShared.js +27 -3
  52. package/src/lightning/datatable/wrapText.js +115 -48
  53. package/src/lightning/formattedDateTime/__docs__/formattedDateTime.md +36 -3
  54. package/src/lightning/formattedDateTime/__examples__/datetime/datetime.html +2 -2
  55. package/src/lightning/formattedDateTime/__examples__/datetime/datetime.js +3 -1
  56. package/src/lightning/formattedDateTime/__examples__/time/time.html +1 -1
  57. package/src/lightning/formattedDateTime/__examples__/time/time.js +3 -1
  58. package/src/lightning/formattedDateTime/formattedDateTime.js +1 -0
  59. package/src/lightning/iconSvgTemplates/buildTemplates/standard/dashboard_component.html +7 -0
  60. package/src/lightning/iconSvgTemplates/buildTemplates/standard/slack.html +7 -0
  61. package/src/lightning/iconSvgTemplates/buildTemplates/standard/tableau.html +7 -0
  62. package/src/lightning/iconSvgTemplates/buildTemplates/standard/travel_mode.html +2 -2
  63. package/src/lightning/iconSvgTemplates/buildTemplates/templates.js +8 -1
  64. package/src/lightning/iconSvgTemplates/buildTemplates/utility/data_model.html +7 -0
  65. package/src/lightning/iconSvgTemplates/buildTemplates/utility/serialized_product.html +1 -1
  66. package/src/lightning/iconSvgTemplates/buildTemplates/utility/serialized_product_transaction.html +2 -1
  67. package/src/lightning/iconSvgTemplates/buildTemplates/utility/slack.html +7 -0
  68. package/src/lightning/iconSvgTemplates/buildTemplates/utility/tableau.html +7 -0
  69. package/src/lightning/iconSvgTemplates/buildTemplates/utility/video_off.html +7 -0
  70. package/src/lightning/iconSvgTemplatesRtl/buildTemplates/standard/dashboard_component.html +7 -0
  71. package/src/lightning/iconSvgTemplatesRtl/buildTemplates/standard/slack.html +7 -0
  72. package/src/lightning/iconSvgTemplatesRtl/buildTemplates/standard/tableau.html +7 -0
  73. package/src/lightning/iconSvgTemplatesRtl/buildTemplates/standard/travel_mode.html +2 -2
  74. package/src/lightning/iconSvgTemplatesRtl/buildTemplates/templates.js +8 -1
  75. package/src/lightning/iconSvgTemplatesRtl/buildTemplates/utility/data_model.html +7 -0
  76. package/src/lightning/iconSvgTemplatesRtl/buildTemplates/utility/serialized_product.html +1 -1
  77. package/src/lightning/iconSvgTemplatesRtl/buildTemplates/utility/serialized_product_transaction.html +2 -1
  78. package/src/lightning/iconSvgTemplatesRtl/buildTemplates/utility/slack.html +7 -0
  79. package/src/lightning/iconSvgTemplatesRtl/buildTemplates/utility/tableau.html +7 -0
  80. package/src/lightning/iconSvgTemplatesRtl/buildTemplates/utility/video_off.html +7 -0
  81. package/src/lightning/iconSvgTemplatesStandard/buildTemplates/standard/dashboard_component.html +7 -0
  82. package/src/lightning/iconSvgTemplatesStandard/buildTemplates/standard/slack.html +7 -0
  83. package/src/lightning/iconSvgTemplatesStandard/buildTemplates/standard/tableau.html +7 -0
  84. package/src/lightning/iconSvgTemplatesStandard/buildTemplates/standard/travel_mode.html +2 -2
  85. package/src/lightning/iconSvgTemplatesStandard/buildTemplates/templates.js +4 -1
  86. package/src/lightning/iconSvgTemplatesStandardRtl/buildTemplates/standard/dashboard_component.html +7 -0
  87. package/src/lightning/iconSvgTemplatesStandardRtl/buildTemplates/standard/slack.html +7 -0
  88. package/src/lightning/iconSvgTemplatesStandardRtl/buildTemplates/standard/tableau.html +7 -0
  89. package/src/lightning/iconSvgTemplatesStandardRtl/buildTemplates/standard/travel_mode.html +2 -2
  90. package/src/lightning/iconSvgTemplatesStandardRtl/buildTemplates/templates.js +4 -1
  91. package/src/lightning/iconSvgTemplatesUtility/buildTemplates/templates.js +5 -1
  92. package/src/lightning/iconSvgTemplatesUtility/buildTemplates/utility/data_model.html +7 -0
  93. package/src/lightning/iconSvgTemplatesUtility/buildTemplates/utility/serialized_product.html +1 -1
  94. package/src/lightning/iconSvgTemplatesUtility/buildTemplates/utility/serialized_product_transaction.html +2 -1
  95. package/src/lightning/iconSvgTemplatesUtility/buildTemplates/utility/slack.html +7 -0
  96. package/src/lightning/iconSvgTemplatesUtility/buildTemplates/utility/tableau.html +7 -0
  97. package/src/lightning/iconSvgTemplatesUtility/buildTemplates/utility/video_off.html +7 -0
  98. package/src/lightning/iconSvgTemplatesUtilityRtl/buildTemplates/templates.js +5 -1
  99. package/src/lightning/iconSvgTemplatesUtilityRtl/buildTemplates/utility/data_model.html +7 -0
  100. package/src/lightning/iconSvgTemplatesUtilityRtl/buildTemplates/utility/serialized_product.html +1 -1
  101. package/src/lightning/iconSvgTemplatesUtilityRtl/buildTemplates/utility/serialized_product_transaction.html +2 -1
  102. package/src/lightning/iconSvgTemplatesUtilityRtl/buildTemplates/utility/slack.html +7 -0
  103. package/src/lightning/iconSvgTemplatesUtilityRtl/buildTemplates/utility/tableau.html +7 -0
  104. package/src/lightning/iconSvgTemplatesUtilityRtl/buildTemplates/utility/video_off.html +7 -0
  105. package/src/lightning/input/__docs__/input.md +2 -0
  106. package/src/lightning/input/input.html +2 -5
  107. package/src/lightning/interactiveDialogBase/interactiveDialogBase.css +494 -0
  108. package/src/lightning/interactiveDialogBase/interactiveDialogBase.html +63 -0
  109. package/src/lightning/interactiveDialogBase/interactiveDialogBase.js +200 -0
  110. package/src/lightning/menuItem/menuItem.js +4 -1
  111. package/src/lightning/modalBase/modalBase.css +20 -0
  112. package/src/lightning/modalBase/modalBase.html +54 -0
  113. package/src/lightning/modalBase/modalBase.js +1039 -0
  114. package/src/lightning/overlay/__docs__/overlay.md +90 -0
  115. package/src/lightning/overlay/__examples__/alert/alert.html +27 -0
  116. package/src/lightning/overlay/__examples__/alert/alert.js +33 -0
  117. package/src/lightning/overlay/__examples__/basic/basic.css +7 -0
  118. package/src/lightning/overlay/__examples__/basic/basic.html +18 -0
  119. package/src/lightning/overlay/__examples__/basic/basic.js +61 -0
  120. package/src/lightning/overlay/__examples__/demo/demo.html +29 -0
  121. package/src/lightning/overlay/__examples__/demo/demo.js +40 -0
  122. package/src/lightning/overlay/__examples__/panel/panel.html +17 -0
  123. package/src/lightning/overlay/__examples__/panel/panel.js +21 -0
  124. package/src/lightning/overlay/overlay.html +3 -0
  125. package/src/lightning/overlay/overlay.js +45 -0
  126. package/src/lightning/overlayContainer/__docs__/overlayContainer.md +0 -0
  127. package/src/lightning/overlayContainer/overlayContainer.html +3 -0
  128. package/src/lightning/overlayContainer/overlayContainer.js +138 -0
  129. package/src/lightning/overlayManager/overlayManager.js +54 -0
  130. package/src/lightning/overlayUtils/overlayUtils.js +17 -0
  131. package/src/lightning/progressBar/progressBar.html +2 -1
  132. package/src/lightning/progressBar/progressBar.js +18 -1
  133. package/src/lightning/prompt/__docs__/prompt.md +102 -0
  134. package/src/lightning/prompt/__examples__disabled/basic/basic.css +7 -0
  135. package/src/lightning/prompt/__examples__disabled/basic/basic.html +8 -0
  136. package/src/lightning/prompt/__examples__disabled/basic/basic.js +15 -0
  137. package/src/lightning/prompt/prompt.css +81 -0
  138. package/src/lightning/prompt/prompt.html +8 -0
  139. package/src/lightning/prompt/prompt.js +92 -0
  140. package/src/lightning/prompt/prompt.js-meta.xml +6 -0
  141. package/src/lightning/spinner/spinner.html +1 -1
  142. package/src/lightning/spinner/spinner.js +12 -0
  143. package/src/lightning/utilsPrivate/phonify.js +1 -1
  144. package/scopedImports/@salesforce-label-LightningModalBase.close.js +0 -1
@@ -49,9 +49,8 @@
49
49
  }
50
50
  ]
51
51
  },
52
- "analyticsDataServiceApi": {
53
- "minVersion": "52.0"
54
- },
52
+ "analyticsDataServiceApi": {},
53
+ "analyticsSmartDataDiscoveryApi": {},
55
54
  "analyticsWaveApi": {
56
55
  "minVersion": "52.0"
57
56
  },
@@ -489,6 +488,7 @@
489
488
  "minVersion": "52.0"
490
489
  },
491
490
  "cmsInternalDeliveryApi": {},
491
+ "cmsOrchestratorApi": {},
492
492
  "cmsTypeApi": {},
493
493
  "combobox": {
494
494
  "minVersion": "0.0",
@@ -858,6 +858,7 @@
858
858
  }
859
859
  ]
860
860
  },
861
+ "flowBuilderApi": {},
861
862
  "flowRuntimeApi": {},
862
863
  "flowSupport": {
863
864
  "minVersion": "0.0"
@@ -1350,17 +1351,23 @@
1350
1351
  },
1351
1352
  "iconUtils": {},
1352
1353
  "industriesCibApi": {},
1354
+ "industriesClmApi": {},
1353
1355
  "industriesDecisionMatrixDesignerApi": {},
1356
+ "industriesEinsteinAIAcceleratorApi": {},
1354
1357
  "industriesExplainabilityApi": {},
1355
1358
  "industriesHealthcloudHpiApi": {},
1356
1359
  "industriesIdentityVerificationApi": {},
1357
1360
  "industriesInterestTaggingApi": {},
1358
1361
  "industriesLoyaltyEngineApi": {},
1362
+ "industriesPublicSectorApi": {},
1359
1363
  "industriesRcgTenantmanagementApi": {},
1360
1364
  "industriesRuleBuilderApi": {},
1365
+ "industriesSustainabilityBeiApi": {},
1366
+ "industriesSustainabilityDgfApi": {},
1361
1367
  "industriesSustainabilityRecalculateApi": {},
1362
1368
  "industriesSustainabilityRecordLockUnlockApi": {},
1363
1369
  "industriesSustainabilityReferenceDataApi": {},
1370
+ "industriesTimelineApi": {},
1364
1371
  "industriesVideoVisitsApi": {},
1365
1372
  "input": {
1366
1373
  "minVersion": "0.0",
@@ -2212,6 +2219,7 @@
2212
2219
  }
2213
2220
  ]
2214
2221
  },
2222
+ "marketingAssetcreationApi": {},
2215
2223
  "menuDivider": {
2216
2224
  "minVersion": "0.0",
2217
2225
  "slotNames": [],
@@ -3395,6 +3403,7 @@
3395
3403
  "uiAssistantPlatformApi": {},
3396
3404
  "uiDuplicatesApi": {},
3397
3405
  "uiLayoutApi": {},
3406
+ "uiLearningContentPlatformApi": {},
3398
3407
  "uiListApi": {
3399
3408
  "minVersion": "45.0"
3400
3409
  },
@@ -3407,12 +3416,36 @@
3407
3416
  },
3408
3417
  "uiRecordActionsApi": {},
3409
3418
  "uiRecordApi": {
3410
- "minVersion": "45.0"
3419
+ "minVersion": "46.0"
3411
3420
  },
3412
3421
  "uiRecordAvatarApi": {},
3413
3422
  "uiRelatedListApi": {
3414
3423
  "minVersion": "53.0"
3415
3424
  },
3425
+ "unstable_analyticsDataServiceApi": {},
3426
+ "unstable_analyticsSmartDataDiscoveryApi": {},
3427
+ "unstable_analyticsWaveApi": {},
3428
+ "unstable_analyticsWavePrivateApi": {},
3429
+ "unstable_cmsAuthoringApi": {},
3430
+ "unstable_cmsDeliveryApi": {},
3431
+ "unstable_cmsTypeApi": {},
3432
+ "unstable_commerceApi": {},
3433
+ "unstable_communityNavigationMenuApi": {},
3434
+ "unstable_communityRecordSeoPropertiesApi": {},
3435
+ "unstable_communitySitesSearchApi": {},
3436
+ "unstable_experienceMarketingIntegrationApi": {},
3437
+ "unstable_industriesCibApi": {},
3438
+ "unstable_industriesDecisionMatrixDesignerApi": {},
3439
+ "unstable_industriesExplainabilityApi": {},
3440
+ "unstable_industriesHealthcloudHpiApi": {},
3441
+ "unstable_industriesInterestTaggingApi": {},
3442
+ "unstable_industriesLoyaltyEngineApi": {},
3443
+ "unstable_industriesPublicSectorApi": {},
3444
+ "unstable_industriesRcgTenantmanagementApi": {},
3445
+ "unstable_industriesRuleBuilderApi": {},
3446
+ "unstable_platformAdminSuccessGuidanceApi": {},
3447
+ "unstable_platformInteractionOrchestratorApi": {},
3448
+ "unstable_platformScaleCenterApi": {},
3416
3449
  "unstable_uiActionsApi": {},
3417
3450
  "unstable_uiAppsApi": {},
3418
3451
  "unstable_uiDuplicatesApi": {},
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "lightning-base-components",
3
- "version": "1.14.3-alpha",
3
+ "version": "1.14.7-alpha",
4
4
  "engines": {
5
- "node": ">=12.18.3"
5
+ "node": ">=14.16.0"
6
6
  },
7
7
  "files": [
8
8
  "external",
@@ -309,6 +309,10 @@
309
309
  "name": "@salesforce/label/LightningProgressBar.progress",
310
310
  "path": "scopedImports/@salesforce-label-LightningProgressBar.progress.js"
311
311
  },
312
+ {
313
+ "name": "@salesforce/label/LightningProgressBar.progressBar",
314
+ "path": "scopedImports/@salesforce-label-LightningProgressBar.progressBar.js"
315
+ },
312
316
  {
313
317
  "name": "@salesforce/label/LightningClickToDial.enabled",
314
318
  "path": "scopedImports/@salesforce-label-LightningClickToDial.enabled.js"
@@ -958,8 +962,8 @@
958
962
  "path": "scopedImports/@salesforce-label-LightningRating.nStars.js"
959
963
  },
960
964
  {
961
- "name": "@salesforce/label/LightningModalBase.close",
962
- "path": "scopedImports/@salesforce-label-LightningModalBase.close.js"
965
+ "name": "@salesforce/label/LightningModalBase.cancelandclose",
966
+ "path": "scopedImports/@salesforce-label-LightningModalBase.cancelandclose.js"
963
967
  },
964
968
  {
965
969
  "name": "@salesforce/label/LightningModalBase.waitstate",
@@ -1085,6 +1089,7 @@
1085
1089
  "expose": [
1086
1090
  "lightning/accordion",
1087
1091
  "lightning/accordionSection",
1092
+ "lightning/alert",
1088
1093
  "lightning/avatar",
1089
1094
  "lightning/badge",
1090
1095
  "lightning/baseFormattedText",
@@ -1102,6 +1107,7 @@
1102
1107
  "lightning/checkboxGroup",
1103
1108
  "lightning/combobox",
1104
1109
  "lightning/configProvider",
1110
+ "lightning/confirm",
1105
1111
  "lightning/context",
1106
1112
  "lightning/datatable",
1107
1113
  "lightning/datatableKeyboardMixins",
@@ -1158,6 +1164,7 @@
1158
1164
  "lightning/progressIndicator",
1159
1165
  "lightning/progressRing",
1160
1166
  "lightning/progressStep",
1167
+ "lightning/prompt",
1161
1168
  "lightning/purifyLib",
1162
1169
  "lightning/radioGroup",
1163
1170
  "lightning/relativeDateTime",
@@ -0,0 +1 @@
1
+ export default 'Cancel and close';
@@ -0,0 +1 @@
1
+ export default 'Progress Bar';
@@ -0,0 +1,101 @@
1
+ The `lightning/alert` module lets you create an alert modal within your component. Use `LightningAlert` on your components to communicate a state that affects the entire system, not just a feature or page.
2
+
3
+ `lightning/alert` is not supported on mobile devices.
4
+
5
+ Use `LightningAlert.open()` instead of the native `window.alert()` for a more consistent user experience. They have similar functions, but `LightningAlert.open()` works in cross-origin iframes, where the `.alert()` method is no longer supported in Chrome and Safari. Unlike `window.alert()`, `LightningAlert.open()` doesn't halt execution on the page, it returns a Promise. Use `async`/`await` or `.then()` for any code you want to execute after the alert has closed.
6
+
7
+ Import `LightningAlert` from the `lightning/alert` module in the component that will launch the alert modal, and call `LightningAlert.open()` with your desired attributes.
8
+
9
+ This example creates an alert modal with an error message and **OK** button. The `.open()` function returns a promise that resolves when you click **OK**.
10
+
11
+ ```html
12
+ <!-- c/myApp.html -->
13
+ <template>
14
+ <lightning-button onclick="{handleAlertClick}" label="Open Alert Modal">
15
+ </lightning-button>
16
+ </template>
17
+ ```
18
+
19
+ ```javascript
20
+ import { LightningElement } from 'lwc';
21
+ import LightningAlert from 'lightning/alert';
22
+
23
+ export default class MyApp extends LightningElement {
24
+ async handleAlertClick() {
25
+ await LightningAlert.open({
26
+ message: 'this is the alert message',
27
+ theme: 'error', // a red theme intended for error states
28
+ label: 'Error!', // this is the header text
29
+ });
30
+ //Alert has been closed
31
+ }
32
+ }
33
+ ```
34
+
35
+ #### Component Styling
36
+
37
+ This component uses the Salesforce Lightning Design System (SLDS) [`prompt` blueprint](https://www.lightningdesignsystem.com/components/prompt/#site-main-content).
38
+
39
+ `LightningAlert` supports the following attributes:
40
+
41
+ - `message`: Message text that displays in the alert.
42
+ - `label`: Header text, also used as the `aria-label`. Default string is `Alert`.
43
+ - `variant`: Two values, `header` and `headerless`. Default value is `header`.
44
+ - `theme`: Color theme for the header. The `theme` attribute supports the following [options](https://www.lightningdesignsystem.com/utilities/themes/#site-main-content) from SLDS:
45
+ - `default`: white
46
+ - `shade`: gray
47
+ - `inverse`: dark blue
48
+ - `alt-inverse`: darker blue
49
+ - `success`: green
50
+ - `info`: gray-ish blue
51
+ - `warning`: yellow
52
+ - `error`: red
53
+ - `offline`: ​black
54
+
55
+ If an invalid value is provided, `LightningAlert` uses the `default` theme.
56
+
57
+ #### Testing Your Component's Alert
58
+
59
+ Code using `LightningAlert` can be tested by mocking the `LightningAlert.open()` method.
60
+
61
+ The example below uses a button to open an alert dialog with text that changes when the alert opens.
62
+
63
+ ```html
64
+ <button data-button onclick="{handleClick}">Open Alert</button>
65
+ <template if:true="{alertViewed}">
66
+ <div data-text>Content Viewed</div>
67
+ </template>
68
+ <template if:false="{alertViewed}">
69
+ <div data-text>Click to View Content</div>
70
+ </template>
71
+ ```
72
+
73
+ ```javascript
74
+ import LightningAlert from 'lightning/alert';
75
+ jest.mock('lightning/alert');
76
+
77
+ test(() => {
78
+ // Create and appendChild(element)
79
+
80
+ const buttonEle = element.shadowRoot.querySelector('[data-button]');
81
+ const textEle = element.shadowRoot.querySelector('[data-text]');
82
+
83
+ // Mock .open()
84
+ // No value passed since LightningAlert doesn't have a return value
85
+ LightningAlert.open = jest.fn().mockResolvedValue();
86
+ // Initial value
87
+ expect(textEle.textContent).toBe('Click to View Content');
88
+ // Click modal open button
89
+ buttonEle.click();
90
+
91
+ // Click handler render cycle
92
+ await Promise.resolve();
93
+ // Render cycle triggered by tracked value {result}
94
+ await Promise.resolve();
95
+
96
+ // Verify alertViewed has updated in template
97
+ expect(textEle.textContent).toBe('Content Viewed');
98
+ // Open triggered once
99
+ expect(LightningAlert.open.mock.calls).toHaveLength(1);
100
+ })
101
+ ```
@@ -0,0 +1,7 @@
1
+ .example {
2
+ margin: 0.5rem;
3
+ border-radius: 0.5rem;
4
+ background: #FFF;
5
+ box-shadow: 0 1px 0.25rem rgba(0, 0, 0, 0.2);
6
+ padding: 1rem;
7
+ }
@@ -0,0 +1,8 @@
1
+ <template>
2
+ <div class="example">
3
+ <button
4
+ aria-haspopup="modal"
5
+ onclick={handleAlertModal}
6
+ >Open the Alert Modal</button>
7
+ </div>
8
+ </template>
@@ -0,0 +1,14 @@
1
+ import { LightningElement } from 'lwc';
2
+ import LightningAlert from 'lightning/alert';
3
+
4
+ export default class AlertBasic extends LightningElement {
5
+ handleAlertModal() {
6
+ LightningAlert.open({
7
+ message: 'this is the alert message',
8
+ //label defaults to "Alert"
9
+ variant: 'headerless',
10
+ }).then((result) => {
11
+ console.log('alert result', result);
12
+ });
13
+ }
14
+ }
@@ -0,0 +1,3 @@
1
+ <template>
2
+ <p>{message}</p>
3
+ </template>
@@ -0,0 +1,78 @@
1
+ import { api } from 'lwc';
2
+ import LightningInteractiveDialogBase from 'lightning/interactiveDialogBase';
3
+ import LightningOverlay from 'lightning/overlay';
4
+ import { parent, instanceName, secure } from 'lightning/overlayUtils';
5
+ import labelDefault from '@salesforce/label/LightningAlert.defaultLabel';
6
+
7
+ /**
8
+ * Create an alert modal within your component that communicates
9
+ * a state that affects the entire system, not just a feature or page.
10
+ */
11
+
12
+ export default class LightningAlert extends LightningOverlay {
13
+ static [instanceName] = 'lightning-alert';
14
+ static [parent] = LightningInteractiveDialogBase;
15
+
16
+ /**
17
+ * value to use for header text in "header" variant
18
+ * or aria-label in "headerless" variant
19
+ * @type {string}
20
+ * @default "Alert" (translated accordingly)
21
+ */
22
+ @api label = labelDefault;
23
+
24
+ /**
25
+ * text to display in body of modal
26
+ */
27
+ @api message = '';
28
+
29
+ /**
30
+ * variant to use for alert; may be
31
+ * set to "header" or "headerless"
32
+ */
33
+ @api variant = 'header';
34
+
35
+ /**
36
+ * theme to use when variant is "header"
37
+ * valid values are based on SLDS themes and are
38
+ * listed in "themeOptions" of interactiveDialogBase.js
39
+ */
40
+ @api theme = 'default';
41
+
42
+ /**
43
+ * Dispatches privateclose event
44
+ * and closes dialog
45
+ */
46
+ close(result) {
47
+ const promise = new Promise((resolve) => {
48
+ this.dispatchEvent(
49
+ new CustomEvent('privateclose', {
50
+ detail: {
51
+ resolve,
52
+ [secure]: true,
53
+ },
54
+ bubbles: true,
55
+ })
56
+ );
57
+ });
58
+ super.close(result, promise);
59
+ }
60
+
61
+ /**
62
+ * Dispatches privatechildrender event
63
+ * with data parent needs to correctly render
64
+ */
65
+ renderedCallback() {
66
+ const evt = new CustomEvent('privatechildrender', {
67
+ bubbles: true,
68
+ detail: {
69
+ message: this.message,
70
+ label: this.label,
71
+ hideCancel: true,
72
+ showDescription: true,
73
+ role: 'alertdialog',
74
+ },
75
+ });
76
+ this.dispatchEvent(evt);
77
+ }
78
+ }
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
3
+ <isExposed>true</isExposed>
4
+ <minApiVersion>54.0</minApiVersion>
5
+ <support>GA</support>
6
+ </LightningComponentBundle>
@@ -47,6 +47,15 @@ describe('AriaObserver', () => {
47
47
  expect(testElement.labelContent).toEqual('Foo\nBar');
48
48
  });
49
49
 
50
+ it('should work with label ids appearing in the opposite of document order', async () => {
51
+ const container = createTestElement();
52
+ container.updateAriaLabelledby('alt-label-id id-label');
53
+ await Promise.resolve();
54
+
55
+ const testElement = container.testElement;
56
+ expect(testElement.labelContent).toEqual('Bar\nFoo');
57
+ });
58
+
50
59
  it('should update the internal label content when external content changes', async () => {
51
60
  const container = createTestElement();
52
61
  container.updateLabelContent();
@@ -13,11 +13,13 @@ function getAttr(elm, attr) {
13
13
  return elm.getAttribute(attr);
14
14
  }
15
15
 
16
- function extractElements(root, selector) {
17
- if (typeof selector !== 'string' || selector === '') {
16
+ function extractElements(root, ids) {
17
+ if (typeof ids !== 'string' || ids === '') {
18
18
  return [];
19
19
  }
20
- return [].slice.call(root.querySelectorAll(selector));
20
+ // We must query the elements in the order of ids, so that
21
+ // the content will be extracted in the correct order.
22
+ return splitIds(ids).map((id) => root.querySelector(`#${id}`));
21
23
  }
22
24
 
23
25
  function extractContent(elements) {
@@ -113,38 +115,28 @@ export default class AriaObserver {
113
115
  connect({ targetSelector, attribute, id, ids }) {
114
116
  ids = ids || id;
115
117
 
116
- let attrState = this.state[attribute];
117
- if (attrState) {
118
- // note: we don't support linking to a different targetSelector, attribute
119
- if (!this.isNative) {
120
- const elm = this.template.querySelector(
121
- attrState.innerSelector
122
- );
123
- if (elm) {
124
- // removing the old ids if possible before setting the new ones
125
- removeAriaRefWhenPossible(elm, attribute, attrState.ids);
126
- }
127
- attrState.ids = ids;
118
+ this.state[attribute] = this.state[attribute] || {};
119
+ const attrState = this.state[attribute];
120
+
121
+ // note: we don't support linking to a different targetSelector
122
+ attrState.innerSelector = attrState.innerSelector || targetSelector;
123
+
124
+ // removing the old ids if possible before setting the new ones
125
+ if (!this.isNative && attrState.ids) {
126
+ const elm = this.template.querySelector(attrState.innerSelector);
127
+ if (elm) {
128
+ removeAriaRefWhenPossible(elm, attribute, attrState.ids);
128
129
  }
129
- } else {
130
- attrState = this.state[attribute] = {
131
- ids,
132
- innerSelector: targetSelector,
133
- };
134
130
  }
135
- if (this.isNative) {
136
- attrState.outerSelector = (ids + '')
137
- .trim()
138
- .split(/\s+/)
139
- .map((ref) => `#${ref}`)
140
- .join(',');
141
131
 
132
+ attrState.ids = ids;
133
+
134
+ if (this.isNative && !attrState.placeholder) {
142
135
  // create placeholder element for copied content
143
- if (!attrState.placeholder) {
144
- attrState.placeholder = document.createElement('span');
145
- attrState.placeholder.id = `auto-link-${attribute}-${this.guid}`;
146
- }
136
+ attrState.placeholder = document.createElement('span');
137
+ attrState.placeholder.id = `auto-link-${attribute}-${this.guid}`;
147
138
  }
139
+
148
140
  if (this.component.isConnected) {
149
141
  this.privateUpdate(attribute);
150
142
  }
@@ -213,12 +205,9 @@ export default class AriaObserver {
213
205
  }
214
206
  let computedIds;
215
207
  if (this.isNative) {
216
- const { outerSelector, content, placeholder } =
217
- this.state[attrName];
208
+ const { ids, content, placeholder } = this.state[attrName];
218
209
 
219
- const newContent = extractContent(
220
- extractElements(this.root, outerSelector)
221
- );
210
+ const newContent = extractContent(extractElements(this.root, ids));
222
211
  if (content !== newContent) {
223
212
  this.state[attrName].content = placeholder.textContent =
224
213
  newContent;
@@ -1,5 +1,10 @@
1
1
  <template>
2
- <template if:false={shouldFormat}>{normalizedValue}</template>
2
+ <template if:false={shouldFormat}>
3
+ <template if:true={ignoreRTL}>
4
+ <span dir="ltr">{normalizedValue}</span>
5
+ </template>
6
+ <template if:false={ignoreRTL}>{normalizedValue}</template>
7
+ </template>
3
8
  <template if:true={shouldFormat} for:each={formattedParts} for:item="part">
4
9
  <template if:true={part.isLink}>
5
10
  <a key={part.key} target='_blank' href={part.href} rel="noopener">{part.value}</a>
@@ -64,4 +64,9 @@ export default class BaseFormattedText extends LightningElement {
64
64
  }
65
65
  return parseToFormattedLinkifiedParts(this.value, true);
66
66
  }
67
+
68
+ get ignoreRTL() {
69
+ // Ignoring RTL for hex color codes
70
+ return this.isString && this.value.match(/^#[0-9abcdef]{6}$/i) !== null;
71
+ }
67
72
  }
@@ -778,6 +778,18 @@ export default class LightningButtonMenu extends LightningElement {
778
778
  }
779
779
 
780
780
  handlePrivateBlur(event) {
781
+ // During navigation of menuitems, after the blur event, focus is set on a new menuitem and hence it should not trigger a blur on the menu itself which causes the menu to close.
782
+ // If navigation is by mouse, this is taken care of by the "handleMouseOverOnMenuItem" function which "cancels" the blur on the menu.
783
+ // If navigation is by touch in mobile, no equivalent handler is available for blur event hence we are using
784
+ // the detail.relatedTarget to know that the blur is from a menuitem and it should not cause blur on the menu itself.
785
+ if (event.detail.relatedTarget) {
786
+ const menuItem = this.findMenuItemFromEventTarget(
787
+ event.detail.relatedTarget
788
+ );
789
+ if (menuItem) {
790
+ this.cancelBlur();
791
+ }
792
+ }
781
793
  // The event may be synthetic from the menu items
782
794
  event.stopPropagation();
783
795
 
@@ -0,0 +1,100 @@
1
+ The `lightning/confirm` module lets you create a confirm modal within your component. Use `LightningConfirm` on your component to ask the user to respond before they continue.
2
+
3
+ `lightning/confirm` is not supported on mobile devices.
4
+
5
+ Use `LightningConfirm.open()` instead of the native `window.confirm()` for a more consistent user experience. They have similar functions, but `LightningConfirm.open()` works in cross-origin iframes, where the `.confirm()` method is no longer supported in Chrome and Safari. Unlike `window.confirm()`, `LightningConfirm.open()` doesn't halt execution on the page, it returns a Promise. Use `async`/`await` or `.then()` for any code you want to execute after the confirm has closed.
6
+
7
+ Import `LightningConfirm` from the `lightning/confirm` module in the component that will launch the confirm modal, and call `LightningConfirm.open()` with your desired attributes.
8
+
9
+ This example creates a headerless confirm modal with two buttons, **OK** and **Cancel**. The `.open()` function returns a promise that resolves to true when you click **OK** and false when you click **Cancel**.
10
+
11
+ ```html
12
+ <!-- c/myApp.html -->
13
+ <template>
14
+ <lightning-button onclick="{handleConfirmClick}" label="Open Confirm Modal">
15
+ </lightning-button>
16
+ </template>
17
+ ```
18
+
19
+ ```javascript
20
+ import { LightningElement } from 'lwc';
21
+ import LightningConfirm from 'lightning/confirm';
22
+
23
+ export default class MyApp extends LightningElement {
24
+ async handleConfirmClick() {
25
+ const result = await LightningConfirm.open({
26
+ message: 'this is the prompt message',
27
+ variant: 'headerless',
28
+ label: 'this is the aria-label value',
29
+ // setting theme would have no effect
30
+ });
31
+ //Confirm has been closed
32
+ //result is true if OK was clicked
33
+ //and false if cancel was clicked
34
+ }
35
+ }
36
+ ```
37
+
38
+ #### Component Styling
39
+
40
+ This component uses the Salesforce Lightning Design System (SLDS) [`prompt` blueprint](https://www.lightningdesignsystem.com/components/prompt/#site-main-content).
41
+
42
+ `LightningConfirm` supports the following attributes:
43
+
44
+ - `message`: Message text that displays in the confirm.
45
+ - `label`: Header text, also used as the `aria-label`. Default string is `Confirm`.
46
+ - `variant`: Two values, `header` and `headerless`. Default value is `header`.
47
+ - `theme`: Color theme for the header. The `theme` attribute supports the following [options](https://www.lightningdesignsystem.com/utilities/themes/#site-main-content) from SLDS:
48
+ - `default`: white
49
+ - `shade`: gray
50
+ - `inverse`: dark blue
51
+ - `alt-inverse`: darker blue
52
+ - `success`: green
53
+ - `info`: gray-ish blue
54
+ - `warning`: yellow
55
+ - `error`: red
56
+ - `offline`: ​black​
57
+
58
+ If an invalid value is provided, `LightningConfirm` uses the `default` theme.
59
+
60
+ #### Testing Your Component's Confirm
61
+
62
+ Code using `LightningConfirm` can be tested by mocking the `LightningConfirm.open()` method.
63
+
64
+ The example below uses a button to open a confirm dialog and sets the result in a template.
65
+
66
+ ```html
67
+ <button data-button onclick="{handleClick}">Open Confirm</button>
68
+ <div data-result>{result}</div>
69
+ ```
70
+
71
+ ```js
72
+ import LightningConfirm from 'lightning/confirm';
73
+ jest.mock('lightning/confirm');
74
+
75
+ test(() => {
76
+ // Create and appendChild(element)
77
+
78
+ const buttonEle = element.shadowRoot.querySelector('[data-button]');
79
+ const resultEle = element.shadowRoot.querySelector('[data-result]');
80
+
81
+ // Mock .open()
82
+ // Pass true if testing when user clicks "OK"
83
+ // Pass false if testing when user clicks "Cancel"
84
+ LightningConfirm.open = jest.fn().mockResolvedValue(true);
85
+ // Initial value
86
+ expect(resultEle.textContent).toBe('unknown');
87
+ // Click modal open button
88
+ buttonEle.click();
89
+
90
+ // Click handler render cycle
91
+ await Promise.resolve();
92
+ // Render cycle triggered by tracked value {result}
93
+ await Promise.resolve();
94
+
95
+ // Verify result is set in the template
96
+ expect(resultEle.textContent).toBe('true');
97
+ // Open triggered once
98
+ expect(LightningConfirm.open.mock.calls).toHaveLength(1);
99
+ })
100
+ ```
@@ -0,0 +1,7 @@
1
+ .example {
2
+ margin: 0.5rem;
3
+ border-radius: 0.5rem;
4
+ background: #FFF;
5
+ box-shadow: 0 1px 0.25rem rgba(0, 0, 0, 0.2);
6
+ padding: 1rem;
7
+ }
@@ -0,0 +1,8 @@
1
+ <template>
2
+ <div class="example">
3
+ <button
4
+ aria-haspopup="modal"
5
+ onclick={handleConfirmModal}
6
+ >Open the Confirm Modal</button>
7
+ </div>
8
+ </template>