From aeb458999a138d135b3299c844af022da5bfadab Mon Sep 17 00:00:00 2001 From: Jin <22962980+JYC333@users.noreply.github.com> Date: Mon, 9 Mar 2026 23:01:05 +0000 Subject: [PATCH] refactor: fix enter can't execute action in dialog --- .../src/services/attribute_autocomplete.ts | 22 ++++++++++++++----- apps/client/src/services/note_autocomplete.ts | 13 ++++++++--- apps/client/src/widgets/dialogs/prompt.tsx | 22 ++++++------------- .../type_widgets/relation_map/RelationMap.tsx | 1 - 4 files changed, 33 insertions(+), 25 deletions(-) diff --git a/apps/client/src/services/attribute_autocomplete.ts b/apps/client/src/services/attribute_autocomplete.ts index 277f36f7a0..9a86eb594c 100644 --- a/apps/client/src/services/attribute_autocomplete.ts +++ b/apps/client/src/services/attribute_autocomplete.ts @@ -200,10 +200,16 @@ function initAttributeNameAutocomplete({ $el, attributeType, open, onValueChange }, 50); }, onKeyDown(e, handlers) { - if (e.key === "Enter" && isPanelOpen && hasActiveItem) { - // Prevent the enter key from propagating to parent dialogs - // (which might interpret it as "submit" or "save and close") - e.stopPropagation(); + if (e.key === "Enter") { + if (isPanelOpen && hasActiveItem) { + // Prevent the enter key from propagating to parent dialogs + // (which might interpret it as "submit" or "save and close") + e.stopPropagation(); + } else if (!isPanelOpen) { + // Panel is closed. Do not pass Enter to autocomplete-core + // so native HTML form submit handlers can run. + return; + } } handlers.onKeyDown(e as any); } @@ -386,8 +392,12 @@ function initLabelValueAutocomplete({ $el, open, nameCallback, onValueChange }: }, 50); }, onKeyDown(e, handlers) { - if (e.key === "Enter" && isPanelOpen && hasActiveItem) { - e.stopPropagation(); + if (e.key === "Enter") { + if (isPanelOpen && hasActiveItem) { + e.stopPropagation(); + } else if (!isPanelOpen) { + return; // Let native submit form bubbling happen + } } handlers.onKeyDown(e as any); } diff --git a/apps/client/src/services/note_autocomplete.ts b/apps/client/src/services/note_autocomplete.ts index 63cbaa68dc..8996a50e67 100644 --- a/apps/client/src/services/note_autocomplete.ts +++ b/apps/client/src/services/note_autocomplete.ts @@ -702,7 +702,7 @@ function initNoteAutocomplete($el: JQuery, options?: Options) { const onCompositionStart = () => { isComposingInput = true; }; - const onCompositionEnd = (e: CompositionEvent) => { + const onCompositionEnd = (e: any) => { isComposingInput = false; rerunQuery(inputEl.value); }; @@ -755,14 +755,21 @@ function initNoteAutocomplete($el: JQuery, options?: Options) { return; } + if (e.key === "Enter" && !wasPanelOpen) { + // Do not pass the Enter key to autocomplete-core if the panel is closed. + // This prevents `preventDefault()` from being called inappropriately and + // allows the native form submission to work. + return; + } + if (e.key === "ArrowDown" || e.key === "ArrowUp") { shouldMirrorActiveItemToInput = true; } handlers.onKeyDown(e as any); }, extraBindings: [ - { type: "compositionstart", listener: onCompositionStart }, - { type: "compositionend", listener: onCompositionEnd } + { type: "compositionstart", listener: onCompositionStart as ((event: Event) => void) }, + { type: "compositionend", listener: onCompositionEnd as ((event: Event) => void) } ] }); diff --git a/apps/client/src/widgets/dialogs/prompt.tsx b/apps/client/src/widgets/dialogs/prompt.tsx index 78741641ae..30f54ef22b 100644 --- a/apps/client/src/widgets/dialogs/prompt.tsx +++ b/apps/client/src/widgets/dialogs/prompt.tsx @@ -1,11 +1,12 @@ import { useRef, useState } from "preact/hooks"; + import { t } from "../../services/i18n"; import Button from "../react/Button"; -import Modal from "../react/Modal"; -import FormTextBox from "../react/FormTextBox"; import FormGroup from "../react/FormGroup"; -import { refToJQuerySelector } from "../react/react_utils"; +import FormTextBox from "../react/FormTextBox"; import { useTriliumEvent } from "../react/hooks"; +import Modal from "../react/Modal"; +import { refToJQuerySelector } from "../react/react_utils"; // JQuery here is maintained for compatibility with existing code. interface ShownCallbackData { @@ -24,7 +25,6 @@ export interface PromptDialogOptions { shown?: PromptShownDialogCallback; callback?: (value: string | null) => void; readOnly?: boolean; - submitWithCtrlEnter?: boolean; } export default function PromptDialog() { @@ -41,7 +41,7 @@ export default function PromptDialog() { opts.current = newOpts; setValue(newOpts.defaultValue ?? ""); setShown(true); - }) + }); return ( { - submitValue.current = value; + submitValue.current = answerRef.current?.value || value; setShown(false); }} onHidden={() => { @@ -70,7 +70,7 @@ export default function PromptDialog() { submitValue.current = null; opts.current = undefined; }} - footer={