char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
92d1bb0c9
char/aliceai-t5-moe
1import { KeyboardKey } from '$lib/enums' ; 2 3/** 4* Shared keyboard navigation state for the chat-form pickers: a highlighted 5* row, a scroll trigger, and Arrow/Escape/Enter handling. 6*/ 7export interface UsePickerNavigationOptions { 8/** Gates all key handling. */ 9isOpen :() => boolean ; 10count :() => number ; 11/** 12* Resolve the row to highlight for a movement step, or -1 when no move 13* is possible. Defaults to plain wraparound across `count()`. 14*/ 15step ?:( from :number , dir :1 | - 1 ) => number ; 16onClose :() => void ; 17/** Called on Enter when `hoveredIndex` points at a selectable row. */ 18onSelect :( index :number ) => void ; 19} 20 21function wrapStep ( from :number , dir :1 | - 1 , count :number ) :number { 22return dir === 1 ?( from + 1 ) % count :from <= 0 ?count - 1 :from - 1 ; 23} 24 25export function usePickerNavigation ( opts :UsePickerNavigationOptions ) { 26let hoveredIndex = $state ( - 1 ); 27let scrollTrigger = $state ( 0 ); 28 29function resolve ( from :number , dir :1 | - 1 ) :number { 30const n = opts . count (); 31 32if ( n === 0 ) return - 1 ; 33 34if ( opts . step ) return opts . step ( from , dir ); 35 36return wrapStep ( from , dir , n ); 37} 38 39function move ( dir :1 | - 1 ) { 40const next = resolve ( hoveredIndex , dir ); 41 42if ( next >= 0 ) { 43hoveredIndex = next ; 44scrollTrigger ++ ; 45} 46} 47 48/** Reset the highlight without bumping the scroll trigger. */ 49function reset ( index :number ) { 50hoveredIndex = index ; 51} 52 53/** Bump the scroll trigger without moving the highlight. */ 54function bumpScroll () { 55scrollTrigger ++ ; 56} 57 58/** Mouse hover highlights a row but must NOT bump the scroll trigger. */ 59function setHover ( index :number ) { 60hoveredIndex = index ; 61} 62 63function handleKeydown ( event :KeyboardEvent ) :boolean { 64if ( ! opts . isOpen ()) return false ; 65 66if ( event . key === KeyboardKey . ESCAPE ) { 67event . preventDefault (); 68opts . onClose (); 69 70return true ; 71} 72 73if ( event . key === KeyboardKey . ARROW_DOWN ) { 74event . preventDefault (); 75move ( 1 ); 76 77return true ; 78} 79 80if ( event . key === KeyboardKey . ARROW_UP ) { 81event . preventDefault (); 82move ( - 1 ); 83 84return true ; 85} 86 87if ( event . key === KeyboardKey . ENTER ) { 88if ( hoveredIndex >= 0 && hoveredIndex < opts . count ()) { 89event . preventDefault (); 90opts . onSelect ( hoveredIndex ); 91 92return true ; 93} 94 95// No selectable row - let the caller's Enter-to-submit run. 96return false ; 97} 98 99return false ; 100} 101 102return { 103 bumpScroll, 104 handleKeydown, 105get hoveredIndex () { 106return hoveredIndex ; 107}, 108 move, 109 reset, 110get scrollTrigger () { 111return scrollTrigger ; 112}, 113 setHover 114}; 115} 116 117export type UsePickerNavigationReturn = ReturnType < typeof usePickerNavigation >;