Add comments explaining extra parsing logic

This commit is contained in:
Ola Hungerford
2025-03-16 15:28:07 -07:00
parent 7c4ed6abca
commit e1b015e40d

View File

@@ -46,15 +46,17 @@ const DynamicJsonForm = ({
}: DynamicJsonFormProps) => { }: DynamicJsonFormProps) => {
const [isJsonMode, setIsJsonMode] = useState(false); const [isJsonMode, setIsJsonMode] = useState(false);
const [jsonError, setJsonError] = useState<string>(); const [jsonError, setJsonError] = useState<string>();
// Add state for storing raw JSON value // Store the raw JSON string to allow immediate feedback during typing
// while deferring parsing until the user stops typing
const [rawJsonValue, setRawJsonValue] = useState<string>( const [rawJsonValue, setRawJsonValue] = useState<string>(
JSON.stringify(value ?? generateDefaultValue(schema), null, 2), JSON.stringify(value ?? generateDefaultValue(schema), null, 2),
); );
// Create a ref to store the timeout ID // Use a ref to manage debouncing timeouts to avoid parsing JSON
// on every keystroke which would be inefficient and error-prone
const timeoutRef = useRef<ReturnType<typeof setTimeout>>(); const timeoutRef = useRef<ReturnType<typeof setTimeout>>();
// Create a debounced function to update parent state // Debounce JSON parsing and parent updates to handle typing gracefully
const debouncedUpdateParent = useCallback( const debouncedUpdateParent = useCallback(
(jsonString: string) => { (jsonString: string) => {
// Clear any existing timeout // Clear any existing timeout
@@ -146,6 +148,8 @@ const DynamicJsonForm = ({
value={(currentValue as string) ?? ""} value={(currentValue as string) ?? ""}
onChange={(e) => { onChange={(e) => {
const val = e.target.value; const val = e.target.value;
// Allow clearing non-required fields by setting undefined
// This preserves the distinction between empty string and unset
if (!val && !propSchema.required) { if (!val && !propSchema.required) {
handleFieldChange(path, undefined); handleFieldChange(path, undefined);
} else { } else {
@@ -163,6 +167,8 @@ const DynamicJsonForm = ({
value={(currentValue as number)?.toString() ?? ""} value={(currentValue as number)?.toString() ?? ""}
onChange={(e) => { onChange={(e) => {
const val = e.target.value; const val = e.target.value;
// Allow clearing non-required number fields
// This preserves the distinction between 0 and unset
if (!val && !propSchema.required) { if (!val && !propSchema.required) {
handleFieldChange(path, undefined); handleFieldChange(path, undefined);
} else { } else {
@@ -184,10 +190,13 @@ const DynamicJsonForm = ({
value={(currentValue as number)?.toString() ?? ""} value={(currentValue as number)?.toString() ?? ""}
onChange={(e) => { onChange={(e) => {
const val = e.target.value; const val = e.target.value;
// Allow clearing non-required integer fields
// This preserves the distinction between 0 and unset
if (!val && !propSchema.required) { if (!val && !propSchema.required) {
handleFieldChange(path, undefined); handleFieldChange(path, undefined);
} else { } else {
const num = Number(val); const num = Number(val);
// Only update if it's a valid integer
if (!isNaN(num) && Number.isInteger(num)) { if (!isNaN(num) && Number.isInteger(num)) {
handleFieldChange(path, num); handleFieldChange(path, num);
} }