Enhance FormFieldWrapper Validation

Add real-time validation feedback to FormFieldWrapper:
- Manage validation state (idle/valid/invalid)
- Show green check icon when valid
- Show inline error icon when invalid
- Integrate with existing Input/Textarea components without altering core behavior
This commit is contained in:
gpt-engineer-app[bot]
2025-11-11 23:38:07 +00:00
parent 6fef107728
commit 7d085a0702

View File

@@ -5,6 +5,7 @@ import { Label } from "@/components/ui/label";
import { TermTooltip } from "@/components/ui/term-tooltip"; import { TermTooltip } from "@/components/ui/term-tooltip";
import { fieldHints } from "@/lib/enhancedValidation"; import { fieldHints } from "@/lib/enhancedValidation";
import { cn } from "@/lib/utils"; import { cn } from "@/lib/utils";
import { CheckCircle2, AlertCircle } from "lucide-react";
/** /**
* Field types that automatically get hints and terminology support * Field types that automatically get hints and terminology support
@@ -201,6 +202,11 @@ export function FormFieldWrapper({
const showCharCount = isTextarea && maxLength && typeof value === 'string'; const showCharCount = isTextarea && maxLength && typeof value === 'string';
const charCount = typeof value === 'string' ? value.length : 0; const charCount = typeof value === 'string' ? value.length : 0;
// Determine validation state
const hasValue = value !== undefined && value !== null && value !== '';
const isValid = !error && hasValue;
const hasError = !!error;
return ( return (
<div className={cn("space-y-2", className)}> <div className={cn("space-y-2", className)}>
{/* Label with optional terminology tooltip */} {/* Label with optional terminology tooltip */}
@@ -220,23 +226,45 @@ export function FormFieldWrapper({
)} )}
</Label> </Label>
{/* Input or Textarea */} {/* Input or Textarea with validation icons */}
{isTextarea ? ( <div className="relative">
<Textarea {isTextarea ? (
id={id} <Textarea
className={cn(error && "border-destructive")} id={id}
maxLength={maxLength} className={cn(
{...textareaProps} "pr-10",
/> error && "border-destructive",
) : ( isValid && "border-green-500/50"
<Input )}
id={id} maxLength={maxLength}
type={inputType} {...textareaProps}
className={cn(error && "border-destructive")} />
maxLength={maxLength} ) : (
{...inputProps} <Input
/> id={id}
)} type={inputType}
className={cn(
"pr-10",
error && "border-destructive",
isValid && "border-green-500/50"
)}
maxLength={maxLength}
{...inputProps}
/>
)}
{/* Validation icon */}
{(isValid || hasError) && (
<div className="absolute right-3 top-1/2 -translate-y-1/2 pointer-events-none">
{isValid && (
<CheckCircle2 className="h-4 w-4 text-green-500" />
)}
{hasError && (
<AlertCircle className="h-4 w-4 text-destructive" />
)}
</div>
)}
</div>
{/* Hint text (if not hidden and exists) */} {/* Hint text (if not hidden and exists) */}
{!hideHint && displayHint && !error && ( {!hideHint && displayHint && !error && (