@@ -154,3 +154,157 @@ and you don't want the UI to look like a Text Field, you can replace the field w
154
154
The same logic can be applied to any Range Picker:
155
155
156
156
{{"demo": "behavior-button/MaterialDateRangePicker.js", "defaultCodeOpen": false}}
157
+
158
+ ## Build your own custom field
159
+
160
+ ::: success
161
+ The sections below show how to build a field for your Picker.
162
+ Unlike the field components exposed by ` @mui/x-date-pickers ` and ` @mui/x-date-pickers-pro ` , those fields are not suitable for a standalone usage.
163
+ :::
164
+
165
+ ### Typing
166
+
167
+ Each Picker component exposes an interface describing the props it passes to its field.
168
+ You can import it from the same endpoint as the Picker component and use it to type the props of your field:
169
+
170
+ ``` tsx
171
+ import { DatePickerFieldProps } from ' @mui/x-date-pickers/DatePicker' ;
172
+ import { DateRangePickerFieldProps } from ' @mui/x-date-pickers-pro/DateRangePicker' ;
173
+
174
+ function CustomDateField(props : DatePickerFieldProps ) {
175
+ // Your custom field
176
+ }
177
+
178
+ function CustomDateRangeField(props : DateRangePickerFieldProps ) {
179
+ // Your custom field
180
+ }
181
+ ```
182
+
183
+ #### Import
184
+
185
+ | Picker component | Field props interface |
186
+ | ---------------------: | :------------------------------ |
187
+ | Date Picker | ` DatePickerFieldProps ` |
188
+ | Time Picker | ` TimePickerFieldProps ` |
189
+ | Date Time Picker | ` DateTimePickerFieldProps ` |
190
+ | Date Range Picker | ` DateRangePickerFieldProps ` |
191
+ | Date Time Range Picker | ` DateTimeRangePickerFieldProps ` |
192
+
193
+ ### Validation
194
+
195
+ You can use the ` useValidation ` hook to check if the current value passed to your field is valid or not:
196
+
197
+ ``` ts
198
+ import { useValidation , validateDate } from ' @mui/x-date-pickers/validation' ;
199
+
200
+ const {
201
+ // The error associated with the current value.
202
+ // For example: "minDate" if `props.value < props.minDate`.
203
+ validationError,
204
+ // `true` if the value is invalid.
205
+ // On range Pickers it is true if the start date or the end date is invalid.
206
+ hasValidationError,
207
+ // Imperatively get the error of a value.
208
+ getValidationErrorForNewValue,
209
+ } = useValidation ({
210
+ // If you have a value in an internal state, you should pass it here.
211
+ // Otherwise, you can pass the value returned by `usePickerContext()`.
212
+ value ,
213
+ timezone ,
214
+ props ,
215
+ validator: validateDate ,
216
+ });
217
+ ```
218
+
219
+ #### Import
220
+
221
+ Each Picker component has a validator adapted to its value type:
222
+
223
+ | Picker component | Import validator |
224
+ | ---------------------: | :--------------------------------------------------------------------------- |
225
+ | Date Picker | ` import { validateDate } from '@mui/x-date-pickers/validation' ` |
226
+ | Time Picker | ` import { validateTime } from '@mui/x-date-pickers/validation' ` |
227
+ | Date Time Picker | ` import { validateDateTime } from '@mui/x-date-pickers/validation' ` |
228
+ | Date Range Picker | ` import { validateDateRange } from '@mui/x-date-pickers-pro/validation' ` |
229
+ | Date Time Range Picker | ` import { validateDateTimeRange } from '@mui/x-date-pickers-pro/validation' ` |
230
+
231
+ ### Localized placeholder
232
+
233
+ You can use the ` useParsedFormat ` to get a clean placeholder.
234
+ This hook applies two main transformations on the format:
235
+
236
+ 1 . It replaces all the localized tokens (for example ` L ` for a date with ` dayjs ` ) with their expanded value (` DD/MM/YYYY ` for the same date with ` dayjs ` ).
237
+ 2 . It replaces each token with its token from the localization object (for example ` YYYY ` remains ` YYYY ` for the English locale but becomes ` AAAA ` for the French locale).
238
+
239
+ ::: warning
240
+ The format returned by ` useParsedFormat ` cannot be parsed by your date library.
241
+ :::
242
+
243
+ ``` js
244
+ import { useParsedFormat } from ' @mui/x-date-pickers/hooks' ;
245
+
246
+ // Uses the format defined by your Picker
247
+ const parsedFormat = useParsedFormat ();
248
+
249
+ // Uses the custom format provided
250
+ const parsedFormat = useParsedFormat ({ format: ' MM/DD/YYYY' });
251
+ ```
252
+
253
+ ### Spread props to the DOM
254
+
255
+ The field receives a lot of props that cannot be forwarded to the DOM element without warnings.
256
+ You can use the ` useSplitFieldProps ` hook to get the props that can be forwarded safely to the DOM:
257
+
258
+ ``` tsx
259
+ const { internalProps, forwardedProps } = useSplitFieldProps (
260
+ // The props received by the field component
261
+ props ,
262
+ // The value type ("date", "time" or "date-time")
263
+ ' date' ,
264
+ );
265
+
266
+ return (
267
+ <TextField { ... forwardedProps } value = { inputValue } onChange = { handleChange } >
268
+ )
269
+ ```
270
+
271
+ :::success
272
+ The `forwardedProps` contain props like `slots`, `slotProps` and `sx` that are specific to MUI.
273
+ You can omit them if the component your are forwarding the props to does not support those concepts:
274
+
275
+ ```jsx
276
+ const { slots , slotProps , sx , ... other } = props;
277
+ const { internalProps , forwardedProps } = useSplitFieldProps(other, 'date');
278
+
279
+ return (
280
+ <input { ... forwardedProps } value = { inputValue } onChange = { handleChange } >
281
+ )
282
+ ```
283
+
284
+ :::
285
+
286
+ ### Pass the field to the Picker
287
+
288
+ You can pass your custom field to your Picker using the `field` slot:
289
+
290
+ ```tsx
291
+ function DatePickerWithCustomField() {
292
+ return (
293
+ <DatePicker slots = { { field: CustomDateField }} >
294
+ )
295
+ }
296
+
297
+ // Also works with the other variants of the component
298
+ function DesktopDatePickerWithCustomField() {
299
+ return (
300
+ <DesktopDatePicker slots = { { field: CustomDateField }} >
301
+ )
302
+ }
303
+
304
+ ```
305
+
306
+ ### Full custom example
307
+
308
+ Here is a live demo of the example created in all the previous sections:
309
+
310
+ { {" demo" : " behavior-tutorial/MaterialDatePicker.js" , " defaultCodeOpen" : false }}
0 commit comments