lightning-base-components 1.16.3-alpha → 1.16.5-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 (111) hide show
  1. package/README.md +7 -0
  2. package/metadata/raptor.json +110 -0
  3. package/package.json +59 -2
  4. package/scopedImports/@salesforce-label-LightningForm.cancel.js +1 -0
  5. package/scopedImports/@salesforce-label-LightningForm.closeError.js +1 -0
  6. package/scopedImports/@salesforce-label-LightningForm.edit.js +1 -0
  7. package/scopedImports/@salesforce-label-LightningForm.editErrorHelp.js +1 -0
  8. package/scopedImports/@salesforce-label-LightningForm.error.js +1 -0
  9. package/scopedImports/@salesforce-label-LightningForm.errorPopoverHeading.js +1 -0
  10. package/scopedImports/@salesforce-label-LightningForm.preview.js +1 -0
  11. package/scopedImports/@salesforce-label-LightningForm.previewHeader.js +1 -0
  12. package/scopedImports/@salesforce-label-LightningForm.reload.js +1 -0
  13. package/scopedImports/@salesforce-label-LightningForm.save.js +1 -0
  14. package/scopedImports/@salesforce-label-LightningForm.saveFieldErrorSummary.js +1 -0
  15. package/scopedImports/@salesforce-label-LightningForm.undo.js +1 -0
  16. package/scopedImports/@salesforce-label-LightningLookup.messageWhenMissingInformation.js +1 -0
  17. package/src/lightning/button/__docs__/button.md +13 -0
  18. package/src/lightning/button/button.slds.css +155 -11
  19. package/src/lightning/buttonGroup/button-group.slds.css +35 -59
  20. package/src/lightning/buttonIcon/button-icon.slds.css +287 -122
  21. package/src/lightning/buttonIconStateful/button-icon-stateful.slds.css +224 -39
  22. package/src/lightning/buttonStateful/button-stateful.slds.css +3269 -0
  23. package/src/lightning/card/card.slds.css +50 -0
  24. package/src/lightning/colorPickerCustom/color-picker-custom.slds.css +180 -364
  25. package/src/lightning/colorPickerPanel/color-picker-panel.slds.css +46 -413
  26. package/src/lightning/datatable/datatable.js +2 -2
  27. package/src/lightning/datatable/rowSelection.js +21 -4
  28. package/src/lightning/datetimepicker/datetimepicker.html +1 -3
  29. package/src/lightning/datetimepicker/datetimepicker.js +5 -0
  30. package/src/lightning/fileDownload/__docs__/fileDownload.md +41 -0
  31. package/src/lightning/helptext/help-text.slds.css +184 -39
  32. package/src/lightning/icon/icon.slds.css +823 -3
  33. package/src/lightning/input/input-checkbox.slds.css +291 -32
  34. package/src/lightning/input/input-text.slds.css +70 -7
  35. package/src/lightning/inputAddress/__docs__/inputAddress.md +1 -1
  36. package/src/lightning/inputAddress/inputAddress.js +2 -1
  37. package/src/lightning/internationalizationLibrary/datetime/intlFormat.js +20 -2
  38. package/src/lightning/iso8601Utils/iso8601Utils.js +2 -3
  39. package/src/lightning/mediaUtils/__docs__/mediaUtils.md +87 -0
  40. package/src/lightning/mediaUtils/mediaUtils.js +321 -0
  41. package/src/lightning/mediaUtils/mediaUtils.js-meta.xml +6 -0
  42. package/src/lightning/modal/__docs__/migration.md +158 -0
  43. package/src/lightning/modal/__docs__/modal.md +414 -0
  44. package/src/lightning/modal/__examples__disabled/all/all.css +7 -0
  45. package/src/lightning/modal/__examples__disabled/all/all.html +9 -0
  46. package/src/lightning/modal/__examples__disabled/all/all.js +25 -0
  47. package/src/lightning/modal/__examples__disabled/allform/allform.css +7 -0
  48. package/src/lightning/modal/__examples__disabled/allform/allform.html +9 -0
  49. package/src/lightning/modal/__examples__disabled/allform/allform.js +49 -0
  50. package/src/lightning/modal/__examples__disabled/allmulti/allmulti.html +24 -0
  51. package/src/lightning/modal/__examples__disabled/allmulti/allmulti.js +12 -0
  52. package/src/lightning/modal/__examples__disabled/basic/basic.css +7 -0
  53. package/src/lightning/modal/__examples__disabled/basic/basic.html +9 -0
  54. package/src/lightning/modal/__examples__disabled/basic/basic.js +27 -0
  55. package/src/lightning/modal/__examples__disabled/demo/demo.html +15 -0
  56. package/src/lightning/modal/__examples__disabled/demo/demo.js +13 -0
  57. package/src/lightning/modal/__examples__disabled/demoall/demoall.html +26 -0
  58. package/src/lightning/modal/__examples__disabled/demoall/demoall.js +13 -0
  59. package/src/lightning/modal/__examples__disabled/demoallform/demoallform.css +3 -0
  60. package/src/lightning/modal/__examples__disabled/demoallform/demoallform.html +146 -0
  61. package/src/lightning/modal/__examples__disabled/demoallform/demoallform.js +240 -0
  62. package/src/lightning/modal/__examples__disabled/demofootless/demofootless.html +17 -0
  63. package/src/lightning/modal/__examples__disabled/demofootless/demofootless.js +11 -0
  64. package/src/lightning/modal/__examples__disabled/demoheadless/demoheadless.html +20 -0
  65. package/src/lightning/modal/__examples__disabled/demoheadless/demoheadless.js +12 -0
  66. package/src/lightning/modal/__examples__disabled/footless/footless.css +7 -0
  67. package/src/lightning/modal/__examples__disabled/footless/footless.html +9 -0
  68. package/src/lightning/modal/__examples__disabled/footless/footless.js +19 -0
  69. package/src/lightning/modal/__examples__disabled/headless/headless.css +7 -0
  70. package/src/lightning/modal/__examples__disabled/headless/headless.html +9 -0
  71. package/src/lightning/modal/__examples__disabled/headless/headless.js +27 -0
  72. package/src/lightning/modal/modal.html +3 -0
  73. package/src/lightning/modal/modal.js +93 -0
  74. package/src/lightning/modal/modal.js-meta.xml +6 -0
  75. package/src/lightning/modalBody/__docs__/modalBody.md +61 -0
  76. package/src/lightning/modalBody/modalBody.html +13 -0
  77. package/src/lightning/modalBody/modalBody.js +203 -0
  78. package/src/lightning/modalBody/modalBody.js-meta.xml +6 -0
  79. package/src/lightning/modalFooter/__docs__/modalFooter.md +72 -0
  80. package/src/lightning/modalFooter/modalFooter.html +8 -0
  81. package/src/lightning/modalFooter/modalFooter.js +161 -0
  82. package/src/lightning/modalFooter/modalFooter.js-meta.xml +6 -0
  83. package/src/lightning/modalHeader/__docs__/modalHeader.md +64 -0
  84. package/src/lightning/modalHeader/modalHeader.html +16 -0
  85. package/src/lightning/modalHeader/modalHeader.js +204 -0
  86. package/src/lightning/modalHeader/modalHeader.js-meta.xml +6 -0
  87. package/src/lightning/primitiveBubble/tooltip.slds.css +45 -1
  88. package/src/lightning/primitiveCellFactory/primitiveCellFactory.js +4 -12
  89. package/src/lightning/primitiveColorpickerButton/color-picker-button.slds.css +2994 -319
  90. package/src/lightning/primitiveDatatableIeditPanel/primitiveDatatableIeditPanel.html +14 -11
  91. package/src/lightning/primitiveDatatableIeditPanel/primitiveDatatableIeditPanel.js +1 -0
  92. package/src/lightning/primitiveIcon/icon.slds.css +823 -3
  93. package/src/lightning/progressStep/base.html +1 -0
  94. package/src/lightning/progressStep/path.html +1 -1
  95. package/src/lightning/radioGroup/input-radio-group.slds.css +168 -379
  96. package/src/lightning/spinner/spinner.slds.css +8 -2
  97. package/src/lightning/timepicker/timepicker.html +1 -4
  98. package/src/lightning/timepicker/timepicker.js +9 -5
  99. package/src/lightning/treeGrid/treeGrid.js +66 -1
  100. package/src/lightning/utilsPrivate/linkUtils.js +1 -1
  101. package/src/lightning/formattedAddress/__component__/formattedAddress.spec.js +0 -61
  102. package/src/lightning/formattedAddress/__component__/formattedAddressDisabled.spec.js +0 -20
  103. package/src/lightning/formattedAddress/__component__/x/basic/basic.html +0 -10
  104. package/src/lightning/formattedAddress/__component__/x/basic/basic.js +0 -17
  105. package/src/lightning/input/__component__/inputCheckbox.spec.js +0 -60
  106. package/src/lightning/input/__component__/inputDateTimePicker.spec.js +0 -60
  107. package/src/lightning/input/__component__/inputNumber.spec.js +0 -75
  108. package/src/lightning/input/__component__/inputSelection.spec.js +0 -83
  109. package/src/lightning/input/__component__/x/tall/tall.css +0 -5
  110. package/src/lightning/input/__component__/x/tall/tall.html +0 -5
  111. package/src/lightning/input/__component__/x/tall/tall.js +0 -7
