@@ -3,27 +3,25 @@ import { getCategoryColorName, getCategoryColorValue, Graph } from "./model"
33import { useEffect , useRef , useState } from "react"
44import { PathNode } from "../page"
55import { cn } from "@/lib/utils"
6- import twcolors from 'tailwindcss/colors'
7-
8- let colors = twcolors as any
6+ import { prepareArg } from "../utils"
97
108interface Props extends React . InputHTMLAttributes < HTMLInputElement > {
119 value ?: string
1210 graph : Graph
1311 onValueChange : ( node : PathNode ) => void
14- handelSubmit ?: ( node : any ) => void
12+ handleSubmit ?: ( node : any ) => void
1513 icon ?: React . ReactNode
1614 node ?: PathNode
1715 parentClassName ?: string
1816 scrollToBottom ?: ( ) => void
1917}
2018
21- export default function Input ( { value, onValueChange, handelSubmit , graph, icon, node, className, parentClassName, scrollToBottom, ...props } : Props ) {
19+ export default function Input ( { value, onValueChange, handleSubmit , graph, icon, node, className, parentClassName, scrollToBottom, ...props } : Props ) {
2220
2321 const [ open , setOpen ] = useState ( false )
2422 const [ options , setOptions ] = useState < any [ ] > ( [ ] )
2523 const [ selectedOption , setSelectedOption ] = useState < number > ( 0 )
26- const inputRef = useRef < HTMLInputElement > ( null )
24+ const [ inputHeight , setInputHeight ] = useState ( 0 )
2725 const containerRef = useRef < HTMLDivElement > ( null )
2826
2927 useEffect ( ( ) => {
@@ -35,6 +33,7 @@ export default function Input({ value, onValueChange, handelSubmit, graph, icon,
3533 } , [ open ] )
3634
3735 useEffect ( ( ) => {
36+ let isLastRequest = true
3837 const timeout = setTimeout ( async ( ) => {
3938
4039 if ( ! value || node ?. id ) {
@@ -45,7 +44,7 @@ export default function Input({ value, onValueChange, handelSubmit, graph, icon,
4544 return
4645 }
4746
48- const result = await fetch ( `/api/repo/${ graph . Id } /?prefix=${ value } ` , {
47+ const result = await fetch ( `/api/repo/${ prepareArg ( graph . Id ) } /?prefix=${ prepareArg ( value ) } ` , {
4948 method : 'POST'
5049 } )
5150
@@ -58,6 +57,8 @@ export default function Input({ value, onValueChange, handelSubmit, graph, icon,
5857 return
5958 }
6059
60+ if ( ! isLastRequest ) return
61+
6162 const json = await result . json ( )
6263 const { completions } = json . result
6364
@@ -70,17 +71,21 @@ export default function Input({ value, onValueChange, handelSubmit, graph, icon,
7071 }
7172 } , 500 )
7273
73- return ( ) => clearTimeout ( timeout )
74+ return ( ) => {
75+ clearTimeout ( timeout )
76+ isLastRequest = false
77+ }
7478 } , [ value ] )
7579
76- const handelKeyDown = ( e : React . KeyboardEvent < HTMLInputElement > ) => {
80+ const handleKeyDown = ( e : React . KeyboardEvent < HTMLInputElement > ) => {
81+ const container = containerRef . current
7782 switch ( e . code ) {
7883 case "Enter" : {
7984 e . preventDefault ( )
8085 const option = options . find ( ( o , i ) => i === selectedOption )
8186 if ( ! option ) return
82- if ( handelSubmit ) {
83- handelSubmit ( option )
87+ if ( handleSubmit ) {
88+ handleSubmit ( option )
8489 } else {
8590 if ( ! open ) return
8691 onValueChange ( { name : option . properties . name , id : option . id } )
@@ -91,16 +96,22 @@ export default function Input({ value, onValueChange, handelSubmit, graph, icon,
9196 case "ArrowUp" : {
9297 e . preventDefault ( )
9398 setSelectedOption ( prev => {
94- containerRef . current ?. scrollTo ( { behavior : 'smooth' , top : ( prev <= 0 ? options . length - 1 : prev - 1 ) * containerRef . current . children [ 0 ] . clientHeight } )
95- return prev <= 0 ? options . length - 1 : prev - 1
99+ const newIndex = prev <= 0 ? options . length - 1 : prev - 1
100+ if ( container ) {
101+ container . scrollTo ( { behavior : 'smooth' , top : 64 * newIndex } )
102+ }
103+ return newIndex
96104 } )
97105 return
98106 }
99107 case "ArrowDown" : {
100108 e . preventDefault ( )
101109 setSelectedOption ( prev => {
102- containerRef . current ?. scrollTo ( { behavior : 'smooth' , top : ( ( prev + 1 ) % options . length ) * containerRef . current . children [ 0 ] . clientHeight } )
103- return ( prev + 1 ) % options . length
110+ const newIndex = ( prev + 1 ) % options . length
111+ if ( container ) {
112+ container . scrollTo ( { behavior : 'smooth' , top : Math . min ( 64 * newIndex , container . scrollHeight ) } )
113+ }
114+ return newIndex
104115 } )
105116 return
106117 }
@@ -124,8 +135,12 @@ export default function Input({ value, onValueChange, handelSubmit, graph, icon,
124135 data-name = 'search-bar'
125136 >
126137 < input
127- ref = { inputRef }
128- onKeyDown = { handelKeyDown }
138+ ref = { ref => {
139+ if ( ref ) {
140+ setInputHeight ( ref . scrollHeight )
141+ }
142+ } }
143+ onKeyDown = { handleKeyDown }
129144 className = { cn ( "w-full border p-2 rounded-md pointer-events-auto" , className ) }
130145 value = { value || "" }
131146 onChange = { ( e ) => {
@@ -146,16 +161,25 @@ export default function Input({ value, onValueChange, handelSubmit, graph, icon,
146161 className = "z-10 w-full bg-white absolute flex flex-col pointer-events-auto border rounded-md max-h-[50dvh] overflow-y-auto overflow-x-hidden p-2 gap-2"
147162 data-name = 'search-bar-list'
148163 style = { {
149- top : ( inputRef . current ?. clientHeight || 0 ) + 16
164+ top : inputHeight + 16
150165 } }
151166 >
152167 {
168+ options . length > 0 &&
153169 options . map ( ( option , index ) => {
154170 const label = option . labels [ 0 ]
155171 const name = option . properties . name
156172 const path = option . properties . path
157- const colorName = getCategoryColorName ( graph . CategoriesMap . get ( label ) ! . index )
158- const color = getCategoryColorValue ( graph . CategoriesMap . get ( label ) ! . index )
173+ let category = graph . CategoriesMap . get ( label )
174+
175+ if ( ! category ) {
176+ category = { name : label , index : graph . CategoriesMap . size , show : true }
177+ graph . CategoriesMap . set ( label , category )
178+ graph . Categories . push ( category )
179+ }
180+
181+ const colorName = getCategoryColorName ( category . index )
182+ const color = getCategoryColorValue ( category . index )
159183 return (
160184 < button
161185 className = { cn (
@@ -165,7 +189,7 @@ export default function Input({ value, onValueChange, handelSubmit, graph, icon,
165189 onMouseEnter = { ( ) => setSelectedOption ( index ) }
166190 onClick = { ( ) => {
167191 onValueChange ( { name : option . properties . name , id : option . id } )
168- handelSubmit && handelSubmit ( option )
192+ handleSubmit && handleSubmit ( option )
169193 setOpen ( false )
170194 } }
171195 key = { option . id }
0 commit comments