@@ -8,6 +8,8 @@ export function useMobilePadding() {
88 const contentRef = useRef < HTMLDivElement > ( null ) ;
99
1010 useEffect ( ( ) => {
11+ let timeoutId : NodeJS . Timeout | null = null ;
12+
1113 const applyPadding = ( ) => {
1214 if ( ! contentRef . current ) return ;
1315
@@ -24,61 +26,51 @@ export function useMobilePadding() {
2426 return ;
2527 }
2628
27- // Remove conflicting Tailwind classes
28- el . classList . remove ( 'pt-48' , 'sm:pt-24' , 'lg:pt-32' ) ;
29+ // Remove conflicting Tailwind classes that add padding-top
30+ el . classList . remove ( 'pt-48' , 'sm:pt-24' , 'lg:pt-32' , 'pt-4' , 'sm:pt-16' , 'lg:pt-24' , 'pt-8' , 'pt-12' , 'pt-16' , 'pt-20' ) ;
2931
3032 // Apply padding using CSS variable
3133 el . style . setProperty ( 'padding-top' , navHeight , 'important' ) ;
3234
33- // Verify no overlap
34- requestAnimationFrame ( ( ) => {
35- const navEl = document . querySelector ( 'nav' ) ;
36- if ( navEl && el ) {
37- const navRect = navEl . getBoundingClientRect ( ) ;
38- const elRect = el . getBoundingClientRect ( ) ;
39- const isOverlapping = elRect . top < navRect . bottom ;
40-
41- // If still overlapping, add extra buffer
42- if ( isOverlapping ) {
43- const neededPadding = navRect . bottom - elRect . top + 20 ; // 20px buffer
44- const currentPadding = parseFloat ( navHeight ) || 0 ;
45- el . style . setProperty ( 'padding-top' , `${ Math . max ( currentPadding , neededPadding ) } px` , 'important' ) ;
46- }
47- }
48- } ) ;
35+ // Removed dynamic overlap checking during scroll to prevent layout shifts
36+ // Padding is set once based on nav height and doesn't change during scroll
37+ } ;
38+
39+ // Debounced version for observers and events
40+ const debouncedApplyPadding = ( ) => {
41+ if ( timeoutId ) clearTimeout ( timeoutId ) ;
42+ timeoutId = setTimeout ( ( ) => {
43+ applyPadding ( ) ;
44+ timeoutId = null ;
45+ } , 50 ) ;
4946 } ;
5047
5148 // Apply immediately
5249 applyPadding ( ) ;
5350
54- // Watch for CSS variable changes
51+ // Watch for CSS variable changes with debouncing
5552 const observer = new MutationObserver ( ( ) => {
56- applyPadding ( ) ;
53+ debouncedApplyPadding ( ) ;
5754 } ) ;
5855
5956 observer . observe ( document . documentElement , {
6057 attributes : true ,
6158 attributeFilter : [ 'style' , 'data-nav-height' ]
6259 } ) ;
6360
64- // Also listen for resize/orientation changes
65- window . addEventListener ( 'resize' , applyPadding ) ;
66- window . addEventListener ( 'orientationchange' , applyPadding ) ;
61+ // Also listen for resize/orientation changes (debounced)
62+ window . addEventListener ( 'resize' , debouncedApplyPadding , { passive : true } ) ;
63+ window . addEventListener ( 'orientationchange' , debouncedApplyPadding ) ;
6764
68- // Apply after delays to catch all render states
69- const timeouts = [
70- setTimeout ( applyPadding , 0 ) ,
71- setTimeout ( applyPadding , 50 ) ,
72- setTimeout ( applyPadding , 100 ) ,
73- setTimeout ( applyPadding , 200 ) ,
74- setTimeout ( applyPadding , 500 )
75- ] ;
65+ // Single delayed check after initial render
66+ const initialTimeout = setTimeout ( applyPadding , 100 ) ;
7667
7768 return ( ) => {
7869 observer . disconnect ( ) ;
79- window . removeEventListener ( 'resize' , applyPadding ) ;
80- window . removeEventListener ( 'orientationchange' , applyPadding ) ;
81- timeouts . forEach ( clearTimeout ) ;
70+ window . removeEventListener ( 'resize' , debouncedApplyPadding ) ;
71+ window . removeEventListener ( 'orientationchange' , debouncedApplyPadding ) ;
72+ if ( timeoutId ) clearTimeout ( timeoutId ) ;
73+ clearTimeout ( initialTimeout ) ;
8274 } ;
8375 } , [ ] ) ;
8476
0 commit comments