1- import { Controller } from "@hotwired/stimulus"
1+ import { Controller } from "@hotwired/stimulus" ;
22
33// TODO: Add suggest help text and aria-live
44// https://accessibility.huit.harvard.edu/technique-aria-autocomplete
55export default class extends Controller {
6- static targets = [ "query" , "suggestions" , "template" , "item" ]
7- static classes = [ "selected" ]
6+ static targets = [ "query" , "suggestions" , "template" , "item" ] ;
7+ static classes = [ "selected" ] ;
88
99 connect ( ) {
1010 this . indexNumber = - 1 ;
1111 this . suggestLength = 0 ;
1212 }
1313
14- disconnect ( ) { this . clear ( ) }
14+ disconnect ( ) {
15+ this . clear ( ) ;
16+ }
1517
1618 clear ( ) {
17- this . suggestionsTarget . classList . add ( ' hidden' ) ;
18- this . suggestionsTarget . innerHTML = ""
19- this . suggestionsTarget . removeAttribute ( ' tabindex' ) ;
20- this . suggestionsTarget . removeAttribute ( ' aria-activedescendant' ) ;
19+ this . suggestionsTarget . classList . add ( " hidden" ) ;
20+ this . suggestionsTarget . innerHTML = "" ;
21+ this . suggestionsTarget . removeAttribute ( " tabindex" ) ;
22+ this . suggestionsTarget . removeAttribute ( " aria-activedescendant" ) ;
2123 }
2224
2325 hide ( e ) {
2426 // Allows adjusting the cursor in the input without hiding the suggestions.
25- if ( ! this . queryTarget . contains ( e . target ) ) this . clear ( )
27+ if ( ! this . queryTarget . contains ( e . target ) ) this . clear ( ) ;
2628 }
2729
2830 next ( ) {
@@ -42,8 +44,8 @@ export default class extends Controller {
4244 // On mouseover, highlight the item, shifting the index,
4345 // but don't change the input because it causes an undesireable feedback loop.
4446 highlight ( e ) {
45- this . indexNumber = this . itemTargets . indexOf ( e . currentTarget )
46- this . focusItem ( e . currentTarget , false )
47+ this . indexNumber = this . itemTargets . indexOf ( e . currentTarget ) ;
48+ this . focusItem ( e . currentTarget , false ) ;
4749 }
4850
4951 choose ( e ) {
@@ -57,19 +59,21 @@ export default class extends Controller {
5759 const term = el . value . trim ( ) ;
5860
5961 if ( term . length >= 2 ) {
60- el . classList . remove ( ' autocomplete-done' ) ;
61- el . classList . add ( ' autocomplete-loading' ) ;
62- const query = new URLSearchParams ( { query : term } )
62+ el . classList . remove ( " autocomplete-done" ) ;
63+ el . classList . add ( " autocomplete-loading" ) ;
64+ const query = new URLSearchParams ( { query : term } ) ;
6365
6466 try {
65- const response = await fetch ( '/api/v1/search/autocomplete?' + query , { method : 'GET' } )
66- const data = await response . json ( )
67- this . showSuggestions ( data . slice ( 0 , 10 ) )
68- } catch ( error ) { }
69- el . classList . remove ( 'autocomplete-loading' ) ;
70- el . classList . add ( 'autocomplete-done' ) ;
67+ const response = await fetch ( "/api/v1/search/autocomplete?" + query , {
68+ method : "GET" ,
69+ } ) ;
70+ const data = await response . json ( ) ;
71+ this . showSuggestions ( data . slice ( 0 , 10 ) ) ;
72+ } catch ( error ) { }
73+ el . classList . remove ( "autocomplete-loading" ) ;
74+ el . classList . add ( "autocomplete-done" ) ;
7175 } else {
72- this . clear ( )
76+ this . clear ( ) ;
7377 }
7478 }
7579
@@ -79,27 +83,31 @@ export default class extends Controller {
7983 return ;
8084 }
8185 items . forEach ( ( item , idx ) => this . appendItem ( item , idx ) ) ;
82- this . suggestionsTarget . setAttribute ( ' tabindex' , 0 ) ;
83- this . suggestionsTarget . setAttribute ( ' role' , ' listbox' ) ;
84- this . suggestionsTarget . classList . remove ( ' hidden' ) ;
86+ this . suggestionsTarget . setAttribute ( " tabindex" , 0 ) ;
87+ this . suggestionsTarget . setAttribute ( " role" , " listbox" ) ;
88+ this . suggestionsTarget . classList . remove ( " hidden" ) ;
8589
8690 this . suggestLength = items . length ;
8791 this . indexNumber = - 1 ;
88- } ;
92+ }
8993
9094 appendItem ( text , idx ) {
9195 const clone = this . templateTarget . content . cloneNode ( true ) ;
92- const li = clone . querySelector ( 'li' )
96+ const li = clone . querySelector ( "li" ) ;
9397 li . textContent = text ;
9498 li . id = `suggest-${ idx } ` ;
95- this . suggestionsTarget . appendChild ( clone )
99+ this . suggestionsTarget . appendChild ( clone ) ;
96100 }
97101
98102 focusItem ( el , change = true ) {
99- if ( ! el ) { return ; }
100- this . itemTargets . forEach ( el => el . classList . remove ( ...this . selectedClasses ) )
103+ if ( ! el ) {
104+ return ;
105+ }
106+ this . itemTargets . forEach ( ( el ) =>
107+ el . classList . remove ( ...this . selectedClasses )
108+ ) ;
101109 el . classList . add ( ...this . selectedClasses ) ;
102- this . suggestionsTarget . setAttribute ( ' aria-activedescendant' , el . id ) ;
110+ this . suggestionsTarget . setAttribute ( " aria-activedescendant" , el . id ) ;
103111 if ( change ) {
104112 this . queryTarget . value = el . textContent ;
105113 this . queryTarget . focus ( ) ;
0 commit comments