@@ -21,7 +21,7 @@ type NodeTypeChipsSearchInputProps = {
2121const isPlainCharacterKey = ( event : React . KeyboardEvent ) : boolean =>
2222 event . key . length === 1 && ! event . altKey && ! event . ctrlKey && ! event . metaKey ;
2323
24- const getUniquePrefixMatch = ( {
24+ const getBestPrefixMatch = ( {
2525 nodeTypes,
2626 query,
2727 selectedTypeIds,
@@ -40,7 +40,12 @@ const getUniquePrefixMatch = ({
4040 node . text . toLowerCase ( ) . startsWith ( normalizedQuery ) ,
4141 ) ;
4242
43- return matches . length === 1 ? matches [ 0 ] : null ;
43+ if ( ! matches . length ) return null ;
44+
45+ const exactMatch = matches . find (
46+ ( node ) => node . text . toLowerCase ( ) === normalizedQuery ,
47+ ) ;
48+ return exactMatch ?? matches [ 0 ] ;
4449} ;
4550
4651export const NodeTypeChipsSearchInput = ( {
@@ -76,9 +81,9 @@ export const NodeTypeChipsSearchInput = ({
7681 [ nodeTypeById , selectedTypeIds ] ,
7782 ) ;
7883
79- const uniquePrefixMatch = useMemo (
84+ const bestPrefixMatch = useMemo (
8085 ( ) =>
81- getUniquePrefixMatch ( {
86+ getBestPrefixMatch ( {
8287 nodeTypes,
8388 query : searchTerm ,
8489 selectedTypeIds,
@@ -87,12 +92,12 @@ export const NodeTypeChipsSearchInput = ({
8792 ) ;
8893
8994 const completionSuffix = useMemo ( ( ) => {
90- if ( ! uniquePrefixMatch ) return "" ;
95+ if ( ! bestPrefixMatch ) return "" ;
9196 const normalizedQuery = searchTerm . trim ( ) ;
92- const nodeText = uniquePrefixMatch . text ;
97+ const nodeText = bestPrefixMatch . text ;
9398 if ( nodeText . toLowerCase ( ) === normalizedQuery . toLowerCase ( ) ) return "" ;
9499 return nodeText . slice ( normalizedQuery . length ) ;
95- } , [ searchTerm , uniquePrefixMatch ] ) ;
100+ } , [ bestPrefixMatch , searchTerm ] ) ;
96101
97102 useEffect ( ( ) => {
98103 if ( focusedChipIndex < 0 ) return ;
@@ -112,11 +117,6 @@ export const NodeTypeChipsSearchInput = ({
112117 onSearchTermChange ( "" ) ;
113118 } ;
114119
115- const removeChipAtIndex = ( chipIndex : number ) : void => {
116- const nextIds = selectedTypeIds . filter ( ( _ , index ) => index !== chipIndex ) ;
117- onSelectedTypeIdsChange ( nextIds ) ;
118- } ;
119-
120120 const handleChipKeyDown = (
121121 event : React . KeyboardEvent < HTMLSpanElement > ,
122122 chipIndex : number ,
@@ -180,9 +180,9 @@ export const NodeTypeChipsSearchInput = ({
180180 event : React . KeyboardEvent < HTMLInputElement > ,
181181 ) : void => {
182182 if ( event . key === "Tab" ) {
183- if ( uniquePrefixMatch ) {
183+ if ( bestPrefixMatch ) {
184184 event . preventDefault ( ) ;
185- commitNodeType ( uniquePrefixMatch ) ;
185+ commitNodeType ( bestPrefixMatch ) ;
186186 }
187187 return ;
188188 }
@@ -240,7 +240,7 @@ export const NodeTypeChipsSearchInput = ({
240240 } ;
241241
242242 return (
243- < div className = "flex min-w-0 flex-1 items-center gap-1 py-0.5" >
243+ < div className = "flex min-w-0 flex-1 flex-wrap items-center gap-1 py-0.5" >
244244 { selectedNodeTypes . map ( ( nodeType , index ) => {
245245 const isFocused = focusedChipIndex === index ;
246246 return (
@@ -262,17 +262,25 @@ export const NodeTypeChipsSearchInput = ({
262262 >
263263 < span
264264 className = "inline-flex items-center gap-1.5 rounded px-2 py-1 text-xs"
265- style = { getNodeTagStyles ( nodeType . canvasSettings ?. color ) }
265+ style = { getNodeTagStyles (
266+ nodeType . canvasSettings ?. color ?? "#000000" ,
267+ ) }
266268 >
267- < span className = "truncate leading-4" > { nodeType . text } </ span >
269+ < span className = "max-w-[10rem] truncate leading-4" >
270+ { nodeType . text }
271+ </ span >
268272 < Button
269273 className = "!h-4 !min-h-0 !w-4 !min-w-0 !p-0"
270274 aria-label = { `Remove ${ nodeType . text } filter` }
271275 icon = { < Icon icon = "cross" size = { 10 } /> }
272276 minimal
273277 onClick = { ( event ) => {
274278 event . stopPropagation ( ) ;
275- removeChipAtIndex ( index ) ;
279+ onSelectedTypeIdsChange (
280+ selectedTypeIds . filter (
281+ ( _ , chipIndex ) => chipIndex !== index ,
282+ ) ,
283+ ) ;
276284 focusInput ( ) ;
277285 } }
278286 onMouseDown = { ( event ) => event . preventDefault ( ) }
@@ -282,7 +290,7 @@ export const NodeTypeChipsSearchInput = ({
282290 </ span >
283291 ) ;
284292 } ) }
285- < span className = "relative min-w-0 flex-1" >
293+ < span className = "relative min-w-[12ch] flex-1" >
286294 { completionSuffix && (
287295 < span className = "pointer-events-none absolute inset-0 flex items-center overflow-hidden whitespace-nowrap text-sm" >
288296 < span className = "invisible" > { searchTerm } </ span >
0 commit comments