Compare commits

..

1 Commits

Author SHA1 Message Date
David Nguyen aa892d8bf8 fix: auto select field on drop 2026-06-25 15:26:03 +10:00
2 changed files with 44 additions and 3 deletions
@@ -237,6 +237,16 @@ export const EnvelopeEditorFieldDragDrop = ({
[selectedRecipientId, getRecipientColorKey],
);
/**
* Begin placing a field type. Also clears the current field selection so the
* previously placed field's action toolbar can't intercept the next placement
* click on the canvas (the renderer mirrors this onto the canvas selection).
*/
const handleStartPlacingField = (type: FieldType) => {
setSelectedField(type);
editorFields.setSelectedField(null);
};
return (
<>
<div className="grid grid-cols-2 gap-x-2 gap-y-2.5">
@@ -245,8 +255,8 @@ export const EnvelopeEditorFieldDragDrop = ({
disabled={isFieldsDisabled}
key={field.type}
type="button"
onClick={() => setSelectedField(field.type)}
onMouseDown={() => setSelectedField(field.type)}
onClick={() => handleStartPlacingField(field.type)}
onMouseDown={() => handleStartPlacingField(field.type)}
data-selected={selectedField === field.type ? true : undefined}
className={cn(
'group flex h-12 cursor-pointer items-center justify-center rounded-lg border border-border px-4 transition-colors',
@@ -521,11 +521,42 @@ export const EnvelopeEditorFieldsPageRenderer = ({ pageData }: { pageData: PageR
setSelectedFields(liveSelectedFieldGroups);
}
// Mirror the editor's single selected field onto the canvas (Konva) selection.
//
// `addField` already marks a newly created field as the selected field, so this
// makes a field placed via the palette (drag-drop) or marquee creation show its
// resize handles immediately -- no second click needed. It also clears the canvas
// selection when the selected field is cleared (e.g. when the author starts
// placing another field), so the floating action toolbar can't intercept the next
// placement click. Runs after the render loop above so the field's group exists.
const selectedFormId = editorFields.selectedField?.formId ?? null;
const isSingleCanvasSelection = selectedKonvaFieldGroups.length === 1;
if (selectedFormId && localPageFields.some((field) => field.formId === selectedFormId)) {
const isAlreadySelected = isSingleCanvasSelection && selectedKonvaFieldGroups[0].id() === selectedFormId;
if (!isAlreadySelected) {
const fieldGroupToSelect = pageLayer.current.findOne(`#${selectedFormId}`);
if (fieldGroupToSelect instanceof Konva.Group) {
setSelectedFields([fieldGroupToSelect]);
}
}
} else if (selectedFormId === null && isSingleCanvasSelection) {
setSelectedFields([]);
}
// Rerender the transformer
interactiveTransformer.current?.forceUpdate();
pageLayer.current.batchDraw();
}, [localPageFields, selectedKonvaFieldGroups, overlappingFieldFormIds, isFieldChanging]);
}, [
localPageFields,
selectedKonvaFieldGroups,
overlappingFieldFormIds,
isFieldChanging,
editorFields.selectedField?.formId,
]);
const setSelectedFields = (nodes: Konva.Node[]) => {
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions