@@ -37,9 +37,15 @@ export default function AnnouncementBanner() {
3737 const $subtitle = < span className = 'announcement-banner__subtitle' /> ;
3838 const $ctaText = < span className = 'announcement-banner__cta-text' /> ;
3939
40+ const $closeBtn = (
41+ < button type = 'button' className = 'announcement-banner__close' aria-label = 'Close announcement' >
42+ < span className = 'icon clear' />
43+ </ button >
44+ ) ;
45+
4046 const $link = (
4147 // biome-ignore lint/a11y/useValidAnchor: URL is dynamic
42- < a target = '_blank' rel = 'noopener noreferrer' className = 'announcement-banner' >
48+ < a target = '_blank' rel = 'noopener noreferrer' data-visible = 'true' className = 'announcement-banner' >
4349 < div className = 'announcement-banner__content' >
4450 < div className = 'announcement-banner__logo-wrapper' > { $logo } </ div >
4551 < div className = 'announcement-banner__text' >
@@ -57,9 +63,42 @@ export default function AnnouncementBanner() {
5763 < span className = { `announcement-banner__indicator ${ index === 0 ? 'active' : '' } ` } data-index = { index } />
5864 ) ) }
5965 </ div >
66+ { $closeBtn }
6067 </ a >
6168 ) ;
6269
70+ let intervalId ;
71+
72+ const updateHeaderTop = ( bannerVisible ) => {
73+ const header = document . getElementById ( 'main-header' ) ;
74+ if ( header ) {
75+ if ( bannerVisible ) {
76+ const bannerHeight = $link . offsetHeight ;
77+ header . style . top = `${ bannerHeight } px` ;
78+ } else {
79+ header . style . top = '0' ;
80+ }
81+ }
82+ } ;
83+
84+ $closeBtn . addEventListener ( 'click' , ( e ) => {
85+ e . preventDefault ( ) ;
86+ e . stopPropagation ( ) ;
87+ $link . classList . add ( 'hidden' ) ;
88+ clearInterval ( intervalId ) ;
89+ sessionStorage . setItem ( 'announcement-banner-closed' , 'true' ) ;
90+ updateHeaderTop ( false ) ;
91+ $link . removeAttribute ( 'data-visible' ) ;
92+ } ) ;
93+
94+ // Check if banner was closed in this session
95+ if ( sessionStorage . getItem ( 'announcement-banner-closed' ) === 'true' ) {
96+ $link . classList . add ( 'hidden' ) ;
97+ } else {
98+ // Set header top after banner is rendered
99+ requestAnimationFrame ( ( ) => updateHeaderTop ( true ) ) ;
100+ }
101+
63102 const $content = $link . querySelector ( '.announcement-banner__content' ) ;
64103
65104 const updateBanner = ( index , animate = false ) => {
@@ -105,7 +144,7 @@ export default function AnnouncementBanner() {
105144 updateBanner ( 0 ) ;
106145
107146 // Toggle banners periodically
108- setInterval ( ( ) => {
147+ intervalId = setInterval ( ( ) => {
109148 currentIndex = ( currentIndex + 1 ) % BANNERS . length ;
110149 updateBanner ( currentIndex , true ) ;
111150 } , TOGGLE_INTERVAL ) ;
0 commit comments