@@ -7,22 +7,27 @@ export class SearchUi implements SearchUiInterface {
77 private searchContainer : HTMLElement | undefined = undefined ;
88 private list : HTMLElement | undefined = undefined ;
99 private input : HTMLInputElement | undefined = undefined ;
10+ private resetButton : HTMLElement | undefined = undefined ;
11+ private spinner : HTMLElement | undefined = undefined ;
1012 private itemClickListeners : ListItemClickListener [ ] = [ ] ;
1113 private currentValue : string = '' ;
1214
1315 constructor ( private searchOptions : SearchOptions , private searchApi : SearchApiInterface ) { }
1416
1517 private listenForInput ( ) : void {
1618 const debouncedSearch = this . debounce ( ( value : string ) => {
19+ this . showOrHideSpinner ( true ) ;
1720 this . searchApi . search ( value )
1821 . then ( ( data : PlaceObject [ ] ) => {
22+ this . showOrHideSpinner ( false ) ;
1923 this . setSearchListItems ( data ) ;
2024 } ) ;
2125 } , 500 ) ;
2226
2327 this . getInput ( ) ?. addEventListener ( 'input' , ( e : Event ) => {
2428 const input = e . target as HTMLInputElement ;
2529 this . currentValue = input . value ;
30+ this . showOrHideReset ( ) ;
2631 debouncedSearch ( input . value ) ;
2732 } ) ;
2833 }
@@ -43,7 +48,7 @@ export class SearchUi implements SearchUiInterface {
4348 } else {
4449 listContainer . innerHTML = '' ;
4550 }
46-
51+ console . log ( items ) ;
4752 items . forEach ( ( item : PlaceObject ) => {
4853 const listItem = this . createListItem ( item ) ;
4954
@@ -76,16 +81,21 @@ export class SearchUi implements SearchUiInterface {
7681 container . className = `openstreetmap__search ${ this . searchOptions . className || '' } ` ;
7782
7883 container . innerHTML = `
79- <input type="text" placeholder="Search location..." />
84+ <div class="openstreetmap__search-container">
85+ <input type="text" placeholder="${ this . searchOptions . placeholder ?? 'Search location...' } " />
86+ <span class="openstreetmap__search-spinner" data-js-search-spinner="true"></span>
87+ <span class="openstreetmap__search-icon" data-js-search-reset="true" role="button" aria-label="${ this . searchOptions . resetButtonLabel ?? 'Reset search' } ">✕</span>
88+ </div>
8089 <ul></ul>
8190 ` ;
8291
8392 const controlContainer = ( map . getAddable ( ) as LeafletMap ) . getContainer ( ) ?. querySelector ( '.leaflet-control-container' ) ;
8493 controlContainer ?. appendChild ( container ) ;
8594 this . searchContainer = container ;
86- this . stopDblClickZoom ( ) ;
8795
96+ this . stopDblClickZoom ( ) ;
8897 this . listenForInput ( ) ;
98+ this . listenForResetButton ( ) ;
8999
90100 return this ;
91101 }
@@ -102,11 +112,67 @@ export class SearchUi implements SearchUiInterface {
102112 this . getContainer ( ) ?. addEventListener ( 'dblclick' , ( e : Event ) => {
103113 e . stopPropagation ( ) ;
104114 } ) ;
115+ }
116+
117+ private listenForResetButton ( ) : void {
118+ this . getResetButton ( ) ?. addEventListener ( 'click' , ( e : Event ) => {
119+ e . preventDefault ( ) ;
120+ e . stopPropagation ( ) ;
121+ console . log ( 'Reset search' ) ;
122+ if ( this . getList ( ) ) {
123+ this . getList ( ) ! . innerHTML = '' ;
124+ }
125+
126+ if ( this . getInput ( ) ) {
127+ this . getInput ( ) ! . value = '' ;
128+ this . getInput ( ) ! . focus ( ) ;
129+ }
130+ } ) ;
131+ }
132+
133+ private showOrHideSpinner ( isSearching : boolean ) : void {
134+ if ( ! this . getSpinner ( ) ) {
135+ return ;
136+ }
137+
138+ if ( isSearching && this . currentValue . length > 0 ) {
139+ this . getSpinner ( ) ! . style . display = 'inline-block' ;
140+ } else {
141+ this . getSpinner ( ) ! . style . display = 'none' ;
142+ }
143+ }
144+
145+ private showOrHideReset ( ) : void {
146+ if ( ! this . getResetButton ( ) ) {
147+ return ;
148+ }
149+
150+ if ( this . currentValue . length > 0 ) {
151+ this . getResetButton ( ) ! . style . display = 'block' ;
152+ } else {
153+ this . getResetButton ( ) ! . style . display = 'none' ;
154+ }
105155 }
106156
107157 public getContainer ( ) : HTMLElement | undefined {
108158 return this . searchContainer ;
109159 }
160+
161+ private getSpinner ( ) : HTMLElement | undefined {
162+ if ( ! this . spinner ) {
163+ this . spinner = this . getContainer ( ) ?. querySelector ( '[data-js-search-spinner]' ) ?? undefined ;
164+ }
165+
166+ return this . spinner ;
167+ }
168+
169+ private getResetButton ( ) : HTMLElement | undefined {
170+ if ( ! this . resetButton ) {
171+ this . resetButton = this . getContainer ( ) ?. querySelector ( '[data-js-search-reset]' ) ?? undefined ;
172+ }
173+
174+ return this . resetButton ;
175+ }
110176
111177 private getInput ( ) : HTMLInputElement | undefined {
112178 if ( ! this . input ) {
0 commit comments