@@ -46,15 +46,14 @@ function normalisedValue<T>(multiple: boolean, values: T[] | undefined): T | T[]
4646
4747interface AutocompleteOptions < T extends OptionLike >
4848 extends PromptOptions < T [ 'value' ] | T [ 'value' ] [ ] , AutocompletePrompt < T > > {
49- options : T [ ] ;
49+ options : T [ ] | ( ( this : AutocompletePrompt < T > ) => T [ ] ) ;
5050 filter ?: FilterFunction < T > ;
5151 multiple ?: boolean ;
5252}
5353
5454export default class AutocompletePrompt < T extends OptionLike > extends Prompt <
5555 T [ 'value' ] | T [ 'value' ] [ ]
5656> {
57- options : T [ ] ;
5857 filteredOptions : T [ ] ;
5958 multiple : boolean ;
6059 isNavigating = false ;
@@ -64,6 +63,7 @@ export default class AutocompletePrompt<T extends OptionLike> extends Prompt<
6463 #cursor = 0 ;
6564 #lastUserInput = '' ;
6665 #filterFn: FilterFunction < T > ;
66+ #options: T [ ] | ( ( ) => T [ ] ) ;
6767
6868 get cursor ( ) : number {
6969 return this . #cursor;
@@ -81,11 +81,19 @@ export default class AutocompletePrompt<T extends OptionLike> extends Prompt<
8181 return `${ s1 } ${ color . inverse ( s2 ) } ${ s3 . join ( '' ) } ` ;
8282 }
8383
84+ get options ( ) : T [ ] {
85+ if ( typeof this . #options === 'function' ) {
86+ return this . #options( ) ;
87+ }
88+ return this . #options;
89+ }
90+
8491 constructor ( opts : AutocompleteOptions < T > ) {
8592 super ( opts ) ;
8693
87- this . options = opts . options ;
88- this . filteredOptions = [ ...this . options ] ;
94+ this . #options = opts . options ;
95+ const options = this . options ;
96+ this . filteredOptions = [ ...options ] ;
8997 this . multiple = opts . multiple === true ;
9098 this . #filterFn = opts . filter ?? defaultFilter ;
9199 let initialValues : unknown [ ] | undefined ;
@@ -103,7 +111,7 @@ export default class AutocompletePrompt<T extends OptionLike> extends Prompt<
103111
104112 if ( initialValues ) {
105113 for ( const selectedValue of initialValues ) {
106- const selectedIndex = this . options . findIndex ( ( opt ) => opt . value === selectedValue ) ;
114+ const selectedIndex = options . findIndex ( ( opt ) => opt . value === selectedValue ) ;
107115 if ( selectedIndex !== - 1 ) {
108116 this . toggleSelected ( selectedValue ) ;
109117 this . #cursor = selectedIndex ;
@@ -113,16 +121,6 @@ export default class AutocompletePrompt<T extends OptionLike> extends Prompt<
113121
114122 this . focusedValue = this . options [ this . #cursor] ?. value ;
115123
116- this . on ( 'finalize' , ( ) => {
117- if ( ! this . value ) {
118- this . value = normalisedValue ( this . multiple , initialValues ) ;
119- }
120-
121- if ( this . state === 'submit' ) {
122- this . value = normalisedValue ( this . multiple , this . selectedValues ) ;
123- }
124- } ) ;
125-
126124 this . on ( 'key' , ( char , key ) => this . #onKey( char , key ) ) ;
127125 this . on ( 'userInput' , ( value ) => this . #onUserInputChanged( value ) ) ;
128126 }
@@ -141,6 +139,7 @@ export default class AutocompletePrompt<T extends OptionLike> extends Prompt<
141139 #onKey( _char : string | undefined , key : Key ) : void {
142140 const isUpKey = key . name === 'up' ;
143141 const isDownKey = key . name === 'down' ;
142+ const isReturnKey = key . name === 'return' ;
144143
145144 // Start navigation mode with up/down arrows
146145 if ( isUpKey || isDownKey ) {
@@ -153,6 +152,8 @@ export default class AutocompletePrompt<T extends OptionLike> extends Prompt<
153152 this . selectedValues = [ this . focusedValue ] ;
154153 }
155154 this . isNavigating = true ;
155+ } else if ( isReturnKey ) {
156+ this . value = normalisedValue ( this . multiple , this . selectedValues ) ;
156157 } else {
157158 if ( this . multiple ) {
158159 if (
@@ -171,6 +172,10 @@ export default class AutocompletePrompt<T extends OptionLike> extends Prompt<
171172 }
172173 }
173174
175+ deselectAll ( ) {
176+ this . selectedValues = [ ] ;
177+ }
178+
174179 toggleSelected ( value : T [ 'value' ] ) {
175180 if ( this . filteredOptions . length === 0 ) {
176181 return ;
@@ -191,13 +196,22 @@ export default class AutocompletePrompt<T extends OptionLike> extends Prompt<
191196 if ( value !== this . #lastUserInput) {
192197 this . #lastUserInput = value ;
193198
199+ const options = this . options ;
200+
194201 if ( value ) {
195- this . filteredOptions = this . options . filter ( ( opt ) => this . #filterFn( value , opt ) ) ;
202+ this . filteredOptions = options . filter ( ( opt ) => this . #filterFn( value , opt ) ) ;
196203 } else {
197- this . filteredOptions = [ ...this . options ] ;
204+ this . filteredOptions = [ ...options ] ;
198205 }
199206 this . #cursor = getCursorForValue ( this . focusedValue , this . filteredOptions ) ;
200207 this . focusedValue = this . filteredOptions [ this . #cursor] ?. value ;
208+ if ( ! this . multiple ) {
209+ if ( this . focusedValue !== undefined ) {
210+ this . toggleSelected ( this . focusedValue ) ;
211+ } else {
212+ this . deselectAll ( ) ;
213+ }
214+ }
201215 }
202216 }
203217}
0 commit comments