import { ComputedRef, Ref, MaybeRef } from 'vue'; import { ValidationResult, ValidationRule, VuetifyValidationRule } from '../../../composables/unifyValidation/useValidation'; import { DateObjectValue, DatePickerRule } from '../types'; import { useDateRangeValidation } from './useDateRangeValidation'; export type DatePickerValidationRule = DatePickerRule; /** * Options de configuration du contrôleur de validation DatePicker. * * Regroupe toutes les entrées réactives et non-réactives nécessaires : * - État du champ (required, readonly, displayRange, noCalendar…) * - Règles de validation (customRules, customWarningRules, customSuccessRules, rules Vuetify) * - Messages externes injectés par le parent (errorMessages, warningMessages, successMessages) * - État interne du DatePicker (selectedDates, isUpdatingFromInternal, isInitialValidation…) * - Configuration du flow (useCalendarModeRequiredFlow, skipValidationWhenReadonly, revalidateOnCustomRulesChange) * - Intégration formulaire (formRegistration pour SyForm) */ export type DatePickerValidationOptions = { showSuccessMessages: MaybeRef; disableErrorHandling: MaybeRef; noCalendar: MaybeRef; required: MaybeRef; displayRange: MaybeRef; customRules: Ref; customSuccessRules?: Ref; customWarningRules: Ref; errorMessages?: Ref; hasErrorProp?: MaybeRef; hasSuccessProp?: MaybeRef; hasWarningProp?: MaybeRef; warningMessages?: Ref; successMessages?: Ref; maxErrors?: MaybeRef; selectedDates: Ref; isUpdatingFromInternal: Ref; readonly?: MaybeRef; disabled?: MaybeRef; useVuetifyValidation?: MaybeRef; rules?: Ref; modelValue?: MaybeRef; skipValidationWhenReadonly?: boolean; useCalendarModeRequiredFlow?: boolean; isInitialValidation?: Ref; isValidateOnBlur?: Ref; hasBlurred?: Ref; fieldIdentifier?: MaybeRef; revalidateOnCustomRulesChange?: boolean; deferCustomRulesRevalidation?: MaybeRef; displayFormat?: MaybeRef; /** * Format de la chaîne transmise au `validate` des règles personnalisées par le flux * de saisie texte. `undefined` → `displayFormat` (comportement historique). * Renseigné par les composants uniquement quand `validateWithReturnFormat` est activé. */ returnFormat?: MaybeRef; parseDate?: (dateStr: string, format: string) => Date | null; hasInteracted?: Ref; formRegistration?: { validateOnSubmit?: () => Promise | boolean; clearValidation?: () => void; reset?: () => void; }; }; /** * Options du point d'entrée unifié `validate()`. * * ## Quand utiliser quelle option ? * * | Contexte d'appel | Options | Flow déclenché | * |---------------------------------------|----------------------------|-----------------------------| * | Saisie texte (blur, input) | `{ textValue: '01/01/25' }`| validateTextInput | * | Fermeture calendrier CalendarMode | `{ calendarMode: true }` | validateCalendarModeDates | * | Blur / submit CalendarMode | `{ force: true, calendarMode: true }` | validateCalendarModeDates (forcé) | * | Montage, watcher selectedDates | `{}` (par défaut) | validateDates (flow standard) | * | Submit ComplexDatePicker | `{ force: true }` | validateDates (forcé) | * * ### Pourquoi `calendarMode` est-il nécessaire ? * CalendarMode a un flow de validation différent du flow standard : * - Il gère le `required` différemment (skip en readonly, au blur sans validateOnBlur, au montage) * - Il valide les champs vides avec `null` si des customRules existent * - Si on utilisait toujours le flow CalendarMode, les custom rules ne s'exécuteraient pas au montage * (à cause du flag `isInitialValidation` qui skipp la validation) * → C'est pourquoi le montage et les watchers utilisent le flow standard (`validateDates`), * tandis que les interactions utilisateur (close, blur, submit) utilisent `calendarMode: true`. */ export interface ValidateOptions { /** * Force la validation même si les conditions interactives ne sont pas remplies. * Utilisé pour : validation on submit, validation au blur, validation forcée. * Sans cette option, la validation peut être skippée si l'utilisateur n'a pas interagi, * si `isInitialValidation` est true, ou si `isValidateOnBlur` est true (la validation * ne doit alors se faire qu'au blur, pas pendant la frappe ou la sélection). */ force?: boolean; /** * Si fourni, déclenche le flow de validation texte (parsing, format, plages). * Si absent, déclenche le flow de validation des dates sélectionnées (calendrier). */ textValue?: string; /** * Utiliser le flow CalendarMode (gestion required spécifique). * Par défaut, le flow standard `validateDates` est utilisé. * Mettre `true` pour les interactions utilisateur dans CalendarMode/DatePicker.vue * (fermeture calendrier, blur, submit). * NE PAS mettre `true` pour le montage ou les watchers — le flow standard exécute * les custom rules même pendant l'initialisation, ce qui est nécessaire pour * les composants parents comme PeriodField qui injectent des custom rules. */ calendarMode?: boolean; } /** * Interface publique du contrôleur de validation DatePicker. * * Exposée aux composants (DatePicker.vue, ComplexDatePicker.vue, DateTextInput.vue) * pour piloter la validation et lire son état. * * ## Point d'entrée principal * * `validate(options?)` — route automatiquement vers le bon flow selon le contexte : * - `{ textValue }` → flow texte (parsing, format, plages) — utilisé par DateTextInput * - `{ calendarMode: true }` → flow CalendarMode (gestion required spécifique) — utilisé par CalendarMode/DatePicker * - `{}` ou `{ force: true }` → flow standard (validation des dates) — utilisé par ComplexDatePicker, watchers, montage * * ## Alias de compatibilité * * Les méthodes `validateDates()`, `validateTextInput()`, `validateCalendarModeDates()` * sont conservées pour les composables qui les reçoivent en paramètre (`useDatePickerVisibility`, * `useDatePickerState`, `useDatePickerInputBlurHandler`) et pour les tests existants. * Dans les nouveaux développements, utiliser `validate()` directement. */ export interface DatePickerValidationController { errors: Ref; warnings: Ref; successes: Ref; hasError: Ref | ComputedRef; hasWarning: Ref | ComputedRef; hasSuccess: Ref | ComputedRef; errorMessages: Ref | ComputedRef; warningMessages: Ref | ComputedRef; successMessages: Ref | ComputedRef; /** Point d'entrée unifié : route vers le bon flow selon les options. */ validate: (options?: ValidateOptions) => ValidationResult | Promise | Promise; clearValidation: () => void; isRangeValid: ReturnType['isRangeValid']; pushError: (message?: string) => void; replaceErrors: (messages: string[]) => void; validateField: (value: unknown, rules?: ValidationRule[], warningRules?: ValidationRule[], successRules?: ValidationRule[]) => ValidationResult | Promise; validateDates: (forceValidation?: boolean) => ValidationResult | Promise; validateTextInput: (value: string, force?: boolean) => Promise; validateCalendarModeDates: (forceValidation?: boolean) => ValidationResult | Promise; } /** * Factory qui crée un contrôleur de validation DatePicker "inactif". * * Utilisé par les composants DatePicker quand la validation n'est pas nécessaire * (ex: `noCalendar` + pas de règles + pas de required). * Toutes les méthodes sont des no-ops, toutes les refs sont vides. */ export declare const createInactiveDatePickerValidationController: () => Pick; export declare function useDatePickerValidation(options: DatePickerValidationOptions): DatePickerValidationController;