Custom field
The Date and Time Pickers let you customize the field by passing props or custom components.
Customize the default field
Customize the TextField
You can use the textField
slot to pass custom props to the TextField
:
Please fill this field
Customize the separator of multi input range fields
You can use the fieldSeparator
slot to pass custom props to the Typography
rendered between the two TextField
:
–
–
Customize the start
and end
fields differently
You can pass conditional props to the textField
slot to customize the input styling based on the position
.
–
Use single input fields on range pickers
You can pass the single input fields to the range picker to use it for keyboard editing:
If you want to create a wrapper around the field, make sure to set the fieldType
static property to 'single-input'
.
Otherwise, the picker won't know your field is a single input one and use the multi input event listeners:
You can manually add an endAdornment
if you want your range picker to look exactly like on a simple picker:
Change the separator of range fields
You can use the dateSeparator
prop to change the separator rendered between the start and end dates:
to
Change the format density
You can control the field format spacing using the formatDensity
prop.
Setting formatDensity
to "spacious"
will add a space before and after each /
, -
and .
character.
With Material UI
Wrapping PickersTextField
You can import the PickersTextField
component to create custom wrappers:
Using Material TextField
Pass the enableAccessibleFieldDOMStructure={false}
to any Field or Picker component to use an <input />
for the editing instead of the new accessible DOM structure:
Using Joy UI
You can use the Joy UI components instead of the Material UI ones:
–
With a custom editing experience
Using an Autocomplete
If your user can only select a value in a small list of available dates, you can replace the field with the Autocomplete component to list those dates:
Using a masked Text Field
If you want to use a simple mask approach for the field editing instead of the built-in logic, you can replace the default field with the TextField component using a masked input value built with the rifm package.
Using a read-only Text Field
If you want users to select a value exclusively through the views but you still want the UI to look like a Text Field, you can replace the field with a read-only Text Field component:
Using a read-only Text Field on mobile
If you want to keep the default behavior on desktop but have a read-only TextField on mobile, you can conditionally render the custom field presented in the previous section:
Using a Button
If you want users to select a value exclusively through the views and you don't want the UI to look like a Text Field, you can replace the field with the Button component:
The same logic can be applied to any Range Picker:
Build your own custom field
Typing
Each Picker component exposes an interface describing the props it passes to its field. You can import it from the same endpoint as the Picker component and use it to type the props of your field:
import { DatePickerFieldProps } from '@mui/x-date-pickers/DatePicker';
import { DateRangePickerFieldProps } from '@mui/x-date-pickers-pro/DateRangePicker';
function CustomDateField(props: DatePickerFieldProps) {
// Your custom field
}
function CustomDateRangeField(props: DateRangePickerFieldProps) {
// Your custom field
}
Import
Picker component | Field props interface |
---|---|
Date Picker | DatePickerFieldProps |
Time Picker | TimePickerFieldProps |
Date Time Picker | DateTimePickerFieldProps |
Date Range Picker | DateRangePickerFieldProps |
Date Time Range Picker | DateTimeRangePickerFieldProps |
Validation
You can use the useValidation
hook to check if the current value passed to your field is valid or not:
import { useValidation, validateDate } from '@mui/x-date-pickers/validation';
const {
// The error associated with the current value.
// For example: "minDate" if `props.value < props.minDate`.
validationError,
// `true` if the value is invalid.
// On range Pickers it is true if the start date or the end date is invalid.
hasValidationError,
// Imperatively get the error of a value.
getValidationErrorForNewValue,
} = useValidation({
// If you have a value in an internal state, you should pass it here.
// Otherwise, you can pass the value returned by `usePickerContext()`.
value,
timezone,
props,
validator: validateDate,
});
Import
Each Picker component has a validator adapted to its value type:
Picker component | Import validator |
---|---|
Date Picker | import { validateDate } from '@mui/x-date-pickers/validation' |
Time Picker | import { validateTime } from '@mui/x-date-pickers/validation' |
Date Time Picker | import { validateDateTime } from '@mui/x-date-pickers/validation' |
Date Range Picker | import { validateDateRange } from '@mui/x-date-pickers-pro/validation' |
Date Time Range Picker | import { validateDateTimeRange } from '@mui/x-date-pickers-pro/validation' |
Localized placeholder
You can use the useParsedFormat
to get a clean placeholder.
This hook applies two main transformations on the format:
- It replaces all the localized tokens (for example
L
for a date withdayjs
) with their expanded value (DD/MM/YYYY
for the same date withdayjs
). - It replaces each token with its token from the localization object (for example
YYYY
remainsYYYY
for the English locale but becomesAAAA
for the French locale).
import { useParsedFormat } from '@mui/x-date-pickers/hooks';
// Uses the format defined by your Picker
const parsedFormat = useParsedFormat();
// Uses the custom format provided
const parsedFormat = useParsedFormat({ format: 'MM/DD/YYYY' });
Spread props to the DOM
The field receives a lot of props that cannot be forwarded to the DOM element without warnings.
You can use the useSplitFieldProps
hook to get the props that can be forwarded safely to the DOM:
const { internalProps, forwardedProps } = useSplitFieldProps(
// The props received by the field component
props,
// The value type ("date", "time" or "date-time")
'date',
);
return (
<TextField {...forwardedProps} value={inputValue} onChange={handleChange}>
)
Pass the field to the Picker
You can pass your custom field to your Picker using the field
slot:
function DatePickerWithCustomField() {
return (
<DatePicker slots={{ field: CustomDateField }}>
)
}
// Also works with the other variants of the component
function DesktopDatePickerWithCustomField() {
return (
<DesktopDatePicker slots={{ field: CustomDateField }}>
)
}
Full custom example
Here is a live demo of the example created in all the previous sections:
API
See the documentation below for a complete reference to all of the props and classes available to the components mentioned here.