1- import React , { ChangeEvent , useCallback , useMemo } from 'react' ;
1+ import React , { ChangeEvent , useCallback , useDeferredValue , useMemo , useState } from 'react' ;
22import { FilterIcon } from 'lucide-react' ;
33import { useQuery } from 'urql' ;
44import { Button } from '@/components/ui/button' ;
@@ -94,6 +94,8 @@ export function TypeFilter(props: {
9494 } ;
9595} ) {
9696 const router = useRouter ( ) ;
97+ const [ inputValue , setInputValue ] = useState ( '' ) ;
98+ const deferredInputValue = useDeferredValue ( inputValue ) ;
9799 const [ query ] = useQuery ( {
98100 query : TypeFilter_AllTypes ,
99101 variables : {
@@ -115,6 +117,29 @@ export function TypeFilter(props: {
115117 [ allNamedTypes ] ,
116118 ) ;
117119
120+ const sortedTypes = useMemo ( ( ) => {
121+ if ( ! deferredInputValue ) return types ;
122+
123+ const search = deferredInputValue . toLowerCase ( ) ;
124+ return [ ...types ] . sort ( ( a , b ) => {
125+ const aName = a . label . toLowerCase ( ) ;
126+ const bName = b . label . toLowerCase ( ) ;
127+
128+ // Exact match gets highest priority
129+ const aExact = aName === search ;
130+ const bExact = bName === search ;
131+ if ( aExact !== bExact ) return aExact ? - 1 : 1 ;
132+
133+ // Prefix match gets second priority
134+ const aPrefix = aName . startsWith ( search ) ;
135+ const bPrefix = bName . startsWith ( search ) ;
136+ if ( aPrefix !== bPrefix ) return aPrefix ? - 1 : 1 ;
137+
138+ // Alphabetical within same relevance
139+ return aName . localeCompare ( bName ) ;
140+ } ) ;
141+ } , [ types , deferredInputValue ] ) ;
142+
118143 const onChange = useCallback (
119144 ( option : SelectOption | null ) => {
120145 void router . navigate ( {
@@ -140,8 +165,9 @@ export function TypeFilter(props: {
140165 className = "min-w-[200px] grow cursor-text"
141166 placeholder = "Search for a type"
142167 defaultValue = { defaultValue }
143- options = { types }
168+ options = { sortedTypes }
144169 onChange = { onChange }
170+ onInputChange = { setInputValue }
145171 loading = { query . fetching }
146172 />
147173 ) ;
0 commit comments