import React from 'react'; import { cn } from '@/lib/utils'; import { Input as DesignSystemInput } from './input'; import { Textarea as DesignSystemTextarea } from './textarea'; import { Select as DesignSystemSelect } from './select'; /** * FormFieldProps - Propriétés du composant FormField * * @interface FormFieldProps */ interface FormFieldProps { /** * Label du champ de formulaire * * @example * ```tsx * * * * ``` */ label: string; /** * Message d'erreur à afficher sous le champ * * @example * ```tsx * * * * ``` */ error?: string; /** * Si `true`, affiche un indicateur requis (*) * * @default false */ required?: boolean; /** * Champ de formulaire enfant (Input, Textarea, Select, etc.) */ children: React.ReactNode; /** * Classes CSS personnalisées */ className?: string; /** * Texte d'aide à afficher sous le champ (si pas d'erreur) * * @example * ```tsx * * * * ``` */ helpText?: string; } /** * FormField - Composant de champ de formulaire avec label et validation * * Composant wrapper pour les champs de formulaire avec support pour : * - Label avec indicateur requis * - Message d'erreur * - Texte d'aide * * @example * ```tsx * // Champ simple * * * * * // Champ requis avec erreur * * * * * // Champ avec texte d'aide * * * * ``` * * @component * @param {FormFieldProps} props - Propriétés du composant * @returns {JSX.Element} Élément div contenant le label, le champ et les messages */ export const FormField: React.FC = ({ label, error, required = false, children, className, helpText, }) => { return ( {label} {required && *} {children} {helpText && !error && ( {helpText} )} {error && ( {error} )} ); }; interface InputProps extends React.InputHTMLAttributes { error?: boolean; } export const Input: React.FC = ({ error = false, className, ...props }) => { return ( ); }; interface TextareaProps extends React.TextareaHTMLAttributes { error?: boolean; } export const Textarea: React.FC = ({ error = false, className, ...props }) => { return ( ); }; interface SelectProps extends Omit, 'onChange'> { error?: boolean; options: Array<{ value: string; label: string }>; placeholder?: string; onChange?: (event: React.ChangeEvent) => void; } export const Select: React.FC = ({ error = false, className, options, value, onChange, placeholder, disabled, 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledBy, }) => { const selectValue = value as string | undefined; const handleChange = (newValue: string | string[]) => { if (onChange) { const event = { target: { value: Array.isArray(newValue) ? newValue[0] : newValue }, } as React.ChangeEvent; onChange(event); } }; return ( ({ value: opt.value, label: opt.label }))} value={selectValue} onChange={handleChange} disabled={disabled} placeholder={placeholder || 'Select an option...'} className={cn( error && 'border-kodo-red', className, )} aria-label={ariaLabel} aria-labelledby={ariaLabelledBy} /> ); };
{helpText}
{error}