+ >(props, 'date');
+
+ const { value, timezone, format } = internalProps;
+ const { InputProps, slotProps, slots, ...other } = forwardedProps;
+
+ const { hasValidationError } = useValidation({
+ validator: validateDate,
+ value,
+ timezone,
+ props: internalProps,
+ });
+
+ return (
+
+ );
+}
+
+export default function CustomField() {
+ return (
+
+
+
+
+
+ );
+}
diff --git a/docs/data/date-pickers/experimentation/CustomField.tsx.preview b/docs/data/date-pickers/experimentation/CustomField.tsx.preview
new file mode 100644
index 0000000000000..b489d70b2175b
--- /dev/null
+++ b/docs/data/date-pickers/experimentation/CustomField.tsx.preview
@@ -0,0 +1,6 @@
+
\ No newline at end of file
diff --git a/docs/data/date-pickers/experimentation/experimentation.md b/docs/data/date-pickers/experimentation/experimentation.md
new file mode 100644
index 0000000000000..d5f906e328682
--- /dev/null
+++ b/docs/data/date-pickers/experimentation/experimentation.md
@@ -0,0 +1,11 @@
+---
+productId: x-date-pickers
+---
+
+# Date and Time Pickers experimentation
+
+Demos not accessible through the navbar of the doc
+
+## Custom field
+
+{{"demo": "CustomField.js"}}
diff --git a/docs/pages/x/react-date-pickers/experimentation.js b/docs/pages/x/react-date-pickers/experimentation.js
new file mode 100644
index 0000000000000..bf599b0bb69ec
--- /dev/null
+++ b/docs/pages/x/react-date-pickers/experimentation.js
@@ -0,0 +1,7 @@
+import * as React from 'react';
+import MarkdownDocs from 'docs/src/modules/components/MarkdownDocs';
+import * as pageProps from 'docsx/data/date-pickers/experimentation/experimentation.md?muiMarkdown';
+
+export default function Page() {
+ return ;
+}
diff --git a/docs/translations/api-docs/date-pickers/date-field/date-field.json b/docs/translations/api-docs/date-pickers/date-field/date-field.json
index e023b91557cb4..618744b87c466 100644
--- a/docs/translations/api-docs/date-pickers/date-field/date-field.json
+++ b/docs/translations/api-docs/date-pickers/date-field/date-field.json
@@ -66,10 +66,10 @@
},
"onClear": { "description": "Callback fired when the clear button is clicked." },
"onError": {
- "description": "Callback fired when the error associated to the current value changes.",
+ "description": "Callback fired when the error associated to the current value changes. When a validation error is detected, the error
parameter contains a non-null value. This can be used to render an appropriate form error.",
"typeDescriptions": {
- "error": "The new error.",
- "value": "The value associated to the error."
+ "error": "The reason why the current value is not valid.",
+ "value": "The value associated to the error"
}
},
"onSelectedSectionsChange": {
diff --git a/docs/translations/api-docs/date-pickers/date-picker/date-picker.json b/docs/translations/api-docs/date-pickers/date-picker/date-picker.json
index fa776f7501a50..5555b7f4ffa45 100644
--- a/docs/translations/api-docs/date-pickers/date-picker/date-picker.json
+++ b/docs/translations/api-docs/date-pickers/date-picker/date-picker.json
@@ -77,10 +77,10 @@
"description": "Callback fired when the popup requests to be closed. Use in controlled mode (see open
)."
},
"onError": {
- "description": "Callback fired when the error associated to the current value changes. If the error has a non-null value, then the TextField
will be rendered in error
state.",
+ "description": "Callback fired when the error associated to the current value changes. When a validation error is detected, the error
parameter contains a non-null value. This can be used to render an appropriate form error.",
"typeDescriptions": {
- "error": "The new error describing why the current value is not valid.",
- "value": "The value associated to the error."
+ "error": "The reason why the current value is not valid.",
+ "value": "The value associated to the error"
}
},
"onMonthChange": {
diff --git a/docs/translations/api-docs/date-pickers/date-range-picker/date-range-picker.json b/docs/translations/api-docs/date-pickers/date-range-picker/date-range-picker.json
index b847113e3e878..e36497d596783 100644
--- a/docs/translations/api-docs/date-pickers/date-range-picker/date-range-picker.json
+++ b/docs/translations/api-docs/date-pickers/date-range-picker/date-range-picker.json
@@ -91,10 +91,10 @@
"description": "Callback fired when the popup requests to be closed. Use in controlled mode (see open
)."
},
"onError": {
- "description": "Callback fired when the error associated to the current value changes. If the error has a non-null value, then the TextField
will be rendered in error
state.",
+ "description": "Callback fired when the error associated to the current value changes. When a validation error is detected, the error
parameter contains a non-null value. This can be used to render an appropriate form error.",
"typeDescriptions": {
- "error": "The new error describing why the current value is not valid.",
- "value": "The value associated to the error."
+ "error": "The reason why the current value is not valid.",
+ "value": "The value associated to the error"
}
},
"onMonthChange": {
diff --git a/docs/translations/api-docs/date-pickers/date-time-field/date-time-field.json b/docs/translations/api-docs/date-pickers/date-time-field/date-time-field.json
index 4e77982370d01..95121dacea2d8 100644
--- a/docs/translations/api-docs/date-pickers/date-time-field/date-time-field.json
+++ b/docs/translations/api-docs/date-pickers/date-time-field/date-time-field.json
@@ -83,10 +83,10 @@
},
"onClear": { "description": "Callback fired when the clear button is clicked." },
"onError": {
- "description": "Callback fired when the error associated to the current value changes.",
+ "description": "Callback fired when the error associated to the current value changes. When a validation error is detected, the error
parameter contains a non-null value. This can be used to render an appropriate form error.",
"typeDescriptions": {
- "error": "The new error.",
- "value": "The value associated to the error."
+ "error": "The reason why the current value is not valid.",
+ "value": "The value associated to the error"
}
},
"onSelectedSectionsChange": {
diff --git a/docs/translations/api-docs/date-pickers/date-time-picker/date-time-picker.json b/docs/translations/api-docs/date-pickers/date-time-picker/date-time-picker.json
index e6bc667be2c41..d9f6a88b0bac8 100644
--- a/docs/translations/api-docs/date-pickers/date-time-picker/date-time-picker.json
+++ b/docs/translations/api-docs/date-pickers/date-time-picker/date-time-picker.json
@@ -97,10 +97,10 @@
"description": "Callback fired when the popup requests to be closed. Use in controlled mode (see open
)."
},
"onError": {
- "description": "Callback fired when the error associated to the current value changes. If the error has a non-null value, then the TextField
will be rendered in error
state.",
+ "description": "Callback fired when the error associated to the current value changes. When a validation error is detected, the error
parameter contains a non-null value. This can be used to render an appropriate form error.",
"typeDescriptions": {
- "error": "The new error describing why the current value is not valid.",
- "value": "The value associated to the error."
+ "error": "The reason why the current value is not valid.",
+ "value": "The value associated to the error"
}
},
"onMonthChange": {
diff --git a/docs/translations/api-docs/date-pickers/date-time-range-picker/date-time-range-picker.json b/docs/translations/api-docs/date-pickers/date-time-range-picker/date-time-range-picker.json
index 38ff71b4a0bc2..5c365483d5c30 100644
--- a/docs/translations/api-docs/date-pickers/date-time-range-picker/date-time-range-picker.json
+++ b/docs/translations/api-docs/date-pickers/date-time-range-picker/date-time-range-picker.json
@@ -108,10 +108,10 @@
"description": "Callback fired when the popup requests to be closed. Use in controlled mode (see open
)."
},
"onError": {
- "description": "Callback fired when the error associated to the current value changes. If the error has a non-null value, then the TextField
will be rendered in error
state.",
+ "description": "Callback fired when the error associated to the current value changes. When a validation error is detected, the error
parameter contains a non-null value. This can be used to render an appropriate form error.",
"typeDescriptions": {
- "error": "The new error describing why the current value is not valid.",
- "value": "The value associated to the error."
+ "error": "The reason why the current value is not valid.",
+ "value": "The value associated to the error"
}
},
"onMonthChange": {
diff --git a/docs/translations/api-docs/date-pickers/desktop-date-picker/desktop-date-picker.json b/docs/translations/api-docs/date-pickers/desktop-date-picker/desktop-date-picker.json
index bd5ad6552128e..c87e5e21816dc 100644
--- a/docs/translations/api-docs/date-pickers/desktop-date-picker/desktop-date-picker.json
+++ b/docs/translations/api-docs/date-pickers/desktop-date-picker/desktop-date-picker.json
@@ -74,10 +74,10 @@
"description": "Callback fired when the popup requests to be closed. Use in controlled mode (see open
)."
},
"onError": {
- "description": "Callback fired when the error associated to the current value changes. If the error has a non-null value, then the TextField
will be rendered in error
state.",
+ "description": "Callback fired when the error associated to the current value changes. When a validation error is detected, the error
parameter contains a non-null value. This can be used to render an appropriate form error.",
"typeDescriptions": {
- "error": "The new error describing why the current value is not valid.",
- "value": "The value associated to the error."
+ "error": "The reason why the current value is not valid.",
+ "value": "The value associated to the error"
}
},
"onMonthChange": {
diff --git a/docs/translations/api-docs/date-pickers/desktop-date-range-picker/desktop-date-range-picker.json b/docs/translations/api-docs/date-pickers/desktop-date-range-picker/desktop-date-range-picker.json
index 280773356bff1..0640005848218 100644
--- a/docs/translations/api-docs/date-pickers/desktop-date-range-picker/desktop-date-range-picker.json
+++ b/docs/translations/api-docs/date-pickers/desktop-date-range-picker/desktop-date-range-picker.json
@@ -88,10 +88,10 @@
"description": "Callback fired when the popup requests to be closed. Use in controlled mode (see open
)."
},
"onError": {
- "description": "Callback fired when the error associated to the current value changes. If the error has a non-null value, then the TextField
will be rendered in error
state.",
+ "description": "Callback fired when the error associated to the current value changes. When a validation error is detected, the error
parameter contains a non-null value. This can be used to render an appropriate form error.",
"typeDescriptions": {
- "error": "The new error describing why the current value is not valid.",
- "value": "The value associated to the error."
+ "error": "The reason why the current value is not valid.",
+ "value": "The value associated to the error"
}
},
"onMonthChange": {
diff --git a/docs/translations/api-docs/date-pickers/desktop-date-time-picker/desktop-date-time-picker.json b/docs/translations/api-docs/date-pickers/desktop-date-time-picker/desktop-date-time-picker.json
index 850e02434af95..fd18750143b3c 100644
--- a/docs/translations/api-docs/date-pickers/desktop-date-time-picker/desktop-date-time-picker.json
+++ b/docs/translations/api-docs/date-pickers/desktop-date-time-picker/desktop-date-time-picker.json
@@ -94,10 +94,10 @@
"description": "Callback fired when the popup requests to be closed. Use in controlled mode (see open
)."
},
"onError": {
- "description": "Callback fired when the error associated to the current value changes. If the error has a non-null value, then the TextField
will be rendered in error
state.",
+ "description": "Callback fired when the error associated to the current value changes. When a validation error is detected, the error
parameter contains a non-null value. This can be used to render an appropriate form error.",
"typeDescriptions": {
- "error": "The new error describing why the current value is not valid.",
- "value": "The value associated to the error."
+ "error": "The reason why the current value is not valid.",
+ "value": "The value associated to the error"
}
},
"onMonthChange": {
diff --git a/docs/translations/api-docs/date-pickers/desktop-date-time-range-picker/desktop-date-time-range-picker.json b/docs/translations/api-docs/date-pickers/desktop-date-time-range-picker/desktop-date-time-range-picker.json
index 44308fe67c437..e078dbbc15d4d 100644
--- a/docs/translations/api-docs/date-pickers/desktop-date-time-range-picker/desktop-date-time-range-picker.json
+++ b/docs/translations/api-docs/date-pickers/desktop-date-time-range-picker/desktop-date-time-range-picker.json
@@ -105,10 +105,10 @@
"description": "Callback fired when the popup requests to be closed. Use in controlled mode (see open
)."
},
"onError": {
- "description": "Callback fired when the error associated to the current value changes. If the error has a non-null value, then the TextField
will be rendered in error
state.",
+ "description": "Callback fired when the error associated to the current value changes. When a validation error is detected, the error
parameter contains a non-null value. This can be used to render an appropriate form error.",
"typeDescriptions": {
- "error": "The new error describing why the current value is not valid.",
- "value": "The value associated to the error."
+ "error": "The reason why the current value is not valid.",
+ "value": "The value associated to the error"
}
},
"onMonthChange": {
diff --git a/docs/translations/api-docs/date-pickers/desktop-time-picker/desktop-time-picker.json b/docs/translations/api-docs/date-pickers/desktop-time-picker/desktop-time-picker.json
index cb08e6dbe9b52..4ddf39b2d428c 100644
--- a/docs/translations/api-docs/date-pickers/desktop-time-picker/desktop-time-picker.json
+++ b/docs/translations/api-docs/date-pickers/desktop-time-picker/desktop-time-picker.json
@@ -66,10 +66,10 @@
"description": "Callback fired when the popup requests to be closed. Use in controlled mode (see open
)."
},
"onError": {
- "description": "Callback fired when the error associated to the current value changes. If the error has a non-null value, then the TextField
will be rendered in error
state.",
+ "description": "Callback fired when the error associated to the current value changes. When a validation error is detected, the error
parameter contains a non-null value. This can be used to render an appropriate form error.",
"typeDescriptions": {
- "error": "The new error describing why the current value is not valid.",
- "value": "The value associated to the error."
+ "error": "The reason why the current value is not valid.",
+ "value": "The value associated to the error"
}
},
"onOpen": {
diff --git a/docs/translations/api-docs/date-pickers/mobile-date-picker/mobile-date-picker.json b/docs/translations/api-docs/date-pickers/mobile-date-picker/mobile-date-picker.json
index 6fdc6eaca82e2..79e03e0738980 100644
--- a/docs/translations/api-docs/date-pickers/mobile-date-picker/mobile-date-picker.json
+++ b/docs/translations/api-docs/date-pickers/mobile-date-picker/mobile-date-picker.json
@@ -74,10 +74,10 @@
"description": "Callback fired when the popup requests to be closed. Use in controlled mode (see open
)."
},
"onError": {
- "description": "Callback fired when the error associated to the current value changes. If the error has a non-null value, then the TextField
will be rendered in error
state.",
+ "description": "Callback fired when the error associated to the current value changes. When a validation error is detected, the error
parameter contains a non-null value. This can be used to render an appropriate form error.",
"typeDescriptions": {
- "error": "The new error describing why the current value is not valid.",
- "value": "The value associated to the error."
+ "error": "The reason why the current value is not valid.",
+ "value": "The value associated to the error"
}
},
"onMonthChange": {
diff --git a/docs/translations/api-docs/date-pickers/mobile-date-range-picker/mobile-date-range-picker.json b/docs/translations/api-docs/date-pickers/mobile-date-range-picker/mobile-date-range-picker.json
index 4f31ae0b29206..9979387f247d7 100644
--- a/docs/translations/api-docs/date-pickers/mobile-date-range-picker/mobile-date-range-picker.json
+++ b/docs/translations/api-docs/date-pickers/mobile-date-range-picker/mobile-date-range-picker.json
@@ -85,10 +85,10 @@
"description": "Callback fired when the popup requests to be closed. Use in controlled mode (see open
)."
},
"onError": {
- "description": "Callback fired when the error associated to the current value changes. If the error has a non-null value, then the TextField
will be rendered in error
state.",
+ "description": "Callback fired when the error associated to the current value changes. When a validation error is detected, the error
parameter contains a non-null value. This can be used to render an appropriate form error.",
"typeDescriptions": {
- "error": "The new error describing why the current value is not valid.",
- "value": "The value associated to the error."
+ "error": "The reason why the current value is not valid.",
+ "value": "The value associated to the error"
}
},
"onMonthChange": {
diff --git a/docs/translations/api-docs/date-pickers/mobile-date-time-picker/mobile-date-time-picker.json b/docs/translations/api-docs/date-pickers/mobile-date-time-picker/mobile-date-time-picker.json
index 3731b8d7d2f73..4d5af55928457 100644
--- a/docs/translations/api-docs/date-pickers/mobile-date-time-picker/mobile-date-time-picker.json
+++ b/docs/translations/api-docs/date-pickers/mobile-date-time-picker/mobile-date-time-picker.json
@@ -94,10 +94,10 @@
"description": "Callback fired when the popup requests to be closed. Use in controlled mode (see open
)."
},
"onError": {
- "description": "Callback fired when the error associated to the current value changes. If the error has a non-null value, then the TextField
will be rendered in error
state.",
+ "description": "Callback fired when the error associated to the current value changes. When a validation error is detected, the error
parameter contains a non-null value. This can be used to render an appropriate form error.",
"typeDescriptions": {
- "error": "The new error describing why the current value is not valid.",
- "value": "The value associated to the error."
+ "error": "The reason why the current value is not valid.",
+ "value": "The value associated to the error"
}
},
"onMonthChange": {
diff --git a/docs/translations/api-docs/date-pickers/mobile-date-time-range-picker/mobile-date-time-range-picker.json b/docs/translations/api-docs/date-pickers/mobile-date-time-range-picker/mobile-date-time-range-picker.json
index 743e5f688d34d..c2eb9b111653d 100644
--- a/docs/translations/api-docs/date-pickers/mobile-date-time-range-picker/mobile-date-time-range-picker.json
+++ b/docs/translations/api-docs/date-pickers/mobile-date-time-range-picker/mobile-date-time-range-picker.json
@@ -102,10 +102,10 @@
"description": "Callback fired when the popup requests to be closed. Use in controlled mode (see open
)."
},
"onError": {
- "description": "Callback fired when the error associated to the current value changes. If the error has a non-null value, then the TextField
will be rendered in error
state.",
+ "description": "Callback fired when the error associated to the current value changes. When a validation error is detected, the error
parameter contains a non-null value. This can be used to render an appropriate form error.",
"typeDescriptions": {
- "error": "The new error describing why the current value is not valid.",
- "value": "The value associated to the error."
+ "error": "The reason why the current value is not valid.",
+ "value": "The value associated to the error"
}
},
"onMonthChange": {
diff --git a/docs/translations/api-docs/date-pickers/mobile-time-picker/mobile-time-picker.json b/docs/translations/api-docs/date-pickers/mobile-time-picker/mobile-time-picker.json
index cd9f9871246e8..9e4aee022d836 100644
--- a/docs/translations/api-docs/date-pickers/mobile-time-picker/mobile-time-picker.json
+++ b/docs/translations/api-docs/date-pickers/mobile-time-picker/mobile-time-picker.json
@@ -66,10 +66,10 @@
"description": "Callback fired when the popup requests to be closed. Use in controlled mode (see open
)."
},
"onError": {
- "description": "Callback fired when the error associated to the current value changes. If the error has a non-null value, then the TextField
will be rendered in error
state.",
+ "description": "Callback fired when the error associated to the current value changes. When a validation error is detected, the error
parameter contains a non-null value. This can be used to render an appropriate form error.",
"typeDescriptions": {
- "error": "The new error describing why the current value is not valid.",
- "value": "The value associated to the error."
+ "error": "The reason why the current value is not valid.",
+ "value": "The value associated to the error"
}
},
"onOpen": {
diff --git a/docs/translations/api-docs/date-pickers/multi-input-date-range-field/multi-input-date-range-field.json b/docs/translations/api-docs/date-pickers/multi-input-date-range-field/multi-input-date-range-field.json
index 3249b81c4e446..5091832ca274a 100644
--- a/docs/translations/api-docs/date-pickers/multi-input-date-range-field/multi-input-date-range-field.json
+++ b/docs/translations/api-docs/date-pickers/multi-input-date-range-field/multi-input-date-range-field.json
@@ -34,10 +34,10 @@
}
},
"onError": {
- "description": "Callback fired when the error associated to the current value changes.",
+ "description": "Callback fired when the error associated to the current value changes. When a validation error is detected, the error
parameter contains a non-null value. This can be used to render an appropriate form error.",
"typeDescriptions": {
- "error": "The new error.",
- "value": "The value associated to the error."
+ "error": "The reason why the current value is not valid.",
+ "value": "The value associated to the error"
}
},
"onSelectedSectionsChange": {
diff --git a/docs/translations/api-docs/date-pickers/multi-input-date-time-range-field/multi-input-date-time-range-field.json b/docs/translations/api-docs/date-pickers/multi-input-date-time-range-field/multi-input-date-time-range-field.json
index 5a80d81c50d94..2657b5ed1a3fb 100644
--- a/docs/translations/api-docs/date-pickers/multi-input-date-time-range-field/multi-input-date-time-range-field.json
+++ b/docs/translations/api-docs/date-pickers/multi-input-date-time-range-field/multi-input-date-time-range-field.json
@@ -51,10 +51,10 @@
}
},
"onError": {
- "description": "Callback fired when the error associated to the current value changes.",
+ "description": "Callback fired when the error associated to the current value changes. When a validation error is detected, the error
parameter contains a non-null value. This can be used to render an appropriate form error.",
"typeDescriptions": {
- "error": "The new error.",
- "value": "The value associated to the error."
+ "error": "The reason why the current value is not valid.",
+ "value": "The value associated to the error"
}
},
"onSelectedSectionsChange": {
diff --git a/docs/translations/api-docs/date-pickers/multi-input-time-range-field/multi-input-time-range-field.json b/docs/translations/api-docs/date-pickers/multi-input-time-range-field/multi-input-time-range-field.json
index 36121c5af67de..29a60e20be62b 100644
--- a/docs/translations/api-docs/date-pickers/multi-input-time-range-field/multi-input-time-range-field.json
+++ b/docs/translations/api-docs/date-pickers/multi-input-time-range-field/multi-input-time-range-field.json
@@ -43,10 +43,10 @@
}
},
"onError": {
- "description": "Callback fired when the error associated to the current value changes.",
+ "description": "Callback fired when the error associated to the current value changes. When a validation error is detected, the error
parameter contains a non-null value. This can be used to render an appropriate form error.",
"typeDescriptions": {
- "error": "The new error.",
- "value": "The value associated to the error."
+ "error": "The reason why the current value is not valid.",
+ "value": "The value associated to the error"
}
},
"onSelectedSectionsChange": {
diff --git a/docs/translations/api-docs/date-pickers/single-input-date-range-field/single-input-date-range-field.json b/docs/translations/api-docs/date-pickers/single-input-date-range-field/single-input-date-range-field.json
index 4b27f2a622210..a24a00361f7d6 100644
--- a/docs/translations/api-docs/date-pickers/single-input-date-range-field/single-input-date-range-field.json
+++ b/docs/translations/api-docs/date-pickers/single-input-date-range-field/single-input-date-range-field.json
@@ -67,10 +67,10 @@
},
"onClear": { "description": "Callback fired when the clear button is clicked." },
"onError": {
- "description": "Callback fired when the error associated to the current value changes.",
+ "description": "Callback fired when the error associated to the current value changes. When a validation error is detected, the error
parameter contains a non-null value. This can be used to render an appropriate form error.",
"typeDescriptions": {
- "error": "The new error.",
- "value": "The value associated to the error."
+ "error": "The reason why the current value is not valid.",
+ "value": "The value associated to the error"
}
},
"onSelectedSectionsChange": {
diff --git a/docs/translations/api-docs/date-pickers/single-input-date-time-range-field/single-input-date-time-range-field.json b/docs/translations/api-docs/date-pickers/single-input-date-time-range-field/single-input-date-time-range-field.json
index 2fd5f39606135..e98b84401aca0 100644
--- a/docs/translations/api-docs/date-pickers/single-input-date-time-range-field/single-input-date-time-range-field.json
+++ b/docs/translations/api-docs/date-pickers/single-input-date-time-range-field/single-input-date-time-range-field.json
@@ -84,10 +84,10 @@
},
"onClear": { "description": "Callback fired when the clear button is clicked." },
"onError": {
- "description": "Callback fired when the error associated to the current value changes.",
+ "description": "Callback fired when the error associated to the current value changes. When a validation error is detected, the error
parameter contains a non-null value. This can be used to render an appropriate form error.",
"typeDescriptions": {
- "error": "The new error.",
- "value": "The value associated to the error."
+ "error": "The reason why the current value is not valid.",
+ "value": "The value associated to the error"
}
},
"onSelectedSectionsChange": {
diff --git a/docs/translations/api-docs/date-pickers/single-input-time-range-field/single-input-time-range-field.json b/docs/translations/api-docs/date-pickers/single-input-time-range-field/single-input-time-range-field.json
index d14d95e0e73be..7814309458a6f 100644
--- a/docs/translations/api-docs/date-pickers/single-input-time-range-field/single-input-time-range-field.json
+++ b/docs/translations/api-docs/date-pickers/single-input-time-range-field/single-input-time-range-field.json
@@ -76,10 +76,10 @@
},
"onClear": { "description": "Callback fired when the clear button is clicked." },
"onError": {
- "description": "Callback fired when the error associated to the current value changes.",
+ "description": "Callback fired when the error associated to the current value changes. When a validation error is detected, the error
parameter contains a non-null value. This can be used to render an appropriate form error.",
"typeDescriptions": {
- "error": "The new error.",
- "value": "The value associated to the error."
+ "error": "The reason why the current value is not valid.",
+ "value": "The value associated to the error"
}
},
"onSelectedSectionsChange": {
diff --git a/docs/translations/api-docs/date-pickers/static-date-picker/static-date-picker.json b/docs/translations/api-docs/date-pickers/static-date-picker/static-date-picker.json
index 7ebb4803d895d..289d1ade78f4e 100644
--- a/docs/translations/api-docs/date-pickers/static-date-picker/static-date-picker.json
+++ b/docs/translations/api-docs/date-pickers/static-date-picker/static-date-picker.json
@@ -60,10 +60,10 @@
"description": "Callback fired when component requests to be closed. Can be fired when selecting (by default on desktop
mode) or clearing a value."
},
"onError": {
- "description": "Callback fired when the error associated to the current value changes. If the error has a non-null value, then the TextField
will be rendered in error
state.",
+ "description": "Callback fired when the error associated to the current value changes. When a validation error is detected, the error
parameter contains a non-null value. This can be used to render an appropriate form error.",
"typeDescriptions": {
- "error": "The new error describing why the current value is not valid.",
- "value": "The value associated to the error."
+ "error": "The reason why the current value is not valid.",
+ "value": "The value associated to the error"
}
},
"onMonthChange": {
diff --git a/docs/translations/api-docs/date-pickers/static-date-range-picker/static-date-range-picker.json b/docs/translations/api-docs/date-pickers/static-date-range-picker/static-date-range-picker.json
index a5948b80f3836..902cddeda7033 100644
--- a/docs/translations/api-docs/date-pickers/static-date-range-picker/static-date-range-picker.json
+++ b/docs/translations/api-docs/date-pickers/static-date-range-picker/static-date-range-picker.json
@@ -70,10 +70,10 @@
"description": "Callback fired when component requests to be closed. Can be fired when selecting (by default on desktop
mode) or clearing a value."
},
"onError": {
- "description": "Callback fired when the error associated to the current value changes. If the error has a non-null value, then the TextField
will be rendered in error
state.",
+ "description": "Callback fired when the error associated to the current value changes. When a validation error is detected, the error
parameter contains a non-null value. This can be used to render an appropriate form error.",
"typeDescriptions": {
- "error": "The new error describing why the current value is not valid.",
- "value": "The value associated to the error."
+ "error": "The reason why the current value is not valid.",
+ "value": "The value associated to the error"
}
},
"onMonthChange": {
diff --git a/docs/translations/api-docs/date-pickers/static-date-time-picker/static-date-time-picker.json b/docs/translations/api-docs/date-pickers/static-date-time-picker/static-date-time-picker.json
index 49348e6733294..f249adf4217e2 100644
--- a/docs/translations/api-docs/date-pickers/static-date-time-picker/static-date-time-picker.json
+++ b/docs/translations/api-docs/date-pickers/static-date-time-picker/static-date-time-picker.json
@@ -80,10 +80,10 @@
"description": "Callback fired when component requests to be closed. Can be fired when selecting (by default on desktop
mode) or clearing a value."
},
"onError": {
- "description": "Callback fired when the error associated to the current value changes. If the error has a non-null value, then the TextField
will be rendered in error
state.",
+ "description": "Callback fired when the error associated to the current value changes. When a validation error is detected, the error
parameter contains a non-null value. This can be used to render an appropriate form error.",
"typeDescriptions": {
- "error": "The new error describing why the current value is not valid.",
- "value": "The value associated to the error."
+ "error": "The reason why the current value is not valid.",
+ "value": "The value associated to the error"
}
},
"onMonthChange": {
diff --git a/docs/translations/api-docs/date-pickers/static-time-picker/static-time-picker.json b/docs/translations/api-docs/date-pickers/static-time-picker/static-time-picker.json
index 8ba5b454d5e6b..df19b36acd95c 100644
--- a/docs/translations/api-docs/date-pickers/static-time-picker/static-time-picker.json
+++ b/docs/translations/api-docs/date-pickers/static-time-picker/static-time-picker.json
@@ -52,10 +52,10 @@
"description": "Callback fired when component requests to be closed. Can be fired when selecting (by default on desktop
mode) or clearing a value."
},
"onError": {
- "description": "Callback fired when the error associated to the current value changes. If the error has a non-null value, then the TextField
will be rendered in error
state.",
+ "description": "Callback fired when the error associated to the current value changes. When a validation error is detected, the error
parameter contains a non-null value. This can be used to render an appropriate form error.",
"typeDescriptions": {
- "error": "The new error describing why the current value is not valid.",
- "value": "The value associated to the error."
+ "error": "The reason why the current value is not valid.",
+ "value": "The value associated to the error"
}
},
"onViewChange": {
diff --git a/docs/translations/api-docs/date-pickers/time-field/time-field.json b/docs/translations/api-docs/date-pickers/time-field/time-field.json
index afe1273696503..e54b304b64b5a 100644
--- a/docs/translations/api-docs/date-pickers/time-field/time-field.json
+++ b/docs/translations/api-docs/date-pickers/time-field/time-field.json
@@ -75,10 +75,10 @@
},
"onClear": { "description": "Callback fired when the clear button is clicked." },
"onError": {
- "description": "Callback fired when the error associated to the current value changes.",
+ "description": "Callback fired when the error associated to the current value changes. When a validation error is detected, the error
parameter contains a non-null value. This can be used to render an appropriate form error.",
"typeDescriptions": {
- "error": "The new error.",
- "value": "The value associated to the error."
+ "error": "The reason why the current value is not valid.",
+ "value": "The value associated to the error"
}
},
"onSelectedSectionsChange": {
diff --git a/docs/translations/api-docs/date-pickers/time-picker/time-picker.json b/docs/translations/api-docs/date-pickers/time-picker/time-picker.json
index 3e18c58879a8d..17d4ee6c9f6ac 100644
--- a/docs/translations/api-docs/date-pickers/time-picker/time-picker.json
+++ b/docs/translations/api-docs/date-pickers/time-picker/time-picker.json
@@ -69,10 +69,10 @@
"description": "Callback fired when the popup requests to be closed. Use in controlled mode (see open
)."
},
"onError": {
- "description": "Callback fired when the error associated to the current value changes. If the error has a non-null value, then the TextField
will be rendered in error
state.",
+ "description": "Callback fired when the error associated to the current value changes. When a validation error is detected, the error
parameter contains a non-null value. This can be used to render an appropriate form error.",
"typeDescriptions": {
- "error": "The new error describing why the current value is not valid.",
- "value": "The value associated to the error."
+ "error": "The reason why the current value is not valid.",
+ "value": "The value associated to the error"
}
},
"onOpen": {
diff --git a/packages/x-date-pickers-pro/src/DateRangePicker/DateRangePicker.tsx b/packages/x-date-pickers-pro/src/DateRangePicker/DateRangePicker.tsx
index 7fa21dbb2ee85..8002fc939798d 100644
--- a/packages/x-date-pickers-pro/src/DateRangePicker/DateRangePicker.tsx
+++ b/packages/x-date-pickers-pro/src/DateRangePicker/DateRangePicker.tsx
@@ -217,12 +217,12 @@ DateRangePicker.propTypes = {
onClose: PropTypes.func,
/**
* Callback fired when the error associated to the current value changes.
- * If the error has a non-null value, then the `TextField` will be rendered in `error` state.
- *
- * @template TValue The value type. Will be either the same type as `value` or `null`. Can be in `[start, end]` format in case of range value.
+ * When a validation error is detected, the `error` parameter contains a non-null value.
+ * This can be used to render an appropriate form error.
* @template TError The validation error type. Will be either `string` or a `null`. Can be in `[start, end]` format in case of range value.
- * @param {TError} error The new error describing why the current value is not valid.
- * @param {TValue} value The value associated to the error.
+ * @template TValue The value type. Will be either the same type as `value` or `null`. Can be in `[start, end]` format in case of range value.
+ * @param {TError} error The reason why the current value is not valid.
+ * @param {TValue} value The value associated to the error
*/
onError: PropTypes.func,
/**
diff --git a/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePicker.tsx b/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePicker.tsx
index 4d94546246f86..9249006814e55 100644
--- a/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePicker.tsx
+++ b/packages/x-date-pickers-pro/src/DateTimeRangePicker/DateTimeRangePicker.tsx
@@ -250,12 +250,12 @@ DateTimeRangePicker.propTypes = {
onClose: PropTypes.func,
/**
* Callback fired when the error associated to the current value changes.
- * If the error has a non-null value, then the `TextField` will be rendered in `error` state.
- *
- * @template TValue The value type. Will be either the same type as `value` or `null`. Can be in `[start, end]` format in case of range value.
+ * When a validation error is detected, the `error` parameter contains a non-null value.
+ * This can be used to render an appropriate form error.
* @template TError The validation error type. Will be either `string` or a `null`. Can be in `[start, end]` format in case of range value.
- * @param {TError} error The new error describing why the current value is not valid.
- * @param {TValue} value The value associated to the error.
+ * @template TValue The value type. Will be either the same type as `value` or `null`. Can be in `[start, end]` format in case of range value.
+ * @param {TError} error The reason why the current value is not valid.
+ * @param {TValue} value The value associated to the error
*/
onError: PropTypes.func,
/**
diff --git a/packages/x-date-pickers-pro/src/DesktopDateRangePicker/DesktopDateRangePicker.tsx b/packages/x-date-pickers-pro/src/DesktopDateRangePicker/DesktopDateRangePicker.tsx
index 1a583b12807bb..025c7c1ca7865 100644
--- a/packages/x-date-pickers-pro/src/DesktopDateRangePicker/DesktopDateRangePicker.tsx
+++ b/packages/x-date-pickers-pro/src/DesktopDateRangePicker/DesktopDateRangePicker.tsx
@@ -1,6 +1,7 @@
import * as React from 'react';
import PropTypes from 'prop-types';
-import { extractValidationProps, PickerViewRendererLookup } from '@mui/x-date-pickers/internals';
+import { PickerViewRendererLookup } from '@mui/x-date-pickers/internals';
+import { extractValidationProps } from '@mui/x-date-pickers/validation';
import { PickerValidDate } from '@mui/x-date-pickers/models';
import resolveComponentProps from '@mui/utils/resolveComponentProps';
import { refType } from '@mui/utils';
@@ -10,7 +11,7 @@ import { useDateRangePickerDefaultizedProps } from '../DateRangePicker/shared';
import { renderDateRangeViewCalendar } from '../dateRangeViewRenderers';
import { MultiInputDateRangeField } from '../MultiInputDateRangeField';
import { useDesktopRangePicker } from '../internals/hooks/useDesktopRangePicker';
-import { validateDateRange } from '../internals/utils/validation/validateDateRange';
+import { validateDateRange } from '../validation';
import { DateRange } from '../models';
type DesktopDateRangePickerComponent = (<
@@ -252,12 +253,12 @@ DesktopDateRangePicker.propTypes = {
onClose: PropTypes.func,
/**
* Callback fired when the error associated to the current value changes.
- * If the error has a non-null value, then the `TextField` will be rendered in `error` state.
- *
- * @template TValue The value type. Will be either the same type as `value` or `null`. Can be in `[start, end]` format in case of range value.
+ * When a validation error is detected, the `error` parameter contains a non-null value.
+ * This can be used to render an appropriate form error.
* @template TError The validation error type. Will be either `string` or a `null`. Can be in `[start, end]` format in case of range value.
- * @param {TError} error The new error describing why the current value is not valid.
- * @param {TValue} value The value associated to the error.
+ * @template TValue The value type. Will be either the same type as `value` or `null`. Can be in `[start, end]` format in case of range value.
+ * @param {TError} error The reason why the current value is not valid.
+ * @param {TValue} value The value associated to the error
*/
onError: PropTypes.func,
/**
diff --git a/packages/x-date-pickers-pro/src/DesktopDateTimeRangePicker/DesktopDateTimeRangePicker.tsx b/packages/x-date-pickers-pro/src/DesktopDateTimeRangePicker/DesktopDateTimeRangePicker.tsx
index 069e4d66cc750..89e375c96dab0 100644
--- a/packages/x-date-pickers-pro/src/DesktopDateTimeRangePicker/DesktopDateTimeRangePicker.tsx
+++ b/packages/x-date-pickers-pro/src/DesktopDateTimeRangePicker/DesktopDateTimeRangePicker.tsx
@@ -2,7 +2,6 @@ import * as React from 'react';
import PropTypes from 'prop-types';
import {
DefaultizedProps,
- extractValidationProps,
isDatePickerView,
isInternalTimeView,
PickerViewRenderer,
@@ -10,6 +9,7 @@ import {
resolveDateTimeFormat,
useUtils,
} from '@mui/x-date-pickers/internals';
+import { extractValidationProps } from '@mui/x-date-pickers/validation';
import { PickerValidDate } from '@mui/x-date-pickers/models';
import resolveComponentProps from '@mui/utils/resolveComponentProps';
import { refType } from '@mui/utils';
@@ -32,7 +32,7 @@ import {
useDesktopRangePicker,
UseDesktopRangePickerProps,
} from '../internals/hooks/useDesktopRangePicker';
-import { validateDateTimeRange } from '../internals/utils/validation/validateDateTimeRange';
+import { validateDateTimeRange } from '../validation';
import { DateTimeRangePickerView } from '../internals/models';
import { DateRange } from '../models';
import {
@@ -418,12 +418,12 @@ DesktopDateTimeRangePicker.propTypes = {
onClose: PropTypes.func,
/**
* Callback fired when the error associated to the current value changes.
- * If the error has a non-null value, then the `TextField` will be rendered in `error` state.
- *
- * @template TValue The value type. Will be either the same type as `value` or `null`. Can be in `[start, end]` format in case of range value.
+ * When a validation error is detected, the `error` parameter contains a non-null value.
+ * This can be used to render an appropriate form error.
* @template TError The validation error type. Will be either `string` or a `null`. Can be in `[start, end]` format in case of range value.
- * @param {TError} error The new error describing why the current value is not valid.
- * @param {TValue} value The value associated to the error.
+ * @template TValue The value type. Will be either the same type as `value` or `null`. Can be in `[start, end]` format in case of range value.
+ * @param {TError} error The reason why the current value is not valid.
+ * @param {TValue} value The value associated to the error
*/
onError: PropTypes.func,
/**
diff --git a/packages/x-date-pickers-pro/src/MobileDateRangePicker/MobileDateRangePicker.tsx b/packages/x-date-pickers-pro/src/MobileDateRangePicker/MobileDateRangePicker.tsx
index 54558b1607ea9..c3605de2d5ace 100644
--- a/packages/x-date-pickers-pro/src/MobileDateRangePicker/MobileDateRangePicker.tsx
+++ b/packages/x-date-pickers-pro/src/MobileDateRangePicker/MobileDateRangePicker.tsx
@@ -1,6 +1,7 @@
import * as React from 'react';
import PropTypes from 'prop-types';
-import { extractValidationProps, PickerViewRendererLookup } from '@mui/x-date-pickers/internals';
+import { PickerViewRendererLookup } from '@mui/x-date-pickers/internals';
+import { extractValidationProps } from '@mui/x-date-pickers/validation';
import { PickerValidDate } from '@mui/x-date-pickers/models';
import resolveComponentProps from '@mui/utils/resolveComponentProps';
import { refType } from '@mui/utils';
@@ -10,7 +11,7 @@ import { useDateRangePickerDefaultizedProps } from '../DateRangePicker/shared';
import { renderDateRangeViewCalendar } from '../dateRangeViewRenderers';
import { MultiInputDateRangeField } from '../MultiInputDateRangeField';
import { useMobileRangePicker } from '../internals/hooks/useMobileRangePicker';
-import { validateDateRange } from '../internals/utils/validation/validateDateRange';
+import { validateDateRange } from '../validation';
import { DateRange } from '../models';
type MobileDateRangePickerComponent = (<
@@ -248,12 +249,12 @@ MobileDateRangePicker.propTypes = {
onClose: PropTypes.func,
/**
* Callback fired when the error associated to the current value changes.
- * If the error has a non-null value, then the `TextField` will be rendered in `error` state.
- *
- * @template TValue The value type. Will be either the same type as `value` or `null`. Can be in `[start, end]` format in case of range value.
+ * When a validation error is detected, the `error` parameter contains a non-null value.
+ * This can be used to render an appropriate form error.
* @template TError The validation error type. Will be either `string` or a `null`. Can be in `[start, end]` format in case of range value.
- * @param {TError} error The new error describing why the current value is not valid.
- * @param {TValue} value The value associated to the error.
+ * @template TValue The value type. Will be either the same type as `value` or `null`. Can be in `[start, end]` format in case of range value.
+ * @param {TError} error The reason why the current value is not valid.
+ * @param {TValue} value The value associated to the error
*/
onError: PropTypes.func,
/**
diff --git a/packages/x-date-pickers-pro/src/MobileDateTimeRangePicker/MobileDateTimeRangePicker.tsx b/packages/x-date-pickers-pro/src/MobileDateTimeRangePicker/MobileDateTimeRangePicker.tsx
index 27036c430d8e7..cdbabfe04eeae 100644
--- a/packages/x-date-pickers-pro/src/MobileDateTimeRangePicker/MobileDateTimeRangePicker.tsx
+++ b/packages/x-date-pickers-pro/src/MobileDateTimeRangePicker/MobileDateTimeRangePicker.tsx
@@ -4,7 +4,6 @@ import { refType } from '@mui/utils';
import {
DIALOG_WIDTH,
VIEW_HEIGHT,
- extractValidationProps,
isInternalTimeView,
isDatePickerView,
PickerViewRenderer,
@@ -14,6 +13,7 @@ import {
resolveDateTimeFormat,
useUtils,
} from '@mui/x-date-pickers/internals';
+import { extractValidationProps } from '@mui/x-date-pickers/validation';
import { PickerValidDate } from '@mui/x-date-pickers/models';
import resolveComponentProps from '@mui/utils/resolveComponentProps';
import {
@@ -32,7 +32,7 @@ import {
UseMobileRangePickerProps,
useMobileRangePicker,
} from '../internals/hooks/useMobileRangePicker';
-import { validateDateTimeRange } from '../internals/utils/validation/validateDateTimeRange';
+import { validateDateTimeRange } from '../validation';
import { DateTimeRangePickerView } from '../internals/models';
import { DateRange } from '../models';
import {
@@ -408,12 +408,12 @@ MobileDateTimeRangePicker.propTypes = {
onClose: PropTypes.func,
/**
* Callback fired when the error associated to the current value changes.
- * If the error has a non-null value, then the `TextField` will be rendered in `error` state.
- *
- * @template TValue The value type. Will be either the same type as `value` or `null`. Can be in `[start, end]` format in case of range value.
+ * When a validation error is detected, the `error` parameter contains a non-null value.
+ * This can be used to render an appropriate form error.
* @template TError The validation error type. Will be either `string` or a `null`. Can be in `[start, end]` format in case of range value.
- * @param {TError} error The new error describing why the current value is not valid.
- * @param {TValue} value The value associated to the error.
+ * @template TValue The value type. Will be either the same type as `value` or `null`. Can be in `[start, end]` format in case of range value.
+ * @param {TError} error The reason why the current value is not valid.
+ * @param {TValue} value The value associated to the error
*/
onError: PropTypes.func,
/**
diff --git a/packages/x-date-pickers-pro/src/MultiInputDateRangeField/MultiInputDateRangeField.tsx b/packages/x-date-pickers-pro/src/MultiInputDateRangeField/MultiInputDateRangeField.tsx
index 909fc6c29e7c0..4fb1f46224280 100644
--- a/packages/x-date-pickers-pro/src/MultiInputDateRangeField/MultiInputDateRangeField.tsx
+++ b/packages/x-date-pickers-pro/src/MultiInputDateRangeField/MultiInputDateRangeField.tsx
@@ -270,10 +270,12 @@ MultiInputDateRangeField.propTypes = {
onChange: PropTypes.func,
/**
* Callback fired when the error associated to the current value changes.
- * @template TValue The value type. Will be either the same type as `value` or `null`. Can be in `[start, end]` format in case of range value.
+ * When a validation error is detected, the `error` parameter contains a non-null value.
+ * This can be used to render an appropriate form error.
* @template TError The validation error type. Will be either `string` or a `null`. Can be in `[start, end]` format in case of range value.
- * @param {TError} error The new error.
- * @param {TValue} value The value associated to the error.
+ * @template TValue The value type. Will be either the same type as `value` or `null`. Can be in `[start, end]` format in case of range value.
+ * @param {TError} error The reason why the current value is not valid.
+ * @param {TValue} value The value associated to the error
*/
onError: PropTypes.func,
/**
diff --git a/packages/x-date-pickers-pro/src/MultiInputDateTimeRangeField/MultiInputDateTimeRangeField.tsx b/packages/x-date-pickers-pro/src/MultiInputDateTimeRangeField/MultiInputDateTimeRangeField.tsx
index 133685debe583..95eee8c613eb6 100644
--- a/packages/x-date-pickers-pro/src/MultiInputDateTimeRangeField/MultiInputDateTimeRangeField.tsx
+++ b/packages/x-date-pickers-pro/src/MultiInputDateTimeRangeField/MultiInputDateTimeRangeField.tsx
@@ -302,10 +302,12 @@ MultiInputDateTimeRangeField.propTypes = {
onChange: PropTypes.func,
/**
* Callback fired when the error associated to the current value changes.
- * @template TValue The value type. Will be either the same type as `value` or `null`. Can be in `[start, end]` format in case of range value.
+ * When a validation error is detected, the `error` parameter contains a non-null value.
+ * This can be used to render an appropriate form error.
* @template TError The validation error type. Will be either `string` or a `null`. Can be in `[start, end]` format in case of range value.
- * @param {TError} error The new error.
- * @param {TValue} value The value associated to the error.
+ * @template TValue The value type. Will be either the same type as `value` or `null`. Can be in `[start, end]` format in case of range value.
+ * @param {TError} error The reason why the current value is not valid.
+ * @param {TValue} value The value associated to the error
*/
onError: PropTypes.func,
/**
diff --git a/packages/x-date-pickers-pro/src/MultiInputDateTimeRangeField/tests/MultiInputDateTimeRangeField.validation.test.tsx b/packages/x-date-pickers-pro/src/MultiInputDateTimeRangeField/tests/MultiInputDateTimeRangeField.validation.test.tsx
deleted file mode 100644
index 4fd962807ba7f..0000000000000
--- a/packages/x-date-pickers-pro/src/MultiInputDateTimeRangeField/tests/MultiInputDateTimeRangeField.validation.test.tsx
+++ /dev/null
@@ -1,21 +0,0 @@
-import { MultiInputDateTimeRangeField } from '@mui/x-date-pickers-pro/MultiInputDateTimeRangeField';
-import {
- createPickerRenderer,
- adapterToUse,
- describeRangeValidation,
- setValueOnFieldInput,
-} from 'test/utils/pickers';
-
-describe('', () => {
- const { render, clock } = createPickerRenderer({ clock: 'fake' });
-
- describeRangeValidation(MultiInputDateTimeRangeField, () => ({
- render,
- clock,
- componentFamily: 'field',
- views: ['year', 'month', 'day', 'hours', 'minutes'],
- setValue: (value, { setEndDate } = {}) => {
- setValueOnFieldInput(adapterToUse.format(value, 'keyboardDateTime'), setEndDate ? 1 : 0);
- },
- }));
-});
diff --git a/packages/x-date-pickers-pro/src/MultiInputDateTimeRangeField/tests/describes.MultiInputDateTimeRangeField.test.tsx b/packages/x-date-pickers-pro/src/MultiInputDateTimeRangeField/tests/describes.MultiInputDateTimeRangeField.test.tsx
index 7bb1d6cc437b2..5bc464f729e50 100644
--- a/packages/x-date-pickers-pro/src/MultiInputDateTimeRangeField/tests/describes.MultiInputDateTimeRangeField.test.tsx
+++ b/packages/x-date-pickers-pro/src/MultiInputDateTimeRangeField/tests/describes.MultiInputDateTimeRangeField.test.tsx
@@ -1,10 +1,15 @@
import * as React from 'react';
import { MultiInputDateTimeRangeField } from '@mui/x-date-pickers-pro/MultiInputDateTimeRangeField';
-import { createPickerRenderer } from 'test/utils/pickers';
+import {
+ adapterToUse,
+ createPickerRenderer,
+ describeRangeValidation,
+ setValueOnFieldInput,
+} from 'test/utils/pickers';
import { describeConformance } from 'test/utils/describeConformance';
describe('', () => {
- const { render } = createPickerRenderer();
+ const { render, clock } = createPickerRenderer();
describeConformance(, () => ({
classes: {} as any,
@@ -14,4 +19,14 @@ describe('', () => {
refInstanceof: window.HTMLDivElement,
skip: ['componentProp', 'componentsProp', 'themeVariants'],
}));
+
+ describeRangeValidation(MultiInputDateTimeRangeField, () => ({
+ render,
+ clock,
+ componentFamily: 'field',
+ views: ['year', 'month', 'day', 'hours', 'minutes'],
+ setValue: (value, { setEndDate } = {}) => {
+ setValueOnFieldInput(adapterToUse.format(value, 'keyboardDateTime'), setEndDate ? 1 : 0);
+ },
+ }));
});
diff --git a/packages/x-date-pickers-pro/src/MultiInputTimeRangeField/MultiInputTimeRangeField.tsx b/packages/x-date-pickers-pro/src/MultiInputTimeRangeField/MultiInputTimeRangeField.tsx
index ee04099dff91d..a682b755b87b9 100644
--- a/packages/x-date-pickers-pro/src/MultiInputTimeRangeField/MultiInputTimeRangeField.tsx
+++ b/packages/x-date-pickers-pro/src/MultiInputTimeRangeField/MultiInputTimeRangeField.tsx
@@ -287,10 +287,12 @@ MultiInputTimeRangeField.propTypes = {
onChange: PropTypes.func,
/**
* Callback fired when the error associated to the current value changes.
- * @template TValue The value type. Will be either the same type as `value` or `null`. Can be in `[start, end]` format in case of range value.
+ * When a validation error is detected, the `error` parameter contains a non-null value.
+ * This can be used to render an appropriate form error.
* @template TError The validation error type. Will be either `string` or a `null`. Can be in `[start, end]` format in case of range value.
- * @param {TError} error The new error.
- * @param {TValue} value The value associated to the error.
+ * @template TValue The value type. Will be either the same type as `value` or `null`. Can be in `[start, end]` format in case of range value.
+ * @param {TError} error The reason why the current value is not valid.
+ * @param {TValue} value The value associated to the error
*/
onError: PropTypes.func,
/**
diff --git a/packages/x-date-pickers-pro/src/MultiInputTimeRangeField/tests/MultiInputTimeRangeField.validation.test.tsx b/packages/x-date-pickers-pro/src/MultiInputTimeRangeField/tests/MultiInputTimeRangeField.validation.test.tsx
deleted file mode 100644
index a84da9d27b0a9..0000000000000
--- a/packages/x-date-pickers-pro/src/MultiInputTimeRangeField/tests/MultiInputTimeRangeField.validation.test.tsx
+++ /dev/null
@@ -1,21 +0,0 @@
-import { MultiInputTimeRangeField } from '@mui/x-date-pickers-pro/MultiInputTimeRangeField';
-import {
- createPickerRenderer,
- adapterToUse,
- describeRangeValidation,
- setValueOnFieldInput,
-} from 'test/utils/pickers';
-
-describe('', () => {
- const { render, clock } = createPickerRenderer({ clock: 'fake' });
-
- describeRangeValidation(MultiInputTimeRangeField, () => ({
- render,
- clock,
- componentFamily: 'field',
- views: ['hours', 'minutes'],
- setValue: (value, { setEndDate } = {}) => {
- setValueOnFieldInput(adapterToUse.format(value, 'fullTime'), setEndDate ? 1 : 0);
- },
- }));
-});
diff --git a/packages/x-date-pickers-pro/src/MultiInputTimeRangeField/tests/describes.MultiInputTimeRangeField.test.tsx b/packages/x-date-pickers-pro/src/MultiInputTimeRangeField/tests/describes.MultiInputTimeRangeField.test.tsx
index 47047c3007d4c..f25cd1cd33f44 100644
--- a/packages/x-date-pickers-pro/src/MultiInputTimeRangeField/tests/describes.MultiInputTimeRangeField.test.tsx
+++ b/packages/x-date-pickers-pro/src/MultiInputTimeRangeField/tests/describes.MultiInputTimeRangeField.test.tsx
@@ -1,10 +1,15 @@
import * as React from 'react';
import { MultiInputTimeRangeField } from '@mui/x-date-pickers-pro/MultiInputTimeRangeField';
-import { createPickerRenderer } from 'test/utils/pickers';
+import {
+ adapterToUse,
+ createPickerRenderer,
+ describeRangeValidation,
+ setValueOnFieldInput,
+} from 'test/utils/pickers';
import { describeConformance } from 'test/utils/describeConformance';
describe('', () => {
- const { render } = createPickerRenderer();
+ const { render, clock } = createPickerRenderer();
describeConformance(, () => ({
classes: {} as any,
@@ -14,4 +19,14 @@ describe('', () => {
refInstanceof: window.HTMLDivElement,
skip: ['themeVariants', 'componentProp', 'componentsProp'],
}));
+
+ describeRangeValidation(MultiInputTimeRangeField, () => ({
+ render,
+ clock,
+ componentFamily: 'field',
+ views: ['hours', 'minutes'],
+ setValue: (value, { setEndDate } = {}) => {
+ setValueOnFieldInput(adapterToUse.format(value, 'fullTime'), setEndDate ? 1 : 0);
+ },
+ }));
});
diff --git a/packages/x-date-pickers-pro/src/SingleInputDateRangeField/SingleInputDateRangeField.tsx b/packages/x-date-pickers-pro/src/SingleInputDateRangeField/SingleInputDateRangeField.tsx
index edc1e5b91b690..88e25ad3ff8e6 100644
--- a/packages/x-date-pickers-pro/src/SingleInputDateRangeField/SingleInputDateRangeField.tsx
+++ b/packages/x-date-pickers-pro/src/SingleInputDateRangeField/SingleInputDateRangeField.tsx
@@ -230,10 +230,12 @@ SingleInputDateRangeField.propTypes = {
onClear: PropTypes.func,
/**
* Callback fired when the error associated to the current value changes.
- * @template TValue The value type. Will be either the same type as `value` or `null`. Can be in `[start, end]` format in case of range value.
+ * When a validation error is detected, the `error` parameter contains a non-null value.
+ * This can be used to render an appropriate form error.
* @template TError The validation error type. Will be either `string` or a `null`. Can be in `[start, end]` format in case of range value.
- * @param {TError} error The new error.
- * @param {TValue} value The value associated to the error.
+ * @template TValue The value type. Will be either the same type as `value` or `null`. Can be in `[start, end]` format in case of range value.
+ * @param {TError} error The reason why the current value is not valid.
+ * @param {TValue} value The value associated to the error
*/
onError: PropTypes.func,
onFocus: PropTypes.func,
diff --git a/packages/x-date-pickers-pro/src/SingleInputDateRangeField/useSingleInputDateRangeField.ts b/packages/x-date-pickers-pro/src/SingleInputDateRangeField/useSingleInputDateRangeField.ts
index acd9177c5fa67..6b49a74f5bdd6 100644
--- a/packages/x-date-pickers-pro/src/SingleInputDateRangeField/useSingleInputDateRangeField.ts
+++ b/packages/x-date-pickers-pro/src/SingleInputDateRangeField/useSingleInputDateRangeField.ts
@@ -7,7 +7,7 @@ import {
import { PickerValidDate } from '@mui/x-date-pickers/models';
import { UseSingleInputDateRangeFieldProps } from './SingleInputDateRangeField.types';
import { rangeValueManager, getRangeFieldValueManager } from '../internals/utils/valueManagers';
-import { validateDateRange } from '../internals/utils/validation/validateDateRange';
+import { validateDateRange } from '../validation';
import { RangeFieldSection, DateRange } from '../models';
export const useSingleInputDateRangeField = <
diff --git a/packages/x-date-pickers-pro/src/SingleInputDateTimeRangeField/SingleInputDateTimeRangeField.tsx b/packages/x-date-pickers-pro/src/SingleInputDateTimeRangeField/SingleInputDateTimeRangeField.tsx
index 57d0a57f3a91f..aded6d5ac2052 100644
--- a/packages/x-date-pickers-pro/src/SingleInputDateTimeRangeField/SingleInputDateTimeRangeField.tsx
+++ b/packages/x-date-pickers-pro/src/SingleInputDateTimeRangeField/SingleInputDateTimeRangeField.tsx
@@ -263,10 +263,12 @@ SingleInputDateTimeRangeField.propTypes = {
onClear: PropTypes.func,
/**
* Callback fired when the error associated to the current value changes.
- * @template TValue The value type. Will be either the same type as `value` or `null`. Can be in `[start, end]` format in case of range value.
+ * When a validation error is detected, the `error` parameter contains a non-null value.
+ * This can be used to render an appropriate form error.
* @template TError The validation error type. Will be either `string` or a `null`. Can be in `[start, end]` format in case of range value.
- * @param {TError} error The new error.
- * @param {TValue} value The value associated to the error.
+ * @template TValue The value type. Will be either the same type as `value` or `null`. Can be in `[start, end]` format in case of range value.
+ * @param {TError} error The reason why the current value is not valid.
+ * @param {TValue} value The value associated to the error
*/
onError: PropTypes.func,
onFocus: PropTypes.func,
diff --git a/packages/x-date-pickers-pro/src/SingleInputDateTimeRangeField/useSingleInputDateTimeRangeField.ts b/packages/x-date-pickers-pro/src/SingleInputDateTimeRangeField/useSingleInputDateTimeRangeField.ts
index c27ab9b259b30..1fe2b4100a06e 100644
--- a/packages/x-date-pickers-pro/src/SingleInputDateTimeRangeField/useSingleInputDateTimeRangeField.ts
+++ b/packages/x-date-pickers-pro/src/SingleInputDateTimeRangeField/useSingleInputDateTimeRangeField.ts
@@ -7,7 +7,7 @@ import {
import { PickerValidDate } from '@mui/x-date-pickers/models';
import { UseSingleInputDateTimeRangeFieldProps } from './SingleInputDateTimeRangeField.types';
import { rangeValueManager, getRangeFieldValueManager } from '../internals/utils/valueManagers';
-import { validateDateTimeRange } from '../internals/utils/validation/validateDateTimeRange';
+import { validateDateTimeRange } from '../validation';
import { RangeFieldSection, DateRange } from '../models';
export const useSingleInputDateTimeRangeField = <
diff --git a/packages/x-date-pickers-pro/src/SingleInputTimeRangeField/SingleInputTimeRangeField.tsx b/packages/x-date-pickers-pro/src/SingleInputTimeRangeField/SingleInputTimeRangeField.tsx
index cd37622a001e2..414b36c21cf21 100644
--- a/packages/x-date-pickers-pro/src/SingleInputTimeRangeField/SingleInputTimeRangeField.tsx
+++ b/packages/x-date-pickers-pro/src/SingleInputTimeRangeField/SingleInputTimeRangeField.tsx
@@ -245,10 +245,12 @@ SingleInputTimeRangeField.propTypes = {
onClear: PropTypes.func,
/**
* Callback fired when the error associated to the current value changes.
- * @template TValue The value type. Will be either the same type as `value` or `null`. Can be in `[start, end]` format in case of range value.
+ * When a validation error is detected, the `error` parameter contains a non-null value.
+ * This can be used to render an appropriate form error.
* @template TError The validation error type. Will be either `string` or a `null`. Can be in `[start, end]` format in case of range value.
- * @param {TError} error The new error.
- * @param {TValue} value The value associated to the error.
+ * @template TValue The value type. Will be either the same type as `value` or `null`. Can be in `[start, end]` format in case of range value.
+ * @param {TError} error The reason why the current value is not valid.
+ * @param {TValue} value The value associated to the error
*/
onError: PropTypes.func,
onFocus: PropTypes.func,
diff --git a/packages/x-date-pickers-pro/src/SingleInputTimeRangeField/useSingleInputTimeRangeField.ts b/packages/x-date-pickers-pro/src/SingleInputTimeRangeField/useSingleInputTimeRangeField.ts
index 98d9703e7eb85..c245dec8acb5e 100644
--- a/packages/x-date-pickers-pro/src/SingleInputTimeRangeField/useSingleInputTimeRangeField.ts
+++ b/packages/x-date-pickers-pro/src/SingleInputTimeRangeField/useSingleInputTimeRangeField.ts
@@ -7,7 +7,7 @@ import {
import { PickerValidDate } from '@mui/x-date-pickers/models';
import { UseSingleInputTimeRangeFieldProps } from './SingleInputTimeRangeField.types';
import { rangeValueManager, getRangeFieldValueManager } from '../internals/utils/valueManagers';
-import { validateTimeRange } from '../internals/utils/validation/validateTimeRange';
+import { validateTimeRange } from '../validation';
import { RangeFieldSection, DateRange } from '../models';
export const useSingleInputTimeRangeField = <
diff --git a/packages/x-date-pickers-pro/src/StaticDateRangePicker/StaticDateRangePicker.tsx b/packages/x-date-pickers-pro/src/StaticDateRangePicker/StaticDateRangePicker.tsx
index 74ff932d922db..163cfddca378b 100644
--- a/packages/x-date-pickers-pro/src/StaticDateRangePicker/StaticDateRangePicker.tsx
+++ b/packages/x-date-pickers-pro/src/StaticDateRangePicker/StaticDateRangePicker.tsx
@@ -7,7 +7,7 @@ import { StaticDateRangePickerProps } from './StaticDateRangePicker.types';
import { useDateRangePickerDefaultizedProps } from '../DateRangePicker/shared';
import { renderDateRangeViewCalendar } from '../dateRangeViewRenderers';
import { rangeValueManager } from '../internals/utils/valueManagers';
-import { validateDateRange } from '../internals/utils/validation/validateDateRange';
+import { validateDateRange } from '../validation';
import { DateRange } from '../models';
type StaticDateRangePickerComponent = ((
@@ -197,12 +197,12 @@ StaticDateRangePicker.propTypes = {
onClose: PropTypes.func,
/**
* Callback fired when the error associated to the current value changes.
- * If the error has a non-null value, then the `TextField` will be rendered in `error` state.
- *
- * @template TValue The value type. Will be either the same type as `value` or `null`. Can be in `[start, end]` format in case of range value.
+ * When a validation error is detected, the `error` parameter contains a non-null value.
+ * This can be used to render an appropriate form error.
* @template TError The validation error type. Will be either `string` or a `null`. Can be in `[start, end]` format in case of range value.
- * @param {TError} error The new error describing why the current value is not valid.
- * @param {TValue} value The value associated to the error.
+ * @template TValue The value type. Will be either the same type as `value` or `null`. Can be in `[start, end]` format in case of range value.
+ * @param {TError} error The reason why the current value is not valid.
+ * @param {TValue} value The value associated to the error
*/
onError: PropTypes.func,
/**
diff --git a/packages/x-date-pickers-pro/src/index.ts b/packages/x-date-pickers-pro/src/index.ts
index 55114fb14fb87..8a7bb7e61c04b 100644
--- a/packages/x-date-pickers-pro/src/index.ts
+++ b/packages/x-date-pickers-pro/src/index.ts
@@ -35,3 +35,4 @@ export * from './MobileDateTimeRangePicker';
export * from './dateRangeViewRenderers';
export * from './models';
+export * from './validation';
diff --git a/packages/x-date-pickers-pro/src/internals/hooks/useDesktopRangePicker/useDesktopRangePicker.tsx b/packages/x-date-pickers-pro/src/internals/hooks/useDesktopRangePicker/useDesktopRangePicker.tsx
index cb635fdba2ca8..55d56d9b6ca58 100644
--- a/packages/x-date-pickers-pro/src/internals/hooks/useDesktopRangePicker/useDesktopRangePicker.tsx
+++ b/packages/x-date-pickers-pro/src/internals/hooks/useDesktopRangePicker/useDesktopRangePicker.tsx
@@ -8,12 +8,16 @@ import {
getActiveElement,
usePicker,
PickersPopper,
- InferError,
ExportedBaseToolbarProps,
DateOrTimeViewWithMeridiem,
ExportedBaseTabsProps,
} from '@mui/x-date-pickers/internals';
-import { PickerValidDate, FieldRef, BaseSingleInputFieldProps } from '@mui/x-date-pickers/models';
+import {
+ PickerValidDate,
+ FieldRef,
+ BaseSingleInputFieldProps,
+ InferError,
+} from '@mui/x-date-pickers/models';
import {
DesktopRangePickerAdditionalViewProps,
UseDesktopRangePickerParams,
diff --git a/packages/x-date-pickers-pro/src/internals/hooks/useMobileRangePicker/useMobileRangePicker.tsx b/packages/x-date-pickers-pro/src/internals/hooks/useMobileRangePicker/useMobileRangePicker.tsx
index 8c0ff74043266..518914bdb1b59 100644
--- a/packages/x-date-pickers-pro/src/internals/hooks/useMobileRangePicker/useMobileRangePicker.tsx
+++ b/packages/x-date-pickers-pro/src/internals/hooks/useMobileRangePicker/useMobileRangePicker.tsx
@@ -6,13 +6,17 @@ import { PickersLayout, PickersLayoutSlotProps } from '@mui/x-date-pickers/Picke
import {
usePicker,
PickersModalDialog,
- InferError,
ExportedBaseToolbarProps,
DateOrTimeViewWithMeridiem,
ExportedBaseTabsProps,
} from '@mui/x-date-pickers/internals';
import { usePickersTranslations } from '@mui/x-date-pickers/hooks';
-import { PickerValidDate, FieldRef, BaseSingleInputFieldProps } from '@mui/x-date-pickers/models';
+import {
+ PickerValidDate,
+ FieldRef,
+ BaseSingleInputFieldProps,
+ InferError,
+} from '@mui/x-date-pickers/models';
import useId from '@mui/utils/useId';
import {
MobileRangePickerAdditionalViewProps,
diff --git a/packages/x-date-pickers-pro/src/internals/hooks/useMultiInputRangeField/useMultiInputDateRangeField.ts b/packages/x-date-pickers-pro/src/internals/hooks/useMultiInputRangeField/useMultiInputDateRangeField.ts
index 84dfaeeb86312..f89396ebc68bf 100644
--- a/packages/x-date-pickers-pro/src/internals/hooks/useMultiInputRangeField/useMultiInputDateRangeField.ts
+++ b/packages/x-date-pickers-pro/src/internals/hooks/useMultiInputRangeField/useMultiInputDateRangeField.ts
@@ -4,23 +4,19 @@ import {
UseDateFieldComponentProps,
} from '@mui/x-date-pickers/DateField';
import {
- useLocalizationContext,
- useValidation,
FieldChangeHandler,
FieldChangeHandlerContext,
UseFieldResponse,
useControlledValueWithTimezone,
useDefaultizedDateField,
} from '@mui/x-date-pickers/internals';
+import { useValidation } from '@mui/x-date-pickers/validation';
import { DateValidationError, PickerValidDate } from '@mui/x-date-pickers/models';
import {
UseMultiInputDateRangeFieldParams,
UseMultiInputDateRangeFieldProps,
} from '../../../MultiInputDateRangeField/MultiInputDateRangeField.types';
-import {
- DateRangeComponentValidationProps,
- validateDateRange,
-} from '../../utils/validation/validateDateRange';
+import { validateDateRange } from '../../../validation';
import { rangeValueManager } from '../../utils/valueManagers';
import type { UseMultiInputRangeFieldResponse } from './useMultiInputRangeField.types';
import { DateRangeValidationError, DateRange } from '../../../models';
@@ -48,8 +44,6 @@ export const useMultiInputDateRangeField = <
typeof inSharedProps
>(inSharedProps);
- const adapter = useLocalizationContext();
-
const {
value: valueProp,
defaultValue,
@@ -75,6 +69,14 @@ export const useMultiInputDateRangeField = <
valueManager: rangeValueManager,
});
+ const { validationError, getValidationErrorForNewValue } = useValidation({
+ props: sharedProps,
+ value,
+ timezone,
+ validator: validateDateRange,
+ onError: sharedProps.onError,
+ });
+
// TODO: Maybe export utility from `useField` instead of copy/pasting the logic
const buildChangeHandler = (
index: 0 | 1,
@@ -85,11 +87,7 @@ export const useMultiInputDateRangeField = <
const context: FieldChangeHandlerContext = {
...rawContext,
- validationError: validateDateRange({
- adapter,
- value: newDateRange,
- props: { ...sharedProps, timezone },
- }),
+ validationError: getValidationErrorForNewValue(newDateRange),
};
handleValueChange(newDateRange, context);
@@ -99,18 +97,6 @@ export const useMultiInputDateRangeField = <
const handleStartDateChange = useEventCallback(buildChangeHandler(0));
const handleEndDateChange = useEventCallback(buildChangeHandler(1));
- const validationError = useValidation<
- DateRange,
- TDate,
- DateRangeValidationError,
- DateRangeComponentValidationProps
- >(
- { ...sharedProps, value, timezone },
- validateDateRange,
- rangeValueManager.isSameError,
- rangeValueManager.defaultErrorState,
- );
-
const selectedSectionsResponse = useMultiInputFieldSelectedSections({
selectedSections,
onSelectedSectionsChange,
diff --git a/packages/x-date-pickers-pro/src/internals/hooks/useMultiInputRangeField/useMultiInputDateTimeRangeField.ts b/packages/x-date-pickers-pro/src/internals/hooks/useMultiInputRangeField/useMultiInputDateTimeRangeField.ts
index cecc16b5cc6eb..60efbe608a10a 100644
--- a/packages/x-date-pickers-pro/src/internals/hooks/useMultiInputRangeField/useMultiInputDateTimeRangeField.ts
+++ b/packages/x-date-pickers-pro/src/internals/hooks/useMultiInputRangeField/useMultiInputDateTimeRangeField.ts
@@ -4,8 +4,6 @@ import {
UseDateTimeFieldComponentProps,
} from '@mui/x-date-pickers/DateTimeField';
import {
- useLocalizationContext,
- useValidation,
FieldChangeHandler,
FieldChangeHandlerContext,
UseFieldResponse,
@@ -13,15 +11,13 @@ import {
useDefaultizedDateTimeField,
} from '@mui/x-date-pickers/internals';
import { DateTimeValidationError, PickerValidDate } from '@mui/x-date-pickers/models';
+import { useValidation } from '@mui/x-date-pickers/validation';
import type {
UseMultiInputDateTimeRangeFieldParams,
UseMultiInputDateTimeRangeFieldProps,
} from '../../../MultiInputDateTimeRangeField/MultiInputDateTimeRangeField.types';
import { DateTimeRangeValidationError, DateRange } from '../../../models';
-import {
- DateTimeRangeComponentValidationProps,
- validateDateTimeRange,
-} from '../../utils/validation/validateDateTimeRange';
+import { validateDateTimeRange } from '../../../validation';
import { rangeValueManager } from '../../utils/valueManagers';
import type { UseMultiInputRangeFieldResponse } from './useMultiInputRangeField.types';
import { excludeProps } from './shared';
@@ -47,7 +43,6 @@ export const useMultiInputDateTimeRangeField = <
UseMultiInputDateTimeRangeFieldProps,
typeof inSharedProps
>(inSharedProps);
- const adapter = useLocalizationContext();
const {
value: valueProp,
@@ -74,6 +69,14 @@ export const useMultiInputDateTimeRangeField = <
valueManager: rangeValueManager,
});
+ const { validationError, getValidationErrorForNewValue } = useValidation({
+ props: sharedProps,
+ value,
+ timezone,
+ validator: validateDateTimeRange,
+ onError: sharedProps.onError,
+ });
+
// TODO: Maybe export utility from `useField` instead of copy/pasting the logic
const buildChangeHandler = (
index: 0 | 1,
@@ -84,11 +87,7 @@ export const useMultiInputDateTimeRangeField = <
const context: FieldChangeHandlerContext = {
...rawContext,
- validationError: validateDateTimeRange({
- adapter,
- value: newDateRange,
- props: { ...sharedProps, timezone },
- }),
+ validationError: getValidationErrorForNewValue(newDateRange),
};
handleValueChange(newDateRange, context);
@@ -98,18 +97,6 @@ export const useMultiInputDateTimeRangeField = <
const handleStartDateChange = useEventCallback(buildChangeHandler(0));
const handleEndDateChange = useEventCallback(buildChangeHandler(1));
- const validationError = useValidation<
- DateRange,
- TDate,
- DateTimeRangeValidationError,
- DateTimeRangeComponentValidationProps
- >(
- { ...sharedProps, value, timezone },
- validateDateTimeRange,
- rangeValueManager.isSameError,
- rangeValueManager.defaultErrorState,
- );
-
const selectedSectionsResponse = useMultiInputFieldSelectedSections({
selectedSections,
onSelectedSectionsChange,
diff --git a/packages/x-date-pickers-pro/src/internals/hooks/useMultiInputRangeField/useMultiInputTimeRangeField.ts b/packages/x-date-pickers-pro/src/internals/hooks/useMultiInputRangeField/useMultiInputTimeRangeField.ts
index a27dcb41a897f..86db843894f5a 100644
--- a/packages/x-date-pickers-pro/src/internals/hooks/useMultiInputRangeField/useMultiInputTimeRangeField.ts
+++ b/packages/x-date-pickers-pro/src/internals/hooks/useMultiInputRangeField/useMultiInputTimeRangeField.ts
@@ -4,19 +4,15 @@ import {
UseTimeFieldComponentProps,
} from '@mui/x-date-pickers/TimeField';
import {
- useLocalizationContext,
- useValidation,
FieldChangeHandler,
FieldChangeHandlerContext,
UseFieldResponse,
useControlledValueWithTimezone,
useDefaultizedTimeField,
} from '@mui/x-date-pickers/internals';
+import { useValidation } from '@mui/x-date-pickers/validation';
import { PickerValidDate, TimeValidationError } from '@mui/x-date-pickers/models';
-import {
- validateTimeRange,
- TimeRangeComponentValidationProps,
-} from '../../utils/validation/validateTimeRange';
+import { validateTimeRange } from '../../../validation';
import { TimeRangeValidationError, DateRange } from '../../../models';
import type {
UseMultiInputTimeRangeFieldParams,
@@ -47,7 +43,6 @@ export const useMultiInputTimeRangeField = <
UseMultiInputTimeRangeFieldProps,
typeof inSharedProps
>(inSharedProps);
- const adapter = useLocalizationContext();
const {
value: valueProp,
@@ -74,6 +69,14 @@ export const useMultiInputTimeRangeField = <
valueManager: rangeValueManager,
});
+ const { validationError, getValidationErrorForNewValue } = useValidation({
+ props: sharedProps,
+ validator: validateTimeRange,
+ value,
+ timezone,
+ onError: sharedProps.onError,
+ });
+
// TODO: Maybe export utility from `useField` instead of copy/pasting the logic
const buildChangeHandler = (
index: 0 | 1,
@@ -84,11 +87,7 @@ export const useMultiInputTimeRangeField = <
const context: FieldChangeHandlerContext = {
...rawContext,
- validationError: validateTimeRange({
- adapter,
- value: newDateRange,
- props: { ...sharedProps, timezone },
- }),
+ validationError: getValidationErrorForNewValue(newDateRange),
};
handleValueChange(newDateRange, context);
@@ -98,18 +97,6 @@ export const useMultiInputTimeRangeField = <
const handleStartDateChange = useEventCallback(buildChangeHandler(0));
const handleEndDateChange = useEventCallback(buildChangeHandler(1));
- const validationError = useValidation<
- DateRange,
- TDate,
- TimeRangeValidationError,
- TimeRangeComponentValidationProps
- >(
- { ...sharedProps, value, timezone },
- validateTimeRange,
- rangeValueManager.isSameError,
- rangeValueManager.defaultErrorState,
- );
-
const selectedSectionsResponse = useMultiInputFieldSelectedSections({
selectedSections,
onSelectedSectionsChange,
diff --git a/packages/x-date-pickers-pro/src/validation/index.ts b/packages/x-date-pickers-pro/src/validation/index.ts
new file mode 100644
index 0000000000000..9b7737a17ed25
--- /dev/null
+++ b/packages/x-date-pickers-pro/src/validation/index.ts
@@ -0,0 +1,8 @@
+export { validateDateRange } from './validateDateRange';
+export type { ValidateDateRangeProps } from './validateDateRange';
+
+export { validateTimeRange } from './validateTimeRange';
+export type { ValidateTimeRangeProps } from './validateTimeRange';
+
+export { validateDateTimeRange } from './validateDateTimeRange';
+export type { ValidateDateTimeRangeProps } from './validateDateTimeRange';
diff --git a/packages/x-date-pickers-pro/src/internals/utils/validation/validateDateRange.ts b/packages/x-date-pickers-pro/src/validation/validateDateRange.ts
similarity index 55%
rename from packages/x-date-pickers-pro/src/internals/utils/validation/validateDateRange.ts
rename to packages/x-date-pickers-pro/src/validation/validateDateRange.ts
index bb138c82f438b..125449ca9a6fc 100644
--- a/packages/x-date-pickers-pro/src/internals/utils/validation/validateDateRange.ts
+++ b/packages/x-date-pickers-pro/src/validation/validateDateRange.ts
@@ -1,25 +1,21 @@
-import { PickerValidDate, TimezoneProps } from '@mui/x-date-pickers/models';
-import {
- Validator,
- validateDate,
- BaseDateValidationProps,
- DefaultizedProps,
-} from '@mui/x-date-pickers/internals';
-import { isRangeValid } from '../date-utils';
-import { DayRangeValidationProps } from '../../models/dateRange';
-import { DateRangeValidationError, DateRange } from '../../../models';
-
-export interface DateRangeComponentValidationProps
+import { PickerValidDate } from '@mui/x-date-pickers/models';
+import { validateDate, Validator } from '@mui/x-date-pickers/validation';
+import { BaseDateValidationProps } from '@mui/x-date-pickers/internals';
+import { isRangeValid } from '../internals/utils/date-utils';
+import { DayRangeValidationProps } from '../internals/models/dateRange';
+import { DateRangeValidationError, DateRange } from '../models';
+import { rangeValueManager } from '../internals/utils/valueManagers';
+
+export interface ValidateDateRangeProps
extends DayRangeValidationProps,
- Required>,
- DefaultizedProps {}
+ Required> {}
export const validateDateRange: Validator<
DateRange,
any,
DateRangeValidationError,
- DateRangeComponentValidationProps
-> = ({ props, value, adapter }) => {
+ ValidateDateRangeProps
+> = ({ adapter, value, timezone, props }) => {
const [start, end] = value;
const { shouldDisableDate, ...otherProps } = props;
@@ -28,6 +24,7 @@ export const validateDateRange: Validator<
validateDate({
adapter,
value: start,
+ timezone,
props: {
...otherProps,
shouldDisableDate: (day) => !!shouldDisableDate?.(day, 'start'),
@@ -36,6 +33,7 @@ export const validateDateRange: Validator<
validateDate({
adapter,
value: end,
+ timezone,
props: {
...otherProps,
shouldDisableDate: (day) => !!shouldDisableDate?.(day, 'end'),
@@ -58,3 +56,5 @@ export const validateDateRange: Validator<
return [null, null];
};
+
+validateDateRange.valueManager = rangeValueManager;
diff --git a/packages/x-date-pickers-pro/src/internals/utils/validation/validateDateTimeRange.ts b/packages/x-date-pickers-pro/src/validation/validateDateTimeRange.ts
similarity index 55%
rename from packages/x-date-pickers-pro/src/internals/utils/validation/validateDateTimeRange.ts
rename to packages/x-date-pickers-pro/src/validation/validateDateTimeRange.ts
index 2eae3041a2e4a..d86d65e8d3b33 100644
--- a/packages/x-date-pickers-pro/src/internals/utils/validation/validateDateTimeRange.ts
+++ b/packages/x-date-pickers-pro/src/validation/validateDateTimeRange.ts
@@ -1,27 +1,22 @@
-import { PickerValidDate, TimezoneProps } from '@mui/x-date-pickers/models';
-import {
- Validator,
- validateDateTime,
- BaseDateValidationProps,
- TimeValidationProps,
- DefaultizedProps,
-} from '@mui/x-date-pickers/internals';
-import { isRangeValid } from '../date-utils';
-import { DayRangeValidationProps } from '../../models/dateRange';
-import { DateTimeRangeValidationError, DateRange } from '../../../models';
-
-export interface DateTimeRangeComponentValidationProps
+import { PickerValidDate } from '@mui/x-date-pickers/models';
+import { validateDateTime, Validator } from '@mui/x-date-pickers/validation';
+import { BaseDateValidationProps, TimeValidationProps } from '@mui/x-date-pickers/internals';
+import { isRangeValid } from '../internals/utils/date-utils';
+import { DayRangeValidationProps } from '../internals/models/dateRange';
+import { DateTimeRangeValidationError, DateRange } from '../models';
+import { rangeValueManager } from '../internals/utils/valueManagers';
+
+export interface ValidateDateTimeRangeProps
extends DayRangeValidationProps,
TimeValidationProps,
- Required>,
- DefaultizedProps {}
+ Required> {}
export const validateDateTimeRange: Validator<
DateRange,
any,
DateTimeRangeValidationError,
- DateTimeRangeComponentValidationProps
-> = ({ props, value, adapter }) => {
+ ValidateDateTimeRangeProps
+> = ({ adapter, value, timezone, props }) => {
const [start, end] = value;
const { shouldDisableDate, ...otherProps } = props;
@@ -30,6 +25,7 @@ export const validateDateTimeRange: Validator<
validateDateTime({
adapter,
value: start,
+ timezone,
props: {
...otherProps,
shouldDisableDate: (day) => !!shouldDisableDate?.(day, 'start'),
@@ -38,6 +34,7 @@ export const validateDateTimeRange: Validator<
validateDateTime({
adapter,
value: end,
+ timezone,
props: {
...otherProps,
shouldDisableDate: (day) => !!shouldDisableDate?.(day, 'end'),
@@ -60,3 +57,5 @@ export const validateDateTimeRange: Validator<
return [null, null];
};
+
+validateDateTimeRange.valueManager = rangeValueManager;
diff --git a/packages/x-date-pickers-pro/src/internals/utils/validation/validateTimeRange.ts b/packages/x-date-pickers-pro/src/validation/validateTimeRange.ts
similarity index 52%
rename from packages/x-date-pickers-pro/src/internals/utils/validation/validateTimeRange.ts
rename to packages/x-date-pickers-pro/src/validation/validateTimeRange.ts
index 15b4a2bc2cd66..483523a4b4994 100644
--- a/packages/x-date-pickers-pro/src/internals/utils/validation/validateTimeRange.ts
+++ b/packages/x-date-pickers-pro/src/validation/validateTimeRange.ts
@@ -1,34 +1,30 @@
-import { TimezoneProps } from '@mui/x-date-pickers/models';
-import {
- Validator,
- validateTime,
- BaseTimeValidationProps,
- DefaultizedProps,
-} from '@mui/x-date-pickers/internals';
-import { isRangeValid } from '../date-utils';
-import { TimeRangeValidationError, DateRange } from '../../../models';
-
-export interface TimeRangeComponentValidationProps
- extends Required,
- DefaultizedProps {}
+import { validateTime, Validator } from '@mui/x-date-pickers/validation';
+import { BaseTimeValidationProps } from '@mui/x-date-pickers/internals';
+import { isRangeValid } from '../internals/utils/date-utils';
+import { TimeRangeValidationError, DateRange } from '../models';
+import { rangeValueManager } from '../internals/utils/valueManagers';
+
+export interface ValidateTimeRangeProps extends Required {}
export const validateTimeRange: Validator<
DateRange,
any,
TimeRangeValidationError,
- TimeRangeComponentValidationProps
-> = ({ props, value, adapter }) => {
+ ValidateTimeRangeProps
+> = ({ adapter, value, timezone, props }) => {
const [start, end] = value;
const dateTimeValidations: TimeRangeValidationError = [
validateTime({
adapter,
value: start,
+ timezone,
props,
}),
validateTime({
adapter,
value: end,
+ timezone,
props,
}),
];
@@ -48,3 +44,5 @@ export const validateTimeRange: Validator<
return [null, null];
};
+
+validateTimeRange.valueManager = rangeValueManager;
diff --git a/packages/x-date-pickers/src/DateCalendar/useIsDateDisabled.ts b/packages/x-date-pickers/src/DateCalendar/useIsDateDisabled.ts
index 7fbde8e847724..2c677f6f7653d 100644
--- a/packages/x-date-pickers/src/DateCalendar/useIsDateDisabled.ts
+++ b/packages/x-date-pickers/src/DateCalendar/useIsDateDisabled.ts
@@ -1,10 +1,8 @@
import * as React from 'react';
-import {
- DateComponentValidationProps,
- validateDate,
-} from '../internals/utils/validation/validateDate';
+import { ValidateDateProps, validateDate } from '../validation';
import { useLocalizationContext } from '../internals/hooks/useUtils';
-import { PickerValidDate } from '../models';
+import { PickerValidDate, TimezoneProps } from '../models';
+import { DefaultizedProps } from '../internals/models/helpers';
export const useIsDateDisabled = ({
shouldDisableDate,
@@ -15,7 +13,7 @@ export const useIsDateDisabled = ({
disableFuture,
disablePast,
timezone,
-}: DateComponentValidationProps) => {
+}: ValidateDateProps & DefaultizedProps) => {
const adapter = useLocalizationContext();
return React.useCallback(
@@ -23,6 +21,7 @@ export const useIsDateDisabled = ({
validateDate({
adapter,
value: day,
+ timezone,
props: {
shouldDisableDate,
shouldDisableMonth,
@@ -31,7 +30,6 @@ export const useIsDateDisabled = ({
maxDate,
disableFuture,
disablePast,
- timezone,
},
}) !== null,
[
diff --git a/packages/x-date-pickers/src/DateField/DateField.tsx b/packages/x-date-pickers/src/DateField/DateField.tsx
index 5f707a99d31ab..9a8b2f4d5bb15 100644
--- a/packages/x-date-pickers/src/DateField/DateField.tsx
+++ b/packages/x-date-pickers/src/DateField/DateField.tsx
@@ -222,10 +222,12 @@ DateField.propTypes = {
onClear: PropTypes.func,
/**
* Callback fired when the error associated to the current value changes.
- * @template TValue The value type. Will be either the same type as `value` or `null`. Can be in `[start, end]` format in case of range value.
+ * When a validation error is detected, the `error` parameter contains a non-null value.
+ * This can be used to render an appropriate form error.
* @template TError The validation error type. Will be either `string` or a `null`. Can be in `[start, end]` format in case of range value.
- * @param {TError} error The new error.
- * @param {TValue} value The value associated to the error.
+ * @template TValue The value type. Will be either the same type as `value` or `null`. Can be in `[start, end]` format in case of range value.
+ * @param {TError} error The reason why the current value is not valid.
+ * @param {TValue} value The value associated to the error
*/
onError: PropTypes.func,
onFocus: PropTypes.func,
diff --git a/packages/x-date-pickers/src/DateField/DateField.types.ts b/packages/x-date-pickers/src/DateField/DateField.types.ts
index cf1bdfcc800ac..57ab1e1830aec 100644
--- a/packages/x-date-pickers/src/DateField/DateField.types.ts
+++ b/packages/x-date-pickers/src/DateField/DateField.types.ts
@@ -11,9 +11,10 @@ import {
FieldSection,
PickerValidDate,
BuiltInFieldTextFieldProps,
+ BaseSingleInputFieldProps,
} from '../models';
import { UseFieldInternalProps } from '../internals/hooks/useField';
-import { MakeOptional } from '../internals/models/helpers';
+import { MakeOptional, DefaultizedProps } from '../internals/models/helpers';
import {
BaseDateValidationProps,
DayValidationProps,
@@ -40,6 +41,19 @@ export interface UseDateFieldProps<
BaseDateValidationProps,
ExportedUseClearableFieldProps {}
+/**
+ * Props the field can receive when used inside a date picker.
+ * (`DatePicker`, `DesktopDatePicker` or `MobileDatePicker` component).
+ */
+export type DateFieldInPickerProps<
+ TDate extends PickerValidDate,
+ TEnableAccessibleFieldDOMStructure extends boolean,
+> = DefaultizedProps<
+ UseDateFieldProps,
+ 'format' | 'timezone' | keyof BaseDateValidationProps
+> &
+ BaseSingleInputFieldProps;
+
export type UseDateFieldComponentProps<
TDate extends PickerValidDate,
TEnableAccessibleFieldDOMStructure extends boolean,
diff --git a/packages/x-date-pickers/src/DateField/index.ts b/packages/x-date-pickers/src/DateField/index.ts
index cd6119e98a255..e5f8fe21dcb29 100644
--- a/packages/x-date-pickers/src/DateField/index.ts
+++ b/packages/x-date-pickers/src/DateField/index.ts
@@ -4,4 +4,5 @@ export type {
UseDateFieldProps,
UseDateFieldComponentProps,
DateFieldProps,
+ DateFieldInPickerProps,
} from './DateField.types';
diff --git a/packages/x-date-pickers/src/DateField/useDateField.ts b/packages/x-date-pickers/src/DateField/useDateField.ts
index a6ea87980fdd4..0ac1bb8c6954a 100644
--- a/packages/x-date-pickers/src/DateField/useDateField.ts
+++ b/packages/x-date-pickers/src/DateField/useDateField.ts
@@ -4,7 +4,7 @@ import {
} from '../internals/utils/valueManagers';
import { useField } from '../internals/hooks/useField';
import { UseDateFieldProps } from './DateField.types';
-import { validateDate } from '../internals/utils/validation/validateDate';
+import { validateDate } from '../validation';
import { splitFieldInternalAndForwardedProps } from '../internals/utils/fields';
import { FieldSection, PickerValidDate } from '../models';
import { useDefaultizedDateField } from '../internals/hooks/defaultizedFieldProps';
diff --git a/packages/x-date-pickers/src/DatePicker/DatePicker.tsx b/packages/x-date-pickers/src/DatePicker/DatePicker.tsx
index e93c88833ba49..15836ef4d4c1d 100644
--- a/packages/x-date-pickers/src/DatePicker/DatePicker.tsx
+++ b/packages/x-date-pickers/src/DatePicker/DatePicker.tsx
@@ -194,12 +194,12 @@ DatePicker.propTypes = {
onClose: PropTypes.func,
/**
* Callback fired when the error associated to the current value changes.
- * If the error has a non-null value, then the `TextField` will be rendered in `error` state.
- *
- * @template TValue The value type. Will be either the same type as `value` or `null`. Can be in `[start, end]` format in case of range value.
+ * When a validation error is detected, the `error` parameter contains a non-null value.
+ * This can be used to render an appropriate form error.
* @template TError The validation error type. Will be either `string` or a `null`. Can be in `[start, end]` format in case of range value.
- * @param {TError} error The new error describing why the current value is not valid.
- * @param {TValue} value The value associated to the error.
+ * @template TValue The value type. Will be either the same type as `value` or `null`. Can be in `[start, end]` format in case of range value.
+ * @param {TError} error The reason why the current value is not valid.
+ * @param {TValue} value The value associated to the error
*/
onError: PropTypes.func,
/**
diff --git a/packages/x-date-pickers/src/DateTimeField/DateTimeField.tsx b/packages/x-date-pickers/src/DateTimeField/DateTimeField.tsx
index 44db7bb3fb500..1b56a21d24e3b 100644
--- a/packages/x-date-pickers/src/DateTimeField/DateTimeField.tsx
+++ b/packages/x-date-pickers/src/DateTimeField/DateTimeField.tsx
@@ -255,10 +255,12 @@ DateTimeField.propTypes = {
onClear: PropTypes.func,
/**
* Callback fired when the error associated to the current value changes.
- * @template TValue The value type. Will be either the same type as `value` or `null`. Can be in `[start, end]` format in case of range value.
+ * When a validation error is detected, the `error` parameter contains a non-null value.
+ * This can be used to render an appropriate form error.
* @template TError The validation error type. Will be either `string` or a `null`. Can be in `[start, end]` format in case of range value.
- * @param {TError} error The new error.
- * @param {TValue} value The value associated to the error.
+ * @template TValue The value type. Will be either the same type as `value` or `null`. Can be in `[start, end]` format in case of range value.
+ * @param {TError} error The reason why the current value is not valid.
+ * @param {TValue} value The value associated to the error
*/
onError: PropTypes.func,
onFocus: PropTypes.func,
diff --git a/packages/x-date-pickers/src/DateTimeField/DateTimeField.types.ts b/packages/x-date-pickers/src/DateTimeField/DateTimeField.types.ts
index 625f70532e552..e19e41a6345ad 100644
--- a/packages/x-date-pickers/src/DateTimeField/DateTimeField.types.ts
+++ b/packages/x-date-pickers/src/DateTimeField/DateTimeField.types.ts
@@ -6,9 +6,10 @@ import {
FieldSection,
PickerValidDate,
BuiltInFieldTextFieldProps,
+ BaseSingleInputFieldProps,
} from '../models';
import { UseFieldInternalProps } from '../internals/hooks/useField';
-import { MakeOptional } from '../internals/models/helpers';
+import { DefaultizedProps, MakeOptional } from '../internals/models/helpers';
import {
BaseDateValidationProps,
BaseTimeValidationProps,
@@ -52,6 +53,23 @@ export interface UseDateTimeFieldProps<
ampm?: boolean;
}
+/**
+ * Props the field can receive when used inside a date time picker.
+ * (`DateTimePicker`, `DesktopDateTimePicker` or `MobileDateTimePicker` component).
+ */
+export type DateTimeFieldInPickerProps<
+ TDate extends PickerValidDate,
+ TEnableAccessibleFieldDOMStructure extends boolean,
+> = DefaultizedProps<
+ UseDateTimeFieldProps,
+ | 'format'
+ | 'timezone'
+ | 'ampm'
+ | keyof BaseDateValidationProps
+ | keyof BaseTimeValidationProps
+> &
+ BaseSingleInputFieldProps;
+
export type UseDateTimeFieldComponentProps<
TDate extends PickerValidDate,
TEnableAccessibleFieldDOMStructure extends boolean,
diff --git a/packages/x-date-pickers/src/DateTimeField/index.ts b/packages/x-date-pickers/src/DateTimeField/index.ts
index 95952dde94748..212ce42432f5a 100644
--- a/packages/x-date-pickers/src/DateTimeField/index.ts
+++ b/packages/x-date-pickers/src/DateTimeField/index.ts
@@ -4,4 +4,5 @@ export type {
UseDateTimeFieldProps,
UseDateTimeFieldComponentProps,
DateTimeFieldProps,
+ DateTimeFieldInPickerProps,
} from './DateTimeField.types';
diff --git a/packages/x-date-pickers/src/DateTimeField/useDateTimeField.ts b/packages/x-date-pickers/src/DateTimeField/useDateTimeField.ts
index b92124fe93731..86a4f826fc09d 100644
--- a/packages/x-date-pickers/src/DateTimeField/useDateTimeField.ts
+++ b/packages/x-date-pickers/src/DateTimeField/useDateTimeField.ts
@@ -4,7 +4,7 @@ import {
} from '../internals/utils/valueManagers';
import { useField } from '../internals/hooks/useField';
import { UseDateTimeFieldProps } from './DateTimeField.types';
-import { validateDateTime } from '../internals/utils/validation/validateDateTime';
+import { validateDateTime } from '../validation';
import { splitFieldInternalAndForwardedProps } from '../internals/utils/fields';
import { FieldSection, PickerValidDate } from '../models';
import { useDefaultizedDateTimeField } from '../internals/hooks/defaultizedFieldProps';
diff --git a/packages/x-date-pickers/src/DateTimePicker/DateTimePicker.tsx b/packages/x-date-pickers/src/DateTimePicker/DateTimePicker.tsx
index a8126e9c5474c..6008984bf9b9c 100644
--- a/packages/x-date-pickers/src/DateTimePicker/DateTimePicker.tsx
+++ b/packages/x-date-pickers/src/DateTimePicker/DateTimePicker.tsx
@@ -232,12 +232,12 @@ DateTimePicker.propTypes = {
onClose: PropTypes.func,
/**
* Callback fired when the error associated to the current value changes.
- * If the error has a non-null value, then the `TextField` will be rendered in `error` state.
- *
- * @template TValue The value type. Will be either the same type as `value` or `null`. Can be in `[start, end]` format in case of range value.
+ * When a validation error is detected, the `error` parameter contains a non-null value.
+ * This can be used to render an appropriate form error.
* @template TError The validation error type. Will be either `string` or a `null`. Can be in `[start, end]` format in case of range value.
- * @param {TError} error The new error describing why the current value is not valid.
- * @param {TValue} value The value associated to the error.
+ * @template TValue The value type. Will be either the same type as `value` or `null`. Can be in `[start, end]` format in case of range value.
+ * @param {TError} error The reason why the current value is not valid.
+ * @param {TValue} value The value associated to the error
*/
onError: PropTypes.func,
/**
diff --git a/packages/x-date-pickers/src/DesktopDatePicker/DesktopDatePicker.tsx b/packages/x-date-pickers/src/DesktopDatePicker/DesktopDatePicker.tsx
index 5e0c6e75ae8a4..df305d499291f 100644
--- a/packages/x-date-pickers/src/DesktopDatePicker/DesktopDatePicker.tsx
+++ b/packages/x-date-pickers/src/DesktopDatePicker/DesktopDatePicker.tsx
@@ -7,12 +7,11 @@ import { DesktopDatePickerProps } from './DesktopDatePicker.types';
import { DatePickerViewRenderers, useDatePickerDefaultizedProps } from '../DatePicker/shared';
import { usePickersTranslations } from '../hooks/usePickersTranslations';
import { useUtils } from '../internals/hooks/useUtils';
-import { validateDate } from '../internals/utils/validation/validateDate';
import { DateView, PickerValidDate } from '../models';
import { useDesktopPicker } from '../internals/hooks/useDesktopPicker';
import { CalendarIcon } from '../icons';
import { DateField } from '../DateField';
-import { extractValidationProps } from '../internals/utils/validation/extractValidationProps';
+import { extractValidationProps, validateDate } from '../validation';
import { renderDateViewCalendar } from '../dateViewRenderers';
import { resolveDateFormat } from '../internals/utils/date-utils';
@@ -239,12 +238,12 @@ DesktopDatePicker.propTypes = {
onClose: PropTypes.func,
/**
* Callback fired when the error associated to the current value changes.
- * If the error has a non-null value, then the `TextField` will be rendered in `error` state.
- *
- * @template TValue The value type. Will be either the same type as `value` or `null`. Can be in `[start, end]` format in case of range value.
+ * When a validation error is detected, the `error` parameter contains a non-null value.
+ * This can be used to render an appropriate form error.
* @template TError The validation error type. Will be either `string` or a `null`. Can be in `[start, end]` format in case of range value.
- * @param {TError} error The new error describing why the current value is not valid.
- * @param {TValue} value The value associated to the error.
+ * @template TValue The value type. Will be either the same type as `value` or `null`. Can be in `[start, end]` format in case of range value.
+ * @param {TError} error The reason why the current value is not valid.
+ * @param {TValue} value The value associated to the error
*/
onError: PropTypes.func,
/**
diff --git a/packages/x-date-pickers/src/DesktopDateTimePicker/DesktopDateTimePicker.tsx b/packages/x-date-pickers/src/DesktopDateTimePicker/DesktopDateTimePicker.tsx
index f728453aa5ae6..cdc5ab894cb57 100644
--- a/packages/x-date-pickers/src/DesktopDateTimePicker/DesktopDateTimePicker.tsx
+++ b/packages/x-date-pickers/src/DesktopDateTimePicker/DesktopDateTimePicker.tsx
@@ -13,11 +13,10 @@ import {
import { renderDateViewCalendar } from '../dateViewRenderers/dateViewRenderers';
import { usePickersTranslations } from '../hooks/usePickersTranslations';
import { useUtils } from '../internals/hooks/useUtils';
-import { validateDateTime } from '../internals/utils/validation/validateDateTime';
import { DateOrTimeViewWithMeridiem } from '../internals/models';
import { CalendarIcon } from '../icons';
import { UseDesktopPickerProps, useDesktopPicker } from '../internals/hooks/useDesktopPicker';
-import { extractValidationProps } from '../internals/utils/validation/extractValidationProps';
+import { extractValidationProps, validateDateTime } from '../validation';
import { PickerViewsRendererProps } from '../internals/hooks/usePicker';
import {
resolveDateTimeFormat,
@@ -413,12 +412,12 @@ DesktopDateTimePicker.propTypes = {
onClose: PropTypes.func,
/**
* Callback fired when the error associated to the current value changes.
- * If the error has a non-null value, then the `TextField` will be rendered in `error` state.
- *
- * @template TValue The value type. Will be either the same type as `value` or `null`. Can be in `[start, end]` format in case of range value.
+ * When a validation error is detected, the `error` parameter contains a non-null value.
+ * This can be used to render an appropriate form error.
* @template TError The validation error type. Will be either `string` or a `null`. Can be in `[start, end]` format in case of range value.
- * @param {TError} error The new error describing why the current value is not valid.
- * @param {TValue} value The value associated to the error.
+ * @template TValue The value type. Will be either the same type as `value` or `null`. Can be in `[start, end]` format in case of range value.
+ * @param {TError} error The reason why the current value is not valid.
+ * @param {TValue} value The value associated to the error
*/
onError: PropTypes.func,
/**
diff --git a/packages/x-date-pickers/src/DesktopTimePicker/DesktopTimePicker.tsx b/packages/x-date-pickers/src/DesktopTimePicker/DesktopTimePicker.tsx
index 31232c0cfb7e8..aecc9706b9df6 100644
--- a/packages/x-date-pickers/src/DesktopTimePicker/DesktopTimePicker.tsx
+++ b/packages/x-date-pickers/src/DesktopTimePicker/DesktopTimePicker.tsx
@@ -8,10 +8,9 @@ import { DesktopTimePickerProps } from './DesktopTimePicker.types';
import { TimePickerViewRenderers, useTimePickerDefaultizedProps } from '../TimePicker/shared';
import { usePickersTranslations } from '../hooks/usePickersTranslations';
import { useUtils } from '../internals/hooks/useUtils';
-import { validateTime } from '../internals/utils/validation/validateTime';
import { ClockIcon } from '../icons';
import { useDesktopPicker } from '../internals/hooks/useDesktopPicker';
-import { extractValidationProps } from '../internals/utils/validation/extractValidationProps';
+import { extractValidationProps, validateTime } from '../validation';
import {
renderDigitalClockTimeView,
renderMultiSectionDigitalClockTimeView,
@@ -265,12 +264,12 @@ DesktopTimePicker.propTypes = {
onClose: PropTypes.func,
/**
* Callback fired when the error associated to the current value changes.
- * If the error has a non-null value, then the `TextField` will be rendered in `error` state.
- *
- * @template TValue The value type. Will be either the same type as `value` or `null`. Can be in `[start, end]` format in case of range value.
+ * When a validation error is detected, the `error` parameter contains a non-null value.
+ * This can be used to render an appropriate form error.
* @template TError The validation error type. Will be either `string` or a `null`. Can be in `[start, end]` format in case of range value.
- * @param {TError} error The new error describing why the current value is not valid.
- * @param {TValue} value The value associated to the error.
+ * @template TValue The value type. Will be either the same type as `value` or `null`. Can be in `[start, end]` format in case of range value.
+ * @param {TError} error The reason why the current value is not valid.
+ * @param {TValue} value The value associated to the error
*/
onError: PropTypes.func,
/**
diff --git a/packages/x-date-pickers/src/MobileDatePicker/MobileDatePicker.tsx b/packages/x-date-pickers/src/MobileDatePicker/MobileDatePicker.tsx
index 5f33b9a15dcfd..bfe87f5b6f3cc 100644
--- a/packages/x-date-pickers/src/MobileDatePicker/MobileDatePicker.tsx
+++ b/packages/x-date-pickers/src/MobileDatePicker/MobileDatePicker.tsx
@@ -7,10 +7,9 @@ import { MobileDatePickerProps } from './MobileDatePicker.types';
import { DatePickerViewRenderers, useDatePickerDefaultizedProps } from '../DatePicker/shared';
import { usePickersTranslations } from '../hooks/usePickersTranslations';
import { useUtils } from '../internals/hooks/useUtils';
-import { validateDate } from '../internals/utils/validation/validateDate';
import { DateView, PickerValidDate } from '../models';
import { DateField } from '../DateField';
-import { extractValidationProps } from '../internals/utils/validation/extractValidationProps';
+import { extractValidationProps, validateDate } from '../validation';
import { singleItemValueManager } from '../internals/utils/valueManagers';
import { renderDateViewCalendar } from '../dateViewRenderers';
import { resolveDateFormat } from '../internals/utils/date-utils';
@@ -236,12 +235,12 @@ MobileDatePicker.propTypes = {
onClose: PropTypes.func,
/**
* Callback fired when the error associated to the current value changes.
- * If the error has a non-null value, then the `TextField` will be rendered in `error` state.
- *
- * @template TValue The value type. Will be either the same type as `value` or `null`. Can be in `[start, end]` format in case of range value.
+ * When a validation error is detected, the `error` parameter contains a non-null value.
+ * This can be used to render an appropriate form error.
* @template TError The validation error type. Will be either `string` or a `null`. Can be in `[start, end]` format in case of range value.
- * @param {TError} error The new error describing why the current value is not valid.
- * @param {TValue} value The value associated to the error.
+ * @template TValue The value type. Will be either the same type as `value` or `null`. Can be in `[start, end]` format in case of range value.
+ * @param {TError} error The reason why the current value is not valid.
+ * @param {TValue} value The value associated to the error
*/
onError: PropTypes.func,
/**
diff --git a/packages/x-date-pickers/src/MobileDateTimePicker/MobileDateTimePicker.tsx b/packages/x-date-pickers/src/MobileDateTimePicker/MobileDateTimePicker.tsx
index 50ab45e2b37f9..24ede5a090c77 100644
--- a/packages/x-date-pickers/src/MobileDateTimePicker/MobileDateTimePicker.tsx
+++ b/packages/x-date-pickers/src/MobileDateTimePicker/MobileDateTimePicker.tsx
@@ -11,10 +11,9 @@ import {
} from '../DateTimePicker/shared';
import { usePickersTranslations } from '../hooks/usePickersTranslations';
import { useUtils } from '../internals/hooks/useUtils';
-import { validateDateTime } from '../internals/utils/validation/validateDateTime';
import { DateOrTimeView, PickerValidDate } from '../models';
import { useMobilePicker } from '../internals/hooks/useMobilePicker';
-import { extractValidationProps } from '../internals/utils/validation/extractValidationProps';
+import { extractValidationProps, validateDateTime } from '../validation';
import { renderDateViewCalendar } from '../dateViewRenderers';
import { renderTimeViewClock } from '../timeViewRenderers';
import { resolveDateTimeFormat } from '../internals/utils/date-time-utils';
@@ -289,12 +288,12 @@ MobileDateTimePicker.propTypes = {
onClose: PropTypes.func,
/**
* Callback fired when the error associated to the current value changes.
- * If the error has a non-null value, then the `TextField` will be rendered in `error` state.
- *
- * @template TValue The value type. Will be either the same type as `value` or `null`. Can be in `[start, end]` format in case of range value.
+ * When a validation error is detected, the `error` parameter contains a non-null value.
+ * This can be used to render an appropriate form error.
* @template TError The validation error type. Will be either `string` or a `null`. Can be in `[start, end]` format in case of range value.
- * @param {TError} error The new error describing why the current value is not valid.
- * @param {TValue} value The value associated to the error.
+ * @template TValue The value type. Will be either the same type as `value` or `null`. Can be in `[start, end]` format in case of range value.
+ * @param {TError} error The reason why the current value is not valid.
+ * @param {TValue} value The value associated to the error
*/
onError: PropTypes.func,
/**
diff --git a/packages/x-date-pickers/src/MobileTimePicker/MobileTimePicker.tsx b/packages/x-date-pickers/src/MobileTimePicker/MobileTimePicker.tsx
index 021ec100c6809..d0c69b038c5b0 100644
--- a/packages/x-date-pickers/src/MobileTimePicker/MobileTimePicker.tsx
+++ b/packages/x-date-pickers/src/MobileTimePicker/MobileTimePicker.tsx
@@ -8,10 +8,9 @@ import { MobileTimePickerProps } from './MobileTimePicker.types';
import { TimePickerViewRenderers, useTimePickerDefaultizedProps } from '../TimePicker/shared';
import { usePickersTranslations } from '../hooks/usePickersTranslations';
import { useUtils } from '../internals/hooks/useUtils';
-import { validateTime } from '../internals/utils/validation/validateTime';
import { PickerValidDate, TimeView } from '../models';
import { useMobilePicker } from '../internals/hooks/useMobilePicker';
-import { extractValidationProps } from '../internals/utils/validation/extractValidationProps';
+import { extractValidationProps, validateTime } from '../validation';
import { renderTimeViewClock } from '../timeViewRenderers';
import { resolveTimeFormat } from '../internals/utils/time-utils';
@@ -228,12 +227,12 @@ MobileTimePicker.propTypes = {
onClose: PropTypes.func,
/**
* Callback fired when the error associated to the current value changes.
- * If the error has a non-null value, then the `TextField` will be rendered in `error` state.
- *
- * @template TValue The value type. Will be either the same type as `value` or `null`. Can be in `[start, end]` format in case of range value.
+ * When a validation error is detected, the `error` parameter contains a non-null value.
+ * This can be used to render an appropriate form error.
* @template TError The validation error type. Will be either `string` or a `null`. Can be in `[start, end]` format in case of range value.
- * @param {TError} error The new error describing why the current value is not valid.
- * @param {TValue} value The value associated to the error.
+ * @template TValue The value type. Will be either the same type as `value` or `null`. Can be in `[start, end]` format in case of range value.
+ * @param {TError} error The reason why the current value is not valid.
+ * @param {TValue} value The value associated to the error
*/
onError: PropTypes.func,
/**
diff --git a/packages/x-date-pickers/src/StaticDatePicker/StaticDatePicker.tsx b/packages/x-date-pickers/src/StaticDatePicker/StaticDatePicker.tsx
index 7482205b4b959..a17c01f09a799 100644
--- a/packages/x-date-pickers/src/StaticDatePicker/StaticDatePicker.tsx
+++ b/packages/x-date-pickers/src/StaticDatePicker/StaticDatePicker.tsx
@@ -4,7 +4,7 @@ import { StaticDatePickerProps } from './StaticDatePicker.types';
import { DatePickerViewRenderers, useDatePickerDefaultizedProps } from '../DatePicker/shared';
import { renderDateViewCalendar } from '../dateViewRenderers';
import { useStaticPicker } from '../internals/hooks/useStaticPicker';
-import { validateDate } from '../internals/utils/validation/validateDate';
+import { validateDate } from '../validation';
import { DateView, PickerValidDate } from '../models';
import { singleItemValueManager } from '../internals/utils/valueManagers';
@@ -175,12 +175,12 @@ StaticDatePicker.propTypes = {
onClose: PropTypes.func,
/**
* Callback fired when the error associated to the current value changes.
- * If the error has a non-null value, then the `TextField` will be rendered in `error` state.
- *
- * @template TValue The value type. Will be either the same type as `value` or `null`. Can be in `[start, end]` format in case of range value.
+ * When a validation error is detected, the `error` parameter contains a non-null value.
+ * This can be used to render an appropriate form error.
* @template TError The validation error type. Will be either `string` or a `null`. Can be in `[start, end]` format in case of range value.
- * @param {TError} error The new error describing why the current value is not valid.
- * @param {TValue} value The value associated to the error.
+ * @template TValue The value type. Will be either the same type as `value` or `null`. Can be in `[start, end]` format in case of range value.
+ * @param {TError} error The reason why the current value is not valid.
+ * @param {TValue} value The value associated to the error
*/
onError: PropTypes.func,
/**
diff --git a/packages/x-date-pickers/src/StaticDateTimePicker/StaticDateTimePicker.tsx b/packages/x-date-pickers/src/StaticDateTimePicker/StaticDateTimePicker.tsx
index 01dd868201d14..50cab5e658830 100644
--- a/packages/x-date-pickers/src/StaticDateTimePicker/StaticDateTimePicker.tsx
+++ b/packages/x-date-pickers/src/StaticDateTimePicker/StaticDateTimePicker.tsx
@@ -10,7 +10,7 @@ import { renderDateViewCalendar } from '../dateViewRenderers';
import { singleItemValueManager } from '../internals/utils/valueManagers';
import { useStaticPicker } from '../internals/hooks/useStaticPicker';
import { DateOrTimeView, PickerValidDate } from '../models';
-import { validateDateTime } from '../internals/utils/validation/validateDateTime';
+import { validateDateTime } from '../validation';
type StaticDateTimePickerComponent = ((
props: StaticDateTimePickerProps & React.RefAttributes,
@@ -227,12 +227,12 @@ StaticDateTimePicker.propTypes = {
onClose: PropTypes.func,
/**
* Callback fired when the error associated to the current value changes.
- * If the error has a non-null value, then the `TextField` will be rendered in `error` state.
- *
- * @template TValue The value type. Will be either the same type as `value` or `null`. Can be in `[start, end]` format in case of range value.
+ * When a validation error is detected, the `error` parameter contains a non-null value.
+ * This can be used to render an appropriate form error.
* @template TError The validation error type. Will be either `string` or a `null`. Can be in `[start, end]` format in case of range value.
- * @param {TError} error The new error describing why the current value is not valid.
- * @param {TValue} value The value associated to the error.
+ * @template TValue The value type. Will be either the same type as `value` or `null`. Can be in `[start, end]` format in case of range value.
+ * @param {TError} error The reason why the current value is not valid.
+ * @param {TValue} value The value associated to the error
*/
onError: PropTypes.func,
/**
diff --git a/packages/x-date-pickers/src/StaticTimePicker/StaticTimePicker.tsx b/packages/x-date-pickers/src/StaticTimePicker/StaticTimePicker.tsx
index b3b2b27047a03..14a4a493badd3 100644
--- a/packages/x-date-pickers/src/StaticTimePicker/StaticTimePicker.tsx
+++ b/packages/x-date-pickers/src/StaticTimePicker/StaticTimePicker.tsx
@@ -6,7 +6,7 @@ import { TimePickerViewRenderers, useTimePickerDefaultizedProps } from '../TimeP
import { renderTimeViewClock } from '../timeViewRenderers';
import { singleItemValueManager } from '../internals/utils/valueManagers';
import { useStaticPicker } from '../internals/hooks/useStaticPicker';
-import { validateTime } from '../internals/utils/validation/validateTime';
+import { validateTime } from '../validation';
type StaticTimePickerComponent = ((
props: StaticTimePickerProps & React.RefAttributes,
@@ -166,12 +166,12 @@ StaticTimePicker.propTypes = {
onClose: PropTypes.func,
/**
* Callback fired when the error associated to the current value changes.
- * If the error has a non-null value, then the `TextField` will be rendered in `error` state.
- *
- * @template TValue The value type. Will be either the same type as `value` or `null`. Can be in `[start, end]` format in case of range value.
+ * When a validation error is detected, the `error` parameter contains a non-null value.
+ * This can be used to render an appropriate form error.
* @template TError The validation error type. Will be either `string` or a `null`. Can be in `[start, end]` format in case of range value.
- * @param {TError} error The new error describing why the current value is not valid.
- * @param {TValue} value The value associated to the error.
+ * @template TValue The value type. Will be either the same type as `value` or `null`. Can be in `[start, end]` format in case of range value.
+ * @param {TError} error The reason why the current value is not valid.
+ * @param {TValue} value The value associated to the error
*/
onError: PropTypes.func,
/**
diff --git a/packages/x-date-pickers/src/TimeField/TimeField.tsx b/packages/x-date-pickers/src/TimeField/TimeField.tsx
index 10d4918133ed3..e11d67c90237a 100644
--- a/packages/x-date-pickers/src/TimeField/TimeField.tsx
+++ b/packages/x-date-pickers/src/TimeField/TimeField.tsx
@@ -237,10 +237,12 @@ TimeField.propTypes = {
onClear: PropTypes.func,
/**
* Callback fired when the error associated to the current value changes.
- * @template TValue The value type. Will be either the same type as `value` or `null`. Can be in `[start, end]` format in case of range value.
+ * When a validation error is detected, the `error` parameter contains a non-null value.
+ * This can be used to render an appropriate form error.
* @template TError The validation error type. Will be either `string` or a `null`. Can be in `[start, end]` format in case of range value.
- * @param {TError} error The new error.
- * @param {TValue} value The value associated to the error.
+ * @template TValue The value type. Will be either the same type as `value` or `null`. Can be in `[start, end]` format in case of range value.
+ * @param {TError} error The reason why the current value is not valid.
+ * @param {TValue} value The value associated to the error
*/
onError: PropTypes.func,
onFocus: PropTypes.func,
diff --git a/packages/x-date-pickers/src/TimeField/TimeField.types.ts b/packages/x-date-pickers/src/TimeField/TimeField.types.ts
index 478cf08ee9ee2..0ce1a53d6e40f 100644
--- a/packages/x-date-pickers/src/TimeField/TimeField.types.ts
+++ b/packages/x-date-pickers/src/TimeField/TimeField.types.ts
@@ -2,13 +2,14 @@ import * as React from 'react';
import { SlotComponentProps } from '@mui/utils';
import TextField from '@mui/material/TextField';
import { UseFieldInternalProps } from '../internals/hooks/useField';
-import { MakeOptional } from '../internals/models/helpers';
+import { DefaultizedProps, MakeOptional } from '../internals/models/helpers';
import { BaseTimeValidationProps, TimeValidationProps } from '../internals/models/validation';
import {
FieldSection,
PickerValidDate,
TimeValidationError,
BuiltInFieldTextFieldProps,
+ BaseSingleInputFieldProps,
} from '../models';
import {
ExportedUseClearableFieldProps,
@@ -39,6 +40,19 @@ export interface UseTimeFieldProps<
ampm?: boolean;
}
+/**
+ * Props the field can receive when used inside a time picker.
+ * (`TimePicker`, `DesktopTimePicker` or `MobileTimePicker` component).
+ */
+export type TimeFieldInPickerProps<
+ TDate extends PickerValidDate,
+ TEnableAccessibleFieldDOMStructure extends boolean,
+> = DefaultizedProps<
+ UseTimeFieldProps,
+ 'format' | 'timezone' | 'ampm' | keyof BaseTimeValidationProps
+> &
+ BaseSingleInputFieldProps;
+
export type UseTimeFieldComponentProps<
TDate extends PickerValidDate,
TEnableAccessibleFieldDOMStructure extends boolean,
diff --git a/packages/x-date-pickers/src/TimeField/index.ts b/packages/x-date-pickers/src/TimeField/index.ts
index f335f0f8fd769..cf9c1e6a58813 100644
--- a/packages/x-date-pickers/src/TimeField/index.ts
+++ b/packages/x-date-pickers/src/TimeField/index.ts
@@ -4,4 +4,5 @@ export type {
UseTimeFieldProps,
UseTimeFieldComponentProps,
TimeFieldProps,
+ TimeFieldInPickerProps,
} from './TimeField.types';
diff --git a/packages/x-date-pickers/src/TimeField/useTimeField.ts b/packages/x-date-pickers/src/TimeField/useTimeField.ts
index bd81134e599f9..691ce2b5741f6 100644
--- a/packages/x-date-pickers/src/TimeField/useTimeField.ts
+++ b/packages/x-date-pickers/src/TimeField/useTimeField.ts
@@ -4,7 +4,7 @@ import {
} from '../internals/utils/valueManagers';
import { useField } from '../internals/hooks/useField';
import { UseTimeFieldProps } from './TimeField.types';
-import { validateTime } from '../internals/utils/validation/validateTime';
+import { validateTime } from '../validation';
import { splitFieldInternalAndForwardedProps } from '../internals/utils/fields';
import { PickerValidDate, FieldSection } from '../models';
import { useDefaultizedTimeField } from '../internals/hooks/defaultizedFieldProps';
diff --git a/packages/x-date-pickers/src/TimePicker/TimePicker.tsx b/packages/x-date-pickers/src/TimePicker/TimePicker.tsx
index 2883b0d1d45bc..ffdf2a0602577 100644
--- a/packages/x-date-pickers/src/TimePicker/TimePicker.tsx
+++ b/packages/x-date-pickers/src/TimePicker/TimePicker.tsx
@@ -182,12 +182,12 @@ TimePicker.propTypes = {
onClose: PropTypes.func,
/**
* Callback fired when the error associated to the current value changes.
- * If the error has a non-null value, then the `TextField` will be rendered in `error` state.
- *
- * @template TValue The value type. Will be either the same type as `value` or `null`. Can be in `[start, end]` format in case of range value.
+ * When a validation error is detected, the `error` parameter contains a non-null value.
+ * This can be used to render an appropriate form error.
* @template TError The validation error type. Will be either `string` or a `null`. Can be in `[start, end]` format in case of range value.
- * @param {TError} error The new error describing why the current value is not valid.
- * @param {TValue} value The value associated to the error.
+ * @template TValue The value type. Will be either the same type as `value` or `null`. Can be in `[start, end]` format in case of range value.
+ * @param {TError} error The reason why the current value is not valid.
+ * @param {TValue} value The value associated to the error
*/
onError: PropTypes.func,
/**
diff --git a/packages/x-date-pickers/src/index.ts b/packages/x-date-pickers/src/index.ts
index cd2e4e9586e5b..f0987002adb1a 100644
--- a/packages/x-date-pickers/src/index.ts
+++ b/packages/x-date-pickers/src/index.ts
@@ -53,7 +53,6 @@ export * from './PickersSectionList';
export { DEFAULT_DESKTOP_MODE_MEDIA_QUERY } from './internals/utils/utils';
export * from './models';
-
export * from './icons';
-
export * from './hooks';
+export * from './validation';
diff --git a/packages/x-date-pickers/src/internals/hooks/useDesktopPicker/useDesktopPicker.tsx b/packages/x-date-pickers/src/internals/hooks/useDesktopPicker/useDesktopPicker.tsx
index 56e943302f79f..0e9097ef1eaeb 100644
--- a/packages/x-date-pickers/src/internals/hooks/useDesktopPicker/useDesktopPicker.tsx
+++ b/packages/x-date-pickers/src/internals/hooks/useDesktopPicker/useDesktopPicker.tsx
@@ -14,12 +14,12 @@ import { useUtils } from '../useUtils';
import { usePicker } from '../usePicker';
import { LocalizationProvider } from '../../../LocalizationProvider';
import { PickersLayout } from '../../../PickersLayout';
-import { InferError } from '../useValidation';
import {
FieldSection,
PickerValidDate,
FieldRef,
BaseSingleInputFieldProps,
+ InferError,
} from '../../../models';
import { DateOrTimeViewWithMeridiem } from '../../models';
diff --git a/packages/x-date-pickers/src/internals/hooks/useField/useField.ts b/packages/x-date-pickers/src/internals/hooks/useField/useField.ts
index 1d8bc5fdcffb3..2ad8363212a92 100644
--- a/packages/x-date-pickers/src/internals/hooks/useField/useField.ts
+++ b/packages/x-date-pickers/src/internals/hooks/useField/useField.ts
@@ -2,7 +2,7 @@ import * as React from 'react';
import useEnhancedEffect from '@mui/utils/useEnhancedEffect';
import useEventCallback from '@mui/utils/useEventCallback';
import { useRtl } from '@mui/system/RtlProvider';
-import { useValidation } from '../useValidation';
+import { useValidation } from '../../../validation';
import { useUtils } from '../useUtils';
import {
UseFieldParams,
@@ -226,12 +226,13 @@ export const useField = <
interactions.syncSelectionToDOM();
});
- const validationError = useValidation(
- { ...internalProps, value: state.value, timezone },
+ const { hasValidationError } = useValidation({
+ props: internalProps,
validator,
- valueManager.isSameError,
- valueManager.defaultErrorState,
- );
+ timezone,
+ value: state.value,
+ onError: internalProps.onError,
+ });
const inputError = React.useMemo(() => {
// only override when `error` is undefined.
@@ -240,8 +241,8 @@ export const useField = <
return error;
}
- return valueManager.hasError(validationError);
- }, [valueManager, validationError, error]);
+ return hasValidationError;
+ }, [hasValidationError, error]);
React.useEffect(() => {
if (!inputError && activeSectionIndex == null) {
diff --git a/packages/x-date-pickers/src/internals/hooks/useField/useField.types.ts b/packages/x-date-pickers/src/internals/hooks/useField/useField.types.ts
index df0915e71b7f1..2d4d0c292e12a 100644
--- a/packages/x-date-pickers/src/internals/hooks/useField/useField.types.ts
+++ b/packages/x-date-pickers/src/internals/hooks/useField/useField.types.ts
@@ -7,12 +7,13 @@ import {
TimezoneProps,
FieldSectionContentType,
FieldValueType,
- PickersTimezone,
PickerValidDate,
FieldRef,
+ OnErrorProps,
+ InferError,
} from '../../../models';
import type { PickerValueManager } from '../usePicker';
-import { InferError, Validator } from '../useValidation';
+import type { Validator } from '../../../validation';
import type { UseFieldStateResponse } from './useFieldState';
import type { UseFieldCharacterEditingResponse } from './useFieldCharacterEditing';
import { PickersSectionElement, PickersSectionListRef } from '../../../PickersSectionList';
@@ -37,12 +38,7 @@ export interface UseFieldParams<
internalProps: TInternalProps;
valueManager: PickerValueManager>;
fieldValueManager: FieldValueManager;
- validator: Validator<
- TValue,
- TDate,
- InferError,
- UseFieldValidationProps
- >;
+ validator: Validator, TInternalProps>;
valueType: FieldValueType;
}
@@ -52,7 +48,8 @@ export interface UseFieldInternalProps<
TSection extends FieldSection,
TEnableAccessibleFieldDOMStructure extends boolean,
TError,
-> extends TimezoneProps {
+> extends TimezoneProps,
+ OnErrorProps {
/**
* The selected value.
* Used when the component is controlled.
@@ -76,14 +73,6 @@ export interface UseFieldInternalProps<
* @param {FieldChangeHandlerContext} context The context containing the validation result of the current value.
*/
onChange?: FieldChangeHandler;
- /**
- * Callback fired when the error associated to the current value changes.
- * @template TValue The value type. Will be either the same type as `value` or `null`. Can be in `[start, end]` format in case of range value.
- * @template TError The validation error type. Will be either `string` or a `null`. Can be in `[start, end]` format in case of range value.
- * @param {TError} error The new error.
- * @param {TValue} value The value associated to the error.
- */
- onError?: (error: TError, value: TValue) => void;
/**
* Format of the date when rendered in the input(s).
*/
@@ -396,14 +385,6 @@ export interface UseFieldState {
tempValueStrAndroid: string | null;
}
-export type UseFieldValidationProps<
- TValue,
- TInternalProps extends { value?: TValue; defaultValue?: TValue; timezone?: PickersTimezone },
-> = Omit & {
- value: TValue;
- timezone: PickersTimezone;
-};
-
export type AvailableAdjustKeyCode =
| 'ArrowUp'
| 'ArrowDown'
diff --git a/packages/x-date-pickers/src/internals/hooks/useField/useFieldState.ts b/packages/x-date-pickers/src/internals/hooks/useField/useFieldState.ts
index 23e6bbc669000..846ab4be676da 100644
--- a/packages/x-date-pickers/src/internals/hooks/useField/useFieldState.ts
+++ b/packages/x-date-pickers/src/internals/hooks/useField/useFieldState.ts
@@ -21,12 +21,12 @@ import {
getLocalizedDigits,
} from './useField.utils';
import { buildSectionsFromFormat } from './buildSectionsFromFormat';
-import { InferError } from '../useValidation';
import {
FieldSection,
FieldSelectedSections,
PickersTimezone,
PickerValidDate,
+ InferError,
} from '../../../models';
import { useValueWithTimezone } from '../useValueWithTimezone';
import {
@@ -228,7 +228,8 @@ export const useFieldState = <
validationError: validator({
adapter,
value,
- props: { ...internalProps, value, timezone },
+ timezone,
+ props: internalProps,
}),
};
diff --git a/packages/x-date-pickers/src/internals/hooks/useMobilePicker/useMobilePicker.tsx b/packages/x-date-pickers/src/internals/hooks/useMobilePicker/useMobilePicker.tsx
index b98cf417300b3..69f3f1d2644fb 100644
--- a/packages/x-date-pickers/src/internals/hooks/useMobilePicker/useMobilePicker.tsx
+++ b/packages/x-date-pickers/src/internals/hooks/useMobilePicker/useMobilePicker.tsx
@@ -13,12 +13,12 @@ import { onSpaceOrEnter } from '../../utils/utils';
import { useUtils } from '../useUtils';
import { LocalizationProvider } from '../../../LocalizationProvider';
import { PickersLayout } from '../../../PickersLayout';
-import { InferError } from '../useValidation';
import {
FieldSection,
BaseSingleInputFieldProps,
PickerValidDate,
FieldRef,
+ InferError,
} from '../../../models';
import { DateOrTimeViewWithMeridiem } from '../../models';
diff --git a/packages/x-date-pickers/src/internals/hooks/usePicker/usePicker.ts b/packages/x-date-pickers/src/internals/hooks/usePicker/usePicker.ts
index b150b8fe3dee3..cb5b46ae746de 100644
--- a/packages/x-date-pickers/src/internals/hooks/usePicker/usePicker.ts
+++ b/packages/x-date-pickers/src/internals/hooks/usePicker/usePicker.ts
@@ -2,9 +2,8 @@ import { UsePickerParams, UsePickerProps, UsePickerResponse } from './usePicker.
import { usePickerValue } from './usePickerValue';
import { usePickerViews } from './usePickerViews';
import { usePickerLayoutProps } from './usePickerLayoutProps';
-import { InferError } from '../useValidation';
import { warnOnce } from '../../utils/warning';
-import { FieldSection, PickerValidDate } from '../../../models';
+import { FieldSection, PickerValidDate, InferError } from '../../../models';
import { DateOrTimeViewWithMeridiem } from '../../models';
export const usePicker = <
diff --git a/packages/x-date-pickers/src/internals/hooks/usePicker/usePickerValue.ts b/packages/x-date-pickers/src/internals/hooks/usePicker/usePickerValue.ts
index 3bd7a5eb08a23..8d6255b5f5627 100644
--- a/packages/x-date-pickers/src/internals/hooks/usePicker/usePickerValue.ts
+++ b/packages/x-date-pickers/src/internals/hooks/usePicker/usePickerValue.ts
@@ -3,8 +3,13 @@ import useEventCallback from '@mui/utils/useEventCallback';
import { useOpenState } from '../useOpenState';
import { useLocalizationContext, useUtils } from '../useUtils';
import { FieldChangeHandlerContext } from '../useField';
-import { InferError, useValidation } from '../useValidation';
-import { FieldSection, PickerChangeHandlerContext, PickerValidDate } from '../../../models';
+import { useValidation } from '../../../validation';
+import {
+ FieldSection,
+ PickerChangeHandlerContext,
+ PickerValidDate,
+ InferError,
+} from '../../../models';
import {
PickerShortcutChangeImportance,
PickersShortcutsItemContext,
@@ -241,12 +246,13 @@ export const usePickerValue = <
};
});
- useValidation(
- { ...props, value: dateState.draft, timezone },
+ const { getValidationErrorForNewValue } = useValidation({
+ props,
validator,
- valueManager.isSameError,
- valueManager.defaultErrorState,
- );
+ timezone,
+ value: dateState.draft,
+ onError: props.onError,
+ });
const updateDate = useEventCallback((action: PickerValueUpdateAction) => {
const updaterParams: PickerValueUpdaterParams = {
@@ -275,11 +281,7 @@ export const usePickerValue = <
const validationError =
action.name === 'setValueFromField'
? action.context.validationError
- : validator({
- adapter,
- value: action.value,
- props: { ...props, value: action.value, timezone },
- });
+ : getValidationErrorForNewValue(action.value);
cachedContext = {
validationError,
@@ -440,7 +442,8 @@ export const usePickerValue = <
const error = validator({
adapter,
value: testedValue,
- props: { ...props, value: testedValue, timezone },
+ timezone,
+ props,
});
return !valueManager.hasError(error);
diff --git a/packages/x-date-pickers/src/internals/hooks/usePicker/usePickerValue.types.ts b/packages/x-date-pickers/src/internals/hooks/usePicker/usePickerValue.types.ts
index 9372640881c4e..94c43c8c3c1b6 100644
--- a/packages/x-date-pickers/src/internals/hooks/usePicker/usePickerValue.types.ts
+++ b/packages/x-date-pickers/src/internals/hooks/usePicker/usePickerValue.types.ts
@@ -1,6 +1,5 @@
import { FieldChangeHandlerContext, UseFieldInternalProps } from '../useField';
-import { InferError, Validator } from '../useValidation';
-import { UseFieldValidationProps } from '../useField/useField.types';
+import { Validator } from '../../../validation';
import { WrapperVariant } from '../../models/common';
import {
FieldSection,
@@ -10,6 +9,8 @@ import {
PickersTimezone,
PickerChangeHandlerContext,
PickerValidDate,
+ OnErrorProps,
+ InferError,
} from '../../../models';
import { GetDefaultReferenceDateProps } from '../../utils/getDefaultReferenceDate';
import {
@@ -207,7 +208,7 @@ export type PickerValueUpdateAction =
/**
* Props used to handle the value that are common to all pickers.
*/
-export interface UsePickerValueBaseProps {
+export interface UsePickerValueBaseProps extends OnErrorProps {
/**
* The selected value.
* Used when the component is controlled.
@@ -234,16 +235,6 @@ export interface UsePickerValueBaseProps {
* @param {FieldChangeHandlerContext} context The context containing the validation result of the current value.
*/
onAccept?: (value: TValue, context: PickerChangeHandlerContext) => void;
- /**
- * Callback fired when the error associated to the current value changes.
- * If the error has a non-null value, then the `TextField` will be rendered in `error` state.
- *
- * @template TValue The value type. Will be either the same type as `value` or `null`. Can be in `[start, end]` format in case of range value.
- * @template TError The validation error type. Will be either `string` or a `null`. Can be in `[start, end]` format in case of range value.
- * @param {TError} error The new error describing why the current value is not valid.
- * @param {TValue} value The value associated to the error.
- */
- onError?: (error: TError, value: TValue) => void;
}
/**
@@ -289,12 +280,7 @@ export interface UsePickerValueParams<
valueManager: PickerValueManager>;
valueType: FieldValueType;
wrapperVariant: WrapperVariant;
- validator: Validator<
- TValue,
- TDate,
- InferError,
- UseFieldValidationProps
- >;
+ validator: Validator, TExternalProps>;
}
export interface UsePickerValueActions {
diff --git a/packages/x-date-pickers/src/internals/hooks/useValidation.ts b/packages/x-date-pickers/src/internals/hooks/useValidation.ts
deleted file mode 100644
index 406dcf61d0db8..0000000000000
--- a/packages/x-date-pickers/src/internals/hooks/useValidation.ts
+++ /dev/null
@@ -1,63 +0,0 @@
-import * as React from 'react';
-import { useLocalizationContext } from './useUtils';
-import { MuiPickersAdapterContextValue } from '../../LocalizationProvider/LocalizationProvider';
-import { PickerValidDate } from '../../models';
-
-interface ValidationCommonProps {
- /**
- * Callback that fired when input value or new `value` prop validation returns **new** validation error (or value is valid after error).
- * In case of validation error detected `reason` prop return non-null value and `TextField` must be displayed in `error` state.
- * This can be used to render appropriate form error.
- * @template TError The validation error type. Will be either `string` or a `null`. Can be in `[start, end]` format in case of range value.
- * @template TValue The value type. Will be either the same type as `value` or `null`. Can be in `[start, end]` format in case of range value.
- * @param {TError} reason The reason why the current value is not valid.
- * @param {TValue} value The invalid value.
- */
- onError?: (reason: TError, value: TValue) => void;
- value: TValue;
-}
-
-export type ValidationProps = ValidationCommonProps<
- TError,
- TValue
-> &
- TValidationProps;
-
-export type InferError =
- TProps extends Pick, 'onError'>
- ? Parameters>[0]
- : never;
-
-export type Validator = (params: {
- adapter: MuiPickersAdapterContextValue;
- value: TValue;
- props: Omit;
-}) => TError;
-
-export function useValidation<
- TValue,
- TDate extends PickerValidDate,
- TError,
- TValidationProps extends {},
->(
- props: ValidationProps,
- validate: Validator,
- isSameError: (a: TError, b: TError | null) => boolean,
- defaultErrorState: TError,
-): TError {
- const { value, onError } = props;
- const adapter = useLocalizationContext();
- const previousValidationErrorRef = React.useRef(defaultErrorState);
-
- const validationError = validate({ adapter, value, props });
-
- React.useEffect(() => {
- if (onError && !isSameError(validationError, previousValidationErrorRef.current)) {
- onError(validationError, value);
- }
-
- previousValidationErrorRef.current = validationError;
- }, [isSameError, onError, previousValidationErrorRef, validationError, value]);
-
- return validationError;
-}
diff --git a/packages/x-date-pickers/src/internals/index.ts b/packages/x-date-pickers/src/internals/index.ts
index bf9c07dd4c1fe..af32e690905cf 100644
--- a/packages/x-date-pickers/src/internals/index.ts
+++ b/packages/x-date-pickers/src/internals/index.ts
@@ -92,8 +92,6 @@ export type {
export { useLocalizationContext, useDefaultDates, useUtils, useNow } from './hooks/useUtils';
export type { ExportedUseViewsOptions, UseViewsOptions } from './hooks/useViews';
export { useViews } from './hooks/useViews';
-export { useValidation } from './hooks/useValidation';
-export type { ValidationProps, Validator, InferError } from './hooks/useValidation';
export { usePreviousMonthDisabled, useNextMonthDisabled } from './hooks/date-helpers-hooks';
export type { BaseFieldProps } from './models/fields';
@@ -146,10 +144,6 @@ export {
useDefaultizedDateTimeField,
} from './hooks/defaultizedFieldProps';
export { useDefaultReduceAnimations } from './hooks/useDefaultReduceAnimations';
-export { extractValidationProps } from './utils/validation/extractValidationProps';
-export { validateDate } from './utils/validation/validateDate';
-export { validateDateTime } from './utils/validation/validateDateTime';
-export { validateTime } from './utils/validation/validateTime';
export { applyDefaultViewProps } from './utils/views';
export { warnOnce } from './utils/warning';
diff --git a/packages/x-date-pickers/src/internals/utils/fields.ts b/packages/x-date-pickers/src/internals/utils/fields.ts
index ef5e19e58f089..93ed036d8548c 100644
--- a/packages/x-date-pickers/src/internals/utils/fields.ts
+++ b/packages/x-date-pickers/src/internals/utils/fields.ts
@@ -3,7 +3,7 @@ import {
DATE_TIME_VALIDATION_PROP_NAMES,
DATE_VALIDATION_PROP_NAMES,
TIME_VALIDATION_PROP_NAMES,
-} from './validation/extractValidationProps';
+} from '../../validation/extractValidationProps';
const SHARED_FIELD_INTERNAL_PROP_NAMES = [
'value',
diff --git a/packages/x-date-pickers/src/internals/utils/validation/validateDateTime.ts b/packages/x-date-pickers/src/internals/utils/validation/validateDateTime.ts
deleted file mode 100644
index ff14f93ac1eb4..0000000000000
--- a/packages/x-date-pickers/src/internals/utils/validation/validateDateTime.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-import { Validator } from '../../hooks/useValidation';
-import { validateDate, DateComponentValidationProps } from './validateDate';
-import { validateTime, TimeComponentValidationProps } from './validateTime';
-import { DateTimeValidationError, PickerValidDate } from '../../../models';
-
-export interface DateTimeComponentValidationProps
- extends DateComponentValidationProps,
- TimeComponentValidationProps {}
-
-export const validateDateTime: Validator<
- any | null,
- any,
- DateTimeValidationError,
- DateTimeComponentValidationProps
-> = ({ props, value, adapter }) => {
- const dateValidationResult = validateDate({
- adapter,
- value,
- props,
- });
-
- if (dateValidationResult !== null) {
- return dateValidationResult;
- }
-
- return validateTime({
- adapter,
- value,
- props,
- });
-};
diff --git a/packages/x-date-pickers/src/models/validation.ts b/packages/x-date-pickers/src/models/validation.ts
index 397ea4334d03a..6d25a672e0f63 100644
--- a/packages/x-date-pickers/src/models/validation.ts
+++ b/packages/x-date-pickers/src/models/validation.ts
@@ -21,3 +21,21 @@ export type TimeValidationError =
| 'shouldDisableTime-seconds';
export type DateTimeValidationError = DateValidationError | TimeValidationError;
+
+export interface OnErrorProps {
+ /**
+ * Callback fired when the error associated to the current value changes.
+ * When a validation error is detected, the `error` parameter contains a non-null value.
+ * This can be used to render an appropriate form error.
+ * @template TError The validation error type. Will be either `string` or a `null`. Can be in `[start, end]` format in case of range value.
+ * @template TValue The value type. Will be either the same type as `value` or `null`. Can be in `[start, end]` format in case of range value.
+ * @param {TError} error The reason why the current value is not valid.
+ * @param {TValue} value The value associated to the error
+ */
+ onError?: (error: TError, value: TValue) => void;
+}
+
+export type InferError =
+ TProps extends Pick, 'onError'>
+ ? Parameters>[0]
+ : never;
diff --git a/packages/x-date-pickers/src/internals/utils/validation/extractValidationProps.ts b/packages/x-date-pickers/src/validation/extractValidationProps.ts
similarity index 97%
rename from packages/x-date-pickers/src/internals/utils/validation/extractValidationProps.ts
rename to packages/x-date-pickers/src/validation/extractValidationProps.ts
index a2d90cde15101..3b2bd180137e2 100644
--- a/packages/x-date-pickers/src/internals/utils/validation/extractValidationProps.ts
+++ b/packages/x-date-pickers/src/validation/extractValidationProps.ts
@@ -6,7 +6,7 @@ import {
MonthValidationProps,
TimeValidationProps,
YearValidationProps,
-} from '../../models/validation';
+} from '../internals/models/validation';
export const DATE_VALIDATION_PROP_NAMES: (
| keyof BaseDateValidationProps
diff --git a/packages/x-date-pickers/src/validation/index.ts b/packages/x-date-pickers/src/validation/index.ts
new file mode 100644
index 0000000000000..b3f964c143f8c
--- /dev/null
+++ b/packages/x-date-pickers/src/validation/index.ts
@@ -0,0 +1,13 @@
+export { validateDate } from './validateDate';
+export type { ValidateDateProps } from './validateDate';
+
+export { validateTime } from './validateTime';
+export type { ValidateTimeProps } from './validateTime';
+
+export { validateDateTime } from './validateDateTime';
+export type { ValidateDateTimeProps } from './validateDateTime';
+
+export { extractValidationProps } from './extractValidationProps';
+
+export { useValidation } from './useValidation';
+export type { Validator } from './useValidation';
diff --git a/packages/x-date-pickers/src/validation/useValidation.ts b/packages/x-date-pickers/src/validation/useValidation.ts
new file mode 100644
index 0000000000000..284e36d4860d3
--- /dev/null
+++ b/packages/x-date-pickers/src/validation/useValidation.ts
@@ -0,0 +1,99 @@
+import * as React from 'react';
+import useEventCallback from '@mui/utils/useEventCallback';
+import { useLocalizationContext } from '../internals/hooks/useUtils';
+import { MuiPickersAdapterContextValue } from '../LocalizationProvider/LocalizationProvider';
+import { OnErrorProps, PickersTimezone, PickerValidDate } from '../models';
+import type { PickerValueManager } from '../internals/hooks/usePicker';
+
+export type Validator = {
+ (params: {
+ adapter: MuiPickersAdapterContextValue;
+ value: TValue;
+ timezone: PickersTimezone;
+ props: TValidationProps;
+ }): TError;
+ valueManager: PickerValueManager;
+};
+
+interface UseValidationOptions<
+ TValue,
+ TDate extends PickerValidDate,
+ TError,
+ TValidationProps extends {},
+> extends OnErrorProps {
+ /**
+ * The value to validate.
+ */
+ value: TValue;
+ /**
+ * The timezone to use for the validation.
+ */
+ timezone: PickersTimezone;
+ /**
+ * The validator function to use.
+ * They can be imported from `@mui/x-date-pickers/validation` and `@mui/x-date-pickers-pro/validation`.
+ */
+ validator: Validator;
+ /**
+ * The validation props, they differ depending on the component.
+ * For example, the `validateTime` function supports `minTime`, `maxTime`, etc.
+ */
+ props: TValidationProps;
+}
+
+interface UseValidationReturnValue {
+ /**
+ * The validation error associated to the value passed to the `useValidation` hook.
+ */
+ validationError: TError;
+ /**
+ * `true` if the current error is not null.
+ * For single value components, it means that the value is invalid.
+ * For range components, it means that either start or end value is invalid.
+ */
+ hasValidationError: boolean;
+ /**
+ * Get the validation error for a new value.
+ * This can be used to validate the value in a change handler before updating the state.
+ * @template TValue The value type.
+ * @param {TValue} newValue The value to validate.
+ * @returns {TError} The validation error associated to the new value.
+ */
+ getValidationErrorForNewValue: (newValue: TValue) => TError;
+}
+
+export function useValidation<
+ TValue,
+ TDate extends PickerValidDate,
+ TError,
+ TValidationProps extends {},
+>(
+ options: UseValidationOptions,
+): UseValidationReturnValue {
+ const { props, validator, value, timezone, onError } = options;
+
+ const adapter = useLocalizationContext();
+ const previousValidationErrorRef = React.useRef(
+ validator.valueManager.defaultErrorState,
+ );
+
+ const validationError = validator({ adapter, value, timezone, props });
+ const hasValidationError = validator.valueManager.hasError(validationError);
+
+ React.useEffect(() => {
+ if (
+ onError &&
+ !validator.valueManager.isSameError(validationError, previousValidationErrorRef.current)
+ ) {
+ onError(validationError, value);
+ }
+
+ previousValidationErrorRef.current = validationError;
+ }, [validator, onError, validationError, value]);
+
+ const getValidationErrorForNewValue = useEventCallback((newValue: TValue) => {
+ return validator({ adapter, value: newValue, timezone, props });
+ });
+
+ return { validationError, hasValidationError, getValidationErrorForNewValue };
+}
diff --git a/packages/x-date-pickers/src/internals/utils/validation/validateDate.ts b/packages/x-date-pickers/src/validation/validateDate.ts
similarity index 67%
rename from packages/x-date-pickers/src/internals/utils/validation/validateDate.ts
rename to packages/x-date-pickers/src/validation/validateDate.ts
index 363b13a96f70c..e3bf707969aae 100644
--- a/packages/x-date-pickers/src/internals/utils/validation/validateDate.ts
+++ b/packages/x-date-pickers/src/validation/validateDate.ts
@@ -1,39 +1,32 @@
-import { Validator } from '../../hooks/useValidation';
+import { Validator } from './useValidation';
import {
BaseDateValidationProps,
DayValidationProps,
MonthValidationProps,
YearValidationProps,
-} from '../../models/validation';
-import { DateValidationError, PickerValidDate, TimezoneProps } from '../../../models';
-import { applyDefaultDate } from '../date-utils';
-import { DefaultizedProps } from '../../models/helpers';
+} from '../internals/models/validation';
+import { DateValidationError, PickerValidDate } from '../models';
+import { applyDefaultDate } from '../internals/utils/date-utils';
+import { singleItemValueManager } from '../internals/utils/valueManagers';
-export interface DateComponentValidationProps
+export interface ValidateDateProps
extends DayValidationProps,
MonthValidationProps,
YearValidationProps,
- Required>,
- DefaultizedProps {}
+ Required> {}
export const validateDate: Validator<
any | null,
any,
DateValidationError,
- DateComponentValidationProps
-> = ({ props, value, adapter }): DateValidationError => {
+ ValidateDateProps
+> = ({ props, value, timezone, adapter }): DateValidationError => {
if (value === null) {
return null;
}
- const {
- shouldDisableDate,
- shouldDisableMonth,
- shouldDisableYear,
- disablePast,
- disableFuture,
- timezone,
- } = props;
+ const { shouldDisableDate, shouldDisableMonth, shouldDisableYear, disablePast, disableFuture } =
+ props;
const now = adapter.utils.date(undefined, timezone);
const minDate = applyDefaultDate(adapter.utils, props.minDate, adapter.defaultDates.minDate);
@@ -68,3 +61,5 @@ export const validateDate: Validator<
return null;
}
};
+
+validateDate.valueManager = singleItemValueManager;
diff --git a/packages/x-date-pickers/src/validation/validateDateTime.ts b/packages/x-date-pickers/src/validation/validateDateTime.ts
new file mode 100644
index 0000000000000..1e48246355326
--- /dev/null
+++ b/packages/x-date-pickers/src/validation/validateDateTime.ts
@@ -0,0 +1,36 @@
+import { Validator } from './useValidation';
+import { validateDate, ValidateDateProps } from './validateDate';
+import { validateTime, ValidateTimeProps } from './validateTime';
+import { DateTimeValidationError, PickerValidDate } from '../models';
+import { singleItemValueManager } from '../internals/utils/valueManagers';
+
+export interface ValidateDateTimeProps
+ extends ValidateDateProps,
+ ValidateTimeProps {}
+
+export const validateDateTime: Validator<
+ any | null,
+ any,
+ DateTimeValidationError,
+ ValidateDateTimeProps
+> = ({ adapter, value, timezone, props }) => {
+ const dateValidationResult = validateDate({
+ adapter,
+ value,
+ timezone,
+ props,
+ });
+
+ if (dateValidationResult !== null) {
+ return dateValidationResult;
+ }
+
+ return validateTime({
+ adapter,
+ value,
+ timezone,
+ props,
+ });
+};
+
+validateDateTime.valueManager = singleItemValueManager;
diff --git a/packages/x-date-pickers/src/internals/utils/validation/validateTime.ts b/packages/x-date-pickers/src/validation/validateTime.ts
similarity index 73%
rename from packages/x-date-pickers/src/internals/utils/validation/validateTime.ts
rename to packages/x-date-pickers/src/validation/validateTime.ts
index c3d109e7ec0f9..2124913a3c14d 100644
--- a/packages/x-date-pickers/src/internals/utils/validation/validateTime.ts
+++ b/packages/x-date-pickers/src/validation/validateTime.ts
@@ -1,20 +1,19 @@
-import { createIsAfterIgnoreDatePart } from '../time-utils';
-import { Validator } from '../../hooks/useValidation';
-import { BaseTimeValidationProps, TimeValidationProps } from '../../models/validation';
-import { PickerValidDate, TimeValidationError, TimezoneProps } from '../../../models';
-import { DefaultizedProps } from '../../models/helpers';
+import { createIsAfterIgnoreDatePart } from '../internals/utils/time-utils';
+import { Validator } from './useValidation';
+import { BaseTimeValidationProps, TimeValidationProps } from '../internals/models/validation';
+import { PickerValidDate, TimeValidationError } from '../models';
+import { singleItemValueManager } from '../internals/utils/valueManagers';
-export interface TimeComponentValidationProps
+export interface ValidateTimeProps
extends Required,
- TimeValidationProps,
- DefaultizedProps {}
+ TimeValidationProps {}
export const validateTime: Validator<
any | null,
any,
TimeValidationError,
- TimeComponentValidationProps
-> = ({ adapter, value, props }): TimeValidationError => {
+ ValidateTimeProps
+> = ({ adapter, value, timezone, props }): TimeValidationError => {
if (value === null) {
return null;
}
@@ -27,7 +26,6 @@ export const validateTime: Validator<
disableIgnoringDatePartForTimeValidation = false,
disablePast,
disableFuture,
- timezone,
} = props;
const now = adapter.utils.date(undefined, timezone);
@@ -68,3 +66,5 @@ export const validateTime: Validator<
return null;
}
};
+
+validateTime.valueManager = singleItemValueManager;
diff --git a/scripts/x-date-pickers-pro.exports.json b/scripts/x-date-pickers-pro.exports.json
index 809ccdd38ed4d..f50b211610e93 100644
--- a/scripts/x-date-pickers-pro.exports.json
+++ b/scripts/x-date-pickers-pro.exports.json
@@ -34,6 +34,7 @@
{ "name": "DateCalendarSlotProps", "kind": "Interface" },
{ "name": "DateCalendarSlots", "kind": "Interface" },
{ "name": "DateField", "kind": "Variable" },
+ { "name": "DateFieldInPickerProps", "kind": "TypeAlias" },
{ "name": "DateFieldProps", "kind": "TypeAlias" },
{ "name": "DateOrTimeView", "kind": "TypeAlias" },
{ "name": "DatePicker", "kind": "Variable" },
@@ -71,6 +72,7 @@
{ "name": "DateRangeValidationError", "kind": "TypeAlias" },
{ "name": "DateRangeViewRendererProps", "kind": "Interface" },
{ "name": "DateTimeField", "kind": "Variable" },
+ { "name": "DateTimeFieldInPickerProps", "kind": "TypeAlias" },
{ "name": "DateTimeFieldProps", "kind": "TypeAlias" },
{ "name": "DateTimePicker", "kind": "Variable" },
{ "name": "DateTimePickerProps", "kind": "Interface" },
@@ -154,6 +156,7 @@
{ "name": "ExportedPickersYearProps", "kind": "Interface" },
{ "name": "ExportedSlideTransitionProps", "kind": "Interface" },
{ "name": "ExportedUseClearableFieldProps", "kind": "Interface" },
+ { "name": "extractValidationProps", "kind": "Variable" },
{ "name": "FieldFormatTokenMap", "kind": "TypeAlias" },
{ "name": "FieldRef", "kind": "Interface" },
{ "name": "FieldSection", "kind": "Interface" },
@@ -184,6 +187,7 @@
{ "name": "getPickersTextFieldUtilityClass", "kind": "Function" },
{ "name": "getTimeClockUtilityClass", "kind": "Function" },
{ "name": "getYearCalendarUtilityClass", "kind": "Function" },
+ { "name": "InferError", "kind": "TypeAlias" },
{ "name": "LicenseInfo", "kind": "Class" },
{ "name": "LocalizationProvider", "kind": "Variable" },
{ "name": "LocalizationProviderProps", "kind": "Interface" },
@@ -242,6 +246,7 @@
{ "name": "MultiSectionDigitalClockSlotProps", "kind": "Interface" },
{ "name": "MultiSectionDigitalClockSlots", "kind": "Interface" },
{ "name": "NonEmptyDateRange", "kind": "TypeAlias" },
+ { "name": "OnErrorProps", "kind": "Interface" },
{ "name": "PickerChangeHandlerContext", "kind": "Interface" },
{ "name": "PickersActionBar", "kind": "Function" },
{ "name": "PickersActionBarAction", "kind": "TypeAlias" },
@@ -366,6 +371,7 @@
{ "name": "TimeClockSlotProps", "kind": "Interface" },
{ "name": "TimeClockSlots", "kind": "Interface" },
{ "name": "TimeField", "kind": "Variable" },
+ { "name": "TimeFieldInPickerProps", "kind": "TypeAlias" },
{ "name": "TimeFieldProps", "kind": "TypeAlias" },
{ "name": "TimeIcon", "kind": "Variable" },
{ "name": "TimePicker", "kind": "Variable" },
@@ -419,6 +425,20 @@
{ "name": "UseSingleInputTimeRangeFieldProps", "kind": "Interface" },
{ "name": "UseTimeFieldComponentProps", "kind": "TypeAlias" },
{ "name": "UseTimeFieldProps", "kind": "Interface" },
+ { "name": "useValidation", "kind": "Function" },
+ { "name": "validateDate", "kind": "Variable" },
+ { "name": "ValidateDateProps", "kind": "Interface" },
+ { "name": "validateDateRange", "kind": "Variable" },
+ { "name": "ValidateDateRangeProps", "kind": "Interface" },
+ { "name": "validateDateTime", "kind": "Variable" },
+ { "name": "ValidateDateTimeProps", "kind": "Interface" },
+ { "name": "validateDateTimeRange", "kind": "Variable" },
+ { "name": "ValidateDateTimeRangeProps", "kind": "Interface" },
+ { "name": "validateTime", "kind": "Variable" },
+ { "name": "ValidateTimeProps", "kind": "Interface" },
+ { "name": "validateTimeRange", "kind": "Variable" },
+ { "name": "ValidateTimeRangeProps", "kind": "Interface" },
+ { "name": "Validator", "kind": "TypeAlias" },
{ "name": "YearCalendar", "kind": "Variable" },
{ "name": "yearCalendarClasses", "kind": "Variable" },
{ "name": "YearCalendarClasses", "kind": "Interface" },
diff --git a/scripts/x-date-pickers.exports.json b/scripts/x-date-pickers.exports.json
index f816e70b63e67..a3e10847b48a2 100644
--- a/scripts/x-date-pickers.exports.json
+++ b/scripts/x-date-pickers.exports.json
@@ -31,6 +31,7 @@
{ "name": "DateCalendarSlotProps", "kind": "Interface" },
{ "name": "DateCalendarSlots", "kind": "Interface" },
{ "name": "DateField", "kind": "Variable" },
+ { "name": "DateFieldInPickerProps", "kind": "TypeAlias" },
{ "name": "DateFieldProps", "kind": "TypeAlias" },
{ "name": "DateOrTimeView", "kind": "TypeAlias" },
{ "name": "DatePicker", "kind": "Variable" },
@@ -44,6 +45,7 @@
{ "name": "DatePickerToolbarProps", "kind": "Interface" },
{ "name": "DateRangeIcon", "kind": "Variable" },
{ "name": "DateTimeField", "kind": "Variable" },
+ { "name": "DateTimeFieldInPickerProps", "kind": "TypeAlias" },
{ "name": "DateTimeFieldProps", "kind": "TypeAlias" },
{ "name": "DateTimePicker", "kind": "Variable" },
{ "name": "DateTimePickerProps", "kind": "Interface" },
@@ -102,6 +104,7 @@
{ "name": "ExportedPickersYearProps", "kind": "Interface" },
{ "name": "ExportedSlideTransitionProps", "kind": "Interface" },
{ "name": "ExportedUseClearableFieldProps", "kind": "Interface" },
+ { "name": "extractValidationProps", "kind": "Variable" },
{ "name": "FieldFormatTokenMap", "kind": "TypeAlias" },
{ "name": "FieldRef", "kind": "Interface" },
{ "name": "FieldSection", "kind": "Interface" },
@@ -123,6 +126,7 @@
{ "name": "getPickersTextFieldUtilityClass", "kind": "Function" },
{ "name": "getTimeClockUtilityClass", "kind": "Function" },
{ "name": "getYearCalendarUtilityClass", "kind": "Function" },
+ { "name": "InferError", "kind": "TypeAlias" },
{ "name": "LocalizationProvider", "kind": "Variable" },
{ "name": "LocalizationProviderProps", "kind": "Interface" },
{ "name": "LocalizedComponent", "kind": "TypeAlias" },
@@ -157,6 +161,7 @@
{ "name": "MultiSectionDigitalClockSectionClassKey", "kind": "TypeAlias" },
{ "name": "MultiSectionDigitalClockSlotProps", "kind": "Interface" },
{ "name": "MultiSectionDigitalClockSlots", "kind": "Interface" },
+ { "name": "OnErrorProps", "kind": "Interface" },
{ "name": "PickerChangeHandlerContext", "kind": "Interface" },
{ "name": "PickersActionBar", "kind": "Function" },
{ "name": "PickersActionBarAction", "kind": "TypeAlias" },
@@ -265,6 +270,7 @@
{ "name": "TimeClockSlotProps", "kind": "Interface" },
{ "name": "TimeClockSlots", "kind": "Interface" },
{ "name": "TimeField", "kind": "Variable" },
+ { "name": "TimeFieldInPickerProps", "kind": "TypeAlias" },
{ "name": "TimeFieldProps", "kind": "TypeAlias" },
{ "name": "TimeIcon", "kind": "Variable" },
{ "name": "TimePicker", "kind": "Variable" },
@@ -301,6 +307,14 @@
{ "name": "usePickersTranslations", "kind": "Variable" },
{ "name": "UseTimeFieldComponentProps", "kind": "TypeAlias" },
{ "name": "UseTimeFieldProps", "kind": "Interface" },
+ { "name": "useValidation", "kind": "Function" },
+ { "name": "validateDate", "kind": "Variable" },
+ { "name": "ValidateDateProps", "kind": "Interface" },
+ { "name": "validateDateTime", "kind": "Variable" },
+ { "name": "ValidateDateTimeProps", "kind": "Interface" },
+ { "name": "validateTime", "kind": "Variable" },
+ { "name": "ValidateTimeProps", "kind": "Interface" },
+ { "name": "Validator", "kind": "TypeAlias" },
{ "name": "YearCalendar", "kind": "Variable" },
{ "name": "yearCalendarClasses", "kind": "Variable" },
{ "name": "YearCalendarClasses", "kind": "Interface" },