mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-20 08:11:13 -05:00
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:
@@ -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,11 +226,16 @@ export function FormFieldWrapper({
|
|||||||
)}
|
)}
|
||||||
</Label>
|
</Label>
|
||||||
|
|
||||||
{/* Input or Textarea */}
|
{/* Input or Textarea with validation icons */}
|
||||||
|
<div className="relative">
|
||||||
{isTextarea ? (
|
{isTextarea ? (
|
||||||
<Textarea
|
<Textarea
|
||||||
id={id}
|
id={id}
|
||||||
className={cn(error && "border-destructive")}
|
className={cn(
|
||||||
|
"pr-10",
|
||||||
|
error && "border-destructive",
|
||||||
|
isValid && "border-green-500/50"
|
||||||
|
)}
|
||||||
maxLength={maxLength}
|
maxLength={maxLength}
|
||||||
{...textareaProps}
|
{...textareaProps}
|
||||||
/>
|
/>
|
||||||
@@ -232,12 +243,29 @@ export function FormFieldWrapper({
|
|||||||
<Input
|
<Input
|
||||||
id={id}
|
id={id}
|
||||||
type={inputType}
|
type={inputType}
|
||||||
className={cn(error && "border-destructive")}
|
className={cn(
|
||||||
|
"pr-10",
|
||||||
|
error && "border-destructive",
|
||||||
|
isValid && "border-green-500/50"
|
||||||
|
)}
|
||||||
maxLength={maxLength}
|
maxLength={maxLength}
|
||||||
{...inputProps}
|
{...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 && (
|
||||||
<p className="text-xs text-muted-foreground">
|
<p className="text-xs text-muted-foreground">
|
||||||
|
|||||||
Reference in New Issue
Block a user