@@ -5,13 +5,15 @@ import {
55 useContextProvider ,
66 createContextId ,
77 useSignal ,
8- Signal ,
8+ type Signal ,
99 QwikIntrinsicElements ,
1010 useStore ,
1111 useVisibleTask$ ,
12+ useTask$ ,
1213 $ ,
1314 useStylesScoped$ ,
1415} from '@builder.io/qwik' ;
16+ import { routeAction$ } from '@builder.io/qwik-city' ;
1517
1618import { computePosition , flip } from '@floating-ui/dom' ;
1719
@@ -103,6 +105,18 @@ import { computePosition, flip } from '@floating-ui/dom';
103105 Compute position & our triggerRef is what determines what is anchored with floating UI.
104106 https://floating-ui.com/docs/computePosition
105107
108+
109+ Autocomplete implementation:
110+ - grab reference to input box and listbox
111+ - search function that has an array of results, returns results
112+ - searchHandler function
113+ - sets input signal as whatever is in the text box
114+ - sets results to empty array
115+ - if input is not empty set results equal to the search function with our input signal value as param
116+ - showSuggestions function with results and our input signal value as params
117+ -
118+
119+
106120*/
107121
108122// Taken similar props from select + input Value
@@ -230,8 +244,45 @@ export type InputProps = QwikIntrinsicElements['input'];
230244
231245// Add required context here
232246export const AutocompleteInput = component$ ( ( props : InputProps ) => {
247+ const ref = useSignal < HTMLElement > ( ) ;
248+ const contextService = useContext ( AutocompleteContextId ) ;
233249 // required prop here
234- return < input id = "autocomplete-test" role = "combobox" { ...props } /> ;
250+
251+ useVisibleTask$ ( ( { track } ) => {
252+ track ( ( ) => contextService . inputValue . value ) ;
253+
254+ if (
255+ contextService . inputValue . value . length > 0 &&
256+ document . activeElement === ref . value
257+ ) {
258+ contextService . isExpanded . value = true ;
259+ }
260+
261+ // Probably better to refactor Signal type later
262+ contextService . options . map ( ( option : Signal ) => {
263+ if (
264+ ! option . value
265+ ?. getAttribute ( 'optionValue' )
266+ ?. match ( contextService . inputValue . value )
267+ ) {
268+ option . value . style . display = 'none' ;
269+ } else {
270+ option . value . style . display = '' ;
271+ }
272+ } ) ;
273+
274+ console . log ( contextService . inputValue . value ) ;
275+ } ) ;
276+
277+ return (
278+ < input
279+ ref = { ref }
280+ id = "autocomplete-test"
281+ role = "combobox"
282+ bind :value = { contextService . inputValue }
283+ { ...props }
284+ />
285+ ) ;
235286} ) ;
236287
237288export type ButtonProps = QwikIntrinsicElements [ 'button' ] ;
@@ -281,6 +332,7 @@ export const AutocompleteListbox = component$((props: ListboxProps) => {
281332 const ref = useSignal < HTMLElement > ( ) ;
282333 const contextService = useContext ( AutocompleteContextId ) ;
283334 contextService . listBoxRef = ref ;
335+
284336 return (
285337 < ul
286338 ref = { ref }
@@ -297,11 +349,23 @@ export const AutocompleteListbox = component$((props: ListboxProps) => {
297349 ) ;
298350} ) ;
299351
300- export type OptionProps = QwikIntrinsicElements [ 'li' ] ;
352+ export type OptionProps = { optionValue : string } & QwikIntrinsicElements [ 'li' ] ;
301353
302354export const AutocompleteOption = component$ ( ( props : OptionProps ) => {
355+ const ref = useSignal < HTMLElement > ( ) ;
356+ const contextService = useContext ( AutocompleteContextId ) ;
357+ contextService . options = [ ...contextService . options , ref ] ;
358+
303359 return (
304- < li role = "option" { ...props } >
360+ < li
361+ ref = { ref }
362+ role = "option"
363+ onClick$ = { ( ) => {
364+ contextService . inputValue . value = props . optionValue ;
365+ contextService . isExpanded . value = false ;
366+ } }
367+ { ...props }
368+ >
305369 < Slot />
306370 </ li >
307371 ) ;
0 commit comments