0
# Validation and Utilities
1
2
Validation functions, utility hooks, and helper components for enhanced picker functionality and custom implementations.
3
4
## Capabilities
5
6
### Validation Functions
7
8
#### validateDate
9
10
Validates date values against constraints and business rules.
11
12
```typescript { .api }
13
/**
14
* Validates a date value against constraints
15
* @param props - Validation configuration properties
16
* @returns Validation error message or null if valid
17
*/
18
function validateDate<TDate>(props: ValidateDateProps<TDate>): string | null;
19
20
interface ValidateDateProps<TDate> {
21
/** Date value to validate */
22
value: TDate | null;
23
/** Minimum allowed date */
24
minDate?: TDate;
25
/** Maximum allowed date */
26
maxDate?: TDate;
27
/** If true, disable dates after today */
28
disableFuture?: boolean;
29
/** If true, disable dates before today */
30
disablePast?: boolean;
31
/** Function to disable specific dates */
32
shouldDisableDate?: (day: TDate) => boolean;
33
/** Date adapter instance */
34
adapter: MuiPickersAdapter<TDate>;
35
/** Timezone for validation */
36
timezone: PickersTimezone;
37
}
38
```
39
40
#### validateTime
41
42
Validates time values against time constraints and business rules.
43
44
```typescript { .api }
45
/**
46
* Validates a time value against constraints
47
* @param props - Time validation configuration properties
48
* @returns Validation error message or null if valid
49
*/
50
function validateTime<TDate>(props: ValidateTimeProps<TDate>): string | null;
51
52
interface ValidateTimeProps<TDate> {
53
/** Time value to validate */
54
value: TDate | null;
55
/** Minimum allowed time */
56
minTime?: TDate;
57
/** Maximum allowed time */
58
maxTime?: TDate;
59
/** Function to disable specific times */
60
shouldDisableTime?: (value: TDate, view: TimeView) => boolean;
61
/** Date adapter instance */
62
adapter: MuiPickersAdapter<TDate>;
63
/** Timezone for validation */
64
timezone: PickersTimezone;
65
/** Current view being validated */
66
view?: TimeView;
67
}
68
69
type TimeView = 'hours' | 'minutes' | 'seconds';
70
```
71
72
#### validateDateTime
73
74
Validates date-time values against combined date and time constraints.
75
76
```typescript { .api }
77
/**
78
* Validates a date-time value against constraints
79
* @param props - Date-time validation configuration properties
80
* @returns Validation error message or null if valid
81
*/
82
function validateDateTime<TDate>(props: ValidateDateTimeProps<TDate>): string | null;
83
84
interface ValidateDateTimeProps<TDate> extends ValidateDateProps<TDate>, ValidateTimeProps<TDate> {
85
/** Minimum allowed date-time */
86
minDateTime?: TDate;
87
/** Maximum allowed date-time */
88
maxDateTime?: TDate;
89
}
90
```
91
92
#### extractValidationProps
93
94
Utility function to extract validation-related props from picker props.
95
96
```typescript { .api }
97
/**
98
* Extracts validation props from picker component props
99
* @param props - Picker component props
100
* @returns Object containing validation props and remaining props
101
*/
102
function extractValidationProps<TProps extends Record<string, any>>(
103
props: TProps
104
): {
105
validationProps: ValidationProps;
106
otherProps: Omit<TProps, keyof ValidationProps>;
107
};
108
109
interface ValidationProps {
110
minDate?: any;
111
maxDate?: any;
112
minTime?: any;
113
maxTime?: any;
114
minDateTime?: any;
115
maxDateTime?: any;
116
disableFuture?: boolean;
117
disablePast?: boolean;
118
shouldDisableDate?: (day: any) => boolean;
119
shouldDisableTime?: (value: any, view: string) => boolean;
120
}
121
```
122
123
### Validation Hook
124
125
#### useValidation
126
127
Hook for managing validation state and error handling in picker components.
128
129
```typescript { .api }
130
/**
131
* Hook for managing validation state in picker components
132
* @param props - Validation hook configuration properties
133
* @returns Validation state and handlers
134
*/
135
function useValidation<TValue, TError>(
136
props: UseValidationProps<TValue, TError>
137
): UseValidationReturnValue<TError>;
138
139
interface UseValidationProps<TValue, TError> {
140
/** Current value to validate */
141
value: TValue;
142
/** Validator function */
143
validator: Validator<TValue, TError>;
144
/** If true, run validation on mount */
145
validateOnMount?: boolean;
146
/** External validation error */
147
externalError?: TError;
148
}
149
150
interface UseValidationReturnValue<TError> {
151
/** Current validation error */
152
validationError: TError;
153
/** Function to trigger validation */
154
validateValue: () => void;
155
/** Function to clear validation error */
156
clearValidationError: () => void;
157
/** If true, validation has been run */
158
hasValidationError: boolean;
159
}
160
161
type Validator<TValue, TError> = (value: TValue) => TError;
162
```
163
164
## Utility Hooks
165
166
### usePickerTranslations
167
168
Hook for accessing localized text for picker components.
169
170
```typescript { .api }
171
/**
172
* Hook for accessing picker translations and localized text
173
* @returns Translation functions and localized strings
174
*/
175
function usePickerTranslations(): PickersTranslations;
176
177
interface PickersTranslations {
178
/** Get localized calendar view label */
179
getCalendarViewSwitchingButtonAriaLabel: (view: CalendarPickerView) => string;
180
/** Get localized clock view label */
181
getClockViewSwitchingButtonAriaLabel: (view: ClockPickerView) => string;
182
/** Get localized date picker dialog label */
183
getOpenDatePickerDialogue: (value: any, adapter: MuiPickersAdapter<any>) => string;
184
/** Get localized time picker dialog label */
185
getOpenTimePickerDialogue: (value: any, adapter: MuiPickersAdapter<any>) => string;
186
/** Localized button labels */
187
cancelButtonLabel: string;
188
clearButtonLabel: string;
189
okButtonLabel: string;
190
todayButtonLabel: string;
191
/** Localized toolbar titles */
192
datePickerToolbarTitle: string;
193
timePickerToolbarTitle: string;
194
dateTimePickerToolbarTitle: string;
195
/** Navigation labels */
196
previousMonth: string;
197
nextMonth: string;
198
}
199
200
type CalendarPickerView = 'year' | 'month' | 'day';
201
type ClockPickerView = 'hours' | 'minutes' | 'seconds';
202
```
203
204
### usePickerAdapter
205
206
Hook for accessing the current date adapter from LocalizationProvider context.
207
208
```typescript { .api }
209
/**
210
* Hook for accessing the current date adapter
211
* @returns Date adapter instance from context
212
*/
213
function usePickerAdapter<TDate>(): MuiPickersAdapter<TDate>;
214
```
215
216
### useIsValidValue
217
218
Hook for checking if a picker value is valid.
219
220
```typescript { .api }
221
/**
222
* Hook for validating picker values
223
* @param props - Validation configuration properties
224
* @returns Boolean indicating if value is valid
225
*/
226
function useIsValidValue<TDate>(props: UseIsValidValueProps<TDate>): boolean;
227
228
interface UseIsValidValueProps<TDate> {
229
/** Value to validate */
230
value: TDate | null;
231
/** Date adapter instance */
232
adapter: MuiPickersAdapter<TDate>;
233
/** Timezone for validation */
234
timezone?: PickersTimezone;
235
/** Additional validator function */
236
validator?: (value: TDate | null) => string | null;
237
}
238
```
239
240
### usePickerContext
241
242
Hook for accessing picker context values.
243
244
```typescript { .api }
245
/**
246
* Hook for accessing picker context
247
* @returns Picker context values
248
*/
249
function usePickerContext<TDate>(): PickerContext<TDate>;
250
251
interface PickerContext<TDate> {
252
/** Current picker value */
253
value: TDate | null;
254
/** If true, picker is open */
255
open: boolean;
256
/** Function to set picker open state */
257
setOpen: (open: boolean) => void;
258
/** Current view */
259
view: string;
260
/** Function to change view */
261
setView: (view: string) => void;
262
/** Date adapter instance */
263
adapter: MuiPickersAdapter<TDate>;
264
/** Current timezone */
265
timezone: PickersTimezone;
266
}
267
```
268
269
### usePickerActionsContext
270
271
Hook for accessing picker action handlers.
272
273
```typescript { .api }
274
/**
275
* Hook for accessing picker action context
276
* @returns Picker action handlers
277
*/
278
function usePickerActionsContext(): PickerActionsContext;
279
280
interface PickerActionsContext {
281
/** Accept current value and close picker */
282
onAccept: () => void;
283
/** Cancel selection and close picker */
284
onCancel: () => void;
285
/** Clear current value */
286
onClear: () => void;
287
/** Set current value to today */
288
onSetToday: () => void;
289
}
290
```
291
292
### useSplitFieldProps
293
294
Hook for splitting field props from other picker props.
295
296
```typescript { .api }
297
/**
298
* Hook for splitting field props from picker props
299
* @param props - Combined picker and field props
300
* @returns Object with separated field and picker props
301
*/
302
function useSplitFieldProps<TProps extends Record<string, any>>(
303
props: TProps
304
): {
305
fieldProps: FieldProps;
306
pickerProps: Omit<TProps, keyof FieldProps>;
307
};
308
309
interface FieldProps {
310
value?: any;
311
defaultValue?: any;
312
onChange?: (value: any, context: any) => void;
313
format?: string;
314
disabled?: boolean;
315
readOnly?: boolean;
316
required?: boolean;
317
shouldRespectLeadingZeros?: boolean;
318
selectedSections?: any;
319
onSelectedSectionsChange?: (sections: any) => void;
320
}
321
```
322
323
### useParsedFormat
324
325
Hook for parsing and validating date format strings.
326
327
```typescript { .api }
328
/**
329
* Hook for parsing date format strings
330
* @param formatString - Date format string to parse
331
* @returns Parsed format information
332
*/
333
function useParsedFormat(formatString: string): ParsedFormat;
334
335
interface ParsedFormat {
336
/** Parsed format sections */
337
sections: FormatSection[];
338
/** If true, format is valid */
339
isValid: boolean;
340
/** Format validation error */
341
error?: string;
342
}
343
344
interface FormatSection {
345
/** Section type */
346
type: FieldSectionType;
347
/** Format token */
348
token: string;
349
/** Section length */
350
length: number;
351
}
352
353
type FieldSectionType = 'year' | 'month' | 'day' | 'weekDay' | 'hours' | 'minutes' | 'seconds' | 'meridiem' | 'empty';
354
```
355
356
## Manager Hooks
357
358
### useDateManager
359
360
Hook for managing date field state and operations.
361
362
```typescript { .api }
363
/**
364
* Hook for managing date field state
365
* @param props - Date manager configuration properties
366
* @returns Date field state and handlers
367
*/
368
function useDateManager<TDate>(props: UseDateManagerParameters<TDate>): UseDateManagerReturnValue<TDate>;
369
370
interface UseDateManagerParameters<TDate> {
371
/** Current date value */
372
value?: TDate | null;
373
/** Default date value */
374
defaultValue?: TDate | null;
375
/** Callback when date changes */
376
onChange?: (value: TDate | null, context: FieldChangeContext<TDate>) => void;
377
/** Date format string */
378
format?: string;
379
/** Date adapter instance */
380
adapter: MuiPickersAdapter<TDate>;
381
/** Validation rules */
382
validation?: Partial<ValidateDateProps<TDate>>;
383
}
384
385
interface UseDateManagerReturnValue<TDate> {
386
/** Current date value */
387
value: TDate | null;
388
/** Formatted date string */
389
formattedValue: string;
390
/** Date change handler */
391
handleValueChange: (value: TDate | null) => void;
392
/** Field sections */
393
sections: FieldSection[];
394
/** Active section index */
395
activeSectionIndex: number | null;
396
/** Validation error */
397
validationError: string | null;
398
}
399
400
interface DateManagerFieldInternalProps<TDate> {
401
value: TDate | null;
402
onChange: (value: TDate | null, context: FieldChangeContext<TDate>) => void;
403
format: string;
404
}
405
```
406
407
### useTimeManager
408
409
Hook for managing time field state and operations.
410
411
```typescript { .api }
412
/**
413
* Hook for managing time field state
414
* @param props - Time manager configuration properties
415
* @returns Time field state and handlers
416
*/
417
function useTimeManager<TDate>(props: UseTimeManagerParameters<TDate>): UseTimeManagerReturnValue<TDate>;
418
419
interface UseTimeManagerParameters<TDate> {
420
/** Current time value */
421
value?: TDate | null;
422
/** Default time value */
423
defaultValue?: TDate | null;
424
/** Callback when time changes */
425
onChange?: (value: TDate | null, context: FieldChangeContext<TDate>) => void;
426
/** Time format string */
427
format?: string;
428
/** Date adapter instance */
429
adapter: MuiPickersAdapter<TDate>;
430
/** If true, use 12-hour format */
431
ampm?: boolean;
432
/** Validation rules */
433
validation?: Partial<ValidateTimeProps<TDate>>;
434
}
435
436
interface UseTimeManagerReturnValue<TDate> {
437
/** Current time value */
438
value: TDate | null;
439
/** Formatted time string */
440
formattedValue: string;
441
/** Time change handler */
442
handleValueChange: (value: TDate | null) => void;
443
/** Field sections */
444
sections: FieldSection[];
445
/** Active section index */
446
activeSectionIndex: number | null;
447
/** Validation error */
448
validationError: string | null;
449
}
450
451
interface TimeManagerFieldInternalProps<TDate> {
452
value: TDate | null;
453
onChange: (value: TDate | null, context: FieldChangeContext<TDate>) => void;
454
format: string;
455
ampm?: boolean;
456
}
457
```
458
459
### useDateTimeManager
460
461
Hook for managing date-time field state and operations.
462
463
```typescript { .api }
464
/**
465
* Hook for managing date-time field state
466
* @param props - Date-time manager configuration properties
467
* @returns Date-time field state and handlers
468
*/
469
function useDateTimeManager<TDate>(props: UseDateTimeManagerParameters<TDate>): UseDateTimeManagerReturnValue<TDate>;
470
471
interface UseDateTimeManagerParameters<TDate> {
472
/** Current date-time value */
473
value?: TDate | null;
474
/** Default date-time value */
475
defaultValue?: TDate | null;
476
/** Callback when date-time changes */
477
onChange?: (value: TDate | null, context: FieldChangeContext<TDate>) => void;
478
/** Date-time format string */
479
format?: string;
480
/** Date adapter instance */
481
adapter: MuiPickersAdapter<TDate>;
482
/** If true, use 12-hour format */
483
ampm?: boolean;
484
/** Validation rules */
485
validation?: Partial<ValidateDateTimeProps<TDate>>;
486
}
487
488
interface UseDateTimeManagerReturnValue<TDate> {
489
/** Current date-time value */
490
value: TDate | null;
491
/** Formatted date-time string */
492
formattedValue: string;
493
/** Date-time change handler */
494
handleValueChange: (value: TDate | null) => void;
495
/** Field sections */
496
sections: FieldSection[];
497
/** Active section index */
498
activeSectionIndex: number | null;
499
/** Validation error */
500
validationError: string | null;
501
}
502
503
interface DateTimeManagerFieldInternalProps<TDate> {
504
value: TDate | null;
505
onChange: (value: TDate | null, context: FieldChangeContext<TDate>) => void;
506
format: string;
507
ampm?: boolean;
508
}
509
```
510
511
**Usage Examples:**
512
513
```typescript
514
import {
515
validateDate,
516
validateTime,
517
usePickerTranslations,
518
usePickerAdapter,
519
useIsValidValue,
520
useDateManager
521
} from '@mui/x-date-pickers';
522
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
523
import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
524
import dayjs, { Dayjs } from 'dayjs';
525
526
// Custom validation example
527
function CustomValidatedPicker() {
528
const [value, setValue] = React.useState<Dayjs | null>(null);
529
const adapter = usePickerAdapter();
530
const translations = usePickerTranslations();
531
532
const handleChange = (newValue: Dayjs | null) => {
533
// Validate before setting
534
const error = validateDate({
535
value: newValue,
536
minDate: dayjs(),
537
disableFuture: false,
538
disablePast: true,
539
adapter,
540
timezone: 'default'
541
});
542
543
if (!error) {
544
setValue(newValue);
545
} else {
546
console.error('Validation error:', error);
547
}
548
};
549
550
return (
551
<LocalizationProvider dateAdapter={AdapterDayjs}>
552
<div>
553
<input
554
type="text"
555
placeholder="Enter date"
556
onChange={(e) => {
557
const parsed = adapter.parse(e.target.value, 'MM/DD/YYYY');
558
handleChange(parsed);
559
}}
560
/>
561
<button onClick={() => setValue(dayjs())}>
562
{translations.todayButtonLabel}
563
</button>
564
</div>
565
</LocalizationProvider>
566
);
567
}
568
569
// Using date manager hook
570
function CustomDateField() {
571
const adapter = usePickerAdapter();
572
const {
573
value,
574
formattedValue,
575
handleValueChange,
576
sections,
577
validationError
578
} = useDateManager({
579
value: null,
580
onChange: (newValue) => console.log('Date changed:', newValue),
581
format: 'MM/DD/YYYY',
582
adapter,
583
validation: {
584
disablePast: true,
585
minDate: dayjs(),
586
}
587
});
588
589
return (
590
<LocalizationProvider dateAdapter={AdapterDayjs}>
591
<div>
592
<input
593
value={formattedValue}
594
onChange={(e) => {
595
const parsed = adapter.parse(e.target.value, 'MM/DD/YYYY');
596
handleValueChange(parsed);
597
}}
598
/>
599
{validationError && (
600
<div style={{ color: 'red' }}>{validationError}</div>
601
)}
602
</div>
603
</LocalizationProvider>
604
);
605
}
606
```
607
608
## Shared Types
609
610
```typescript { .api }
611
interface FieldChangeContext<TDate> {
612
validationError: string | null;
613
}
614
615
type PickersTimezone = string | 'default' | 'system';
616
617
interface FieldSection {
618
value: string;
619
format: string;
620
maxLength: number | null;
621
placeholder: string;
622
type: FieldSectionType;
623
contentType: FieldSectionContentType;
624
hasLeadingZerosInFormat: boolean;
625
hasLeadingZerosInInput: boolean;
626
modified: boolean;
627
startSeparator: string;
628
endSeparator: string;
629
isEndFormatSeparator?: boolean;
630
}
631
632
type FieldSectionType = 'year' | 'month' | 'day' | 'weekDay' | 'hours' | 'minutes' | 'seconds' | 'meridiem' | 'empty';
633
type FieldSectionContentType = 'digit' | 'digit-with-letter' | 'letter';
634
```