@@ -24,6 +24,7 @@ export class SearchBarElement extends LitElement {
2424
2525 private toggleBtn : HTMLButtonElement | null = null
2626 private panel : HTMLElement | null = null
27+ private clearBtn : HTMLButtonElement | null = null
2728 private isExpanded = true
2829
2930 private isOutsideListenersAttached = false
@@ -61,7 +62,7 @@ export class SearchBarElement extends LitElement {
6162
6263 private cacheElements ( ) : void {
6364 const { form, input, resultsContainer, resultsList } = getSearchBarElements ( this )
64- const { toggleBtn, panel } = getSearchBarOptionalElements ( this )
65+ const { toggleBtn, panel, clearBtn } = getSearchBarOptionalElements ( this )
6566
6667 this . form = form
6768 this . input = input
@@ -70,7 +71,10 @@ export class SearchBarElement extends LitElement {
7071
7172 this . toggleBtn = toggleBtn
7273 this . panel = panel
74+ this . clearBtn = clearBtn
7375 this . isExpanded = this . toggleBtn ? getHeaderSearchExpanded ( ) : this . getIsExpandedFromDom ( )
76+
77+ this . updateClearButtonVisibility ( )
7478 }
7579
7680 private initHeaderExpandedState ( ) : void {
@@ -144,6 +148,11 @@ export class SearchBarElement extends LitElement {
144148 this . toggleBtn . dataset [ 'searchListener' ] = 'true'
145149 }
146150
151+ if ( this . clearBtn && ! this . clearBtn . dataset [ 'searchListener' ] ) {
152+ this . clearBtn . addEventListener ( 'click' , this . handleClearClick )
153+ this . clearBtn . dataset [ 'searchListener' ] = 'true'
154+ }
155+
147156 if ( ! this . dataset [ 'searchKeyListener' ] ) {
148157 this . addEventListener ( 'keydown' , this . handleKeyDown )
149158 this . dataset [ 'searchKeyListener' ] = 'true'
@@ -164,6 +173,7 @@ export class SearchBarElement extends LitElement {
164173 if ( this . toggleBtn ) {
165174 this . toggleBtn . setAttribute ( 'aria-expanded' , isExpanded ? 'true' : 'false' )
166175 this . toggleBtn . setAttribute ( 'data-state' , isExpanded ? 'open' : 'closed' )
176+ this . toggleBtn . toggleAttribute ( 'hidden' , isExpanded )
167177 }
168178
169179 const state = isExpanded ? 'open' : 'closed'
@@ -185,6 +195,19 @@ export class SearchBarElement extends LitElement {
185195 } else {
186196 this . attachOutsideListeners ( )
187197 }
198+
199+ this . updateClearButtonVisibility ( )
200+ }
201+
202+ private updateClearButtonVisibility ( ) : void {
203+ if ( ! this . clearBtn ) {
204+ return
205+ }
206+
207+ const query = this . getQuery ( )
208+ const shouldShow = this . isExpanded
209+ this . clearBtn . toggleAttribute ( 'hidden' , ! shouldShow )
210+ this . clearBtn . setAttribute ( 'aria-label' , query . length > 0 ? 'Clear search' : 'Close search' )
188211 }
189212
190213 private expand ( ) : void {
@@ -338,6 +361,8 @@ export class SearchBarElement extends LitElement {
338361 }
339362
340363 private readonly handleInput = ( ) => {
364+ this . updateClearButtonVisibility ( )
365+
341366 const query = this . getQuery ( )
342367
343368 if ( ! query || query . length < 2 ) {
@@ -359,6 +384,25 @@ export class SearchBarElement extends LitElement {
359384 return ( this . input ?. value ?? '' ) . trim ( )
360385 }
361386
387+ private readonly handleClearClick = ( ) => {
388+ if ( ! this . input ) {
389+ return
390+ }
391+
392+ const query = this . getQuery ( )
393+
394+ if ( query . length === 0 ) {
395+ this . collapse ( { restoreFocus : true } )
396+ return
397+ }
398+
399+ this . input . value = ''
400+ this . updateClearButtonVisibility ( )
401+ this . clearResults ( )
402+ this . hideResults ( )
403+ this . input . focus ( )
404+ }
405+
362406 private showResults ( ) : void {
363407 this . resultsContainer ?. classList . remove ( 'hidden' )
364408 }
0 commit comments