Fix double node creation when picking a palette entry by click

- TextField: new onSubmit callback (Enter only, independent of value change)
- NodePalette: use onSubmit instead of onChange, add per-open picked guard
- e2e: new check 13a (type + click row -> exactly one node), wait for
  Chromium exit in finally with SIGKILL escalation after 5s

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
rootandClaude Fable 5.1 committed 2026-09-07 13:03:10 +02:00
1 parent 922774778b
commit 06b1007015
3 files changed
+48 -4

No files matched your search

+8 -1
View File
@@ -8,6 +8,8 @@ export class NodePalette extends Popup {
private readonly search: TextField;
private readonly list = new ListView();
private filtered: NodeDef[] = [];
/** Guards against a second pick per opening (e.g. Enter and a row click racing). */
private picked = false;
constructor(private readonly onPick: (def: NodeDef) => void) {
super({ padding: 4, gap: 4 });
@@ -15,7 +17,9 @@ export class NodePalette extends Popup {
this.search = new TextField('', {
placeholder: 'Search nodes…',
onInput: () => this.refresh(),
onChange: () => {
// Enter only. NOT onChange: that also fires when the search field loses focus because
// the user clicked a list row, which would add the first match *and* the clicked one.
onSubmit: () => {
const first = this.filtered[0];
if (first) this.pick(first);
},
@@ -36,6 +40,7 @@ export class NodePalette extends Popup {
override open(globalX: number, globalY: number): void {
super.open(globalX, globalY);
this.picked = false;
ui().focus.focus(this.search);
}
@@ -49,6 +54,8 @@ export class NodePalette extends Popup {
}
private pick(def: NodeDef): void {
if (this.picked) return;
this.picked = true;
this.close();
this.onPick(def);
}