From f3a9bf7763b79e7f0cd092cd77a17f792cefa3d2 Mon Sep 17 00:00:00 2001 From: Josh Hawkins <32435876+hawkeye217@users.noreply.github.com> Date: Sat, 4 Apr 2026 21:55:27 -0500 Subject: [PATCH] fix DictAsYamlField feedback loop formData sync overwrites user input, fix was to skip external sync while the field is focused --- .../config-form/theme/fields/DictAsYamlField.tsx | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/web/src/components/config-form/theme/fields/DictAsYamlField.tsx b/web/src/components/config-form/theme/fields/DictAsYamlField.tsx index 0b21f9b1aa..ff1145cfcc 100644 --- a/web/src/components/config-form/theme/fields/DictAsYamlField.tsx +++ b/web/src/components/config-form/theme/fields/DictAsYamlField.tsx @@ -2,7 +2,7 @@ import type { FieldPathList, FieldProps } from "@rjsf/utils"; import yaml from "js-yaml"; import { Textarea } from "@/components/ui/textarea"; import { cn } from "@/lib/utils"; -import { useCallback, useEffect, useMemo, useState } from "react"; +import { useCallback, useEffect, useMemo, useRef, useState } from "react"; function formatYaml(value: unknown): string { if ( @@ -54,10 +54,14 @@ export function DictAsYamlField(props: FieldProps) { const [text, setText] = useState(() => formatYaml(formData)); const [error, setError] = useState(); + const focusedRef = useRef(false); useEffect(() => { - setText(formatYaml(formData)); - setError(undefined); + // Only sync from external formData changes, not our own onChange + if (!focusedRef.current) { + setText(formatYaml(formData)); + setError(undefined); + } }, [formData]); const handleChange = useCallback( @@ -73,8 +77,13 @@ export function DictAsYamlField(props: FieldProps) { [onChange, fieldPath], ); + const handleFocus = useCallback(() => { + focusedRef.current = true; + }, []); + const handleBlur = useCallback( (_e: React.FocusEvent) => { + focusedRef.current = false; // Reformat on blur if valid const { value } = parseYaml(text); if (value !== undefined) { @@ -101,6 +110,7 @@ export function DictAsYamlField(props: FieldProps) { placeholder={"key: value"} rows={Math.max(3, text.split("\n").length + 1)} onChange={handleChange} + onFocus={handleFocus} onBlur={handleBlur} /> {error &&

{error}

}