@@ -68,14 +68,23 @@ export var SearchButton = Control.extend({
6868 function ( e ) {
6969 if ( e . key === 'Escape' ) {
7070 DomEvent . stop ( e ) ;
71- this . _closePanel ( ) ;
71+ if ( this . _input . value ) {
72+ this . _input . value = '' ;
73+ this . _results . innerHTML = '' ;
74+ } else {
75+ this . _closePanel ( ) ;
76+ }
7277 } else if ( e . key === 'Enter' ) {
7378 DomEvent . stop ( e ) ;
7479 if ( this . _debounceTimer ) {
7580 clearTimeout ( this . _debounceTimer ) ;
7681 this . _debounceTimer = null ;
7782 }
7883 this . _doSearch ( this . _input . value . trim ( ) ) ;
84+ } else if ( e . key === 'ArrowDown' || e . key === 'Down' ) {
85+ DomEvent . stop ( e ) ;
86+ let first = this . _results . querySelector ( '.mapml-search-result' ) ;
87+ if ( first ) first . focus ( ) ;
7988 }
8089 } ,
8190 this
@@ -381,6 +390,44 @@ export var SearchButton = Control.extend({
381390
382391 _defaultSearchHandler : function ( { query, responses } ) {
383392 this . _renderResults ( responses ) ;
393+ // Navigate to the first result
394+ for ( let { data } of responses ) {
395+ if ( ! data || ! data . features ) continue ;
396+ for ( let feature of data . features ) {
397+ this . _navigateToFeature ( feature ) ;
398+ break ;
399+ }
400+ break ;
401+ }
402+ // Keep focus on the search input so the user can refine or review
403+ this . _input . focus ( ) ;
404+ } ,
405+
406+ _navigateToFeature : function ( feature ) {
407+ let map = this . _map ;
408+ // Standard GeoJSON bbox
409+ let bbox = feature . bbox ;
410+ // Photon stores extent in properties.extent [west, south, east, north]
411+ if (
412+ ( ! bbox || bbox . length !== 4 ) &&
413+ feature . properties &&
414+ feature . properties . extent &&
415+ feature . properties . extent . length === 4
416+ ) {
417+ bbox = feature . properties . extent ;
418+ }
419+ if ( bbox && bbox . length === 4 ) {
420+ let [ west , south , east , north ] = bbox ;
421+ map . fitBounds ( latLngBounds ( [ south , west ] , [ north , east ] ) ) ;
422+ } else if (
423+ feature . geometry &&
424+ feature . geometry . coordinates &&
425+ feature . geometry . coordinates . length >= 2
426+ ) {
427+ let [ lon , lat ] = feature . geometry . coordinates ;
428+ let zoom = ( feature . properties && feature . properties . zoom ) || 14 ;
429+ map . setView ( [ lat , lon ] , zoom ) ;
430+ }
384431 } ,
385432
386433 _renderResults : function ( responses ) {
@@ -399,11 +446,44 @@ export var SearchButton = Control.extend({
399446 this . _selectResult ( f , l )
400447 ) ( feature , layer )
401448 ) ;
449+ btn . addEventListener ( 'keydown' , this . _resultKeydown . bind ( this ) ) ;
402450 this . _results . appendChild ( btn ) ;
403451 }
404452 }
405453 } ,
406454
455+ _resultKeydown : function ( e ) {
456+ let btn = e . target ;
457+ let prev = btn . previousElementSibling ;
458+ let next = btn . nextElementSibling ;
459+ if (
460+ e . key === 'ArrowDown' ||
461+ e . key === 'ArrowRight' ||
462+ e . key === 'Down' ||
463+ e . key === 'Right'
464+ ) {
465+ DomEvent . stop ( e ) ;
466+ if ( next && next . classList . contains ( 'mapml-search-result' ) ) {
467+ next . focus ( ) ;
468+ }
469+ } else if (
470+ e . key === 'ArrowUp' ||
471+ e . key === 'ArrowLeft' ||
472+ e . key === 'Up' ||
473+ e . key === 'Left'
474+ ) {
475+ DomEvent . stop ( e ) ;
476+ if ( prev && prev . classList . contains ( 'mapml-search-result' ) ) {
477+ prev . focus ( ) ;
478+ } else {
479+ this . _input . focus ( ) ;
480+ }
481+ } else if ( e . key === 'Escape' ) {
482+ DomEvent . stop ( e ) ;
483+ this . _input . focus ( ) ;
484+ }
485+ } ,
486+
407487 _formatResultName : function ( props ) {
408488 if ( ! props ) return this . _locale ?. searchResultWithNoName || 'Unnamed' ;
409489 if ( props . display_name ) return props . display_name ;
@@ -420,31 +500,10 @@ export var SearchButton = Control.extend({
420500 } ,
421501
422502 _selectResult : function ( feature , layer ) {
423- let map = this . _map ;
424- // Standard GeoJSON bbox
425- let bbox = feature . bbox ;
426- // Photon stores extent in properties.extent [west, south, east, north]
427- if (
428- ( ! bbox || bbox . length !== 4 ) &&
429- feature . properties &&
430- feature . properties . extent &&
431- feature . properties . extent . length === 4
432- ) {
433- bbox = feature . properties . extent ;
434- }
435- if ( bbox && bbox . length === 4 ) {
436- let [ west , south , east , north ] = bbox ;
437- map . fitBounds ( latLngBounds ( [ south , west ] , [ north , east ] ) ) ;
438- } else if (
439- feature . geometry &&
440- feature . geometry . coordinates &&
441- feature . geometry . coordinates . length >= 2
442- ) {
443- let [ lon , lat ] = feature . geometry . coordinates ;
444- let zoom = ( feature . properties && feature . properties . zoom ) || 14 ;
445- map . setView ( [ lat , lon ] , zoom ) ;
446- }
447- this . _closePanel ( ) ;
503+ // Use the suggestion's display name as a refined search query
504+ let name = this . _formatResultName ( feature . properties ) ;
505+ this . _input . value = name ;
506+ this . _doSearch ( name ) ;
448507 }
449508} ) ;
450509
0 commit comments