@@ -0,0 +1,61 @@
1
+ The `lightning-modal-body` component renders the content of a modal.
2
+
3
+ The modal components render in the order they appear in the template. Place the `lightning-modal-body`
4
+ component after `lightning-modal-header` and before `lightning-modal-footer` components, if you're providing them.
5
+
6
+ This sample code shows the expected order of the modal components. The modal content is
7
+ created in a separate component extended from `LightningModal`. See
8
+ [Lightning Web Components Developer Guide](docs/component-library/documentation/en/lwc/)
9
+
10
+ ```html
11
+ <!-- my/modalDialog.html -->
12
+ <template>
13
+ <lightning-modal-header label="My Modal Heading">
14
+ Tagline content with <a href="https://salesforce.com">Salesforce.com link</a>
15
+ </lightning-modal-header>
16
+ <lightning-modal-body>
17
+ <!-- modal content specified in LightningModal component -->
18
+ { content }
19
+ <!-- alternatively, add content here directly -->
20
+ </lightning-modal-body>
21
+ <lightning-modal-footer>
22
+ Footer Content
23
+ </lightning-modal-footer>
24
+ </template>
25
+ ```
26
+
27
+ You can nest content in `lightning-modal-body` or
28
+ `lightning-modal-body` automatically scrolls the modal's content when necessary.
29
+ The modal's maximum height is calculated to prevent the content from exceeding the screen height,
30
+ and scroll bars are automatically added.
31
+ #### Component Styling
32
+
33
+ `lightning-modal-body` implements the [modals](https://www.lightningdesignsystem.com/components/modals/) blueprint in the Salesforce Lightning Design System (SLDS).
34
+
35
+ To apply custom styling, use the `:host` selector or define a custom class using the `class` attribute.
36
+
37
+ ```html
38
+ <lightning-modal-body class="my-modal-body">
39
+
40
+ </lightning-modal-body>
41
+ ```
42
+
43
+ Use SLDS styling hooks to customize the component's styles. The `--sds-c-modal-content-*` hooks
44
+ enable you to customize the background color and text color of the modal body.
45
+
46
+ For example, specify the background color on the modal using the `sds-c-modal-content-color-background` custom property.
47
+
48
+ ```css
49
+ .my-modal-body {
50
+ --sds-c-modal-content-color-background: LightBlue;
51
+ }
52
+ ```
53
+
54
+ See the modal blueprint's [Styling Hooks Overview](https://www.lightningdesignsystem.com/components/modals/#Styling-Hooks-Overview) for a list of CSS custom properties.
55
+
56
+ For more information, see [Style Components Using Lightning Design System Styling Hooks](docs/component-library/documentation/lwc/lwc.create_components_css_custom_properties) in the Lightning Web Components Developer Guide.
57
+
58
+ #### Accessibility
59
+
60
+ See [Lightning Web Components Developer Guide](docs/component-library/documentation/en/lwc/) for more information about accessibility in modals.
61
+
@@ -0,0 +1,13 @@
1
+ <template>
2
+ <div
3
+ id="modal-content"
4
+ class={modalBodyCssClasses}
5
+ data-content-container
6
+ onprivatescrollablecontainer={handleScrollableContainerRepositionEvent}
7
+ >
8
+ <slot
9
+ data-default-slot
10
+ onslotchange={handleDefaultSlotChange}
11
+ ></slot>
12
+ </div>
13
+ </template>
@@ -0,0 +1,203 @@
1
+ import { LightningElement } from 'lwc';
2
+ import { classSet } from 'lightning/utils';
3
+ import { getRealDOMId } from 'lightning/utilsPrivate';
4
+ import { findAllTabbableElements, filterTooltips } from 'lightning/focusUtils';
5
+
6
+ /**
7
+ * The modal body component to display main content area in lightning modal.
8
+ * */
9
+ export default class LightningModalBody extends LightningElement {
10
+ // private tracked state
11
+ initialRender = true;
12
+ initialSlotRender = true;
13
+ unregisterCallback = null;
14
+ headerPresent = false;
15
+ footerPresent = false;
16
+
17
+ /**
18
+ * Handle the default slot change event
19
+ * Always register with parent every slot change
20
+ * @private
21
+ */
22
+ handleDefaultSlotChange() {
23
+ // Set this once so that parent can know slot has rendered
24
+ if (this.initialSlotRender) {
25
+ this.initialSlotRender = false;
26
+ }
27
+ this.registerWithParent();
28
+ }
29
+
30
+ /**
31
+ * Handle the 'privatescrollablecontainer from positionLibrary.js
32
+ * This repositions elements with overlays that use positionLibrary
33
+ * like helptext, combobox, etc
34
+ * @private
35
+ */
36
+ handleScrollableContainerRepositionEvent(event) {
37
+ const { callback: repositionCallback } = event.detail;
38
+ repositionCallback(event.composedPath());
39
+ event.stopPropagation();
40
+ }
41
+
42
+ /**
43
+ * Gets the CSS classes applicable to the modal body element.
44
+ * Hidden classes included for sibling components
45
+ * @return {string} CSS class applied to modal body
46
+ * @private
47
+ */
48
+ get modalBodyCssClasses() {
49
+ const classes = classSet('slds-modal__content slds-p-around_medium');
50
+ classes.add({
51
+ 'slds-modal__content_headless': !this.headerPresent,
52
+ 'slds-modal__content_footless': !this.footerPresent,
53
+ });
54
+ return classes.toString();
55
+ }
56
+
57
+ /**
58
+ * Get a reference to the modal body content area wrapper div element
59
+ * @returns {(HTMLElement|null)} Outer wrapper for modal body
60
+ * @private
61
+ */
62
+ get contentElem() {
63
+ return this.template.querySelector('[data-content-container]');
64
+ }
65
+
66
+ /**
67
+ * Get the main content div element assigned ID value
68
+ * @type {(string|null)}
69
+ * @private
70
+ */
71
+ get modalContentId() {
72
+ return getRealDOMId(this.contentElem);
73
+ }
74
+
75
+ /**
76
+ * Get the default slot element for modal body component
77
+ * @returns {(HTMLElement|null)}
78
+ * @private
79
+ */
80
+ get defaultSlotElement() {
81
+ return this.template.querySelector('[data-default-slot]');
82
+ }
83
+
84
+ /**
85
+ * Determine whether the default slot is populated
86
+ * @returns {boolean}
87
+ * @private
88
+ */
89
+ get isDefaultSlotPopulated() {
90
+ const slotElement = this.defaultSlotElement;
91
+ if (slotElement && slotElement.assignedNodes) {
92
+ return slotElement.assignedNodes().length > 0;
93
+ }
94
+ return false;
95
+ }
96
+
97
+ /**
98
+ * Get first tabbable element within modalBody, if exists
99
+ * This is passed to parent in order to autoFocus
100
+ * @return {(HTMLElement|null)}
101
+ * @private
102
+ */
103
+ get firstTabbableElement() {
104
+ let firstElem = null;
105
+ if (this.isDefaultSlotPopulated) {
106
+ const tabbableElements = findAllTabbableElements(
107
+ this.defaultSlotElement
108
+ );
109
+ const filteredElements = filterTooltips(tabbableElements);
110
+ if (filteredElements.length > 0) {
111
+ firstElem = filteredElements[0];
112
+ }
113
+ }
114
+ return firstElem;
115
+ }
116
+
117
+ /**
118
+ * Set the max-height style inline on modalBody to prevent vertical height
119
+ * of overall modal to overflow
120
+ * This function is passed to the parent modal as a callback
121
+ * and will be called on first modal load, and then on window resize events
122
+ * as long as modalBody is present
123
+ * @param {Object} values Representing headerHeight, footerHeight, backdropHeight
124
+ * @returns {object} Representing headerHeight, footerHeight, backdropHeight
125
+ * @private
126
+ */
127
+ handleUpdateHeight({ headerHeight, footerHeight, backdropHeight }) {
128
+ if (!this.initialRender) {
129
+ const paddingTop = 48; // 3rem
130
+ const paddingBottom = 80; // 5rem
131
+ const modalBodyMinHeight = 80;
132
+ const modalUsableHeight =
133
+ backdropHeight - paddingTop - paddingBottom;
134
+ const modalBodyUsableHeight =
135
+ modalUsableHeight - headerHeight - footerHeight;
136
+ const divElem = this.contentElem;
137
+ const styles = {
138
+ maxHeight: `${modalBodyUsableHeight}px`,
139
+ minHeight: `${modalBodyMinHeight}px`,
140
+ };
141
+ // set the max and min height value on modal body wrapper div
142
+ Object.assign(divElem.style, styles);
143
+ this.headerPresent = headerHeight !== 0;
144
+ this.footerPresent = footerHeight !== 0;
145
+ }
146
+ }
147
+
148
+ /**
149
+ * Register modalBody with modal parent, including callbacks to
150
+ * unregister the modal body, and update the modal body height
151
+ * this will get called multiple times over component lifecycle
152
+ * @type {CustomEvent}
153
+ * @private
154
+ */
155
+ registerWithParent() {
156
+ const evtRegister = new CustomEvent('privatemodalbodyregister', {
157
+ bubbles: true,
158
+ composed: true,
159
+ detail: {
160
+ bodyId: this.modalContentId,
161
+ bodyIsPopulated: this.isDefaultSlotPopulated,
162
+ defaultSlotHasRendered: !this.initialSlotRender,
163
+ updateBodyCallback: this.handleUpdateHeight.bind(this),
164
+ unRegisterCallback: (unregisterCallback) => {
165
+ this.unregisterCallback = unregisterCallback;
166
+ },
167
+ firstTabbableElemRef: this.firstTabbableElement,
168
+ },
169
+ });
170
+ this.dispatchEvent(evtRegister);
171
+ }
172
+
173
+ /**
174
+ * When modal body is being created, initialize
175
+ * private tracked modal body state
176
+ * @private
177
+ */
178
+ initState() {
179
+ this.initialRender = true;
180
+ this.initialSlotRender = true;
181
+ this.unregisterCallback = null;
182
+ this.headerPresent = false;
183
+ this.footerPresent = false;
184
+ }
185
+
186
+ connectedCallback() {
187
+ // handle case where modalBody is added/removed/re-added to DOM
188
+ this.initState();
189
+ }
190
+
191
+ disconnectedCallback() {
192
+ if (this.unregisterCallback) {
193
+ this.unregisterCallback();
194
+ }
195
+ }
196
+
197
+ renderedCallback() {
198
+ if (this.initialRender) {
199
+ this.registerWithParent();
200
+ this.initialRender = false;
201
+ }
202
+ }
203
+ }
@@ -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>55.0</minApiVersion>
5
+ <support>GA</support>
6
+ </LightningComponentBundle>
@@ -0,0 +1,72 @@
1
+ The `lightning-modal-footer` component creates a footer at the bottom of a modal dialog.
2
+ Use of a footer is optional.
3
+
4
+ The modal components render in the order they appear in the template.
5
+ Place the `lightning-modal-footer` component after the `lightning-modal-body` component.
6
+
7
+ This sample code shows the expected order of the modal components. The modal content is
8
+ created in a separate component extended from `LightningModal`. See
9
+ [Lightning Web Components Developer Guide](docs/component-library/documentation/en/lwc/)
10
+
11
+ This sample's `lightning-modal-footer` includes two `lightning-button` components,
12
+ but you can also use `<button>` elements.
13
+
14
+ ```html
15
+ <!-- my/modalDialog.html -->
16
+ <template>
17
+ <lightning-modal-header label="My Modal">
18
+ </lightning-modal-header>
19
+ <lightning-modal-body>
20
+ <!-- modal content specified in LightningModal component -->
21
+ </lightning-modal-body>
22
+ <lightning-modal-footer>
23
+ <lightning-button
24
+ class="slds-button"
25
+ variant="neutral"
26
+ label="Cancel"
27
+ onclick={handleDismiss}
28
+ ></lightning-button>
29
+ <lightning-button
30
+ class="slds-button slds-m-left_x-small"
31
+ variant="brand"
32
+ label="Save"
33
+ ></lightning-button>
34
+ </lightning-modal-footer>
35
+ </template>
36
+ ```
37
+ #### Component Styling
38
+
39
+ `lightning-modal-footer` implements the [modals](https://www.lightningdesignsystem.com/components/modals/) blueprint in the Salesforce Lightning Design System (SLDS).
40
+
41
+ To apply custom styling, use the `:host` selector or define a custom class using the `class` attribute.
42
+
43
+ ```html
44
+ <lightning-modal-footer class="my-modal-footer">
45
+
46
+ </lightning-modal-footer>
47
+ ```
48
+
49
+ Use SLDS styling hooks to customize the component's styles. Several `--sds-c-modal-footer-*` hooks
50
+ enable you to customize the footer spacing, background color, and text color.
51
+
52
+ For example, specify the background color on the footer using the `sds-c-modal-footer-color-background` custom property.
53
+
54
+ ```css
55
+ .my-modal-footer {
56
+ --sds-c-modal-footer-color-background: LightGray;
57
+ }
58
+ ```
59
+
60
+ See the modal blueprint's [Styling Hooks Overview](https://www.lightningdesignsystem.com/components/modals/#Styling-Hooks-Overview) for a list of CSS custom properties.
61
+
62
+ For more information, see [Style Components Using Lightning Design System Styling Hooks](docs/component-library/documentation/lwc/lwc.create_components_css_custom_properties) in the Lightning Web Components Developer Guide.
63
+
64
+ #### Accessibility
65
+
66
+ If you add buttons to the footer, you can use the accessibility attributes described in [`lightning-button`](bundle/lightning-button/documentation).
67
+
68
+ When the modal opens, focus goes to the first interactive element in the modal. If there are no links in the header or any interactive elements
69
+ in the modal body, the first footer button gets initial focus.
70
+
71
+ See [Lightning Web Components Developer Guide](docs/component-library/documentation/en/lwc/) for more information about accessibility in modals.
72
+
@@ -0,0 +1,8 @@
1
+ <template>
2
+ <div class={footerCssClasses}>
3
+ <slot
4
+ data-footer-slot
5
+ onslotchange={handleDefaultSlotChange}
6
+ ></slot>
7
+ </div>
8
+ </template>
@@ -0,0 +1,161 @@
1
+ import { LightningElement } from 'lwc';
2
+ import { classSet } from 'lightning/utils';
3
+ import { findAllTabbableElements, filterTooltips } from 'lightning/focusUtils';
4
+
5
+ // SLDS Modal Footer classes
6
+ const footerClass = 'slds-modal__footer';
7
+ const hideClass = 'slds-hide';
8
+ // selectors
9
+ const footerSelector = `.${footerClass}`;
10
+ const footerSlotSelector = '[data-footer-slot]';
11
+
12
+ /**
13
+ * The modal footer component to display footer content in lightning modal.
14
+ * */
15
+ export default class LightningModalFooter extends LightningElement {
16
+ // tracked private state
17
+ initialRender = true;
18
+ initialSlotRender = true;
19
+ hideFooter = false;
20
+ unregisterCallback = null;
21
+
22
+ /**
23
+ * Handle the default slot change event
24
+ * Always register with parent every slot change
25
+ * @private
26
+ */
27
+ handleDefaultSlotChange() {
28
+ // Set this once so that parent can know slot
29
+ // has rendered
30
+ if (this.initialSlotRender) {
31
+ this.initialSlotRender = false;
32
+ }
33
+ this.registerWithParent();
34
+ this.hideFooter = !this.isDefaultSlotPopulated;
35
+ }
36
+
37
+ /**
38
+ * Gets the CSS classes applicable to the modal footer element.
39
+ * Hidden classes are set when the footer is hidden
40
+ * @returns {string} CSS class applied to modal footer
41
+ * @private
42
+ */
43
+ get footerCssClasses() {
44
+ const classes = classSet(footerClass);
45
+ classes.add({
46
+ [hideClass]: this.hideFooter,
47
+ });
48
+ return classes.toString();
49
+ }
50
+
51
+ /**
52
+ * Get the height of outer wrapper of modal footer
53
+ * @returns {number} represents a height value in pixels
54
+ * @private
55
+ */
56
+ get footerHeight() {
57
+ const divElem = this.template.querySelector(footerSelector);
58
+ const footerRect = divElem ? divElem.getBoundingClientRect() : {};
59
+ const { height } = footerRect;
60
+ return height || 0;
61
+ }
62
+
63
+ /**
64
+ * Get an element reference to the modal footer's slot element
65
+ * @returns {(HTMLElement|null)}
66
+ * @private
67
+ */
68
+ get defaultSlotElement() {
69
+ return this.template.querySelector(footerSlotSelector);
70
+ }
71
+
72
+ /**
73
+ * Determine whether the default slot is populated
74
+ * @returns {boolean}
75
+ * @private
76
+ */
77
+ get isDefaultSlotPopulated() {
78
+ const slotElement = this.defaultSlotElement;
79
+ if (slotElement && slotElement.assignedNodes) {
80
+ return slotElement.assignedNodes().length > 0;
81
+ }
82
+ return true;
83
+ }
84
+
85
+ /**
86
+ * Get first tabbable element within modalFooter's slot, if exists
87
+ * This is passed to parent in order to possibly be used for autoFocus
88
+ * @returns {(HTMLElement|null)}
89
+ * @private
90
+ */
91
+ get firstTabbableElement() {
92
+ let firstElem = null;
93
+ if (this.isDefaultSlotPopulated) {
94
+ const filteredElements = filterTooltips(
95
+ findAllTabbableElements(this.defaultSlotElement)
96
+ );
97
+ if (filteredElements.length > 0) {
98
+ firstElem = filteredElements[0];
99
+ }
100
+ }
101
+ return firstElem;
102
+ }
103
+
104
+ /**
105
+ * Register modalFooter with modal parent, including callbacks to
106
+ * unregister the modal footer
107
+ * this will get called multiple times over component lifecycle
108
+ * @type {CustomEvent}
109
+ * @private
110
+ */
111
+ registerWithParent() {
112
+ const evtRegister = new CustomEvent('privatemodalfooterregister', {
113
+ bubbles: true,
114
+ composed: true,
115
+ detail: {
116
+ footerHeight: this.footerHeight,
117
+ defaultSlotIsPopulated: this.isDefaultSlotPopulated,
118
+ defaultSlotHasRendered: !this.initialSlotRender,
119
+ firstTabbableElemRef: this.firstTabbableElement,
120
+ unRegisterCallback: (unregisterCallback) => {
121
+ this.unregisterCallback = unregisterCallback;
122
+ },
123
+ },
124
+ });
125
+ this.dispatchEvent(evtRegister);
126
+ }
127
+
128
+ /**
129
+ * When modal footer is being created, initialize
130
+ * private tracked modal footer state
131
+ * This is need because modal footer can be added back to
132
+ * the DOM, after being removed, and need to re-initialize state values
133
+ * @private
134
+ */
135
+ initState() {
136
+ this.initialRender = true;
137
+ this.initialSlotRender = true;
138
+ this.hideFooter = false;
139
+ this.unregisterCallback = null;
140
+ }
141
+
142
+ connectedCallback() {
143
+ // handle case where modalFooter is added/removed/added to DOM
144
+ // so registerWithParent gets called
145
+ this.initState();
146
+ }
147
+
148
+ disconnectedCallback() {
149
+ if (this.unregisterCallback) {
150
+ this.unregisterCallback();
151
+ }
152
+ }
153
+
154
+ renderedCallback() {
155
+ if (this.initialRender) {
156
+ this.registerWithParent();
157
+ this.initialRender = false;
158
+ }
159
+ this.hideFooter = !this.isDefaultSlotPopulated;
160
+ }
161
+ }
@@ -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>55.0</minApiVersion>
5
+ <support>GA</support>
6
+ </LightningComponentBundle>
@@ -0,0 +1,64 @@
1
+ The `lightning-modal-header` component displays header text in a panel at the top of a modal dialog.
2
+ Use of a header is optional, but when you provide a header you must specify the header text with the `label` attribute.
3
+
4
+ If you don't use the `lightning-modal-header` component, you must set a label
5
+ in the modal you create by extending `LightningModal`. A label is required for accessibility.
6
+
7
+ The modal components render in the order they appear in the template. Place the `lightning-modal-header`
8
+ component before the `lightning-modal-body` component in the template.
9
+
10
+ `lightning-modal-header` supports optional tagline text, which displays in smaller text below the heading. Enclose the
11
+ tagline text directly in the `lightning-modal-header` component, no HTML tag or attribute is needed. You can include links with `<a>`
12
+ tags, which are the only HTML elements permitted. If the header text is too long to fit on one line, it wraps in the modal header.
13
+
14
+ This sample code shows the expected order of the modal components. The modal content is
15
+ created in a separate component extended from `LightningModal`. See
16
+ [Lightning Web Components Developer Guide](docs/component-library/documentation/en/lwc/)
17
+
18
+ ```html
19
+ <!-- my/modalDialog.html -->
20
+ <template>
21
+ <lightning-modal-header label="My Modal">
22
+ Tagline can be descriptive content with <a href="https://www.example.com">links</a> and can wrap to multiple lines.
23
+ </lightning-modal-header>
24
+ <lightning-modal-body>
25
+ <!-- modal content specified in LightningModal component -->
26
+ </lightning-modal-body>
27
+ </template>
28
+ ```
29
+ #### Component Styling
30
+
31
+ `lightning-modal-header` implements the [modals](https://www.lightningdesignsystem.com/components/modals/) blueprint in the Salesforce Lightning Design System (SLDS).
32
+
33
+ To apply custom styling, use the `:host` selector or define a custom class using the `class` attribute.
34
+
35
+ ```html
36
+ <lightning-modal-header label="My Modal" class="my-modal-header">
37
+
38
+ </lightning-modal-header>
39
+ ```
40
+
41
+ Use SLDS styling hooks to customize the component's styles. Several `--sds-c-modal-header-*` and `--sds-c-modal-heading-*` hooks
42
+ enable you to customize the header.
43
+
44
+ For example, specify the background color on the button using the `sds-c-modal-header-color-background` custom property.
45
+
46
+ ```css
47
+ .my-modal-header {
48
+ --sds-c-modal-header-color-background: LightGray;
49
+ }
50
+ ```
51
+
52
+ See the modal blueprint's [Styling Hooks Overview](https://www.lightningdesignsystem.com/components/modals/#Styling-Hooks-Overview) for a list of CSS custom properties.
53
+
54
+ For more information, see [Style Components Using Lightning Design System Styling Hooks](docs/component-library/documentation/lwc/lwc.create_components_css_custom_properties) in the Lightning Web Components Developer Guide.
55
+
56
+ #### Accessibility
57
+
58
+ When you use `lightning-modal-header` in your modal, the rendered modal provides an `aria-labelledby` attribute set to the ID of the header element.
59
+ If you don't use `lightning-modal-header`, the accessible label is provided using `aria-label` set to the label you provide in the modal.
60
+
61
+ When the modal opens, focus goes to the first interactive element in the modal. If the header includes a link in tagline text, the link
62
+ gets initial focus.
63
+
64
+ See [Lightning Web Components Developer Guide](docs/component-library/documentation/en/lwc/) for more information about accessibility in modals.
@@ -0,0 +1,16 @@
1
+ <template>
2
+ <div class="slds-modal__header">
3
+ <template if:true={label}>
4
+ <h1
5
+ id="modal-label"
6
+ class="slds-modal__title slds-hyphenate"
7
+ tabindex="-1"
8
+ data-label
9
+ >{label}</h1>
10
+ </template>
11
+ <slot
12
+ data-default-slot
13
+ onslotchange={handleDefaultSlotChange}
14
+ ></slot>
15
+ </div>
16
+ </template>