lightning-base-components 1.17.6-alpha → 1.18.1-alpha

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lightning-base-components",
3
- "version": "1.17.6-alpha",
3
+ "version": "1.18.1-alpha",
4
4
  "license": "MIT",
5
5
  "files": [
6
6
  "external",
@@ -1 +1 @@
1
- export default '242';
1
+ export default '244';
@@ -165,7 +165,7 @@ export default class AriaObserver {
165
165
  }
166
166
  }
167
167
 
168
- privateExtractCorrectElements(selector, elements) {
168
+ privateExtractCorrectElements(selector = '', elements) {
169
169
  // Example: 'foo' + '-1'
170
170
  const selectors = selector.split(/\s/g);
171
171
  const matchSelectors = `(${selectors.join('|')})`;
@@ -193,11 +193,25 @@ export default class AriaObserver {
193
193
  for (const liveId in this.liveIds) {
194
194
  if (Object.prototype.hasOwnProperty.call(this.liveIds, liveId)) {
195
195
  const thisId = this.liveIds[liveId];
196
- if (!thisId.elements) {
196
+ if (!thisId.elements?.length) {
197
+ const splitRefIds = splitIds(liveId);
197
198
  // element refs are cached
198
- thisId.elements = Array.prototype.slice.call(
199
- root.querySelectorAll(thisId.selector)
200
- );
199
+ const refElements = [
200
+ ...root.querySelectorAll(thisId.selector),
201
+ ];
202
+
203
+ thisId.elements = refElements.sort((a, b) => {
204
+ const idA = a
205
+ .getAttribute('id')
206
+ ?.replace(/-[0-9]+$/g, '');
207
+ const idB = b
208
+ .getAttribute('id')
209
+ ?.replace(/-[0-9]+$/g, '');
210
+
211
+ return (
212
+ splitRefIds.indexOf(idA) - splitRefIds.indexOf(idB)
213
+ );
214
+ });
201
215
  }
202
216
  const newThisId = this.privateExtractCorrectElements(
203
217
  thisId.refs,
@@ -143,6 +143,7 @@ export default class LightningButtonIcon extends LightningPrimitiveButton {
143
143
  tooltipValue = null;
144
144
  tooltipType = TooltipType.Info;
145
145
  rendered = false;
146
+ showTitle = true;
146
147
 
147
148
  /**
148
149
  * Generate a tooltip with the specified value and current tooltip type
@@ -164,7 +165,7 @@ export default class LightningButtonIcon extends LightningPrimitiveButton {
164
165
  }
165
166
 
166
167
  get computedTitle() {
167
- return this.title || this.alternativeText || '';
168
+ return this.showTitle ? this.title || this.alternativeText || '' : null;
168
169
  }
169
170
 
170
171
  normalizeVariant(variant) {
@@ -322,9 +323,14 @@ export default class LightningButtonIcon extends LightningPrimitiveButton {
322
323
  cancelable: true,
323
324
  bubbles: true,
324
325
  detail: {
326
+ // Tooltip type should be toggle for some consumers like helptext
325
327
  setTooltipType: (tooltipType) => {
326
328
  this.tooltipType = tooltipType;
327
329
  },
330
+ // Title should not be set for some consumers like helptext (see W-12496300)
331
+ showTitle: (showTitle) => {
332
+ this.showTitle = showTitle;
333
+ },
328
334
  },
329
335
  })
330
336
  );
@@ -13,7 +13,7 @@
13
13
  </template>
14
14
 
15
15
  <template if:true={showMapLink}>
16
- <a title={mapQuery} href={mapUrl}
16
+ <a aria-label={mapQuery} href={mapUrl}
17
17
  tabindex={internalTabIndex} target="_blank" rel="noopener">
18
18
  <template for:each={addressLines} for:item="line">
19
19
  <div key={line} class="slds-truncate">
@@ -148,11 +148,12 @@ export default class LightningHelptext extends LightningElement {
148
148
 
149
149
  /**
150
150
  * Set lightning-button-icon tooltips to be created with toggle events
151
- *
151
+ * and without the title attribute computed from alternative text (see W-12496300)
152
152
  * @param {*} event
153
153
  */
154
154
  handleButtonIconRegister(event) {
155
155
  event.stopPropagation();
156
156
  event.detail.setTooltipType(TooltipType.Toggle);
157
+ event.detail.showTitle(false);
157
158
  }
158
159
  }
@@ -322,6 +322,8 @@ A modal can only fire events captured by the component that opened it, not the m
322
322
 
323
323
  To capture modal events, attach them in the `.open()` method invoked by the component that opens the modal.
324
324
 
325
+ Capturing modal events requires [Lightning Web Security (LWS)](https://developer.salesforce.com/docs/component-library/documentation/en/lwc/lwc.security_lwsec_enable) to be enabled in the Salesforce org. See the **Modal Events with LWS and Lightning Locker** section for more information.
326
+
325
327
  For example, here's a custom `select` event dispatched from `MyModal`.
326
328
 
327
329
  ```js
@@ -374,6 +376,14 @@ handleOpenModal() {
374
376
 
375
377
  See [Create and Dispatch Events](https://developer.salesforce.com/docs/component-library/documentation/en/lwc/events_create_dispatch) in the LWC Dev Guide for more information about events.
376
378
 
379
+ #### Modal Events with LWS and Lightning Locker
380
+
381
+ Modal events work as expected when Lightning Web Security (LWS) is enabled within a Salesforce org, as described in the **Modal Events** section. If LWS isn't enabled in an org, Lightning Locker is in effect.
382
+
383
+ LWS is replacing Lightning Locker over time and is already enabled in many customer orgs. New orgs have LWS enabled by default. To enable LWS, see [Enable Lightning Web Security in an Org](https://developer.salesforce.com/docs/component-library/documentation/en/lwc/security_lwsec_enable) in the Lightning Web Components Developer Guide.
384
+
385
+ Under Lightning Locker, when you fire events within `LightningModal`, the browser throws a `TypeError` related to `dispatchEvent`. If your modal component runs in an org that can’t enable LWS yet, the workaround is to wrap the code that calls `dispatchEvent` in a child component that extends `LightningElement`. Use the wrapper component as a child of one of the modal components in the modal template.
386
+
377
387
  #### Modal Events with Aura
378
388
 
379
389
  For `LightningModal`, only the top level LWC component or application can communicate to the parent Aura component or application layer with eventing. This topmost component is usually the one that opens the `LightningModal`. `LightningModal`'s child components can't event to a parent Aura component or application layer.
@@ -579,3 +589,4 @@ Customizing the styling on the white modal frame and background, close button, o
579
589
  The `lightning-modal-header` component renders the `label` value in an `<h1>` element. If your modal uses the header, begin any additional heading levels in the modal with `<h2>` for accessibility. Provide accessible structure by using heading levels up to `<h6>` appropriately. For more information, see [Semantic Structure, Headings on WebAim.org](https://webaim.org/techniques/semanticstructure/#headings).
580
590
 
581
591
  To include tagline text or link content for the header section, add it between the `<lightning-modal-header>` tags.
592
+
@@ -1,6 +1,6 @@
1
1
  <template>
2
2
  <lightning-modal-header label={header}>
3
- Here’s a tagline if you need it. It is allowed to extend across
3
+ Here’s a tagline if you need it. It is allowed to extend across
4
4
  mulitple lines, so I’m making up content to show that to you.
5
5
  It is allowed to have links but this one doesn't have any links.
6
6
  </lightning-modal-header>
@@ -50,6 +50,7 @@ export default class LightningModalBase extends LightningElement {
50
50
  headerLabelIsPopulated = null;
51
51
  headerTitleRef = null;
52
52
  headerTabElemRef = null;
53
+ headerHeightCheck = null;
53
54
 
54
55
  // modalBody, child
55
56
  bodyRegistered = false;
@@ -71,6 +72,7 @@ export default class LightningModalBase extends LightningElement {
71
72
  footerSlotHasRendered = false;
72
73
  footerDefaultSlotIsPopulated = false;
73
74
  footerTabElemRef = null;
75
+ footerHeightCheck = null;
74
76
 
75
77
  // aria attributes
76
78
  modalLabel = null;
@@ -360,9 +362,7 @@ export default class LightningModalBase extends LightningElement {
360
362
  * @private
361
363
  */
362
364
  get computedCloseButtonVariant() {
363
- return this.isSmallScreenSize && this.size === SIZE_FULL
364
- ? 'bare'
365
- : 'bare-inverse';
365
+ return this.shouldModalBeFullScreen() ? 'bare' : 'bare-inverse';
366
366
  }
367
367
 
368
368
  /**
@@ -820,6 +820,14 @@ export default class LightningModalBase extends LightningElement {
820
820
  this.updateAriaLabel();
821
821
  }
822
822
 
823
+ /**
824
+ * update the modalBase tracked header height value
825
+ * @private
826
+ */
827
+ updateHeaderHeight(value) {
828
+ this.headerHeight = !Number.isNaN(value) && value >= 0 ? value : 0;
829
+ }
830
+
823
831
  /**
824
832
  * Registers modalHeader with its parent modal, when present
825
833
  * Sets private tracked state about modalHeader
@@ -832,6 +840,7 @@ export default class LightningModalBase extends LightningElement {
832
840
  firstTabbableElemRef,
833
841
  defaultSlotWrapperId,
834
842
  defaultSlotHasRendered,
843
+ checkHeaderHeightCallback,
835
844
  unRegisterCallback,
836
845
  labelIsPopulated,
837
846
  headerHeight,
@@ -839,7 +848,7 @@ export default class LightningModalBase extends LightningElement {
839
848
  labelId,
840
849
  }) {
841
850
  this.headerRegistered = true;
842
- this.headerHeight = headerHeight || 0;
851
+ this.updateHeaderHeight(headerHeight);
843
852
  this.headerDefaultSlotIsPopulated = defaultSlotIsPopulated;
844
853
  this.headerSlotHasRendered = defaultSlotHasRendered;
845
854
  this.headerSlotWrapperId = defaultSlotWrapperId;
@@ -847,6 +856,7 @@ export default class LightningModalBase extends LightningElement {
847
856
  this.headerLabelIsPopulated = labelIsPopulated;
848
857
  this.headerTitleRef = headerRef;
849
858
  this.headerTabElemRef = firstTabbableElemRef;
859
+ this.headerHeightCheck = checkHeaderHeightCallback;
850
860
  unRegisterCallback(() => {
851
861
  this.unregisterHeader();
852
862
  });
@@ -884,6 +894,7 @@ export default class LightningModalBase extends LightningElement {
884
894
  this.headerLabelIsPopulated = null;
885
895
  this.headerTitleRef = null;
886
896
  this.headerTabElemRef = null;
897
+ this.headerHeightCheck = null;
887
898
  }
888
899
 
889
900
  /**
@@ -894,6 +905,14 @@ export default class LightningModalBase extends LightningElement {
894
905
  this.initFooterState();
895
906
  }
896
907
 
908
+ /**
909
+ * update the modalBase tracked footer height value
910
+ * @private
911
+ */
912
+ updateFooterHeight(value) {
913
+ this.footerHeight = !Number.isNaN(value) && value >= 0 ? value : 0;
914
+ }
915
+
897
916
  /**
898
917
  * Registers modalFooter with its parent modal, when present
899
918
  * Sets private tracked state about modalFooter
@@ -907,12 +926,14 @@ export default class LightningModalBase extends LightningElement {
907
926
  footerHeight,
908
927
  unRegisterCallback,
909
928
  firstTabbableElemRef,
929
+ checkFooterHeightCallback,
910
930
  }) {
911
931
  this.footerRegistered = true;
912
932
  this.footerDefaultSlotIsPopulated = defaultSlotIsPopulated;
913
933
  this.footerSlotHasRendered = defaultSlotHasRendered;
914
- this.footerHeight = footerHeight || 0;
934
+ this.updateFooterHeight(footerHeight);
915
935
  this.footerTabElemRef = firstTabbableElemRef || null;
936
+ this.footerHeightCheck = checkFooterHeightCallback;
916
937
  unRegisterCallback(() => {
917
938
  this.unregisterFooter();
918
939
  });
@@ -945,6 +966,7 @@ export default class LightningModalBase extends LightningElement {
945
966
  this.footerSlotHasRendered = false;
946
967
  this.footerDefaultSlotIsPopulated = false;
947
968
  this.footerTabElemRef = null;
969
+ this.footerHeightCheck = null;
948
970
  }
949
971
 
950
972
  /**
@@ -960,6 +982,63 @@ export default class LightningModalBase extends LightningElement {
960
982
  return this._resizing;
961
983
  }
962
984
 
985
+ /**
986
+ * Test to determine whether modal should display full screen behavior
987
+ * @returns {Boolean}
988
+ * @private
989
+ */
990
+ shouldModalBeFullScreen() {
991
+ return this.size === SIZE_FULL && this.isSmallScreenSize;
992
+ }
993
+
994
+ /**
995
+ * Under the right conditions, update the local tracked header height value
996
+ * @private
997
+ */
998
+ checkAndUpdateHeaderHeight() {
999
+ // important to verify that header is registered,
1000
+ // and not on initial render of modal parent, since
1001
+ // child component may not yet exist
1002
+ const shouldCheckHeaderHeight =
1003
+ !this.initialRender &&
1004
+ this.headerRegistered &&
1005
+ this.shouldModalBeFullScreen();
1006
+ // when screen size changes, variable height content within the
1007
+ // modal header can reflow
1008
+ // for example: 3 rows of content in tagline can become 2 rows
1009
+ if (shouldCheckHeaderHeight) {
1010
+ const { changed: headerChangedHeight, value: newHeaderHeight } =
1011
+ this.headerHeightCheck();
1012
+ if (headerChangedHeight) {
1013
+ this.updateHeaderHeight(newHeaderHeight);
1014
+ }
1015
+ }
1016
+ }
1017
+
1018
+ /**
1019
+ * Under the right conditions, update the local tracked footer height value
1020
+ * @private
1021
+ */
1022
+ checkAndUpdateFooterHeight() {
1023
+ // important to verify that footer is registered,
1024
+ // and not on initial render of modal parent, since
1025
+ // child component may not yet exist
1026
+ const shouldCheckFooterHeight =
1027
+ !this.initialRender &&
1028
+ this.footerRegistered &&
1029
+ this.shouldModalBeFullScreen();
1030
+ // when screen size changes, variable height content within the
1031
+ // modal footer can reflow
1032
+ // for example: 1 row of buttons to 2 rows, or 2 rows to 1 row
1033
+ if (shouldCheckFooterHeight) {
1034
+ const { changed: footerChangedHeight, value: newFooterHeight } =
1035
+ this.footerHeightCheck();
1036
+ if (footerChangedHeight) {
1037
+ this.updateFooterHeight(newFooterHeight);
1038
+ }
1039
+ }
1040
+ }
1041
+
963
1042
  /**
964
1043
  * When the modalBody content height is tall, it requires max-height
965
1044
  * to be set in order to prevent overflow of the modal offscreen
@@ -970,17 +1049,18 @@ export default class LightningModalBase extends LightningElement {
970
1049
  updateModalBodyHeight() {
971
1050
  clearTimeout(this.timeoutId);
972
1051
  this.timeoutId = 0;
973
- const { bodyResizeScheduled, bodyRegistered, baseUpdateBodyCallback } =
974
- this;
975
1052
 
976
- if (bodyRegistered && !bodyResizeScheduled) {
1053
+ if (this.bodyRegistered && !this.bodyResizeScheduled) {
977
1054
  // check, and update isSmallScreenSize before
978
1055
  // callback to modalBody
979
1056
  this.setIsSmallScreenSize();
1057
+ // check for height changes in header or footer
1058
+ this.checkAndUpdateHeaderHeight();
1059
+ this.checkAndUpdateFooterHeight();
980
1060
  // eslint-disable-next-line @lwc/lwc/no-async-operation
981
1061
  requestAnimationFrame(() => {
982
1062
  this.bodyResizeScheduled = false;
983
- if (bodyRegistered && baseUpdateBodyCallback) {
1063
+ if (this.baseUpdateBodyCallback) {
984
1064
  const values = {
985
1065
  footerHeight: this.footerHeight || 0,
986
1066
  headerHeight: this.headerHeight || 0,
@@ -990,7 +1070,7 @@ export default class LightningModalBase extends LightningElement {
990
1070
  sizeSetFull: this.size === SIZE_FULL,
991
1071
  isSmallScreenSize: this.isSmallScreenSize,
992
1072
  };
993
- baseUpdateBodyCallback(values);
1073
+ this.baseUpdateBodyCallback(values);
994
1074
  }
995
1075
  });
996
1076
  this.bodyResizeScheduled = true;
@@ -1050,8 +1130,7 @@ export default class LightningModalBase extends LightningElement {
1050
1130
  * @private
1051
1131
  */
1052
1132
  removeOrientationChangeListener() {
1053
- // TODO START HERE, check for this.windowOrientationEventBound === true
1054
- if (this.portraitMatchMedia) {
1133
+ if (this.windowOrientationEventBound && this.portraitMatchMedia) {
1055
1134
  this.portraitMatchMedia.removeEventListener(
1056
1135
  'change',
1057
1136
  this.screenOrientationChangeHandler
@@ -1072,7 +1151,7 @@ export default class LightningModalBase extends LightningElement {
1072
1151
  this.portraitMatchMedia = window.matchMedia('(orientation: portrait)');
1073
1152
  this.screenOrientationChangeHandler =
1074
1153
  this.handleWindowResizeEvent.bind(this);
1075
- if (typeof this.portraitMatchMedia === 'function') {
1154
+ if (this.portraitMatchMedia) {
1076
1155
  this.portraitMatchMedia.addEventListener(
1077
1156
  'change',
1078
1157
  this.screenOrientationChangeHandler
@@ -9,7 +9,11 @@ const hideClass = 'slds-hide';
9
9
  const footerSelector = `.${footerClass}`;
10
10
  const footerSlotSelector = '[data-footer-slot]';
11
11
  // timeout footer height check
12
+ // checking quickly yields faster resolution of correct
13
+ // footer (not a typo) placement
12
14
  const SIZE_CHECK_TIMER = 50;
15
+ // limited to 4 quick checks totalling 200 ms, which catches
16
+ // any misreported heights based on reflow of content in modalFooter
13
17
  const MAX_HEIGHT_CHECKS = 4;
14
18
 
15
19
  /**
@@ -109,6 +113,20 @@ export default class LightningModalFooter extends LightningElement {
109
113
  return firstElem;
110
114
  }
111
115
 
116
+ /**
117
+ * if not the intial render, check for footer height chnage,
118
+ * when a window resize occurs
119
+ * @returns {Object}
120
+ * @private
121
+ */
122
+ handleModalFooterResizeCheck() {
123
+ // when not intial render, and footer height changed
124
+ // return the tracked value, otherwise indicate no change
125
+ return !this.initialRender && this.hasFooterHeightChanged()
126
+ ? { changed: true, value: this.footerHeightTracked }
127
+ : { changed: false, value: null };
128
+ }
129
+
112
130
  /**
113
131
  * Register modalFooter with modal parent, including callbacks to
114
132
  * unregister the modal footer
@@ -125,6 +143,8 @@ export default class LightningModalFooter extends LightningElement {
125
143
  defaultSlotIsPopulated: this.isDefaultSlotPopulated,
126
144
  defaultSlotHasRendered: !this.initialSlotRender,
127
145
  firstTabbableElemRef: this.firstTabbableElement,
146
+ checkFooterHeightCallback:
147
+ this.handleModalFooterResizeCheck.bind(this),
128
148
  unRegisterCallback: (unregisterCallback) => {
129
149
  this.unregisterCallback = unregisterCallback;
130
150
  },
@@ -165,8 +185,7 @@ export default class LightningModalFooter extends LightningElement {
165
185
  this.footerHeightChecked = 0;
166
186
  } else {
167
187
  this.footerHeightChecked++;
168
- const hasChanged = this.hasFooterHeightChanged();
169
- if (hasChanged) {
188
+ if (this.hasFooterHeightChanged()) {
170
189
  this.registerWithParent();
171
190
  }
172
191
  }
@@ -7,6 +7,12 @@ const modalHeaderSelector = '.slds-modal__header';
7
7
  const labelSelector = '[data-label]';
8
8
  const slotWrapperSelector = '[data-slot-wrapper]';
9
9
  const defaultSlotSelector = '[data-default-slot]';
10
+ // timeout header height check
11
+ // checking quickly yields faster resolution of footer placement
12
+ const SIZE_CHECK_TIMER = 50;
13
+ // limited to 4 quick checks totalling 200 ms, which catches
14
+ // any misreported heights based on reflow of content
15
+ const MAX_HEIGHT_CHECKS = 4;
10
16
 
11
17
  /**
12
18
  * Creates a header to display the heading and tagline at the top of a modal.
@@ -16,6 +22,9 @@ export default class LightningModalHeader extends LightningElement {
16
22
  initialRender = true;
17
23
  initialSlotRender = true;
18
24
  unregisterCallback = null;
25
+ headerHeightTracked = 0;
26
+ headerHeightChecked = 0;
27
+ timeoutId = 0;
19
28
 
20
29
  /**
21
30
  * Text to display as the heading at the top of the modal
@@ -44,7 +53,9 @@ export default class LightningModalHeader extends LightningElement {
44
53
  const divElem = this.template.querySelector(modalHeaderSelector);
45
54
  const headerRect = divElem ? divElem.getBoundingClientRect() : {};
46
55
  const { height } = headerRect;
47
- return height || 0;
56
+ const heightValue = height || 0;
57
+ this.headerHeightTracked = heightValue;
58
+ return heightValue;
48
59
  }
49
60
 
50
61
  /**
@@ -144,6 +155,18 @@ export default class LightningModalHeader extends LightningElement {
144
155
  return (this.label && this.label.trim().length > 0) || false;
145
156
  }
146
157
 
158
+ /**
159
+ * if not the intial render, check for header height chnage,
160
+ * when a window resize occurs
161
+ * @returns {Object}
162
+ * @private
163
+ */
164
+ handleModalHeaderResizeCheck() {
165
+ return !this.initialRender && this.hasHeaderHeightChanged()
166
+ ? { changed: true, value: this.headerHeightTracked }
167
+ : { changed: false, value: null };
168
+ }
169
+
147
170
  /**
148
171
  * Register modalHeader with modal parent, including callbacks to
149
172
  * unregister the modal header
@@ -162,6 +185,8 @@ export default class LightningModalHeader extends LightningElement {
162
185
  defaultSlotWrapperId: this.defaultSlotWrapperId,
163
186
  defaultSlotIsPopulated: this.isDefaultSlotPopulated,
164
187
  defaultSlotHasRendered: !this.initialSlotRender,
188
+ checkHeaderHeightCallback:
189
+ this.handleModalHeaderResizeCheck.bind(this),
165
190
  unRegisterCallback: (unregisterCallback) => {
166
191
  this.unregisterCallback = unregisterCallback;
167
192
  },
@@ -172,6 +197,46 @@ export default class LightningModalHeader extends LightningElement {
172
197
  this.dispatchEvent(evtRegister);
173
198
  }
174
199
 
200
+ /**
201
+ * Provide a means to check whether the tracked header height
202
+ * is different than the current header height to only call modalBase
203
+ * when there is a change in header height
204
+ * @private
205
+ */
206
+ hasHeaderHeightChanged() {
207
+ // note: calling this.headerHeight updates this.headerHeightTracked
208
+ // order of values checked here is required
209
+ const previousRenderedHeight = this.headerHeightTracked;
210
+ const currentRenderedHeight = this.headerHeight;
211
+ return currentRenderedHeight !== previousRenderedHeight;
212
+ }
213
+
214
+ /**
215
+ * On first render, provide a quick means of updating modalBase,
216
+ * if the modalHeader height changes.
217
+ * In rare cases, the height of the header between the
218
+ * normal or full size rendering can change depending on
219
+ * content within the header and the window width
220
+ * @private
221
+ */
222
+ scheduleHeaderHeightCheck() {
223
+ if (this.initialRender && this.timeoutId === 0) {
224
+ // eslint-disable-next-line @lwc/lwc/no-async-operation
225
+ this.timeoutId = setInterval(() => {
226
+ if (this.headerHeightChecked >= MAX_HEIGHT_CHECKS) {
227
+ clearTimeout(this.timeoutId);
228
+ this.timeoutId = 0;
229
+ this.headerHeightChecked = 0;
230
+ } else {
231
+ this.headerHeightChecked++;
232
+ if (this.hasHeaderHeightChanged()) {
233
+ this.registerWithParent();
234
+ }
235
+ }
236
+ }, SIZE_CHECK_TIMER);
237
+ }
238
+ }
239
+
175
240
  /**
176
241
  * When modal header is being created, initialize
177
242
  * private tracked modal header state
@@ -183,6 +248,9 @@ export default class LightningModalHeader extends LightningElement {
183
248
  this.initialRender = true;
184
249
  this.initialSlotRender = true;
185
250
  this.unregisterCallback = null;
251
+ this.headerHeightTracked = 0;
252
+ this.headerHeightChecked = 0;
253
+ this.timeoutId = 0;
186
254
  }
187
255
 
188
256
  connectedCallback() {
@@ -192,6 +260,7 @@ export default class LightningModalHeader extends LightningElement {
192
260
  renderedCallback() {
193
261
  if (this.initialRender) {
194
262
  this.registerWithParent();
263
+ this.scheduleHeaderHeightCheck();
195
264
  this.initialRender = false;
196
265
  }
197
266
  }
@@ -44,19 +44,10 @@ Licensed under BSD 3-Clause - see LICENSE.txt or git.io/sfdc-license */
44
44
  cursor: pointer;
45
45
  }
46
46
 
47
- [type='search'] {
48
- -webkit-appearance: textfield;
49
- outline-offset: -2px;
50
- }
51
- button,
52
- input,
53
- optgroup,
54
- select,
55
- textarea {
56
- color: inherit;
57
- font: inherit;
58
- margin: 0;
59
- }
47
+ [type='search'] {
48
+ appearance: textfield;
49
+ outline-offset: -2px;
50
+ }
60
51
 
61
52
  input:focus,
62
53
  button:focus,
@@ -103,11 +94,3 @@ textarea {
103
94
  iframe {
104
95
  border-style: none;
105
96
  }
106
-
107
- svg:not([fill]) {
108
- fill: currentColor;
109
- }
110
-
111
- abbr[title] {
112
- text-decoration: none;
113
- }