greatly simplified app

This commit is contained in:
Joeri Exelmans 2025-05-13 18:29:37 +02:00
parent 9c0c2dab90
commit 35d1034c67
8 changed files with 156 additions and 204 deletions

View file

@ -18,7 +18,6 @@ export interface InputBlockState {
interface InputBlockProps extends State2Props<InputBlockState> {
filter: (suggestion: [string, Dynamic]) => boolean;
onResolve: (state: InputBlockState) => void;
onCancel: () => void;
}
@ -31,6 +30,7 @@ const computeSuggestions = (text, env, filter) => {
... (asInt ? [[asInt.toString(), newDynamic(BigInt(asInt))(Int)]] : []),
... trie.suggest(env.name2dyn)(text)(Infinity),
]
return ls;
return [
...ls.filter(filter), // ones that match filter come first
...ls.filter(s => !filter(s)),
@ -38,17 +38,13 @@ const computeSuggestions = (text, env, filter) => {
// .slice(0,30);
}
export function InputBlock({ state, setState, filter, onResolve, onCancel }: InputBlockProps) {
export function InputBlock({ state, setState, filter, onCancel }: InputBlockProps) {
const {text, resolved, focus} = state;
const env = useContext(EnvContext);
const inputRef = useRef<HTMLInputElement>(null);
const [i, setI] = useState(0); // selected suggestion idx
const [haveFocus, setHaveFocus] = useState(false); // whether to render suggestions or not
const setText = (text: string) => {
setState({...state, text});
}
const singleSuggestion = trie.growPrefix(env.name2dyn)(text);
const suggestions = useMemo(() => computeSuggestions(text, env, filter), [text]);
@ -60,20 +56,21 @@ export function InputBlock({ state, setState, filter, onResolve, onCancel }: Inp
}
}, [focus]);
const onSelectSuggestion = ([name, dynamic]) => {
console.log('resolving input block', text, '->', name);
onResolve({
kind: "input",
text: name,
resolved: dynamic,
focus: false,
});
};
useEffect(() => {
if (suggestions.length >= i) {
setI(0);
}
}, [suggestions.length]);
const getCaretPosition = () => {
return inputRef.current?.selectionStart || -1;
}
const onTextChange = newText => {
const found = trie.get(env.name2dyn)(newText);
setState(state => ({...state, text: newText, resolved: found}));
}
// fired before onInput
const onKeyDown = (e: React.KeyboardEvent) => {
const fns = {
@ -86,7 +83,7 @@ export function InputBlock({ state, setState, filter, onResolve, onCancel }: Inp
// not shift key
if (singleSuggestion.length > 0) {
const newText = text + singleSuggestion;
setText(newText);
onTextChange(newText);
setRightMostCaretPosition(inputRef.current);
e.preventDefault();
}
@ -105,7 +102,7 @@ export function InputBlock({ state, setState, filter, onResolve, onCancel }: Inp
e.preventDefault();
},
ArrowLeft: () => {
if (getCaretPosition() === 0) {
if (getCaretPosition() <= 0) {
focusPrevElement();
e.preventDefault();
}
@ -131,21 +128,11 @@ export function InputBlock({ state, setState, filter, onResolve, onCancel }: Inp
};
const onInput = e => {
const found = trie.get(env.name2dyn)(e.target.value);
if (found) {
console.log('resolving input block..', e.target.value);
onResolve({...state, text: e.target.value, resolved: found});
}
else {
if (resolved) {
// un-resolve
console.log('un-resolving input block..', e.target.value);
onResolve({...state, text: e.target.value, resolved: undefined});
}
else {
setText(e.target.value);
}
}
onTextChange(e.target.value);
};
const onSelectSuggestion = ([name, dynamic]) => {
setState(state => ({...state, text: name, resolved: dynamic}));
};
return <span>