Make nodes editable: norms, goals and keyword triggers

This commit is contained in:
Twirre
2025-11-13 10:50:12 +00:00
committed by Gerla, J. (Justin)
parent f534f0cefa
commit aeaf526797
14 changed files with 580 additions and 100 deletions

View File

@@ -0,0 +1,101 @@
import {useState} from "react";
import styles from "./TextField.module.css";
/**
* A text input element in our own style that calls `setValue` at every keystroke.
*
* @param {Object} props - The component props.
* @param {string} props.value - The value of the text input.
* @param {(value: string) => void} props.setValue - A function that sets the value of the text input.
* @param {string} [props.placeholder] - The placeholder text for the text input.
* @param {string} [props.className] - Additional CSS classes for the text input.
* @param {string} [props.id] - The ID of the text input.
* @param {string} [props.ariaLabel] - The ARIA label for the text input.
*/
export function RealtimeTextField({
value = "",
setValue,
onCommit,
placeholder,
className,
id,
ariaLabel,
invalid = false,
} : {
value: string,
setValue: (value: string) => void,
onCommit: () => void,
placeholder?: string,
className?: string,
id?: string,
ariaLabel?: string,
invalid?: boolean,
}) {
const [readOnly, setReadOnly] = useState(true);
const updateData = () => {
setReadOnly(true);
onCommit();
};
const updateOnEnter = (event: React.KeyboardEvent<HTMLInputElement>) => { if (event.key === "Enter") (event.target as HTMLInputElement).blur(); };
return <input
type={"text"}
placeholder={placeholder}
value={value}
onChange={(e) => setValue(e.target.value)}
onFocus={() => setReadOnly(false)}
onBlur={updateData}
onKeyDown={updateOnEnter}
readOnly={readOnly}
id={id}
// ReactFlow uses the "drag" / "nodrag" classes to enable / disable dragging of nodes
className={`${readOnly ? "drag" : "nodrag"} ${styles.textField} ${invalid ? styles.invalid : ""} ${className}`}
aria-label={ariaLabel}
/>;
}
/**
* A text input element in our own style that calls `setValue` once the user presses the enter key or clicks outside the input.
*
* @param {Object} props - The component props.
* @param {string} props.value - The value of the text input.
* @param {(value: string) => void} props.setValue - A function that sets the value of the text input.
* @param {string} [props.placeholder] - The placeholder text for the text input.
* @param {string} [props.className] - Additional CSS classes for the text input.
* @param {string} [props.id] - The ID of the text input.
* @param {string} [props.ariaLabel] - The ARIA label for the text input.
*/
export function TextField({
value = "",
setValue,
placeholder,
className,
id,
ariaLabel,
invalid = false,
} : {
value: string,
setValue: (value: string) => void,
placeholder?: string,
className?: string,
id?: string,
ariaLabel?: string,
invalid?: boolean,
}) {
const [inputValue, setInputValue] = useState(value);
const onCommit = () => setValue(inputValue);
return <RealtimeTextField
placeholder={placeholder}
value={inputValue}
setValue={setInputValue}
onCommit={onCommit}
id={id}
className={className}
ariaLabel={ariaLabel}
invalid={invalid}
/>;
}