@carbon/ibmdotcom-utilities 2.10.0-nightly.9410213135.0 → 2.10.0

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.
@@ -21,32 +21,20 @@ var StickyHeader = /*#__PURE__*/function () {
21
21
  function StickyHeader() {
22
22
  _classCallCheck(this, StickyHeader);
23
23
  this.ownerDocument = root.document;
24
- this._state = {
25
- cumulativeOffset: 0,
26
- hasBanner: false,
27
- leadspaceSearchThreshold: 0,
28
- mastheadL0IsActive: false,
29
- mastheadL1IsActive: false,
30
- maxScrollaway: 0,
31
- scrollPosPrevious: 0,
32
- scrollPos: 0,
33
- searchIsAtTop: false,
34
- tocShouldStick: false,
35
- tocIsAtTop: false,
36
- tocIsAtSearch: false
37
- };
38
- this._elements = {
39
- banner: undefined,
40
- leadspaceSearch: undefined,
41
- leadspaceSearchBar: undefined,
42
- leadspaceSearchInput: undefined,
43
- localeModal: undefined,
44
- masthead: undefined,
45
- mastheadL0: undefined,
46
- mastheadL1: undefined,
47
- tableOfContents: undefined,
48
- tableOfContentsInnerBar: undefined
49
- };
24
+ this._banner = undefined;
25
+ this._cumulativeHeight = 0;
26
+ this._hasBanner = false;
27
+ this._lastScrollPosition = 0;
28
+ this._leadspaceWithSearch = undefined;
29
+ this._leadspaceSearchBar = undefined;
30
+ this._leadspaceWithSearchStickyThreshold = 0;
31
+ this._localeModal = undefined;
32
+ this._masthead = undefined;
33
+ this._mastheadL0 = undefined;
34
+ this._mastheadL1 = undefined;
35
+ this._tableOfContents = undefined;
36
+ this._tableOfContentsInnerBar = undefined;
37
+ this._tableOfContentsLayout = undefined;
50
38
  this._throttled = false;
51
39
  this._resizeObserver = new ResizeObserver(this._handleResize.bind(this));
52
40
  root.addEventListener('scroll', this._throttledHandler.bind(this));
@@ -58,7 +46,7 @@ var StickyHeader = /*#__PURE__*/function () {
58
46
  return _createClass(StickyHeader, [{
59
47
  key: "height",
60
48
  get: function get() {
61
- return this._state.cumulativeOffset;
49
+ return this._cumulativeHeight;
62
50
  }
63
51
 
64
52
  /**
@@ -79,71 +67,73 @@ var StickyHeader = /*#__PURE__*/function () {
79
67
  return true;
80
68
  }
81
69
  }
82
-
83
- /**
84
- * Stores references to TOC sub-elements that are relevant to current viewport
85
- * dimensions.
86
- */
87
70
  }, {
88
- key: "_updateTableOfContentsRefs",
89
- value: function _updateTableOfContentsRefs() {
90
- var toc = this._elements.tableOfContents;
71
+ key: "_tableOfContentsStickyUpdate",
72
+ value: function _tableOfContentsStickyUpdate() {
73
+ var toc = this._tableOfContents;
91
74
  var tocRoot = toc.shadowRoot;
92
- this._elements.tableOfContentsInnerBar = tocRoot.querySelector(window.innerWidth >= gridBreakpoint && (toc === null || toc === void 0 ? void 0 : toc.layout) !== 'horizontal' ? ".".concat(c4dPrefix, "-ce--table-of-contents__items-container") : ".".concat(prefix, "--tableofcontents__navbar"));
75
+ this._tableOfContentsInnerBar = tocRoot.querySelector(".".concat(prefix, "--tableofcontents__navbar"));
76
+ if (window.innerWidth > gridBreakpoint) {
77
+ if (toc.layout === 'horizontal') {
78
+ this._tableOfContentsLayout = 'horizontal';
79
+ } else {
80
+ this._tableOfContentsInnerBar = tocRoot.querySelector(".".concat(c4dPrefix, "-ce--table-of-contents__items-container"));
81
+ }
82
+ }
93
83
  }
94
84
  }, {
95
85
  key: "banner",
96
86
  set: function set(component) {
97
87
  if (this._validateComponent(component, "".concat(c4dPrefix, "-global-banner"))) {
98
- this._elements.banner = component;
99
- this._state.hasBanner = true;
100
- if (this._elements.masthead) {
101
- this._elements.masthead.setAttribute('with-banner', '');
88
+ this._banner = component;
89
+ this.hasBanner = true;
90
+ if (this._masthead) {
91
+ this._masthead.setAttribute('with-banner', '');
102
92
  }
103
- this._manageStickyElements();
93
+ this._calculateCumulativeHeight();
104
94
  }
105
95
  }
106
96
  }, {
107
- key: "leadspaceSearch",
97
+ key: "leadspaceWithSearch",
108
98
  set: function set(component) {
109
99
  if (this._validateComponent(component, "".concat(c4dPrefix, "-leadspace-with-search"))) {
110
- this._elements.leadspaceSearch = component;
100
+ this._leadspaceWithSearch = component;
111
101
  var leadspaceSearchBar = component.shadowRoot.querySelector(".".concat(prefix, "--search-container"));
112
- this._elements.leadspaceSearchBar = leadspaceSearchBar;
113
- this._elements.leadspaceSearchInput = component.querySelector("".concat(c4dPrefix, "-search-with-typeahead"));
114
- this._state.leadspaceSearchThreshold = parseInt(window.getComputedStyle(leadspaceSearchBar).paddingBottom) - 16;
115
- this._manageStickyElements();
102
+ this._leadspaceSearchBar = leadspaceSearchBar;
103
+ this._leadspaceWithSearchInput = component.querySelector("".concat(c4dPrefix, "-search-with-typeahead"));
104
+ this._leadspaceWithSearchStickyThreshold = parseInt(window.getComputedStyle(leadspaceSearchBar).paddingBottom) - 16;
105
+ this._calculateCumulativeHeight();
116
106
  }
117
107
  }
118
108
  }, {
119
109
  key: "localeModal",
120
110
  set: function set(component) {
121
111
  if (this._validateComponent(component, "".concat(c4dPrefix, "-locale-modal"))) {
122
- this._elements.localeModal = component;
123
- this._manageStickyElements();
112
+ this._localeModal = component;
113
+ this._calculateCumulativeHeight();
124
114
  }
125
115
  }
126
116
  }, {
127
117
  key: "masthead",
128
118
  set: function set(component) {
129
119
  if (this._validateComponent(component, "".concat(c4dPrefix, "-masthead"))) {
130
- this._elements.masthead = component;
131
- if (this._elements.banner) {
132
- this._elements.masthead.setAttribute('with-banner', '');
120
+ this._masthead = component;
121
+ if (this._banner) {
122
+ this._masthead.setAttribute('with-banner', '');
133
123
  }
134
- this._elements.mastheadL0 = component.shadowRoot.querySelector(".".concat(prefix, "--masthead__l0"));
135
- this._elements.mastheadL1 = component.querySelector("".concat(c4dPrefix, "-masthead-l1"));
136
- this._manageStickyElements();
124
+ this._mastheadL0 = component.shadowRoot.querySelector(".".concat(prefix, "--masthead__l0"));
125
+ this._mastheadL1 = component.querySelector("".concat(c4dPrefix, "-masthead-l1"));
126
+ this._calculateCumulativeHeight();
137
127
  }
138
128
  }
139
129
  }, {
140
130
  key: "tableOfContents",
141
131
  set: function set(component) {
142
132
  if (this._validateComponent(component, "".concat(c4dPrefix, "-table-of-contents"))) {
143
- this._elements.tableOfContents = component;
144
- this._updateTableOfContentsRefs();
145
- this._resizeObserver.observe(this._elements.tableOfContents);
146
- this._manageStickyElements();
133
+ this._tableOfContents = component;
134
+ this._tableOfContentsStickyUpdate();
135
+ this._resizeObserver.observe(this._tableOfContents);
136
+ this._calculateCumulativeHeight();
147
137
  }
148
138
  }
149
139
 
@@ -156,7 +146,7 @@ var StickyHeader = /*#__PURE__*/function () {
156
146
  var _this = this;
157
147
  if (!this._throttled) {
158
148
  this._throttled = true;
159
- this._manageStickyElements();
149
+ this._calculateCumulativeHeight();
160
150
  setTimeout(function () {
161
151
  _this._throttled = false;
162
152
  }, 20);
@@ -165,197 +155,95 @@ var StickyHeader = /*#__PURE__*/function () {
165
155
  }, {
166
156
  key: "_handleResize",
167
157
  value: function _handleResize() {
168
- var hasBanner = this._state._hasBanner;
169
- var _this$_elements = this._elements,
170
- masthead = _this$_elements.masthead,
171
- toc = _this$_elements.tableOfContents,
172
- leadspaceSearchBar = _this$_elements.leadspaceSearchBar;
158
+ var hasBanner = this._hasBanner,
159
+ masthead = this._masthead,
160
+ toc = this._tableOfContents,
161
+ tocLayout = this._tableOfContentsLayout,
162
+ leadspaceSearchBar = this._leadspaceSearchBar;
173
163
  if (toc && masthead) {
174
- this._updateTableOfContentsRefs();
175
- if (window.innerWidth >= gridBreakpoint && toc.layout !== 'horizontal' && !hasBanner) {
176
- masthead.style.insetBlockStart = '0';
164
+ this._tableOfContentsStickyUpdate();
165
+ if (window.innerWidth >= gridBreakpoint && tocLayout !== 'horizontal' && !hasBanner) {
166
+ masthead.style.top = '0';
177
167
  } else {
178
- // This has to happen after the _updateTableOfContentsRefs method.
179
- var tocInner = this._elements.tableOfContentsInnerBar;
168
+ // This has to happen after the tocStickyUpdate method.
169
+ var tocInner = this._tableOfContentsInnerBar;
180
170
  if (masthead.offsetTop === 0) {
181
- tocInner.style.insetBlockStart = "".concat(masthead.offsetHeight, "px");
171
+ tocInner.style.top = "".concat(masthead.offsetHeight, "px");
182
172
  }
183
173
  }
184
- this._manageStickyElements();
174
+ this._calculateCumulativeHeight();
185
175
  }
186
176
  if (leadspaceSearchBar) {
187
- this._state.leadspaceSearchThreshold = parseInt(window.getComputedStyle(leadspaceSearchBar).paddingBottom) - 16;
177
+ this._leadspaceWithSearchStickyThreshold = parseInt(window.getComputedStyle(leadspaceSearchBar).paddingBottom) - 16;
188
178
  }
189
179
  }
190
-
191
- /**
192
- * Handles the banner given the current scroll position.
193
- */
194
180
  }, {
195
- key: "_handleBanner",
196
- value: function _handleBanner() {
197
- var banner = this._elements.banner;
198
- var scrollPos = this._state.scrollPos;
199
- this._state.cumulativeOffset += Math.max(banner.offsetHeight - scrollPos, 0);
200
- }
201
-
202
- /**
203
- * Handles the masthead given the current scroll position.
204
- */
205
- }, {
206
- key: "_handleMasthead",
207
- value: function _handleMasthead() {
208
- var masthead = this._elements.masthead;
209
- masthead.style.transition = 'none';
210
- masthead.style.insetBlockStart = "".concat(this._state.cumulativeOffset, "px");
211
-
212
- // Masthead always sticks, therefore always add its height.
213
- this._state.cumulativeOffset += masthead.offsetHeight;
214
- }
215
-
216
- /**
217
- * Handles the table of contents given the current scroll position.
218
- */
219
- }, {
220
- key: "_handleToc",
221
- value: function _handleToc() {
222
- var tableOfContentsInnerBar = this._elements.tableOfContentsInnerBar;
223
- var tocShouldStick = this._state.tocShouldStick;
224
- tableOfContentsInnerBar.style.transition = 'none';
225
- tableOfContentsInnerBar.style.insetBlockStart = "".concat(this._state.cumulativeOffset, "px");
226
- var tocIsStuck = Math.round(tableOfContentsInnerBar.getBoundingClientRect().top) <= this._state.cumulativeOffset + 1;
227
- if (tocShouldStick && tocIsStuck) {
228
- this._state.cumulativeOffset += tableOfContentsInnerBar.offsetHeight;
229
- }
230
- }
231
-
232
- /**
233
- * Handles the leadspace search given the current scroll position.
234
- */
235
- }, {
236
- key: "_handleLeadspaceSearch",
237
- value: function _handleLeadspaceSearch() {
238
- var _this$_elements2 = this._elements,
239
- leadspaceSearch = _this$_elements2.leadspaceSearch,
240
- leadspaceSearchBar = _this$_elements2.leadspaceSearchBar,
241
- leadspaceSearchInput = _this$_elements2.leadspaceSearchInput;
242
- var leadspaceSearchThreshold = this._state.leadspaceSearchThreshold;
243
- var searchShouldBeSticky = leadspaceSearch.getBoundingClientRect().bottom <= leadspaceSearchThreshold;
244
- var searchIsSticky = leadspaceSearch.hasAttribute('sticky-search');
245
- if (searchShouldBeSticky) {
246
- if (!searchIsSticky) {
247
- leadspaceSearch.style.paddingBottom = "".concat(leadspaceSearchBar.offsetHeight, "px");
248
- leadspaceSearch.setAttribute('sticky-search', '');
249
- leadspaceSearchInput.setAttribute('large', '');
250
- window.requestAnimationFrame(function () {
251
- leadspaceSearchBar.style.transitionDuration = '110ms';
252
- leadspaceSearchBar.style.transform = 'translateY(0)';
253
- });
254
- }
255
- leadspaceSearchBar.style.insetBlockStart = "".concat(this._state.cumulativeOffset, "px");
256
- this._state.cumulativeOffset += leadspaceSearchBar.offsetHeight;
257
- } else if (searchIsSticky) {
258
- leadspaceSearch.style.paddingBottom = '';
259
- leadspaceSearch.removeAttribute('sticky-search');
260
- leadspaceSearchInput.removeAttribute('large');
261
- leadspaceSearchBar.style.transitionDuration = '';
262
- leadspaceSearchBar.style.transform = '';
263
- leadspaceSearchBar.style.insetBlockStart = '';
181
+ key: "_calculateCumulativeHeight",
182
+ value: function _calculateCumulativeHeight() {
183
+ var _StickyHeader$global = StickyHeader.global,
184
+ oldY = _StickyHeader$global._lastScrollPosition,
185
+ banner = _StickyHeader$global._banner,
186
+ masthead = _StickyHeader$global._masthead,
187
+ mastheadL0 = _StickyHeader$global._mastheadL0,
188
+ mastheadL1 = _StickyHeader$global._mastheadL1,
189
+ localeModal = _StickyHeader$global._localeModal,
190
+ toc = _StickyHeader$global._tableOfContents,
191
+ tocInner = _StickyHeader$global._tableOfContentsInnerBar,
192
+ leadspaceSearch = _StickyHeader$global._leadspaceWithSearch,
193
+ leadspaceSearchBar = _StickyHeader$global._leadspaceSearchBar,
194
+ leadspaceSearchInput = _StickyHeader$global._leadspaceWithSearchInput,
195
+ leadspaceSearchThreshold = _StickyHeader$global._leadspaceWithSearchStickyThreshold;
196
+ var customPropertyName = this.constructor.customPropertyName;
197
+ if (localeModal && localeModal.hasAttribute('open')) {
198
+ return;
264
199
  }
265
- }
266
-
267
- /**
268
- * Calculates a value matching the height of all components that are allowed
269
- * to hide above the viewport.
270
- *
271
- * Adding an item's height to this value indicates we expect it to be hidden
272
- * above the viewport.
273
- *
274
- * Items that stick, in order
275
- * - L0
276
- * - L1
277
- * - The TOC in horizontal bar form
278
- * - The leadspace with search (if no TOC)
279
- */
280
- }, {
281
- key: "_calculateMaxScrollaway",
282
- value: function _calculateMaxScrollaway() {
283
- var _this$_elements3 = this._elements,
284
- masthead = _this$_elements3.masthead,
285
- mastheadL0 = _this$_elements3.mastheadL0,
286
- mastheadL1 = _this$_elements3.mastheadL1,
287
- tableOfContents = _this$_elements3.tableOfContents,
288
- tableOfContentsInnerBar = _this$_elements3.tableOfContentsInnerBar,
289
- leadspaceSearchBar = _this$_elements3.leadspaceSearchBar;
290
-
291
- // Reset the value before performing any further calculations.
292
- this._state.maxScrollaway = 0;
200
+ var newY = window.scrollY;
201
+ this._lastScrollPosition = Math.max(0, newY);
293
202
 
294
- // Collect conditions we may want to test for to make logic easier to read.
295
- this._state.tocShouldStick = tableOfContents ? tableOfContents.layout === 'horizontal' || window.innerWidth < gridBreakpoint : false;
296
- this._state.tocIsAtTop = tableOfContentsInnerBar ? tableOfContentsInnerBar.getBoundingClientRect().top <= this.height + 1 : false;
297
- this._state.searchIsAtTop = leadspaceSearchBar ? leadspaceSearchBar.getBoundingClientRect().top <= this.height + 1 : false;
298
- this._state.tocIsAtSearch = leadspaceSearchBar && tableOfContentsInnerBar ? tableOfContentsInnerBar.getBoundingClientRect().top <= leadspaceSearchBar.getBoundingClientRect().bottom : false;
299
- this._state.mastheadL0IsActive = Boolean(masthead === null || masthead === void 0 ? void 0 : masthead.querySelector('[expanded]'));
300
- this._state.mastheadL1IsActive = mastheadL1 && mastheadL1.hasAttribute('active');
301
- var _this$_state = this._state,
302
- tocShouldStick = _this$_state.tocShouldStick,
303
- tocIsAtTop = _this$_state.tocIsAtTop,
304
- searchIsAtTop = _this$_state.searchIsAtTop,
305
- tocIsAtSearch = _this$_state.tocIsAtSearch,
306
- mastheadL0IsActive = _this$_state.mastheadL0IsActive,
307
- mastheadL1IsActive = _this$_state.mastheadL1IsActive;
308
-
309
- // Begin calculating maxScrollAway.
310
-
311
- // If L0 is open, lock it to the top of the page.
312
- if (mastheadL0 && mastheadL0IsActive) {
313
- this._state.maxScrollaway = 0;
314
- }
315
- // If L1 is open, lock it to the top of the page.
316
- else if (mastheadL1IsActive && mastheadL0) {
317
- this._state.maxScrollaway = mastheadL0.offsetHeight;
318
- } else {
319
- // In cases where we have both an eligible ToC and leadspace search, we want
320
- // the ToC to take precedence. Scroll away leadspace search.
321
- if (searchIsAtTop && tocIsAtSearch && tocShouldStick) {
322
- this._state.maxScrollaway += leadspaceSearchBar.offsetHeight;
323
- }
203
+ /**
204
+ * maxScrollaway is a calculated value matching the height of all components
205
+ * that are allowed to hide above the viewport.
206
+ *
207
+ * We should only have one sticky header showing as the page scrolls down.
208
+ *
209
+ * Items that stick, in order
210
+ * - L0
211
+ * - L1
212
+ * - The TOC in horizontal bar form
213
+ * - The leadspace with search (if no TOC)
214
+ */
215
+ var maxScrollaway = 0;
324
216
 
325
- // Scroll away entire masthead if either ToC or leadspace search is eligible
326
- // to be the stuck element (unless L1 is open). Otherwise, scroll away the
327
- // L0 if we have an L1.
328
- if (searchIsAtTop || tocIsAtTop && tocShouldStick) {
329
- if (masthead) {
330
- this._state.maxScrollaway += masthead.offsetHeight;
217
+ // Calculate maxScrollaway values based on TOC positon
218
+ var tocIsAtTop = false;
219
+ var tocShouldStick = false;
220
+ if (tocInner) {
221
+ tocIsAtTop = tocInner.getBoundingClientRect().top <= (masthead ? masthead.offsetTop + masthead.offsetHeight : 0) + 1;
222
+ tocShouldStick = toc.layout === 'horizontal' || window.innerWidth < gridBreakpoint;
223
+ if (masthead && tocIsAtTop && (tocShouldStick || mastheadL1)) {
224
+ maxScrollaway += masthead.offsetHeight;
225
+ if (mastheadL1 && !tocShouldStick) {
226
+ maxScrollaway -= mastheadL1.offsetHeight;
331
227
  }
332
- } else if (masthead && mastheadL0 && mastheadL1) {
333
- this._state.maxScrollaway += mastheadL0.offsetHeight;
228
+ } else if (mastheadL0 && mastheadL1) {
229
+ maxScrollaway += mastheadL0.offsetHeight;
334
230
  }
335
231
  }
336
- }
337
232
 
338
- /**
339
- * Positions sticky elements. Does so by checking the scroll position and where
340
- * tracked elements are in relation to it, then applying the correct styles to
341
- * each element in succession to ensure that only one element is stuck to the
342
- * top of the page, and all other elements that have been scrolled past can be
343
- * revealed when scrolling back up.
344
- */
345
- }, {
346
- key: "_positionElements",
347
- value: function _positionElements() {
348
- var _this$_elements4 = this._elements,
349
- banner = _this$_elements4.banner,
350
- masthead = _this$_elements4.masthead,
351
- tocInner = _this$_elements4.tableOfContentsInnerBar,
352
- leadspaceSearchBar = _this$_elements4.leadspaceSearchBar;
353
- var oldY = this._state.scrollPosPrevious;
233
+ // Calculate maxScrollaway values based on leadspace search position
234
+ if (!tocInner && leadspaceSearchBar) {
235
+ var searchIsAtTop = leadspaceSearchBar.getBoundingClientRect().top <= (masthead ? masthead.offsetTop + masthead.offsetHeight : 0) + 1;
236
+ if (masthead && searchIsAtTop) {
237
+ maxScrollaway += masthead.offsetHeight;
238
+ }
239
+ }
354
240
 
355
241
  /**
356
- * Reset to a value that is equal to the difference between the previous
357
- * scrollY and the current scrollY values, but is positively and negatively
358
- * limited.
242
+ * Cumulative offset is a calculated value used to set the `top` property of
243
+ * components that stick to the top of the viewport.
244
+ *
245
+ * This value is equal to the difference between the previous scrollY and
246
+ * the current scrollY values, but is positively and negatively limited.
359
247
  *
360
248
  * Positive limit: 0
361
249
  * all elements visible, starting at the top of the viewport.
@@ -365,58 +253,55 @@ var StickyHeader = /*#__PURE__*/function () {
365
253
  * with the elements that should be visible starting at the top of the
366
254
  * viewport.
367
255
  */
368
- this._state.cumulativeOffset = Math.max(Math.min((masthead ? masthead.offsetTop : 0) + oldY - this._state.scrollPos, 0), this._state.maxScrollaway * -1);
369
-
370
- /**
371
- * Handle each potentially sticky element in the order we expect them to
372
- * appear on the page. Important to do this sequentially for
373
- * cumulativeOffset to be correctly calculated by the time each of these
374
- * methods accesses it.
375
- *
376
- * To-do: One idea for improving this so the execution order doesn't matter
377
- * is to collect our elements into an array ordered by document position,
378
- * then loop over that array and execute a corresponding handler method.
379
- */
256
+ var cumulativeOffset = Math.max(Math.min((masthead ? masthead.offsetTop : 0) + oldY - newY, 0), maxScrollaway * -1);
380
257
  if (banner) {
381
- this._handleBanner();
258
+ cumulativeOffset += Math.max(banner.offsetHeight - newY, 0);
382
259
  }
383
260
  if (masthead) {
384
- this._handleMasthead();
385
- }
386
- if (leadspaceSearchBar) {
387
- this._handleLeadspaceSearch();
261
+ masthead.style.transition = 'none';
262
+ masthead.style.top = "".concat(cumulativeOffset, "px");
263
+ cumulativeOffset += masthead.offsetHeight;
388
264
  }
389
265
  if (tocInner) {
390
- this._handleToc();
266
+ tocInner.style.transition = 'none';
267
+ tocInner.style.top = "".concat(cumulativeOffset, "px");
268
+ tocShouldStick = toc.layout === 'horizontal' || window.innerWidth < gridBreakpoint;
269
+ var tocIsStuck = Math.round(tocInner.getBoundingClientRect().top) <= cumulativeOffset + 1;
270
+ if (tocShouldStick && tocIsStuck) {
271
+ cumulativeOffset += tocInner.offsetHeight;
272
+ }
391
273
  }
392
- }
393
-
394
- /**
395
- * Manages which elements are stuck and where they are positioned. We should
396
- * only have one element stuck to the top of the viewport as the page scrolls
397
- * down.
398
- */
399
- }, {
400
- key: "_manageStickyElements",
401
- value: function _manageStickyElements() {
402
- var localeModal = this._elements.localeModal;
403
- var scrollPosPrevious = this._state.scrollPos;
404
-
405
- // Exit early if locale modal is open.
406
- if (localeModal && localeModal.hasAttribute('open')) {
407
- return;
274
+ if (!tocInner && leadspaceSearchBar) {
275
+ var searchShouldBeSticky = leadspaceSearch.getBoundingClientRect().bottom <= leadspaceSearchThreshold;
276
+ var searchIsSticky = leadspaceSearch.hasAttribute('sticky-search');
277
+ if (searchShouldBeSticky) {
278
+ if (!searchIsSticky) {
279
+ leadspaceSearch.style.paddingBottom = "".concat(leadspaceSearchBar.offsetHeight, "px");
280
+ leadspaceSearch.setAttribute('sticky-search', '');
281
+ leadspaceSearchInput.setAttribute('large', '');
282
+ window.requestAnimationFrame(function () {
283
+ leadspaceSearchBar.style.transitionDuration = '110ms';
284
+ leadspaceSearchBar.style.transform = 'translateY(0)';
285
+ });
286
+ }
287
+ leadspaceSearchBar.style.top = "".concat(cumulativeOffset, "px");
288
+ cumulativeOffset += leadspaceSearchBar.offsetHeight;
289
+ }
290
+ if (!searchShouldBeSticky && searchIsSticky) {
291
+ leadspaceSearch.removeAttribute('sticky-search');
292
+ leadspaceSearch.style.paddingBottom = '';
293
+ leadspaceSearchBar.style.top = '';
294
+ leadspaceSearchBar.style.transitionDuration = '';
295
+ leadspaceSearchBar.style.transform = '';
296
+ leadspaceSearchInput.removeAttribute('large');
297
+ }
408
298
  }
409
299
 
410
- // Store scroll positions.
411
- this._state.scrollPosPrevious = scrollPosPrevious;
412
- this._state.scrollPos = Math.max(0, window.scrollY);
413
-
414
- // Given the current state, calculate how elements should be positioned.
415
- this._calculateMaxScrollaway();
416
- this._positionElements();
300
+ // Set internal property for use in scripts
301
+ this._cumulativeHeight = cumulativeOffset;
417
302
 
418
303
  // Set custom property for use in stylesheets
419
- root.document.documentElement.style.setProperty(this.constructor.customPropertyName, "".concat(this._state.cumulativeOffset, "px"));
304
+ root.document.documentElement.style.setProperty(customPropertyName, "".concat(this._cumulativeHeight, "px"));
420
305
  }
421
306
  }], [{
422
307
  key: "global",
@@ -26,32 +26,20 @@ var StickyHeader = /*#__PURE__*/function () {
26
26
  function StickyHeader() {
27
27
  _classCallCheck(this, StickyHeader);
28
28
  this.ownerDocument = _windowOrGlobal.default.document;
29
- this._state = {
30
- cumulativeOffset: 0,
31
- hasBanner: false,
32
- leadspaceSearchThreshold: 0,
33
- mastheadL0IsActive: false,
34
- mastheadL1IsActive: false,
35
- maxScrollaway: 0,
36
- scrollPosPrevious: 0,
37
- scrollPos: 0,
38
- searchIsAtTop: false,
39
- tocShouldStick: false,
40
- tocIsAtTop: false,
41
- tocIsAtSearch: false
42
- };
43
- this._elements = {
44
- banner: undefined,
45
- leadspaceSearch: undefined,
46
- leadspaceSearchBar: undefined,
47
- leadspaceSearchInput: undefined,
48
- localeModal: undefined,
49
- masthead: undefined,
50
- mastheadL0: undefined,
51
- mastheadL1: undefined,
52
- tableOfContents: undefined,
53
- tableOfContentsInnerBar: undefined
54
- };
29
+ this._banner = undefined;
30
+ this._cumulativeHeight = 0;
31
+ this._hasBanner = false;
32
+ this._lastScrollPosition = 0;
33
+ this._leadspaceWithSearch = undefined;
34
+ this._leadspaceSearchBar = undefined;
35
+ this._leadspaceWithSearchStickyThreshold = 0;
36
+ this._localeModal = undefined;
37
+ this._masthead = undefined;
38
+ this._mastheadL0 = undefined;
39
+ this._mastheadL1 = undefined;
40
+ this._tableOfContents = undefined;
41
+ this._tableOfContentsInnerBar = undefined;
42
+ this._tableOfContentsLayout = undefined;
55
43
  this._throttled = false;
56
44
  this._resizeObserver = new ResizeObserver(this._handleResize.bind(this));
57
45
  _windowOrGlobal.default.addEventListener('scroll', this._throttledHandler.bind(this));
@@ -63,7 +51,7 @@ var StickyHeader = /*#__PURE__*/function () {
63
51
  return _createClass(StickyHeader, [{
64
52
  key: "height",
65
53
  get: function get() {
66
- return this._state.cumulativeOffset;
54
+ return this._cumulativeHeight;
67
55
  }
68
56
 
69
57
  /**
@@ -84,71 +72,73 @@ var StickyHeader = /*#__PURE__*/function () {
84
72
  return true;
85
73
  }
86
74
  }
87
-
88
- /**
89
- * Stores references to TOC sub-elements that are relevant to current viewport
90
- * dimensions.
91
- */
92
75
  }, {
93
- key: "_updateTableOfContentsRefs",
94
- value: function _updateTableOfContentsRefs() {
95
- var toc = this._elements.tableOfContents;
76
+ key: "_tableOfContentsStickyUpdate",
77
+ value: function _tableOfContentsStickyUpdate() {
78
+ var toc = this._tableOfContents;
96
79
  var tocRoot = toc.shadowRoot;
97
- this._elements.tableOfContentsInnerBar = tocRoot.querySelector(window.innerWidth >= gridBreakpoint && (toc === null || toc === void 0 ? void 0 : toc.layout) !== 'horizontal' ? ".".concat(c4dPrefix, "-ce--table-of-contents__items-container") : ".".concat(prefix, "--tableofcontents__navbar"));
80
+ this._tableOfContentsInnerBar = tocRoot.querySelector(".".concat(prefix, "--tableofcontents__navbar"));
81
+ if (window.innerWidth > gridBreakpoint) {
82
+ if (toc.layout === 'horizontal') {
83
+ this._tableOfContentsLayout = 'horizontal';
84
+ } else {
85
+ this._tableOfContentsInnerBar = tocRoot.querySelector(".".concat(c4dPrefix, "-ce--table-of-contents__items-container"));
86
+ }
87
+ }
98
88
  }
99
89
  }, {
100
90
  key: "banner",
101
91
  set: function set(component) {
102
92
  if (this._validateComponent(component, "".concat(c4dPrefix, "-global-banner"))) {
103
- this._elements.banner = component;
104
- this._state.hasBanner = true;
105
- if (this._elements.masthead) {
106
- this._elements.masthead.setAttribute('with-banner', '');
93
+ this._banner = component;
94
+ this.hasBanner = true;
95
+ if (this._masthead) {
96
+ this._masthead.setAttribute('with-banner', '');
107
97
  }
108
- this._manageStickyElements();
98
+ this._calculateCumulativeHeight();
109
99
  }
110
100
  }
111
101
  }, {
112
- key: "leadspaceSearch",
102
+ key: "leadspaceWithSearch",
113
103
  set: function set(component) {
114
104
  if (this._validateComponent(component, "".concat(c4dPrefix, "-leadspace-with-search"))) {
115
- this._elements.leadspaceSearch = component;
105
+ this._leadspaceWithSearch = component;
116
106
  var leadspaceSearchBar = component.shadowRoot.querySelector(".".concat(prefix, "--search-container"));
117
- this._elements.leadspaceSearchBar = leadspaceSearchBar;
118
- this._elements.leadspaceSearchInput = component.querySelector("".concat(c4dPrefix, "-search-with-typeahead"));
119
- this._state.leadspaceSearchThreshold = parseInt(window.getComputedStyle(leadspaceSearchBar).paddingBottom) - 16;
120
- this._manageStickyElements();
107
+ this._leadspaceSearchBar = leadspaceSearchBar;
108
+ this._leadspaceWithSearchInput = component.querySelector("".concat(c4dPrefix, "-search-with-typeahead"));
109
+ this._leadspaceWithSearchStickyThreshold = parseInt(window.getComputedStyle(leadspaceSearchBar).paddingBottom) - 16;
110
+ this._calculateCumulativeHeight();
121
111
  }
122
112
  }
123
113
  }, {
124
114
  key: "localeModal",
125
115
  set: function set(component) {
126
116
  if (this._validateComponent(component, "".concat(c4dPrefix, "-locale-modal"))) {
127
- this._elements.localeModal = component;
128
- this._manageStickyElements();
117
+ this._localeModal = component;
118
+ this._calculateCumulativeHeight();
129
119
  }
130
120
  }
131
121
  }, {
132
122
  key: "masthead",
133
123
  set: function set(component) {
134
124
  if (this._validateComponent(component, "".concat(c4dPrefix, "-masthead"))) {
135
- this._elements.masthead = component;
136
- if (this._elements.banner) {
137
- this._elements.masthead.setAttribute('with-banner', '');
125
+ this._masthead = component;
126
+ if (this._banner) {
127
+ this._masthead.setAttribute('with-banner', '');
138
128
  }
139
- this._elements.mastheadL0 = component.shadowRoot.querySelector(".".concat(prefix, "--masthead__l0"));
140
- this._elements.mastheadL1 = component.querySelector("".concat(c4dPrefix, "-masthead-l1"));
141
- this._manageStickyElements();
129
+ this._mastheadL0 = component.shadowRoot.querySelector(".".concat(prefix, "--masthead__l0"));
130
+ this._mastheadL1 = component.querySelector("".concat(c4dPrefix, "-masthead-l1"));
131
+ this._calculateCumulativeHeight();
142
132
  }
143
133
  }
144
134
  }, {
145
135
  key: "tableOfContents",
146
136
  set: function set(component) {
147
137
  if (this._validateComponent(component, "".concat(c4dPrefix, "-table-of-contents"))) {
148
- this._elements.tableOfContents = component;
149
- this._updateTableOfContentsRefs();
150
- this._resizeObserver.observe(this._elements.tableOfContents);
151
- this._manageStickyElements();
138
+ this._tableOfContents = component;
139
+ this._tableOfContentsStickyUpdate();
140
+ this._resizeObserver.observe(this._tableOfContents);
141
+ this._calculateCumulativeHeight();
152
142
  }
153
143
  }
154
144
 
@@ -161,7 +151,7 @@ var StickyHeader = /*#__PURE__*/function () {
161
151
  var _this = this;
162
152
  if (!this._throttled) {
163
153
  this._throttled = true;
164
- this._manageStickyElements();
154
+ this._calculateCumulativeHeight();
165
155
  setTimeout(function () {
166
156
  _this._throttled = false;
167
157
  }, 20);
@@ -170,197 +160,95 @@ var StickyHeader = /*#__PURE__*/function () {
170
160
  }, {
171
161
  key: "_handleResize",
172
162
  value: function _handleResize() {
173
- var hasBanner = this._state._hasBanner;
174
- var _this$_elements = this._elements,
175
- masthead = _this$_elements.masthead,
176
- toc = _this$_elements.tableOfContents,
177
- leadspaceSearchBar = _this$_elements.leadspaceSearchBar;
163
+ var hasBanner = this._hasBanner,
164
+ masthead = this._masthead,
165
+ toc = this._tableOfContents,
166
+ tocLayout = this._tableOfContentsLayout,
167
+ leadspaceSearchBar = this._leadspaceSearchBar;
178
168
  if (toc && masthead) {
179
- this._updateTableOfContentsRefs();
180
- if (window.innerWidth >= gridBreakpoint && toc.layout !== 'horizontal' && !hasBanner) {
181
- masthead.style.insetBlockStart = '0';
169
+ this._tableOfContentsStickyUpdate();
170
+ if (window.innerWidth >= gridBreakpoint && tocLayout !== 'horizontal' && !hasBanner) {
171
+ masthead.style.top = '0';
182
172
  } else {
183
- // This has to happen after the _updateTableOfContentsRefs method.
184
- var tocInner = this._elements.tableOfContentsInnerBar;
173
+ // This has to happen after the tocStickyUpdate method.
174
+ var tocInner = this._tableOfContentsInnerBar;
185
175
  if (masthead.offsetTop === 0) {
186
- tocInner.style.insetBlockStart = "".concat(masthead.offsetHeight, "px");
176
+ tocInner.style.top = "".concat(masthead.offsetHeight, "px");
187
177
  }
188
178
  }
189
- this._manageStickyElements();
179
+ this._calculateCumulativeHeight();
190
180
  }
191
181
  if (leadspaceSearchBar) {
192
- this._state.leadspaceSearchThreshold = parseInt(window.getComputedStyle(leadspaceSearchBar).paddingBottom) - 16;
182
+ this._leadspaceWithSearchStickyThreshold = parseInt(window.getComputedStyle(leadspaceSearchBar).paddingBottom) - 16;
193
183
  }
194
184
  }
195
-
196
- /**
197
- * Handles the banner given the current scroll position.
198
- */
199
185
  }, {
200
- key: "_handleBanner",
201
- value: function _handleBanner() {
202
- var banner = this._elements.banner;
203
- var scrollPos = this._state.scrollPos;
204
- this._state.cumulativeOffset += Math.max(banner.offsetHeight - scrollPos, 0);
205
- }
206
-
207
- /**
208
- * Handles the masthead given the current scroll position.
209
- */
210
- }, {
211
- key: "_handleMasthead",
212
- value: function _handleMasthead() {
213
- var masthead = this._elements.masthead;
214
- masthead.style.transition = 'none';
215
- masthead.style.insetBlockStart = "".concat(this._state.cumulativeOffset, "px");
216
-
217
- // Masthead always sticks, therefore always add its height.
218
- this._state.cumulativeOffset += masthead.offsetHeight;
219
- }
220
-
221
- /**
222
- * Handles the table of contents given the current scroll position.
223
- */
224
- }, {
225
- key: "_handleToc",
226
- value: function _handleToc() {
227
- var tableOfContentsInnerBar = this._elements.tableOfContentsInnerBar;
228
- var tocShouldStick = this._state.tocShouldStick;
229
- tableOfContentsInnerBar.style.transition = 'none';
230
- tableOfContentsInnerBar.style.insetBlockStart = "".concat(this._state.cumulativeOffset, "px");
231
- var tocIsStuck = Math.round(tableOfContentsInnerBar.getBoundingClientRect().top) <= this._state.cumulativeOffset + 1;
232
- if (tocShouldStick && tocIsStuck) {
233
- this._state.cumulativeOffset += tableOfContentsInnerBar.offsetHeight;
234
- }
235
- }
236
-
237
- /**
238
- * Handles the leadspace search given the current scroll position.
239
- */
240
- }, {
241
- key: "_handleLeadspaceSearch",
242
- value: function _handleLeadspaceSearch() {
243
- var _this$_elements2 = this._elements,
244
- leadspaceSearch = _this$_elements2.leadspaceSearch,
245
- leadspaceSearchBar = _this$_elements2.leadspaceSearchBar,
246
- leadspaceSearchInput = _this$_elements2.leadspaceSearchInput;
247
- var leadspaceSearchThreshold = this._state.leadspaceSearchThreshold;
248
- var searchShouldBeSticky = leadspaceSearch.getBoundingClientRect().bottom <= leadspaceSearchThreshold;
249
- var searchIsSticky = leadspaceSearch.hasAttribute('sticky-search');
250
- if (searchShouldBeSticky) {
251
- if (!searchIsSticky) {
252
- leadspaceSearch.style.paddingBottom = "".concat(leadspaceSearchBar.offsetHeight, "px");
253
- leadspaceSearch.setAttribute('sticky-search', '');
254
- leadspaceSearchInput.setAttribute('large', '');
255
- window.requestAnimationFrame(function () {
256
- leadspaceSearchBar.style.transitionDuration = '110ms';
257
- leadspaceSearchBar.style.transform = 'translateY(0)';
258
- });
259
- }
260
- leadspaceSearchBar.style.insetBlockStart = "".concat(this._state.cumulativeOffset, "px");
261
- this._state.cumulativeOffset += leadspaceSearchBar.offsetHeight;
262
- } else if (searchIsSticky) {
263
- leadspaceSearch.style.paddingBottom = '';
264
- leadspaceSearch.removeAttribute('sticky-search');
265
- leadspaceSearchInput.removeAttribute('large');
266
- leadspaceSearchBar.style.transitionDuration = '';
267
- leadspaceSearchBar.style.transform = '';
268
- leadspaceSearchBar.style.insetBlockStart = '';
186
+ key: "_calculateCumulativeHeight",
187
+ value: function _calculateCumulativeHeight() {
188
+ var _StickyHeader$global = StickyHeader.global,
189
+ oldY = _StickyHeader$global._lastScrollPosition,
190
+ banner = _StickyHeader$global._banner,
191
+ masthead = _StickyHeader$global._masthead,
192
+ mastheadL0 = _StickyHeader$global._mastheadL0,
193
+ mastheadL1 = _StickyHeader$global._mastheadL1,
194
+ localeModal = _StickyHeader$global._localeModal,
195
+ toc = _StickyHeader$global._tableOfContents,
196
+ tocInner = _StickyHeader$global._tableOfContentsInnerBar,
197
+ leadspaceSearch = _StickyHeader$global._leadspaceWithSearch,
198
+ leadspaceSearchBar = _StickyHeader$global._leadspaceSearchBar,
199
+ leadspaceSearchInput = _StickyHeader$global._leadspaceWithSearchInput,
200
+ leadspaceSearchThreshold = _StickyHeader$global._leadspaceWithSearchStickyThreshold;
201
+ var customPropertyName = this.constructor.customPropertyName;
202
+ if (localeModal && localeModal.hasAttribute('open')) {
203
+ return;
269
204
  }
270
- }
271
-
272
- /**
273
- * Calculates a value matching the height of all components that are allowed
274
- * to hide above the viewport.
275
- *
276
- * Adding an item's height to this value indicates we expect it to be hidden
277
- * above the viewport.
278
- *
279
- * Items that stick, in order
280
- * - L0
281
- * - L1
282
- * - The TOC in horizontal bar form
283
- * - The leadspace with search (if no TOC)
284
- */
285
- }, {
286
- key: "_calculateMaxScrollaway",
287
- value: function _calculateMaxScrollaway() {
288
- var _this$_elements3 = this._elements,
289
- masthead = _this$_elements3.masthead,
290
- mastheadL0 = _this$_elements3.mastheadL0,
291
- mastheadL1 = _this$_elements3.mastheadL1,
292
- tableOfContents = _this$_elements3.tableOfContents,
293
- tableOfContentsInnerBar = _this$_elements3.tableOfContentsInnerBar,
294
- leadspaceSearchBar = _this$_elements3.leadspaceSearchBar;
295
-
296
- // Reset the value before performing any further calculations.
297
- this._state.maxScrollaway = 0;
205
+ var newY = window.scrollY;
206
+ this._lastScrollPosition = Math.max(0, newY);
298
207
 
299
- // Collect conditions we may want to test for to make logic easier to read.
300
- this._state.tocShouldStick = tableOfContents ? tableOfContents.layout === 'horizontal' || window.innerWidth < gridBreakpoint : false;
301
- this._state.tocIsAtTop = tableOfContentsInnerBar ? tableOfContentsInnerBar.getBoundingClientRect().top <= this.height + 1 : false;
302
- this._state.searchIsAtTop = leadspaceSearchBar ? leadspaceSearchBar.getBoundingClientRect().top <= this.height + 1 : false;
303
- this._state.tocIsAtSearch = leadspaceSearchBar && tableOfContentsInnerBar ? tableOfContentsInnerBar.getBoundingClientRect().top <= leadspaceSearchBar.getBoundingClientRect().bottom : false;
304
- this._state.mastheadL0IsActive = Boolean(masthead === null || masthead === void 0 ? void 0 : masthead.querySelector('[expanded]'));
305
- this._state.mastheadL1IsActive = mastheadL1 && mastheadL1.hasAttribute('active');
306
- var _this$_state = this._state,
307
- tocShouldStick = _this$_state.tocShouldStick,
308
- tocIsAtTop = _this$_state.tocIsAtTop,
309
- searchIsAtTop = _this$_state.searchIsAtTop,
310
- tocIsAtSearch = _this$_state.tocIsAtSearch,
311
- mastheadL0IsActive = _this$_state.mastheadL0IsActive,
312
- mastheadL1IsActive = _this$_state.mastheadL1IsActive;
313
-
314
- // Begin calculating maxScrollAway.
315
-
316
- // If L0 is open, lock it to the top of the page.
317
- if (mastheadL0 && mastheadL0IsActive) {
318
- this._state.maxScrollaway = 0;
319
- }
320
- // If L1 is open, lock it to the top of the page.
321
- else if (mastheadL1IsActive && mastheadL0) {
322
- this._state.maxScrollaway = mastheadL0.offsetHeight;
323
- } else {
324
- // In cases where we have both an eligible ToC and leadspace search, we want
325
- // the ToC to take precedence. Scroll away leadspace search.
326
- if (searchIsAtTop && tocIsAtSearch && tocShouldStick) {
327
- this._state.maxScrollaway += leadspaceSearchBar.offsetHeight;
328
- }
208
+ /**
209
+ * maxScrollaway is a calculated value matching the height of all components
210
+ * that are allowed to hide above the viewport.
211
+ *
212
+ * We should only have one sticky header showing as the page scrolls down.
213
+ *
214
+ * Items that stick, in order
215
+ * - L0
216
+ * - L1
217
+ * - The TOC in horizontal bar form
218
+ * - The leadspace with search (if no TOC)
219
+ */
220
+ var maxScrollaway = 0;
329
221
 
330
- // Scroll away entire masthead if either ToC or leadspace search is eligible
331
- // to be the stuck element (unless L1 is open). Otherwise, scroll away the
332
- // L0 if we have an L1.
333
- if (searchIsAtTop || tocIsAtTop && tocShouldStick) {
334
- if (masthead) {
335
- this._state.maxScrollaway += masthead.offsetHeight;
222
+ // Calculate maxScrollaway values based on TOC positon
223
+ var tocIsAtTop = false;
224
+ var tocShouldStick = false;
225
+ if (tocInner) {
226
+ tocIsAtTop = tocInner.getBoundingClientRect().top <= (masthead ? masthead.offsetTop + masthead.offsetHeight : 0) + 1;
227
+ tocShouldStick = toc.layout === 'horizontal' || window.innerWidth < gridBreakpoint;
228
+ if (masthead && tocIsAtTop && (tocShouldStick || mastheadL1)) {
229
+ maxScrollaway += masthead.offsetHeight;
230
+ if (mastheadL1 && !tocShouldStick) {
231
+ maxScrollaway -= mastheadL1.offsetHeight;
336
232
  }
337
- } else if (masthead && mastheadL0 && mastheadL1) {
338
- this._state.maxScrollaway += mastheadL0.offsetHeight;
233
+ } else if (mastheadL0 && mastheadL1) {
234
+ maxScrollaway += mastheadL0.offsetHeight;
339
235
  }
340
236
  }
341
- }
342
237
 
343
- /**
344
- * Positions sticky elements. Does so by checking the scroll position and where
345
- * tracked elements are in relation to it, then applying the correct styles to
346
- * each element in succession to ensure that only one element is stuck to the
347
- * top of the page, and all other elements that have been scrolled past can be
348
- * revealed when scrolling back up.
349
- */
350
- }, {
351
- key: "_positionElements",
352
- value: function _positionElements() {
353
- var _this$_elements4 = this._elements,
354
- banner = _this$_elements4.banner,
355
- masthead = _this$_elements4.masthead,
356
- tocInner = _this$_elements4.tableOfContentsInnerBar,
357
- leadspaceSearchBar = _this$_elements4.leadspaceSearchBar;
358
- var oldY = this._state.scrollPosPrevious;
238
+ // Calculate maxScrollaway values based on leadspace search position
239
+ if (!tocInner && leadspaceSearchBar) {
240
+ var searchIsAtTop = leadspaceSearchBar.getBoundingClientRect().top <= (masthead ? masthead.offsetTop + masthead.offsetHeight : 0) + 1;
241
+ if (masthead && searchIsAtTop) {
242
+ maxScrollaway += masthead.offsetHeight;
243
+ }
244
+ }
359
245
 
360
246
  /**
361
- * Reset to a value that is equal to the difference between the previous
362
- * scrollY and the current scrollY values, but is positively and negatively
363
- * limited.
247
+ * Cumulative offset is a calculated value used to set the `top` property of
248
+ * components that stick to the top of the viewport.
249
+ *
250
+ * This value is equal to the difference between the previous scrollY and
251
+ * the current scrollY values, but is positively and negatively limited.
364
252
  *
365
253
  * Positive limit: 0
366
254
  * all elements visible, starting at the top of the viewport.
@@ -370,58 +258,55 @@ var StickyHeader = /*#__PURE__*/function () {
370
258
  * with the elements that should be visible starting at the top of the
371
259
  * viewport.
372
260
  */
373
- this._state.cumulativeOffset = Math.max(Math.min((masthead ? masthead.offsetTop : 0) + oldY - this._state.scrollPos, 0), this._state.maxScrollaway * -1);
374
-
375
- /**
376
- * Handle each potentially sticky element in the order we expect them to
377
- * appear on the page. Important to do this sequentially for
378
- * cumulativeOffset to be correctly calculated by the time each of these
379
- * methods accesses it.
380
- *
381
- * To-do: One idea for improving this so the execution order doesn't matter
382
- * is to collect our elements into an array ordered by document position,
383
- * then loop over that array and execute a corresponding handler method.
384
- */
261
+ var cumulativeOffset = Math.max(Math.min((masthead ? masthead.offsetTop : 0) + oldY - newY, 0), maxScrollaway * -1);
385
262
  if (banner) {
386
- this._handleBanner();
263
+ cumulativeOffset += Math.max(banner.offsetHeight - newY, 0);
387
264
  }
388
265
  if (masthead) {
389
- this._handleMasthead();
390
- }
391
- if (leadspaceSearchBar) {
392
- this._handleLeadspaceSearch();
266
+ masthead.style.transition = 'none';
267
+ masthead.style.top = "".concat(cumulativeOffset, "px");
268
+ cumulativeOffset += masthead.offsetHeight;
393
269
  }
394
270
  if (tocInner) {
395
- this._handleToc();
271
+ tocInner.style.transition = 'none';
272
+ tocInner.style.top = "".concat(cumulativeOffset, "px");
273
+ tocShouldStick = toc.layout === 'horizontal' || window.innerWidth < gridBreakpoint;
274
+ var tocIsStuck = Math.round(tocInner.getBoundingClientRect().top) <= cumulativeOffset + 1;
275
+ if (tocShouldStick && tocIsStuck) {
276
+ cumulativeOffset += tocInner.offsetHeight;
277
+ }
396
278
  }
397
- }
398
-
399
- /**
400
- * Manages which elements are stuck and where they are positioned. We should
401
- * only have one element stuck to the top of the viewport as the page scrolls
402
- * down.
403
- */
404
- }, {
405
- key: "_manageStickyElements",
406
- value: function _manageStickyElements() {
407
- var localeModal = this._elements.localeModal;
408
- var scrollPosPrevious = this._state.scrollPos;
409
-
410
- // Exit early if locale modal is open.
411
- if (localeModal && localeModal.hasAttribute('open')) {
412
- return;
279
+ if (!tocInner && leadspaceSearchBar) {
280
+ var searchShouldBeSticky = leadspaceSearch.getBoundingClientRect().bottom <= leadspaceSearchThreshold;
281
+ var searchIsSticky = leadspaceSearch.hasAttribute('sticky-search');
282
+ if (searchShouldBeSticky) {
283
+ if (!searchIsSticky) {
284
+ leadspaceSearch.style.paddingBottom = "".concat(leadspaceSearchBar.offsetHeight, "px");
285
+ leadspaceSearch.setAttribute('sticky-search', '');
286
+ leadspaceSearchInput.setAttribute('large', '');
287
+ window.requestAnimationFrame(function () {
288
+ leadspaceSearchBar.style.transitionDuration = '110ms';
289
+ leadspaceSearchBar.style.transform = 'translateY(0)';
290
+ });
291
+ }
292
+ leadspaceSearchBar.style.top = "".concat(cumulativeOffset, "px");
293
+ cumulativeOffset += leadspaceSearchBar.offsetHeight;
294
+ }
295
+ if (!searchShouldBeSticky && searchIsSticky) {
296
+ leadspaceSearch.removeAttribute('sticky-search');
297
+ leadspaceSearch.style.paddingBottom = '';
298
+ leadspaceSearchBar.style.top = '';
299
+ leadspaceSearchBar.style.transitionDuration = '';
300
+ leadspaceSearchBar.style.transform = '';
301
+ leadspaceSearchInput.removeAttribute('large');
302
+ }
413
303
  }
414
304
 
415
- // Store scroll positions.
416
- this._state.scrollPosPrevious = scrollPosPrevious;
417
- this._state.scrollPos = Math.max(0, window.scrollY);
418
-
419
- // Given the current state, calculate how elements should be positioned.
420
- this._calculateMaxScrollaway();
421
- this._positionElements();
305
+ // Set internal property for use in scripts
306
+ this._cumulativeHeight = cumulativeOffset;
422
307
 
423
308
  // Set custom property for use in stylesheets
424
- _windowOrGlobal.default.document.documentElement.style.setProperty(this.constructor.customPropertyName, "".concat(this._state.cumulativeOffset, "px"));
309
+ _windowOrGlobal.default.document.documentElement.style.setProperty(customPropertyName, "".concat(this._cumulativeHeight, "px"));
425
310
  }
426
311
  }], [{
427
312
  key: "global",
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@carbon/ibmdotcom-utilities",
3
3
  "description": "Carbon for IBM.com Utilities",
4
- "version": "2.10.0-nightly.9410213135.0+f2470de",
4
+ "version": "2.10.0",
5
5
  "license": "Apache-2.0",
6
6
  "main": "lib/index.js",
7
7
  "module": "es/index.js",
@@ -88,5 +88,5 @@
88
88
  "rollup-plugin-sizes": "^1.0.4",
89
89
  "whatwg-fetch": "^2.0.3"
90
90
  },
91
- "gitHead": "f2470dea34a4de7b3ff0649ce8c1f4b087a4bee8"
91
+ "gitHead": "b278340f97ec7714b4adedaada0d1d5e8ae37990"
92
92
  }