1
1
import { baseStyles , CSSResultArray , html , LitElement , nothing , PropertyValues , TemplateResult } from '@inventage-web-components/common' ;
2
2
import { property , state , query } from '@inventage-web-components/common/lib/src/decorators.js' ;
3
3
import { classMap , ClassInfo , ifDefined } from '@inventage-web-components/common/lib/src/directives.js' ;
4
- import { debounce } from 'ts-debounce' ;
5
4
import '@inventage-web-components/hamburger-menu/lib/src/hamburger-menu.js' ;
6
5
7
6
import { IdPath } from './IdPath.js' ;
@@ -335,6 +334,10 @@ export class PortalNavigation extends LitElement {
335
334
336
335
private initialAnchorElementPadding ?: string ;
337
336
337
+ private anchorElementPaddingRefreshInterval ?: number ;
338
+ private anchorElementPaddingRefreshCount = 0 ;
339
+ private anchorElementPaddingRefreshMaxCount = 100 ;
340
+
338
341
static get styles ( ) : CSSResultArray {
339
342
return [ baseStyles , styles ] ;
340
343
}
@@ -375,13 +378,8 @@ export class PortalNavigation extends LitElement {
375
378
this . __setActiveUrlEventListener = this . __setActiveUrlEventListener . bind ( this ) ;
376
379
this . __globalClickListener = this . __globalClickListener . bind ( this ) ;
377
380
378
- // Always debounce anchor padding updates
379
- /**
380
- * @internal
381
- */
382
- this . updateAnchorPaddingWhenSticky = debounce ( this . updateAnchorPaddingWhenSticky , 100 , {
383
- isImmediate : true ,
384
- } ) . bind ( this ) ;
381
+ // We bind this as well since we bind it to the global resize event listener
382
+ this . updateAnchorPaddingWhenSticky = this . updateAnchorPaddingWhenSticky . bind ( this ) ;
385
383
}
386
384
387
385
connectedCallback ( ) : void {
@@ -481,13 +479,22 @@ export class PortalNavigation extends LitElement {
481
479
this . dispatchEvent ( new CustomEvent ( NavigationEvents . breakpointChanged , { detail : this . isMobileBreakpoint , composed : true , bubbles : true } ) ) ;
482
480
}
483
481
484
- // This code will be run ASAP after Style and Layout information have been calculated and the paint has occurred.
485
- // @see https://firefox-source-docs.mozilla.org/performance/bestpractices.html
486
- requestAnimationFrame ( ( ) => {
487
- setTimeout ( ( ) => {
488
- this . updateAnchorPaddingWhenStickyInternal ( ) ;
489
- } , 0 ) ;
490
- } ) ;
482
+ this . anchorElementPaddingRefreshInterval && cancelAnimationFrame ( this . anchorElementPaddingRefreshInterval ) ;
483
+ if ( this . shouldUpdateAnchorPadding ( ) ) {
484
+ this . anchorElementPaddingRefreshCount = 0 ;
485
+ this . anchorElementPaddingRefreshInterval = window . requestAnimationFrame ( ( ) => this . anchorElementPaddingRefresh ( ) ) ;
486
+ }
487
+ }
488
+
489
+ private anchorElementPaddingRefresh ( ) {
490
+ if ( ++ this . anchorElementPaddingRefreshCount >= this . anchorElementPaddingRefreshMaxCount ) {
491
+ this . anchorElementPaddingRefreshCount = 0 ;
492
+ this . anchorElementPaddingRefreshInterval && cancelAnimationFrame ( this . anchorElementPaddingRefreshInterval ) ;
493
+ return ;
494
+ }
495
+
496
+ this . updateAnchorPaddingWhenSticky ( ) ;
497
+ this . anchorElementPaddingRefreshInterval = window . requestAnimationFrame ( ( ) => this . anchorElementPaddingRefresh ( ) ) ;
491
498
}
492
499
493
500
render ( ) : unknown {
@@ -1164,28 +1171,11 @@ export class PortalNavigation extends LitElement {
1164
1171
1165
1172
/**
1166
1173
* Updates the padding of the anchor when navigation should be sticky.
1167
- * This function is bound to events and is debounced by default.
1168
- * Use updateAnchorPaddingWhenStickyInternal() when you want to call the non-debounced version.
1169
1174
*
1170
1175
* @private
1171
1176
*/
1172
1177
private updateAnchorPaddingWhenSticky ( ) {
1173
- this . updateAnchorPaddingWhenStickyInternal ( ) ;
1174
- }
1175
-
1176
- /**
1177
- * Updates the padding of the anchor when navigation should be sticky.
1178
- *
1179
- * @private
1180
- */
1181
- private updateAnchorPaddingWhenStickyInternal ( ) {
1182
- // Bail when anchor is available, or we're not in sticky mode
1183
- if ( ! this . sticky || ! this . anchorElement ) {
1184
- return ;
1185
- }
1186
-
1187
- // Do nothing to the padding when the mobile menu is open
1188
- if ( this . isMobileBreakpoint && this . hamburgerMenuExpanded ) {
1178
+ if ( ! this . shouldUpdateAnchorPadding ( ) ) {
1189
1179
return ;
1190
1180
}
1191
1181
@@ -1195,16 +1185,32 @@ export class PortalNavigation extends LitElement {
1195
1185
}
1196
1186
1197
1187
const targetPadding = `${ height } px` ;
1198
- if ( this . anchorElement . style . paddingTop === targetPadding ) {
1188
+ if ( this . anchorElement ! . style . paddingTop === targetPadding ) {
1199
1189
return ;
1200
1190
}
1201
1191
1202
1192
// Save initial padding in case we need to restore it later
1203
1193
if ( this . initialAnchorElementPadding === undefined ) {
1204
- this . initialAnchorElementPadding = this . anchorElement . style . paddingTop ;
1194
+ this . initialAnchorElementPadding = this . anchorElement ! . style . paddingTop ;
1205
1195
}
1206
1196
1207
- this . anchorElement . style . paddingTop = targetPadding ;
1197
+ this . anchorElement ! . style . paddingTop = targetPadding ;
1198
+ }
1199
+
1200
+ /**
1201
+ * The anchor padding should be updated when we're in sticky mode, the anchor is available,
1202
+ * and we're not in mobile breakpoint with an expanded hamburger menu.
1203
+ *
1204
+ * @private
1205
+ */
1206
+ private shouldUpdateAnchorPadding ( ) {
1207
+ // Bail when anchor is available, or we're not in sticky mode
1208
+ if ( ! this . sticky || ! this . anchorElement ) {
1209
+ return false ;
1210
+ }
1211
+
1212
+ // Do nothing to the padding when the mobile menu is open
1213
+ return ! ( this . isMobileBreakpoint && this . hamburgerMenuExpanded ) ;
1208
1214
}
1209
1215
1210
1216
/**
0 commit comments