this repo has no description
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix: ArrowUp/Down nav no longer skips a segment on multi-line cards

prevent_default() stops the browser moving the cursor before the async
JS check runs; cursor movement is now handled manually in JS so the
boundary detection sees the pre-keypress position.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

+32 -2
+32 -2
crates/tala/src/editor.rs
··· 1039 1039 }); 1040 1040 1041 1041 // ── Keyboard nav: Up/Down at textarea boundary → switch segment ──────────── 1042 + // prevent_default() is called synchronously so the browser never moves the 1043 + // cursor; we replicate the movement in JS when not at a boundary. 1042 1044 let on_keydown = move |e: Event<KeyboardData>| { 1043 1045 let key = e.data().key().to_string(); 1044 1046 if key == "ArrowUp" || key == "ArrowDown" { 1047 + e.prevent_default(); 1045 1048 let going_up = key == "ArrowUp"; 1046 1049 let cur_idx = *active_idx.read(); 1047 1050 let n = make_segments(&source.read().clone()).len(); 1048 1051 let mut ai = active_idx; 1049 1052 spawn(async move { 1053 + // Each branch: if on the boundary line → send true (navigate). 1054 + // Otherwise move the cursor one line and send false. 1050 1055 let js = if going_up { 1051 1056 "var t=document.querySelector('.card-row.active textarea');\ 1052 - dioxus.send(t?!t.value.slice(0,t.selectionStart).includes('\\n'):false);" 1057 + if(!t){dioxus.send(false);return;}\ 1058 + var pos=t.selectionStart;\ 1059 + var before=t.value.slice(0,pos);\ 1060 + var prevNl=before.lastIndexOf('\\n');\ 1061 + if(prevNl===-1){dioxus.send(true);}\ 1062 + else{\ 1063 + var col=pos-(prevNl+1);\ 1064 + var prevPrevNl=before.lastIndexOf('\\n',prevNl-1);\ 1065 + var newPos=Math.min(prevPrevNl+1+col,prevNl);\ 1066 + t.setSelectionRange(newPos,newPos);\ 1067 + dioxus.send(false);\ 1068 + }" 1053 1069 } else { 1054 1070 "var t=document.querySelector('.card-row.active textarea');\ 1055 - dioxus.send(t?!t.value.slice(t.selectionStart).includes('\\n'):false);" 1071 + if(!t){dioxus.send(false);return;}\ 1072 + var pos=t.selectionStart;\ 1073 + var after=t.value.slice(pos);\ 1074 + var nextNl=after.indexOf('\\n');\ 1075 + if(nextNl===-1){dioxus.send(true);}\ 1076 + else{\ 1077 + var before=t.value.slice(0,pos);\ 1078 + var col=pos-(before.lastIndexOf('\\n')+1);\ 1079 + var nextLineStart=pos+nextNl+1;\ 1080 + var afterNext=t.value.slice(nextLineStart);\ 1081 + var nextNextNl=afterNext.indexOf('\\n');\ 1082 + var nextLineEnd=nextNextNl===-1?t.value.length:nextLineStart+nextNextNl;\ 1083 + t.setSelectionRange(Math.min(nextLineStart+col,nextLineEnd),Math.min(nextLineStart+col,nextLineEnd));\ 1084 + dioxus.send(false);\ 1085 + }" 1056 1086 }; 1057 1087 if let Ok(at_boundary) = document::eval(js).recv::<bool>().await { 1058 1088 if at_boundary {