diff --git a/apps/client/src/widgets/collections/board/card.tsx b/apps/client/src/widgets/collections/board/card.tsx
index fc81e9f0e..0ee92a11d 100644
--- a/apps/client/src/widgets/collections/board/card.tsx
+++ b/apps/client/src/widgets/collections/board/card.tsx
@@ -119,7 +119,7 @@ export default function Card({
setTitle(newTitle);
}}
dismiss={() => api.dismissEditingTitle()}
- multiline
+ mode="multiline"
/>
)}
diff --git a/apps/client/src/widgets/collections/board/column.tsx b/apps/client/src/widgets/collections/board/column.tsx
index 791eb585e..f014b67bf 100644
--- a/apps/client/src/widgets/collections/board/column.tsx
+++ b/apps/client/src/widgets/collections/board/column.tsx
@@ -124,6 +124,7 @@ export default function Column({
currentValue={column}
save={newTitle => api.renameColumn(column, newTitle)}
dismiss={() => setColumnNameToEdit?.(undefined)}
+ mode={isInRelationMode ? "relation" : "normal"}
/>
)}
@@ -187,7 +188,7 @@ function AddNewItem({ column, api }: { column: string, api: BoardApi }) {
placeholder={t("board_view.new-item-placeholder")}
save={(title) => api.createNewItem(column, title)}
dismiss={() => setIsCreatingNewItem(false)}
- multiline isNewItem
+ mode="multiline" isNewItem
/>
)}
diff --git a/apps/client/src/widgets/collections/board/index.tsx b/apps/client/src/widgets/collections/board/index.tsx
index effcb7fda..97b9632bf 100644
--- a/apps/client/src/widgets/collections/board/index.tsx
+++ b/apps/client/src/widgets/collections/board/index.tsx
@@ -13,6 +13,7 @@ import Column from "./column";
import BoardApi from "./api";
import FormTextArea from "../../react/FormTextArea";
import FNote from "../../../entities/fnote";
+import NoteAutocomplete from "../../react/NoteAutocomplete";
export interface BoardViewData {
columns?: BoardColumnData[];
@@ -188,14 +189,14 @@ export default function BoardView({ note: parentNote, noteIds, viewConfig, saveC
)}
-
+
)
}
-function AddNewColumn({ api }: { api: BoardApi }) {
+function AddNewColumn({ api, isInRelationMode }: { api: BoardApi, isInRelationMode: boolean }) {
const [ isCreatingNewColumn, setIsCreatingNewColumn ] = useState(false);
const addColumnCallback = useCallback(() => {
@@ -215,19 +216,20 @@ function AddNewColumn({ api }: { api: BoardApi }) {
save={(columnName) => api.addNewColumn(columnName)}
dismiss={() => setIsCreatingNewColumn(false)}
isNewItem
+ mode={isInRelationMode ? "relation" : "normal"}
/>
)}
)
}
-export function TitleEditor({ currentValue, placeholder, save, dismiss, multiline, isNewItem }: {
+export function TitleEditor({ currentValue, placeholder, save, dismiss, mode, isNewItem }: {
currentValue?: string;
placeholder?: string;
save: (newValue: string) => void;
dismiss: () => void;
- multiline?: boolean;
isNewItem?: boolean;
+ mode?: "normal" | "multiline" | "relation";
}) {
const inputRef = useRef(null);
const focusElRef = useRef(null);
@@ -240,8 +242,6 @@ export function TitleEditor({ currentValue, placeholder, save, dismiss, multilin
inputRef.current?.select();
}, [ inputRef ]);
- const Element = multiline ? FormTextArea : FormTextBox;
-
useEffect(() => {
if (dismissOnNextRefreshRef.current) {
dismiss();
@@ -249,31 +249,52 @@ export function TitleEditor({ currentValue, placeholder, save, dismiss, multilin
}
});
- return (
- ) => {
- if (e.key === "Enter" || e.key === "Escape") {
- e.preventDefault();
- e.stopPropagation();
- shouldDismiss.current = (e.key === "Escape");
- if (focusElRef.current instanceof HTMLElement) {
- focusElRef.current.focus();
- }
- }
- }}
- onBlur={(newValue) => {
- if (!shouldDismiss.current && newValue.trim() && (newValue !== currentValue || isNewItem)) {
- save(newValue);
- dismissOnNextRefreshRef.current = true;
- } else {
- dismiss();
- }
- }}
- />
- );
+ const onKeyDown = (e: TargetedKeyboardEvent | KeyboardEvent) => {
+ if (e.key === "Enter" || e.key === "Escape") {
+ e.preventDefault();
+ e.stopPropagation();
+ shouldDismiss.current = (e.key === "Escape");
+ if (focusElRef.current instanceof HTMLElement) {
+ focusElRef.current.focus();
+ }
+ }
+ };
+
+ const onBlur = (newValue) => {
+ if (!shouldDismiss.current && newValue.trim() && (newValue !== currentValue || isNewItem)) {
+ save(newValue);
+ dismissOnNextRefreshRef.current = true;
+ } else {
+ dismiss();
+ }
+ };
+
+ if (mode !== "relation") {
+ const Element = mode === "multiline" ? FormTextArea : FormTextBox;
+
+ return (
+
+ );
+ } else {
+ return (
+
+ )
+ }
}
diff --git a/apps/client/src/widgets/react/NoteAutocomplete.tsx b/apps/client/src/widgets/react/NoteAutocomplete.tsx
index 223dbb5d4..198e69695 100644
--- a/apps/client/src/widgets/react/NoteAutocomplete.tsx
+++ b/apps/client/src/widgets/react/NoteAutocomplete.tsx
@@ -5,7 +5,7 @@ import type { RefObject } from "preact";
import type { CSSProperties } from "preact/compat";
import { useSyncedRef } from "./hooks";
-interface NoteAutocompleteProps {
+interface NoteAutocompleteProps {
id?: string;
inputRef?: RefObject;
text?: string;
@@ -15,13 +15,15 @@ interface NoteAutocompleteProps {
opts?: Omit;
onChange?: (suggestion: Suggestion | null) => void;
onTextChange?: (text: string) => void;
+ onKeyDown?: (e: KeyboardEvent) => void;
+ onBlur?: (newValue: string) => void;
noteIdChanged?: (noteId: string) => void;
noteId?: string;
}
-export default function NoteAutocomplete({ id, inputRef: externalInputRef, text, placeholder, onChange, onTextChange, container, containerStyle, opts, noteId, noteIdChanged }: NoteAutocompleteProps) {
+export default function NoteAutocomplete({ id, inputRef: externalInputRef, text, placeholder, onChange, onTextChange, container, containerStyle, opts, noteId, noteIdChanged, onKeyDown, onBlur }: NoteAutocompleteProps) {
const ref = useSyncedRef(externalInputRef);
-
+
useEffect(() => {
if (!ref.current) return;
const $autoComplete = $(ref.current);
@@ -57,6 +59,12 @@ export default function NoteAutocomplete({ id, inputRef: externalInputRef, text,
if (onTextChange) {
$autoComplete.on("input", () => onTextChange($autoComplete[0].value));
}
+ if (onKeyDown) {
+ $autoComplete.on("keydown", (e) => e.originalEvent && onKeyDown(e.originalEvent));
+ }
+ if (onBlur) {
+ $autoComplete.on("blur", () => onBlur($autoComplete.getSelectedNoteId() ?? ""));
+ }
}, [opts, container?.current]);
useEffect(() => {
@@ -81,4 +89,4 @@ export default function NoteAutocomplete({ id, inputRef: externalInputRef, text,
placeholder={placeholder ?? t("add_link.search_note")} />
);
-}
\ No newline at end of file
+}