From debc1a9c0b3edd03683e0205cc9cb7713c0ea09e Mon Sep 17 00:00:00 2001 From: Thiago Alves Date: Sat, 28 Feb 2026 23:45:11 -0500 Subject: [PATCH] fix: constants silently dropped when pressing Enter in LD/FBD autocomplete MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When typing a constant (e.g. T#500ms, 5, 'hello') on a block input/output and pressing Enter, the autocomplete tried to create a new variable with that name. Since constants fail isLegalIdentifier(), this showed an "Illegal variable name" toast and returned early without updating the node. In LD, the blur handler (which correctly handles constants) was also suppressed by blur({ submit: false }), causing the constant to be silently dropped — the input appeared to accept the value but compiled as 0. Fix: detect literals via getLiteralType() in two layers: - Autocomplete submit functions (LD + FBD): skip createVariable for literals - LD Enter handlers (variable, contact, coil): pass submit:true for literals so the blur handler processes them with proper type validation Co-Authored-By: Claude Opus 4.6 --- .../_atoms/graphical-editor/fbd/autocomplete/index.tsx | 2 ++ .../_atoms/graphical-editor/ladder/autocomplete/index.tsx | 2 ++ .../components/_atoms/graphical-editor/ladder/coil.tsx | 4 +++- .../components/_atoms/graphical-editor/ladder/contact.tsx | 4 +++- .../components/_atoms/graphical-editor/ladder/variable.tsx | 4 +++- 5 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/renderer/components/_atoms/graphical-editor/fbd/autocomplete/index.tsx b/src/renderer/components/_atoms/graphical-editor/fbd/autocomplete/index.tsx index 11013763a..07d3db619 100644 --- a/src/renderer/components/_atoms/graphical-editor/fbd/autocomplete/index.tsx +++ b/src/renderer/components/_atoms/graphical-editor/fbd/autocomplete/index.tsx @@ -4,6 +4,7 @@ import { useOpenPLCStore } from '@root/renderer/store' import { extractNumberAtEnd } from '@root/renderer/store/slices/project/validation/variables' import { PLCVariable } from '@root/types/PLC' import { cn } from '@root/utils' +import { getLiteralType } from '@root/utils/keywords' import { newGraphicalEditorNodeID } from '@root/utils/new-graphical-editor-node-id' import { expandArrayVariables } from '@root/utils/PLC/array-variable-utils' import { Node } from '@xyflow/react' @@ -241,6 +242,7 @@ const FBDBlockAutoComplete = forwardRef { if (variable.id === 'add') { + if (getLiteralType(valueToSearch)) return submitAddVariable({ variableName: valueToSearch }) return } diff --git a/src/renderer/components/_atoms/graphical-editor/ladder/autocomplete/index.tsx b/src/renderer/components/_atoms/graphical-editor/ladder/autocomplete/index.tsx index 1b516811c..c7475b0fb 100644 --- a/src/renderer/components/_atoms/graphical-editor/ladder/autocomplete/index.tsx +++ b/src/renderer/components/_atoms/graphical-editor/ladder/autocomplete/index.tsx @@ -3,6 +3,7 @@ import { useOpenPLCStore } from '@root/renderer/store' import { extractNumberAtEnd } from '@root/renderer/store/slices/project/validation/variables' import { PLCVariable } from '@root/types/PLC' import { cn } from '@root/utils' +import { getLiteralType } from '@root/utils/keywords' import { expandArrayVariables } from '@root/utils/PLC/array-variable-utils' import { Node } from '@xyflow/react' import { ComponentPropsWithRef, forwardRef } from 'react' @@ -212,6 +213,7 @@ const VariablesBlockAutoComplete = forwardRef { if (variable.id === 'add') { + if (getLiteralType(valueToSearch)) return submitAddVariable({ variableName: valueToSearch }) return } diff --git a/src/renderer/components/_atoms/graphical-editor/ladder/coil.tsx b/src/renderer/components/_atoms/graphical-editor/ladder/coil.tsx index 68838595d..bb05640ab 100644 --- a/src/renderer/components/_atoms/graphical-editor/ladder/coil.tsx +++ b/src/renderer/components/_atoms/graphical-editor/ladder/coil.tsx @@ -10,6 +10,7 @@ import { } from '@root/renderer/assets/icons/flow/Coil' import { useOpenPLCStore } from '@root/renderer/store' import { cn, generateNumericUUID } from '@root/utils' +import { getLiteralType } from '@root/utils/keywords' import type { Node, NodeProps } from '@xyflow/react' import { Position } from '@xyflow/react' import type { ReactNode } from 'react' @@ -476,7 +477,8 @@ export const Coil = (block: CoilProps) => { // Call triggerSubmit synchronously before blur to avoid race condition // where autocomplete unmounts before processing the Enter key autocompleteRef.current?.triggerSubmit?.() - inputVariableRef.current?.blur({ submit: false }) + // For literals/constants, let the blur handler process them + inputVariableRef.current?.blur({ submit: !!getLiteralType(coilVariableValue) }) return } setKeyPressedAtTextarea(e.key) diff --git a/src/renderer/components/_atoms/graphical-editor/ladder/contact.tsx b/src/renderer/components/_atoms/graphical-editor/ladder/contact.tsx index e58925c47..cdb4f21ce 100644 --- a/src/renderer/components/_atoms/graphical-editor/ladder/contact.tsx +++ b/src/renderer/components/_atoms/graphical-editor/ladder/contact.tsx @@ -8,6 +8,7 @@ import { } from '@root/renderer/assets/icons/flow/Contact' import { useOpenPLCStore } from '@root/renderer/store' import { cn, generateNumericUUID } from '@root/utils' +import { getLiteralType } from '@root/utils/keywords' import type { Node, NodeProps } from '@xyflow/react' import { Position } from '@xyflow/react' import type { ReactNode } from 'react' @@ -446,7 +447,8 @@ export const Contact = (block: ContactProps) => { // Call triggerSubmit synchronously before blur to avoid race condition // where autocomplete unmounts before processing the Enter key autocompleteRef.current?.triggerSubmit?.() - inputVariableRef.current?.blur({ submit: false }) + // For literals/constants, let the blur handler process them + inputVariableRef.current?.blur({ submit: !!getLiteralType(contactVariableValue) }) return } setKeyPressedAtTextarea(e.key) diff --git a/src/renderer/components/_atoms/graphical-editor/ladder/variable.tsx b/src/renderer/components/_atoms/graphical-editor/ladder/variable.tsx index c4b5cbf6d..c225171eb 100644 --- a/src/renderer/components/_atoms/graphical-editor/ladder/variable.tsx +++ b/src/renderer/components/_atoms/graphical-editor/ladder/variable.tsx @@ -498,7 +498,9 @@ const VariableElement = (block: VariableProps) => { // Call triggerSubmit synchronously before blur to avoid race condition // where autocomplete unmounts before processing the Enter key autocompleteRef.current?.triggerSubmit?.() - inputVariableRef.current?.blur({ submit: false }) + // For literals/constants, let the blur handler process them + // instead of suppressing it (triggerSubmit skips variable creation for literals) + inputVariableRef.current?.blur({ submit: !!getLiteralType(variableValue) }) return } setKeyPressedAtTextarea(e.key)