Created
September 10, 2024 18:11
-
-
Save EvanMarie/36e21139721b11e355251d08d1affb7a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export function ValidatedJSONNumberedInput({ | |
initialValue, | |
onChange, | |
}: { | |
initialValue?: string; | |
onChange: (e: React.ChangeEvent<HTMLTextAreaElement>) => void; | |
}) { | |
// State to track textarea content and JSON validation errors | |
const [value, setValue] = useState(initialValue); | |
const [jsonError, setJsonError] = useState<string | null>(null); | |
// Update value state when initialValue changes | |
useEffect(() => { | |
setValue(initialValue || ""); // Set value when initialValue changes | |
}, [initialValue]); | |
// Function to calculate the line number from a given position in the string | |
const getLineNumber = (input: string, position: number): number => { | |
const normalizedInput = input.replace(/\r\n/g, "\n"); // Normalize line breaks | |
const lines = normalizedInput.substring(0, position).split("\n"); | |
return lines.length; // Return the number of lines up to the error | |
}; | |
// Function to validate the JSON input and identify the error line if parsing fails | |
const validateJSON = (input: string) => { | |
try { | |
JSON.parse(input); // Attempt to parse JSON | |
setJsonError(null); // Clear error if valid | |
} catch (error: any) { | |
const positionMatch = error.message.match(/position (\d+)/); | |
if (positionMatch) { | |
const position = parseInt(positionMatch[1], 10); | |
const lineNumber = getLineNumber(input, position); // Get line number of error | |
setJsonError(`Invalid JSON format at line ${lineNumber}`); | |
} else { | |
setJsonError("Invalid JSON format"); // General error message | |
} | |
} | |
}; | |
// Handler function triggered when the content of the textarea changes | |
const handleTextAreaChange = ( | |
event: React.ChangeEvent<HTMLTextAreaElement> | |
) => { | |
const inputValue = event.target.value; | |
setValue(inputValue); // Update value | |
validateJSON(inputValue); // Validate the input as JSON | |
if (onChange) { | |
onChange(event); // Call parent onChange handler | |
} | |
}; | |
return ( | |
<Center className="w-full"> | |
{/* Use Flex to layout the content relatively */} | |
<FlexFull className="relative"> | |
{jsonError && <JsonError jsonError={jsonError} />}{" "} | |
{/* Show error if present */} | |
<TextAreaNumberedLines | |
value={value} // Pass current value to textarea | |
onChange={handleTextAreaChange} // Trigger onChange event to validate JSON | |
/> | |
</FlexFull> | |
</Center> | |
); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment